aboutsummaryrefslogtreecommitdiff
path: root/modules/test/test-vfs-checkpoint.js
blob: 03a8c8a30a852351ef2134c4d1759d6f39c2d3c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// modules/test/test-vfs-checkpoint.js — run: node modules/test/test-vfs-checkpoint.js
// Proves the name a checkpoint is SAVED under is the name the UI prints and the name
// `rollback` resolves. RED on v4.6.101: two independent new Date().toISOString() calls
// made the printed name differ from the stored one, so `checkpoint` then
// `rollback <printed name>` failed with "checkpoint not found or invalid".
const fsMod = require('fs'), path = require('path');
const ROOT = path.join(__dirname, '..', 'core');

// ── guarded stubs for the browser globals the VFS touches ──────────────────
const ls = {};
global.localStorage = {
    getItem: k => (k in ls ? ls[k] : null),
    setItem: (k, v) => { ls[k] = String(v); },
    removeItem: k => { delete ls[k]; },
};
global.indexedDB = {
    open() { throw new Error('indexedDB not available in test'); },
    deleteDatabase() { throw new Error('indexedDB not available in test'); },
};
global.window = global;

function loadClass(file, clsName) {
    const src = fsMod.readFileSync(path.join(ROOT, file), 'utf8');
    return new Function(src + '\nreturn ' + clsName + ';')();
}
const VirtualFileSystem = loadClass('virtual-fs.js', 'VirtualFileSystem');
const SystemModule = loadClass('module-system.js', 'SystemModule');

function mkFs() {
    const fs = new VirtualFileSystem();
    fs.saveToStorage = () => true;      // isolate from timers / compression
    return fs;
}

let fails = 0, passes = 0;
function ok(name, cond, detail) {
    if (cond) { passes++; return; }
    fails++;
    console.log('FAIL ' + name + (detail ? ' — ' + detail : ''));
}

// A. checkpoint('') must return the resolved name, and two calls must differ
{
    const fs = mkFs();
    const a = fs.checkpoint('');
    const b = fs.checkpoint('');
    ok('A1 checkpoint returns a name string', typeof a === 'string' && a.length > 0, 'got ' + typeof a + ' ' + a);
    ok('A2 second name also a string', typeof b === 'string' && b.length > 0, 'got ' + typeof b);
    ok('A3 two unnamed checkpoints get distinct names', a !== b, 'both=' + a);
    ok('A4 stored under the returned name', !!fs.fsReadJSON('/_snapshots/checkpoint-' + a + '.json'));
}

// B. rollback with the returned name must succeed
{
    const fs = mkFs();
    fs.mkdirRecursive('/marker');
    const name = fs.checkpoint('');
    ok('B1 checkpoint-list shows the returned name', fs.listCheckpoints().includes(name), 'name=' + name);
    ok('B2 rollback(returned name) is true', fs.rollback(name) === true, 'name=' + name);
}

// C. the `checkpoint` command prints exactly the name it created
{
    const fsv = mkFs();
    const out = [];
    const sys = new SystemModule();
    sys.terminal = { print: m => out.push(String(m)), fs: fsv };
    sys.registerCommands();

    out.length = 0;
    sys.commands['checkpoint']([]);
    const line = out.join('\n');
    const printed = (line.match(/Checkpoint created:\s*(.+)$/m) || [])[1];
    ok('C1 command prints a created name', !!printed, 'output=' + JSON.stringify(line));
    const listed = fsv.listCheckpoints();
    ok('C2 printed name exists on disk', !!printed && listed.includes(printed.trim()),
        'printed=' + printed + ' listed=' + JSON.stringify(listed));
    ok('C3 rollback of the printed name succeeds', !!printed && fsv.rollback(printed.trim()) === true);

    // C4: an explicit name is echoed verbatim
    out.length = 0;
    sys.commands['checkpoint'](['myname']);
    ok('C4 explicit name echoed verbatim', /Checkpoint created:\s*myname\s*$/.test(out.join('\n')),
        'output=' + JSON.stringify(out.join('\n')));
}

if (fails === 0) {
    console.log('test-vfs-checkpoint: ' + passes + ' passed, 0 failed');
} else {
    console.log('test-vfs-checkpoint: ' + passes + ' passed, ' + fails + ' FAILED');
    process.exit(1);
}