This commit is contained in:
+4
-2
@@ -32,7 +32,9 @@ function atomicWriteFileSync(file, data) {
|
||||
}
|
||||
|
||||
function writeJsonSync(file, obj) {
|
||||
atomicWriteFileSync(file, JSON.stringify(obj, null, 2) + '\n');
|
||||
const json = JSON.stringify(obj, null, 2);
|
||||
if (json === undefined) throw new TypeError(`writeJsonSync: value for ${file} is not JSON-serializable`);
|
||||
atomicWriteFileSync(file, json + '\n');
|
||||
}
|
||||
|
||||
function readJsonSync(file) {
|
||||
@@ -43,7 +45,7 @@ function readJsonIfExists(file, fallback) {
|
||||
try {
|
||||
return readJsonSync(file);
|
||||
} catch (err) {
|
||||
if (err.code === 'ENOENT') return fallback;
|
||||
if (err.code === 'ENOENT' || err instanceof SyntaxError) return fallback;
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,6 +78,11 @@ Initial release.
|
||||
earlier) and use it for the click-marker placement, and the
|
||||
click-capture cache is armed as soon as recording starts so the very
|
||||
first click is captured instantly.
|
||||
- Settings no longer fails to open if `app-settings.json` or
|
||||
`placeholders.json` was previously corrupted (e.g. left containing the
|
||||
literal text "undefined" by an old bug); a corrupted file is now
|
||||
treated as empty instead of crashing the dialog, and is overwritten
|
||||
with valid JSON the next time settings are saved.
|
||||
|
||||
### Added (initial feature set)
|
||||
|
||||
|
||||
@@ -3,12 +3,16 @@
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
const {
|
||||
systemPlaceholders, resolveScopes, expandPlaceholders,
|
||||
listPlaceholders, collectGuidePlaceholders,
|
||||
} = require('../../core/placeholders');
|
||||
const { createGuide, createStep } = require('../../core/schema');
|
||||
const { Settings, DEFAULT_SETTINGS } = require('../../core/settings');
|
||||
const { writeJsonSync } = require('../../core/util');
|
||||
const { makeTmpDir, rmrf } = require('./helpers');
|
||||
|
||||
test('placeholder expansion respects guide > global > system precedence', () => {
|
||||
@@ -61,3 +65,29 @@ test('settings persist, deep-merge with defaults, and store global placeholders'
|
||||
assert.equal(s2.get('capture.clickMarker'), DEFAULT_SETTINGS.capture.clickMarker);
|
||||
assert.deepEqual(s2.getGlobalPlaceholders(), { Company: 'Acme', Author: 'Tyler' });
|
||||
});
|
||||
|
||||
test('a corrupted placeholders/settings file falls back instead of crashing the settings dialog', (t) => {
|
||||
const dir = makeTmpDir('settings-corrupt');
|
||||
t.after(() => rmrf(dir));
|
||||
|
||||
// Simulate a file left over from a past bug: literal "undefined" instead of JSON.
|
||||
fs.writeFileSync(path.join(dir, 'placeholders.json'), 'undefined\n');
|
||||
fs.writeFileSync(path.join(dir, 'app-settings.json'), 'undefined\n');
|
||||
|
||||
const s = new Settings(dir);
|
||||
assert.deepEqual(s.getGlobalPlaceholders(), {});
|
||||
assert.equal(s.get('appearance'), DEFAULT_SETTINGS.appearance);
|
||||
|
||||
// Saving afterwards overwrites the corrupted file with valid JSON.
|
||||
s.setGlobalPlaceholders({ Author: 'Tyler' });
|
||||
assert.deepEqual(s.getGlobalPlaceholders(), { Author: 'Tyler' });
|
||||
});
|
||||
|
||||
test('writeJsonSync refuses to write a non-JSON value instead of writing the literal string "undefined"', () => {
|
||||
const dir = makeTmpDir('write-json-guard');
|
||||
try {
|
||||
assert.throws(() => writeJsonSync(path.join(dir, 'bad.json'), undefined), TypeError);
|
||||
} finally {
|
||||
rmrf(dir);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user