$NJS_BUILD_DIR/lvlhsh_unit_test
$NJS_BUILD_DIR/unicode_unit_test
+test262: njs
+
+ test/test262
+
unit_test: $NJS_BUILD_DIR/njs_auto_config.h \\
$NJS_BUILD_DIR/njs_unit_test
$NJS_BUILD_DIR/njs_unit_test
-test: expect_test unit_test
+test: expect_test unit_test test262
benchmark: $NJS_BUILD_DIR/njs_auto_config.h \\
$NJS_BUILD_DIR/njs_benchmark
--- /dev/null
+#!/bin/sh
+
+# Copyright (C) Dmitry Volyntsev
+# Copyright (C) NGINX, Inc.
+
+if [ -z "$NJS_TEST_VERBOSE" ]; then
+ verbose "Removing dir: $NJS_TEST_DIR\n"
+ verbose "\n"
+
+ rm -fr $NJS_TEST_DIR
+fi
-var fs = require('fs');
-
-async function run(tlist) {
- function validate(t, r, i) {
- if (r.status == "fulfilled") {
- return r.value === "SUCCESS";
- }
-
- if (r.status == "rejected" && t[i].exception) {
- if (process.argv[2] === '--match-exception-text') {
- /* is not compatible with node.js format */
- return r.reason.toString().startsWith(t[i].exception);
- }
-
- return true;
- }
-
- if (r.status == "rejected" && t[i].optional) {
- return r.reason.toString().startsWith("Error: No such file or directory");
- }
-
- return false;
- }
-
- for (let k = 0; k < tlist.length; k++) {
- let ts = tlist[k];
- let results = await Promise.allSettled(ts.tests.map(t => ts.T(ts.prepare_args(t, ts.opts))));
- let r = results.map((r, i) => validate(ts.tests, r, i));
-
- console.log(`${ts.name} ${r.every(v=>v == true) ? "SUCCESS" : "FAILED"}`);
-
- r.forEach((v, i) => {
- if (!v) {
- console.log(`FAILED ${i}: ${JSON.stringify(ts.tests[i])}\n with reason: ${results[i].reason}`);
- }
- })
- }
-}
+/*---
+includes: [compatFs.js, compatBuffer.js, runTsuite.js]
+flags: [async]
+---*/
function p(args, default_opts) {
let params = Object.assign({}, default_opts, args);
switch (params.type) {
case "sync":
- try {
- data = fs[name + "Sync"].apply(null, params.args);
-
- } catch (e) {
- if (!params.stringify) {
- throw e;
- }
-
- data = Buffer.from(JSON.stringify(e));
- }
-
+ data = fs[name + "Sync"].apply(null, params.args);
break;
case "callback":
- data = await promisify(fs[name]).apply(null, params.args)
- .catch(e => {
- if (!params.stringify) {
- throw e;
- }
-
- return Buffer.from(JSON.stringify(e));
- });
-
+ data = await promisify(fs[name]).apply(null, params.args);
break;
case "promise":
- data = await fs.promises[name].apply(null, params.args)
- .catch(e => {
- if (!params.stringify) {
- throw e;
- }
-
- return Buffer.from(JSON.stringify(e));
- });
-
+ data = await fs.promises[name].apply(null, params.args);
break;
}
}
async function read_test(params) {
- let data = await method("readFile", params);
+ let data = await method("readFile", params).catch(e => ({error:e}));
- if (params.slice) {
+ if (params.slice && !data.error) {
data = data.slice.apply(data, params.slice);
}
- let success = true;
- if (data instanceof Buffer) {
- if (data.compare(params.expected) != 0) {
- success = false;
+ if (params.check) {
+ if (!params.check(data, params)) {
+ throw Error(`readFile failed check`);
}
- } else if (data != params.expected) {
- success = false;
- }
+ } else if (params.exception) {
+ throw data.error;
+
+ } else {
+ let success = true;
+ if (data instanceof Buffer) {
+ if (data.compare(params.expected) != 0) {
+ success = false;
+ }
+
+ } else if (data != params.expected) {
+ success = false;
+ }
- if (!success) {
- throw Error(`readFile unexpected data`);
+ if (!success) {
+ throw Error(`readFile unexpected data`);
+ }
}
return 'SUCCESS';
}
-let read_tests = [
+let read_tests = () => [
{ args: ["test/fs/utf8"], expected: Buffer.from("αβZγ") },
{ args: [Buffer.from("@test/fs/utf8").slice(1)], expected: Buffer.from("αβZγ") },
{ args: ["test/fs/utf8", "utf8"], expected: "αβZγ" },
{ args: ["test/fs/utf8", {encoding: "utf8", flags:"r+"}], expected: "αβZγ" },
- { args: ["test/fs/nonexistent"], stringify: true,
- expected: Buffer.from('{"errno":2,"code":"ENOENT","path":"test/fs/nonexistent","syscall":"open"}'),
- exception: "Error: No such file or directory" },
+ { args: ["test/fs/nonexistent"],
+ check: (err, params) => {
+ let e = err.error;
+
+ if (e.syscall != 'open') {
+ throw Error(`${e.syscall} unexpected syscall`);
+ }
+
+ if (e.code != "ENOENT") {
+ throw Error(`${e.code} unexpected code`);
+ }
+
+ if (e.path != "test/fs/nonexistent") {
+ throw Error(`${e.path} unexpected path`);
+ }
+
+ return true;
+ } },
+
{ args: ["test/fs/non_utf8", "utf8"], expected: "��" },
{ args: ["test/fs/non_utf8", {encoding: "hex"}], expected: "8080" },
{ args: ["test/fs/non_utf8", "base64"], expected: "gIA=" },
{ args: [Buffer.from([0x80, 0x80])], exception: "Error: No such file or directory" },
{ args: ['x'.repeat(8192)], exception: "TypeError: \"path\" is too long" },
- { args: ["/proc/version"], slice:[0,5], expected: Buffer.from("Linux"), optional: true },
- { args: ["/proc/cpuinfo"], slice:[0,9], expected: Buffer.from("processor"), optional: true },
+ { args: ["/proc/version"], slice:[0,5], expected: Buffer.from("Linux"),
+ check: (data, params) => {
+
+ if (data.error) {
+ let e = data.error;
+ if (e.syscall != 'open') {
+ throw Error(`${e.syscall} unexpected syscall`);
+ }
+
+ return true;
+ }
+
+ return data.compare(params.expected) == 0;
+ } },
+ { args: ["/proc/cpuinfo"], slice:[0,9], expected: Buffer.from("processor"),
+ check: (data, params) => {
+
+ if (data.error) {
+ let e = data.error;
+ if (e.syscall != 'open') {
+ throw Error(`${e.syscall} unexpected syscall`);
+ }
+
+ return true;
+ }
+
+ return data.compare(params.expected) == 0;
+ } },
];
let readFile_tsuite = {
name: "fs readFile",
+ skip: () => (!has_fs() || !has_buffer()),
T: read_test,
prepare_args: p,
opts: { type: "callback" },
- tests: read_tests,
+ get tests() { return read_tests() },
};
let readFileSync_tsuite = {
name: "fs readFileSync",
+ skip: () => (!has_fs() || !has_buffer()),
T: read_test,
prepare_args: p,
opts: { type: "sync" },
- tests: read_tests,
+ get tests() { return read_tests() },
};
let readFileP_tsuite = {
name: "fsp readFile",
+ skip: () => (!has_fs() || !has_buffer()),
T: read_test,
prepare_args: p,
opts: { type: "promise" },
- tests: read_tests,
+ get tests() { return read_tests() },
};
async function write_test(params) {
return 'SUCCESS';
}
-let write_tests = [
+let write_tests = () => [
{ args: ["@", Buffer.from(Buffer.alloc(4).fill(65).buffer, 1)],
expected: Buffer.from("AAA") },
{ args: ["@", Buffer.from("XYZ"), "utf8"], expected: Buffer.from("XYZ") },
let writeFile_tsuite = {
name: "fs writeFile",
+ skip: () => (!has_fs() || !has_buffer()),
T: write_test,
prepare_args: p,
opts: { type: "callback" },
- tests: write_tests,
+ get tests() { return write_tests() },
};
let writeFileSync_tsuite = {
name: "fs writeFileSync",
+ skip: () => (!has_fs() || !has_buffer()),
T: write_test,
prepare_args: p,
opts: { type: "sync" },
- tests: write_tests,
+ get tests() { return write_tests() },
};
let writeFileP_tsuite = {
name: "fsp writeFile",
+ skip: () => (!has_fs() || !has_buffer()),
T: write_test,
prepare_args: p,
opts: { type: "promise" },
- tests: write_tests,
+ get tests() { return write_tests() },
};
async function append_test(params) {
return 'SUCCESS';
}
-let append_tests = [
+let append_tests = () => [
{ args: ["@", Buffer.from(Buffer.alloc(4).fill(65).buffer, 1)],
expected: Buffer.from("AAAAAA") },
{ args: ["@", Buffer.from("XYZ"), "utf8"], expected: Buffer.from("XYZXYZ") },
let appendFile_tsuite = {
name: "fs appendFile",
+ skip: () => (!has_fs() || !has_buffer()),
T: append_test,
prepare_args: p,
opts: { type: "callback" },
- tests: append_tests,
+ get tests() { return append_tests() },
};
let appendFileSync_tsuite = {
name: "fs appendFileSync",
+ skip: () => (!has_fs() || !has_buffer()),
T: append_test,
prepare_args: p,
opts: { type: "sync" },
- tests: append_tests,
+ get tests() { return append_tests() },
};
let appendFileP_tsuite = {
name: "fsp appendFile",
+ skip: () => (!has_fs() || !has_buffer()),
T: append_test,
prepare_args: p,
opts: { type: "promise" },
- tests: append_tests,
+ get tests() { return append_tests() },
};
async function realpath_test(params) {
return 'SUCCESS';
}
-let realpath_tests = [
- { args: ["./build/test/.."],
+let realpath_tests = () => [
+ { args: ["build/test/.."],
check: (data) => data.endsWith("build") },
- { args: ["./build/test/", {encoding:'buffer'}],
+ { args: ["build/test/", {encoding:'buffer'}],
check: (data) => data instanceof Buffer },
];
let realpath_tsuite = {
name: "fs realpath",
+ skip: () => (!has_fs() || !has_buffer()),
T: realpath_test,
prepare_args: p,
opts: { type: "callback" },
- tests: realpath_tests,
+ get tests() { return realpath_tests() },
};
let realpathSync_tsuite = {
name: "fs realpathSync",
+ skip: () => (!has_fs() || !has_buffer()),
T: realpath_test,
prepare_args: p,
opts: { type: "sync" },
- tests: realpath_tests,
+ get tests() { return realpath_tests() },
};
let realpathP_tsuite = {
name: "fsp realpath",
+ skip: () => (!has_fs() || !has_buffer()),
T: realpath_test,
prepare_args: p,
opts: { type: "promise" },
- tests: realpath_tests,
+ get tests() { return realpath_tests() },
};
async function stat_test(params) {
});
}
-let stat_tests = [
+let stat_tests = () => [
{ args: ["/invalid_path"],
check: (err, params) => {
let e = err.error;
return true;
} },
- { args: ["./build/"],
+ { args: ["build/"],
check: (st) => contains(Object.keys(st),
[ "atime", "atimeMs", "birthtime", "birthtimeMs",
"blksize", "blocks", "ctime", "ctimeMs", "dev",
"gid", "ino", "mode", "mtime", "mtimeMs","nlink",
"rdev", "size", "uid" ]) },
- { args: ["./build/"],
+ { args: ["build/"],
check: (st) => Object.keys(st).every(p => {
let v = st[p];
if (p == 'atime' || p == 'ctime' || p == 'mtime' || p == 'birthtime') {
return true;
}) },
- { args: ["./build/"],
+ { args: ["build/"],
check: (st) => ['atime', 'birthtime', 'ctime', 'mtime'].every(p => {
let date = st[p].valueOf();
let num = st[p + 'Ms'];
return true;
}) },
- { args: ["./build/"],
+ { args: ["build/"],
check: (st) => ['isBlockDevice',
'isCharacterDevice',
'isDirectory',
let stat_tsuite = {
name: "fs stat",
+ skip: () => (!has_fs() || !has_buffer()),
T: stat_test,
prepare_args: p,
opts: { type: "callback", method: "stat" },
- tests: stat_tests,
+ get tests() { return stat_tests() },
};
let statSync_tsuite = {
name: "fs statSync",
+ skip: () => (!has_fs() || !has_buffer()),
T: stat_test,
prepare_args: p,
opts: { type: "sync", method: "stat" },
- tests: stat_tests,
+ get tests() { return stat_tests() },
};
let statP_tsuite = {
name: "fsp stat",
+ skip: () => (!has_fs() || !has_buffer()),
T: stat_test,
prepare_args: p,
opts: { type: "promise", method: "stat" },
- tests: stat_tests,
+ get tests() { return stat_tests() },
};
let lstat_tsuite = {
name: "fs lstat",
+ skip: () => (!has_fs() || !has_buffer()),
T: stat_test,
prepare_args: p,
opts: { type: "callback", method: "lstat" },
- tests: stat_tests,
+ get tests() { return stat_tests() },
};
let lstatSync_tsuite = {
name: "fs lstatSync",
+ skip: () => (!has_fs() || !has_buffer()),
T: stat_test,
prepare_args: p,
opts: { type: "sync", method: "lstat" },
- tests: stat_tests,
+ get tests() { return stat_tests() },
};
let lstatP_tsuite = {
name: "fsp lstat",
+ skip: () => (!has_fs() || !has_buffer()),
T: stat_test,
prepare_args: p,
opts: { type: "promise", method: "lstat" },
- tests: stat_tests,
+ get tests() { return stat_tests() },
};
run([
lstat_tsuite,
lstatSync_tsuite,
lstatP_tsuite,
-]);
+])
+.then($DONE, $DONE);
--- /dev/null
+/*---
+includes: [compareArray.js, compatFs.js]
+flags: [async]
+---*/
+
+var fname = 'build/test/fs_promises_01';
+
+let stages = [];
+
+Promise.resolve()
+.then(() => {
+ return fsp.writeFile(fname, fname);
+})
+.then(data => {
+ stages.push('init');
+ assert.sameValue(data, undefined, 'init');
+})
+.then(() => {
+ return fsp.readFile(fname).then(fsp.readFile);
+})
+.then(data => {
+ stages.push('short circut');
+ assert.sameValue(data.toString(), fname, 'short circut');
+})
+.then(() => {
+ var read = fsp.readFile.bind(fsp, fname, 'utf8');
+ var write = fsp.writeFile.bind(fsp, fname);
+ var append = fsp.appendFile.bind(fsp, fname);
+
+ return write(fname).then(read).then(append).then(read);
+})
+.then(data => {
+ stages.push('chain');
+ assert.sameValue(data, fname + fname, 'chain');
+})
+.then(() => {
+ stages.push('errors ok');
+})
+.then(() => {
+ assert.compareArray(stages, ["init", "short circut", "chain", "errors ok"]);
+})
+.then($DONE, $DONE);
-var fs = require('fs');
-var fsp = fs.promises;
-var fname = './build/test/fs_promises_002';
+/*---
+includes: [compareArray.js, compatFs.js]
+flags: [async]
+---*/
+
+var fname = 'build/test/fs_promises_02';
var testSync = new Promise((resolve, reject) => {
var failed = false;
} catch(e) {
failed = (e.syscall != 'access') || e.code != 'ENOENT';
}
- resolve(failed);
+ resolve(Boolean(failed));
} catch (e) {
reject(e);
}
fs.access(fname + '___', (err) => {
failed |= ((err === undefined) || (err.syscall != 'access')
|| err.code != 'ENOENT');
- resolve(failed);
+ resolve(Boolean(failed));
});
});
});
});
+let stages = [];
+
Promise.resolve()
.then(() => testSync)
-.then((failed) => {
- console.log('testSync ok', !failed);
-})
-.catch((e) => {
- console.log('testSync failed', e);
+.then(failed => {
+ stages.push('testSync');
+ assert.sameValue(failed, false, 'testSync');
})
.then(() => testCallback)
-.then((failed) => {
- console.log('testCallback ok', !failed);
-})
-.catch((e) => {
- console.log('testCallback failed', e);
+.then(failed => {
+ stages.push('testCallback');
+ assert.sameValue(failed, false, 'testCallback');
})
.then(() => {
fs.writeFileSync(fname, fname);
.then(() => fsp.access(fname + '___'));
})
.then(() => {
- console.log('testPromise failed');
+ $DONOTEVALUATE();
+})
+.catch(e => {
+ stages.push('testPromise');
+ assert.sameValue(e.syscall, 'access', 'testPromise');
+ assert.sameValue(e.path, fname + '___', 'testPromise');
+ assert.sameValue(e.code, 'ENOENT', 'testPromise');
})
-.catch((e) => {
- console.log('testPromise ok', (e.syscall == 'access') && (e.path == fname + '___')
- && e.code == 'ENOENT');
+.then(() => {
+ assert.compareArray(stages, ["testSync", "testCallback", "testPromise"]);
})
-;
+.then($DONE, $DONE);
-var fs = require('fs');
-var fsp = fs.promises;
-var fname = './build/test/fs_promises_003';
+/*---
+includes: [compareArray.js, compatFs.js]
+flags: [async]
+---*/
+var fname = 'build/test/fs_promises_03';
var testSync = () => new Promise((resolve, reject) => {
try {
});
});
+let stages = [];
Promise.resolve()
.then(testSync)
.then(() => {
- console.log('test fs.unlinkSync');
-})
-.catch((e) => {
- console.log('test fs.unlinkSync failed', e);
+ stages.push("unlinkSync");
})
.then(testCallback)
.then(() => {
- console.log('test fs.unlink');
-})
-.catch((e) => {
- console.log('test fs.unlink failed', e);
+ stages.push("unlink");
})
.then(() => fsp.unlink(fname)
.catch((e) => { if (e.syscall != 'access') { throw e; } })
.then(() => {
- console.log('test fsp.unlink');
+ stages.push("fsp.unlink");
})
-.catch((e) => {
- console.log('test fsp.unlink failed', e);
-});
+.then(() => assert.compareArray(stages, ['unlinkSync', 'unlink', 'fsp.unlink']))
+.then($DONE, $DONE);
-var fs = require('fs');
-var fsp = fs.promises;
-var dname = './build/test/';
-var fname = dname + 'fs_promises_004';
-var fname_utf8 = dname + 'fs_promises_αβγ_004';
-var lname = dname + 'fs_promises_004_lnk';
+/*---
+includes: [compareArray.js, compatFs.js]
+flags: [async]
+---*/
+var dname = 'build/test/';
+var fname = dname + 'fs_promises_04';
+var fname_utf8 = dname + 'fs_promises_αβγ_04';
+var lname = dname + 'fs_promises_04_lnk';
var testSync = () => new Promise((resolve, reject) => {
try {
}
var rname_utf8 = fs.realpathSync(fname_utf8);
- if (rname_utf8.slice(-7,-4) != 'αβγ') {
+ if (rname_utf8.slice(-6,-3) != 'αβγ') {
throw new Error('fs.realpathSync error 2');
}
}
});
+let stages = [];
Promise.resolve()
.then(testSync)
.then(() => {
- console.log('test fs.symlinkSync');
-})
-.catch((e) => {
- console.log('test fs.symlinkSync failed', e);
+ stages.push("symlinkSync");
})
.then(testCallback)
.then(() => {
- console.log('test fs.symlink');
-})
-.catch((e) => {
- console.log('test fs.symlink failed', e);
+ stages.push("symlink");
})
.then(() => fsp.unlink(fname)
.then((rname) => fsp.realpath(lname)
.then((xname) => {
if (rname != xname) {
- throw new Error('fsp.symlink error 2');
+ throw new Error(`fsp.symlink error 2`);
}
}))
.then(() => {
})
.then(() => {
- console.log('test fsp.symlink');
+ stages.push("fsp.symlink");
})
-.catch((e) => {
- console.log('test fsp.symlink failed', e);
-});
+.then(() => assert.compareArray(stages, ['symlinkSync', 'symlink', 'fsp.symlink']))
+.then($DONE, $DONE);
-var fs = require('fs');
-var fsp = fs.promises;
-var rname = './build/test/';
-var dname = rname + 'fs_promises_005';
-var dname_utf8 = rname + 'fs_promises_αβγ_005';
-var fname = (d) => d + '/fs_promises_005_file';
+/*---
+includes: [compareArray.js, compatFs.js]
+flags: [async]
+---*/
+var rname = 'build/test/';
+var dname = rname + 'fs_promises_05';
+var dname_utf8 = rname + 'fs_promises_αβγ_05';
+var fname = (d) => d + '/fs_promises_05_file';
var testSync = () => new Promise((resolve, reject) => {
try {
});
+let stages = [];
+
Promise.resolve()
.then(testSync)
.then(() => {
- console.log('test fs.mkdirSync');
-})
-.catch((e) => {
- console.log('test fs.mkdirSync failed', JSON.stringify(e));
+ stages.push("mkdirSync");
})
+
.then(testCallback)
.then(() => {
- console.log('test fs.mkdir');
-})
-.catch((e) => {
- console.log('test fs.mkdir failed', JSON.stringify(e));
+ stages.push("mkdir");
})
.then(() => {
})
.then(() => fsp.rmdir(dname))
.then(() => {
- console.log('test fsp.mkdir');
+ stages.push("fsp.mkdir");
})
-.catch((e) => {
- console.log('test fsp.mkdir failed', JSON.stringify(e));
-});
+.then(() => assert.compareArray(stages, ['mkdirSync', 'mkdir', 'fsp.mkdir']))
+.then($DONE, $DONE);
-var fs = require('fs');
-var fsp = fs.promises;
-var dname = './build/test/';
-var fname = (d) => d + '/fs_promises_006_file';
-var fname_utf8 = (d) => d + '/fs_promises_αβγ_006';
+/*---
+includes: [compareArray.js, compatFs.js]
+flags: [async]
+---*/
+
+var dname = 'build/test/';
+var fname = (d) => d + '/fs_promises_06_file';
+var fname_utf8 = (d) => d + '/fs_promises_αβγ_06';
var testSync = new Promise((resolve, reject) => {
try {
}
});
+let stages = [];
+
Promise.resolve()
.then(() => testSync)
.then(() => {
- console.log('test fs.renameSync');
-})
-.catch((e) => {
- console.log('test fs.renameSync failed', JSON.stringify(e));
+ stages.push("renameSync");
})
.then(testCallback)
.then(() => {
- console.log('test fs.rename');
+ stages.push("rename");
})
.catch((e) => {
console.log('test fs.rename failed', JSON.stringify(e));
}
})
.then(() => {
- console.log('test fsp.rename');
+ stages.push("fsp.rename");
})
-.catch((e) => {
- console.log('test fsp.rename failed', JSON.stringify(e));
-});
+.then(() => assert.compareArray(stages, ["renameSync", "rename", "fsp.rename"]))
+.then($DONE, $DONE);
-var fs = require('fs');
-var fsp = fs.promises;
-var dname = './build/test/fs_promises_007';
-var dname_utf8 = './build/test/fs_promises_αβγ_007';
-var fname = (d) => d + '/fs_promises_007_file';
-var lname = (d) => d + '/fs_promises_007_link';
-var cname = (d) => d + '/fs_promises_αβγ_007_dir';
+/*---
+includes: [compareArray.js, compatFs.js]
+flags: [async]
+---*/
+
+var dname = 'build/test/fs_promises_07';
+var dname_utf8 = 'build/test/fs_promises_αβγ_07';
+var fname = (d) => d + '/fs_promises_07_file';
+var lname = (d) => d + '/fs_promises_07_link';
+var cname = (d) => d + '/fs_promises_αβγ_07_dir';
var dir_test = [cname(''), lname(''), fname('')].map((x) => x.substring(1));
});
+let stages = [];
+
Promise.resolve()
.then(testSync)
.then(() => {
- console.log('test fs.readdirSync');
-})
-.catch((e) => {
- console.log('test fs.readdirSync failed', e, JSON.stringify(e));
+ stages.push("readdirSync");
})
.then(testCallback)
.then(() => {
- console.log('test fs.readdir');
-})
-.catch((e) => {
- console.log('test fs.readdir failed', e, JSON.stringify(e));
+ stages.push("readdir");
})
.then(() => {
}
})
.then(() => {
- console.log('test fsp.readdir');
+ stages.push("fsp.readdir");
})
-.catch((e) => {
- console.log('test fsp.readdir failed', e, JSON.stringify(e));
-});
+.then(() => assert.compareArray(stages, ["readdirSync", "readdir", "fsp.readdir"]))
+.then($DONE, $DONE);
-var fs = require('fs');
-var fsp = fs.promises;
-var dname = './build/test/fs_promises_αβγ_008/';
+/*---
+includes: [compareArray.js, compatFs.js]
+flags: [async]
+---*/
+
+var dname = 'build/test/fs_promises_αβγ_08/';
var path = 'one/two/three/αβγ';
var wipePath = (root, path, nofail) => {
}
});
+let stages = [];
+
Promise.resolve()
.then(testSync)
.then(() => {
- console.log('test recursive fs.mkdirSync');
+ stages.push("mkdirSync");
})
.catch((e) => {
- console.log('test failed recursive fs.mkdirSync', JSON.stringify(e));
+ $DONOTEVALUATE();
})
+.then(() => assert.compareArray(stages, ["mkdirSync"]))
+.then($DONE, $DONE);
-var fs = require('fs');
-var fsp = fs.promises;
-var root = './build/test/';
-var dname = 'fs_promises_αβγ_009/';
-var lname = 'fs_promises_αβγ_009_lnk';
+/*---
+includes: [compareArray.js, compatFs.js]
+flags: [async]
+---*/
+
+var root = 'build/test/';
+var dname = 'fs_promises_αβγ_09/';
+var lname = 'fs_promises_αβγ_09_lnk';
var path = 'one/two/three/αβγ';
-
var setContent = (root, path) => {
fs.mkdirSync(root + path, { recursive: true });
path
});
+let stages = [];
+
Promise.resolve()
.then(testSync)
.then(() => {
- console.log('test recursive fs.rmdirSync()');
+ stages.push("rmdirSync");
})
-.catch((e) => {
- console.log('test failed recursive fs.rmdirSync()', e.message, JSON.stringify(e));
-});
+.then(() => assert.compareArray(stages, ["rmdirSync"]))
+.then($DONE, $DONE);
--- /dev/null
+// Copyright (C) 2017 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+ Collection of assertion functions used throughout test262
+defines: [assert]
+---*/
+
+
+function assert(mustBeTrue, message) {
+ if (mustBeTrue === true) {
+ return;
+ }
+
+ if (message === undefined) {
+ message = 'Expected true but got ' + assert._toString(mustBeTrue);
+ }
+ throw new Test262Error(message);
+}
+
+assert._isSameValue = function (a, b) {
+ if (a === b) {
+ // Handle +/-0 vs. -/+0
+ return a !== 0 || 1 / a === 1 / b;
+ }
+
+ // Handle NaN vs. NaN
+ return a !== a && b !== b;
+};
+
+assert.sameValue = function (actual, expected, message) {
+ try {
+ if (assert._isSameValue(actual, expected)) {
+ return;
+ }
+ } catch (error) {
+ throw new Test262Error(message + ' (_isSameValue operation threw) ' + error);
+ return;
+ }
+
+ if (message === undefined) {
+ message = '';
+ } else {
+ message += ' ';
+ }
+
+ message += 'Expected SameValue(«' + assert._toString(actual) + '», «' + assert._toString(expected) + '») to be true';
+
+ throw new Test262Error(message);
+};
+
+assert.notSameValue = function (actual, unexpected, message) {
+ if (!assert._isSameValue(actual, unexpected)) {
+ return;
+ }
+
+ if (message === undefined) {
+ message = '';
+ } else {
+ message += ' ';
+ }
+
+ message += 'Expected SameValue(«' + assert._toString(actual) + '», «' + assert._toString(unexpected) + '») to be false';
+
+ throw new Test262Error(message);
+};
+
+assert.throws = function (expectedErrorConstructor, func, message) {
+ var expectedName, actualName;
+ if (typeof func !== "function") {
+ throw new Test262Error('assert.throws requires two arguments: the error constructor ' +
+ 'and a function to run');
+ return;
+ }
+ if (message === undefined) {
+ message = '';
+ } else {
+ message += ' ';
+ }
+
+ try {
+ func();
+ } catch (thrown) {
+ if (typeof thrown !== 'object' || thrown === null) {
+ message += 'Thrown value was not an object!';
+ throw new Test262Error(message);
+ } else if (thrown.constructor !== expectedErrorConstructor) {
+ expectedName = expectedErrorConstructor.name;
+ actualName = thrown.constructor.name;
+ if (expectedName === actualName) {
+ message += 'Expected a ' + expectedName + ' but got a different error constructor with the same name';
+ } else {
+ message += 'Expected a ' + expectedName + ' but got a ' + actualName;
+ }
+ throw new Test262Error(message);
+ }
+ return;
+ }
+
+ message += 'Expected a ' + expectedErrorConstructor.name + ' to be thrown but no exception was thrown at all';
+ throw new Test262Error(message);
+};
+
+assert._toString = function (value) {
+ try {
+ if (value === 0 && 1 / value === -Infinity) {
+ return '-0';
+ }
+
+ return String(value);
+ } catch (err) {
+ if (err.name === 'TypeError') {
+ return Object.prototype.toString.call(value);
+ }
+
+ throw err;
+ }
+};
--- /dev/null
+// Copyright (C) 2017 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+ Compare the contents of two arrays
+defines: [compareArray]
+---*/
+
+function compareArray(a, b) {
+ if (b.length !== a.length) {
+ return false;
+ }
+
+ for (var i = 0; i < a.length; i++) {
+ if (!compareArray.isSameValue(b[i], a[i])) {
+ return false;
+ }
+ }
+ return true;
+}
+
+compareArray.isSameValue = function(a, b) {
+ if (a === 0 && b === 0) return 1 / a === 1 / b;
+ if (a !== a && b !== b) return true;
+
+ return a === b;
+};
+
+compareArray.format = function(array) {
+ return `[${array.map(String).join(', ')}]`;
+};
+
+assert.compareArray = function(actual, expected, message) {
+ message = message === undefined ? '' : message;
+ assert(actual != null, `First argument shouldn't be nullish. ${message}`);
+ assert(expected != null, `Second argument shouldn't be nullish. ${message}`);
+ var format = compareArray.format;
+ assert(
+ compareArray(actual, expected),
+ `Expected ${format(actual)} and ${format(expected)} to have the same contents. ${message}`
+ );
+};
--- /dev/null
+function has_buffer() {
+ return (typeof Buffer === 'function') && Buffer.from;
+}
--- /dev/null
+let fs = null;
+let fsp = null;
+
+if (typeof require == 'function') {
+ fs = require('fs');
+ fsp = fs.promises;
+}
+
+function has_fs() {
+ return fs;
+}
--- /dev/null
+if (typeof print !== 'function') {
+ print = console.log;
+}
--- /dev/null
+if (typeof crypto == 'undefined' && typeof require == 'function') {
+ crypto = require('crypto').webcrypto;
+}
+
+function has_webcrypto() {
+ return (typeof crypto != 'undefied') ? crypto : null;
+}
+
--- /dev/null
+// Copyright (C) 2017 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+defines: [$DONE]
+---*/
+
+function __consolePrintHandle__(msg) {
+ print(msg);
+}
+
+function $DONE(error) {
+ if (error) {
+ if(typeof error === 'object' && error !== null && 'name' in error) {
+ __consolePrintHandle__('Test262:AsyncTestFailure:' + error.name + ': ' + error.message);
+ } else {
+ __consolePrintHandle__('Test262:AsyncTestFailure:Test262Error: ' + error);
+ }
+ } else {
+ __consolePrintHandle__('Test262:AsyncTestComplete');
+ }
+}
--- /dev/null
+async function run(tlist) {
+ function validate(t, r, i) {
+ if (r.status == "fulfilled" && r.value === "SKIPPED") {
+ return true;
+ }
+
+ if (r.status == "fulfilled" && !t[i].exception) {
+ return r.value === "SUCCESS";
+ }
+
+ if (r.status == "rejected" && t[i].exception) {
+ return true;
+ }
+
+ if (r.status == "rejected" && t[i].optional) {
+ return r.reason.toString().startsWith("InternalError: not implemented");
+ }
+
+ return false;
+ }
+
+ for (let k = 0; k < tlist.length; k++) {
+ let ts = tlist[k];
+
+ if (ts.skip && ts.skip()) {
+ continue;
+ }
+
+ let results = await Promise.allSettled(ts.tests.map(t => ts.T(ts.prepare_args(t, ts.opts))));
+ let r = results.map((r, i) => validate(ts.tests, r, i));
+
+ r.forEach((v, i) => {
+ assert.sameValue(v, true, `FAILED ${i}: ${JSON.stringify(ts.tests[i])}\n with reason: ${results[i].reason}`);
+ })
+ }
+}
+
+function merge(to, from) {
+ let r = Object.assign({}, to);
+ Object.keys(from).forEach(v => {
+ if (typeof r[v] == 'object' && typeof from[v] == 'object') {
+ r[v] = merge(r[v], from[v]);
+
+ } else if (typeof from[v] == 'object') {
+ r[v] = Object.assign({}, from[v]);
+
+ } else {
+ r[v] = from[v];
+ }
+ })
+
+ return r;
+}
+
--- /dev/null
+// Copyright (c) 2012 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+ Provides both:
+
+ - An error class to avoid false positives when testing for thrown exceptions
+ - A function to explicitly throw an exception using the Test262Error class
+defines: [Test262Error, $DONOTEVALUATE]
+---*/
+
+
+function Test262Error(message) {
+ this.message = message || "";
+}
+
+Test262Error.prototype.toString = function () {
+ return "Test262Error: " + this.message;
+};
+
+Test262Error.thrower = (message) => {
+ throw new Test262Error(message);
+};
+
+function $DONOTEVALUATE() {
+ throw "Test262: This statement should not be evaluated.";
+}
--- /dev/null
+function pem_to_der(pem, type) {
+ const pemJoined = pem.toString().split('\n').join('');
+ const pemHeader = `-----BEGIN ${type} KEY-----`;
+ const pemFooter = `-----END ${type} KEY-----`;
+ const pemContents = pemJoined.substring(pemHeader.length, pemJoined.length - pemFooter.length);
+ return Buffer.from(pemContents, 'base64');
+}
+
+function base64decode(b64) {
+ const joined = b64.toString().split('\n').join('');
+ return Buffer.from(joined, 'base64');
+}
+
+++ /dev/null
-async function af(x) {
- const y = await new Promise(resolve => {resolve(x + 10)});
-
- return x + y;
-}
-
-af(50).then(v => console.log(v));
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+async function af(x) {
+ const y = await new Promise(resolve => {resolve(x + 10)});
+
+ return x + y;
+}
+
+af(50).then(v => {
+ assert.sameValue(v, 110);
+})
+.then($DONE, $DONE);
+++ /dev/null
-async function af(x) {
- return x;
-}
-
-af(12345).then(v => console.log(v));
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+async function af(x) {
+ return x;
+}
+
+af(12345).then(v => {
+ assert.sameValue(v, 12345)
+})
+.then($DONE, $DONE);
+++ /dev/null
-async function add(x) {
- return await new Promise((resolve, reject) => {reject(x)}).catch(v => v + 1);
-}
-
-add(50).then(v => {console.log(v)});
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+async function add(x) {
+ return await new Promise((resolve, reject) => {reject(x)}).catch(v => v + 1);
+}
+
+add(50).then(v => {
+ assert.sameValue(v, 51);
+})
+.then($DONE, $DONE);
+++ /dev/null
-async function add(x) {
- return await new Promise((resolve, reject) => {reject(x)})
- .finally(() => console.log(x + 1));
-}
-
-add(50).then(v => {console.log(v)});
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+let called = false;
+async function add(x) {
+ return await new Promise((resolve, reject) => {reject(x + 1)})
+ .finally(() => {called = true});
+}
+
+add(50).catch(e => {
+ assert.sameValue(e, 51);
+ assert.sameValue(called, true, "finally was not invoked");
+}).then($DONE, $DONE);
+/*---
+includes: [compareArray.js]
+flags: [async]
+---*/
+
let stage = [];
async function f() {
stage.push(1);
-f().then(v => {console.log(v, stage.join(", "))})
+f().then(v => {
+ assert.sameValue(v, 85);
+ assert.compareArray(stage, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, "end"]);
+}).then($DONE, $DONE);
stage.push(3);
+/*---
+includes: []
+flags: [async]
+---*/
+
function pr(x) {
return new Promise(resolve => {resolve(x)});
}
-async function add(x) {
+async function add() {
const a = pr(20);
const b = pr(50);
return await a + await b;
}
-add(50).then(v => {console.log(v)});
+add().then(v => {
+ assert.sameValue(v, 70);
+}).then($DONE, $DONE);
+/*---
+includes: [compareArray.js]
+flags: [async]
+---*/
+
async function test(name) {
let k1, k2;
Promise.all(['First', 'Second', 'Third'].map(v => test(v)))
.then(results => {
- console.log(results)
-})
+ assert.compareArray(results, ['First: SUN MOON','Second: CAT MOUSE','Third: MAN WOMAN']);
+}).then($DONE, $DONE);
+++ /dev/null
-async function add(x) {
- return await new Promise((resolve, reject) => {reject(x)});
-}
-
-add(50).then(v => {console.log(v)});
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+async function add(x) {
+ return await new Promise((resolve, reject) => {reject(x)});
+}
+
+add(50)
+.then(v => $DONOTEVALUATE())
+.catch(v => {
+ assert.sameValue(v, 50);
+})
+.then($DONE, $DONE);
+/*---
+includes: [compareArray.js]
+flags: [async]
+---*/
+
function pr(x) {
return new Promise(resolve => {resolve(x)})
.then(v => v).then(v => v);
stage.push(1);
-f().then(v => {console.log(v, stage.join(", "))})
+f().then(v => {
+ stage.push(v);
+ assert.compareArray(stage, [1, 2, 3, 4, 5, 30]);
+}).then($DONE, $DONE);
stage.push(3);
+/*---
+includes: []
+flags: [async]
+---*/
+
function pr(x) {
return new Promise(resolve => {resolve(x)}).then(v => {throw v});
}
return a + b;
}
-add(50).then(v => {console.log(v)});
+add(50)
+.then(v => $DONOTEVALUATE())
+.catch(v => {
+ assert.sameValue(v, 50);
+})
+.then($DONE, $DONE);
+/*---
+includes: []
+flags: [async]
+---*/
+
function pr(x) {
return new Promise(resolve => {resolve(x)});
}
return a + b;
}
-add(50).then(v => {console.log(v - 1)}).catch(v => console.log(v));
+add(50)
+.then(v => $DONOTEVALUATE())
+.catch(v => {
+ assert.sameValue(v, 51);
+})
+.then($DONE, $DONE);
+/*---
+includes: []
+flags: [async]
+---*/
+
function pr(x) {
return new Promise(resolve => {resolve(x)}).then(v => {throw v}).catch(v => v);
}
return a + b;
}
-add(50).then(v => {console.log(v)});
+add(50).then(v => {
+ assert.sameValue(v, 110);
+})
+.then($DONE, $DONE);
+/*---
+includes: []
+flags: [async]
+---*/
+
function pr(x) {
return new Promise(resolve => {resolve(x)});
}
return a + b;
}
-add(50).then(v => {console.log(v)});
+add(50)
+.then(v => $DONOTEVALUATE())
+.catch(v => {
+ assert.sameValue(v, 51);
+})
+.then($DONE, $DONE);
+++ /dev/null
-async function af() {
- try {
- await new Promise(function(resolve, reject) {
- reject("reject");
- });
-
- console.log("shouldn't happen");
- }
- catch (v) {
- console.log(v);
- }
- finally {
- console.log("finally");
- }
-
- return "end";
-};
-
-af().then(v => console.log(v));
--- /dev/null
+/*---
+includes: [compareArray.js]
+flags: [async]
+---*/
+
+let stages = [];
+
+async function af() {
+ try {
+ await new Promise(function(resolve, reject) {
+ reject("reject");
+ });
+
+ $DONOTEVALUATE();
+ }
+ catch (v) {
+ stages.push(v);
+ }
+ finally {
+ stages.push('finally');
+ }
+
+ return "end";
+};
+
+af().then(v => {
+ stages.push(v);
+ assert.compareArray(stages, ['reject', 'finally', 'end']);
+})
+.then($DONE, $DONE)
+/*---
+includes: []
+flags: [async]
+---*/
+
+let stages = [];
+
async function af() {
try {
await new Promise(function(resolve, reject) {
reject("reject");
});
- console.log("shouldn't happen: try");
+ $DONOTEVALUATE();
}
finally {
await new Promise(function(resolve, reject) {
reject("finally reject");
});
- console.log("shouldn't happen: finally");
+ $DONOTEVALUATE();
}
return "shouldn't happen: end";
};
-af().then(v => console.log(v));
+af()
+.then(v => $DONOTEVALUATE())
+.catch(v => {
+ assert.sameValue(v, "finally reject");
+})
+.then($DONE, $DONE);
+/*---
+includes: []
+flags: [async]
+---*/
+
async function af() {
let key;
return key;
};
-af().then(v => console.log(v));
+af().then(v => {
+ assert.sameValue(v, "key: resolve");
+})
+.then($DONE, $DONE);
+++ /dev/null
-async function af() {
- try {
- throw "try";
-
- console.log("shouldn't happen: try");
- }
- finally {
- console.log("finally");
- }
-
- return "shouldn't happen: end";
-};
-
-af().then(v => console.log(v));
--- /dev/null
+/*---
+includes: [compareArray.js]
+flags: [async]
+---*/
+
+let stages = [];
+
+async function af() {
+ try {
+ throw "try";
+
+ $DONOTEVALUATE();
+ }
+ finally {
+ stages.push("finally");
+ }
+
+ return "shouldn't happen: end";
+};
+
+af()
+.then(v => $DONOTEVALUATE())
+.catch(v => {
+ stages.push(v);
+ assert.compareArray(stages, ['finally', 'try']);
+})
+.then($DONE, $DONE)
+++ /dev/null
-async function af() {
- try {
- throw "try";
-
- console.log("shouldn't happen: try");
- }
- catch (v) {
- console.log(v);
- }
- finally {
- console.log("finally");
- }
-
- return "end";
-};
-
-af().then(v => console.log(v));
--- /dev/null
+/*---
+includes: [compareArray.js]
+flags: [async]
+---*/
+
+let stage = [];
+
+async function af() {
+ try {
+ throw "try";
+
+ $DONOTEVALUATE();
+ }
+ catch (v) {
+ stage.push(v);
+ }
+ finally {
+ stage.push("finally");
+ }
+
+ return "end";
+};
+
+af().then(v => {
+ stage.push(v);
+ assert.compareArray(stage, ['try', 'finally', 'end'])
+}).then($DONE, $DONE);
+++ /dev/null
-var fs = require('fs').promises;
-var fname = './build/test/fs_promises_001';
-
-Promise.resolve()
-.then(() => {
- return fs.writeFile(fname, fname);
-})
-.then((data) => {
- console.log('init ok', data === undefined);
-})
-.catch((e) => {
- console.log('init failed', e);
-})
-.then(() => {
- return fs.readFile(fname).then(fs.readFile);
-})
-.then((data) => {
- console.log('short circut ok', data == fname);
-})
-.catch((e) => {
- console.log('short circut failed', e);
-})
-.then(() => {
- var read = fs.readFile.bind(fs, fname, 'utf8');
- var write = fs.writeFile.bind(fs, fname);
- var append = fs.appendFile.bind(fs, fname);
-
- return write(fname).then(read).then(append).then(read);
-})
-.then((data) => {
- console.log('chain ok', data == (fname + fname));
-})
-.catch((e) => {
- console.log('chain failed', e);
-})
-.then(() => {
- // nodejs incompatible
- try {
- return fs.readFile();
- } catch (e) {
- console.log('error 1 ok', e instanceof TypeError)
- }
- try {
- return fs.writeFile();
- } catch (e) {
- console.log('error 2 ok', e instanceof TypeError)
- }
-})
-.then((data) => {
- console.log('errors ok');
-})
-.catch((e) => {
- console.log('errors failed - reject on bad args');
-})
-;
+++ /dev/null
-function resolve(value) {
- return new Promise(resolve => setTimeout(() => resolve(value), 0));
-}
-
-Promise.all([resolve(['one', 'two']), resolve(['three', 'four'])])
-.then(
- (v) => {console.log(`resolved:${njs.dump(v)}`)},
- (v) => {console.log(`rejected:${njs.dump(v)}`)}
-);
--- /dev/null
+/*---
+includes: [compareArray.js]
+flags: [async]
+---*/
+
+function resolve(value) {
+ return new Promise(resolve => setTimeout(() => resolve(value), 0));
+}
+
+Promise.all([resolve(['one', 'two']), resolve(['three', 'four'])])
+.then(
+ v => { assert.compareArray(v[0], ['one', 'two']);
+ assert.compareArray(v[1], ['three', 'four']); },
+ v => $DONOTEVALUATE(),
+)
+.then($DONE, $DONE);
+/*---
+includes: []
+flags: [async]
+---*/
+
var p0 = Promise.resolve(2).then(v => v + 1);
var p1 = Promise.reject(21).catch(v => v * 2);
var p2 = Promise.resolve('nope').then(() => { throw 'foo' });
}
Promise.allSettled([p0, p1, p2, p3, p4, p5, p6, p7, p8]).then(
- (v) => {console.log(`resolved:${dump(v)}`)},
- (v) => {console.log(`rejected:${dump(v)}`)}
-);
+ v => assert.sameValue(dump(v), "F:0,3,42,here|R:finally,finally after rejected,foo,here too,yes"),
+ v => $DONOTEVALUATE(),
+)
+.then($DONE, $DONE);
+/*---
+includes: []
+flags: [async]
+---*/
+
function dump(v) {
var fulfilled = v.filter(v=>v.status == 'fulfilled').map(v=>v.value).sort();
var rejected = v.filter(v=>v.status == 'rejected').map(v=>v.reason).sort();
}
Promise.allSettled("abc").then(
- (v) => {console.log(`resolved:${dump(v)}`)},
- (v) => {console.log(`rejected:${dump(v)}`)}
-);
+ v => assert.sameValue(dump(v), "F:a,b,c|R:"),
+ v => $DONOTEVALUATE(),
+)
+.then($DONE, $DONE);
+/*---
+includes: []
+flags: [async]
+---*/
+
var p0 = Promise.resolve(1).then(v => v + 1);
var p1 = Promise.reject(2).catch(v => v * 2);
var p2 = Promise.resolve().then(() => { throw 'foo' });
var p3 = Promise.reject().then(() => { throw 'oof'; });
Promise.all([p0, p1, p2, p3]).then(
- (v) => {console.log(`resolved:${v}`)},
- (v) => {console.log(`rejected:${v}`)}
-);
+ v => $DONOTEVALUATE(),
+ v => assert.sameValue(v, 'foo')
+)
+.then($DONE, $DONE);
+/*---
+includes: []
+flags: [async]
+---*/
+
var p0 = Promise.resolve().then(() => { throw 'foo' });
var p1 = Promise.reject(2).catch(v => v * 2);
var p2 = Promise.resolve(1).then(v => v + 1);
Promise.any([p0, p1, p2]).then(
- (v) => {console.log(`resolved:${v}`)},
- (v) => {console.log(`rejected:${v}`)}
-);
+ v => assert.sameValue(v, 4),
+ v => $DONOTEVALUATE(),
+)
+.then($DONE, $DONE);
+++ /dev/null
-var p0 = Promise.reject(1);
-var p1 = Promise.reject(2);
-
-Promise.any([p0, p1]).then(
- (v) => {console.log(`resolve:${v}`)},
- (v) => {console.log(`reject:${v}`)}
-);
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+var p0 = Promise.reject(1);
+var p1 = Promise.reject(2);
+
+Promise.any([p0, p1]).then(
+ v => $DONOTEVALUATE(),
+ v => assert.sameValue(v.constructor, AggregateError),
+)
+.then($DONE, $DONE);
+++ /dev/null
-Promise.resolve()
-.then(() => {})
-.catch(() => {})
-.then(() => {nonExsisting()})
-.catch(() => {console.log("Done")});
\ No newline at end of file
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+let called = false;
+
+Promise.resolve()
+.then(() => {})
+.catch(() => {})
+.then(() => {nonExsisting()})
+.catch(() => { called = true; })
+.then(() => assert.sameValue(called, true))
+.then($DONE, $DONE);
+++ /dev/null
-Promise.resolve()
-.then(() => {nonExsisting()})
-.catch(() => {nonExsistingInCatch()});
\ No newline at end of file
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+Promise.resolve()
+.then(() => {nonExsisting()})
+.catch(() => {nonExsistingInCatch()})
+.catch(v => assert.sameValue(v.constructor, ReferenceError))
+.then($DONE, $DONE);
+++ /dev/null
-Promise.resolve('here')
-.finally(() => {'nope'})
-.then(v => {console.log(v)});
-
-Promise.resolve('here')
-.finally(() => {throw 'nope'})
-.then(v => {console.log(v)});
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+Promise.resolve('here')
+.finally(() => {'nope'})
+.then(v => assert.sameValue(v, 'here'));
+
+Promise.resolve('here')
+.finally(() => {throw 'nope'})
+.then(v => $DONOTEVALUATE())
+.catch(v => assert.sameValue(v, 'nope'))
+.then($DONE, $DONE);
+++ /dev/null
-Promise.resolve()
-.finally(() => {nonExsistingInFinally()});
\ No newline at end of file
--- /dev/null
+/*---
+includes: []
+flags: []
+negative:
+ phase: runtime
+---*/
+
+Promise.resolve()
+.finally(() => {nonExsistingInFinally()});
+++ /dev/null
-Promise.resolve()
-.finally(() => {nonExsistingInFinally()})
-.catch(() => {console.log("Done")});
\ No newline at end of file
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+Promise.resolve()
+.finally(() => {nonExsistingInFinally()})
+.catch(e => {})
+.then($DONE, $DONE);
+/*---
+includes: []
+flags: [async]
+---*/
+
var p1 = new Promise((resolve, reject) => {
setTimeout(resolve, 0, 'one');
});
});
Promise.race([p1, p2]).then(
- (v) => {console.log(`resolved:${v}`)},
- (v) => {console.log(`rejected:${v}`)}
-);
+ v => assert.sameValue(v, 'one'),
+ v => $DONOTEVALUATE(),
+)
+.then($DONE, $DONE);
+/*---
+includes: []
+flags: [async]
+---*/
+
var p1 = new Promise((resolve, reject) => {
throw 'one';
});
});
Promise.race([p1, p2]).then(
- (v) => {console.log(`resolved:${v}`)},
- (v) => {console.log(`rejected:${v}`)}
-);
+ v => $DONOTEVALUATE(),
+ v => assert.sameValue(v, 'one'),
+)
+.then($DONE, $DONE);
+++ /dev/null
-Promise.reject("test").catch((x) => console.log('rejected', x));
\ No newline at end of file
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+Promise.reject("test")
+.catch(v => assert.sameValue(v, "test"))
+.then($DONE, $DONE);
+++ /dev/null
-var p = Promise.reject();
-setImmediate(() => {p.catch(() => {})});
\ No newline at end of file
--- /dev/null
+/*---
+includes: []
+flags: []
+negative:
+ phase: runtime
+---*/
+
+var p = Promise.reject();
+setImmediate(() => {p.catch(() => {})});
+++ /dev/null
-Promise.reject(1);
\ No newline at end of file
--- /dev/null
+/*---
+includes: []
+flags: []
+negative:
+ phase: runtime
+---*/
+
+Promise.reject(1);
+
--- /dev/null
+/*---
+includes: [compareArray.js]
+flags: [async]
+---*/
+
+let stages = [];
+
+var promise = new Promise(function(resolve, reject) {
+ stages.push('One');
+
+ reject(123);
+}).catch((v) => {stages.push(v)});
+
+stages.push('Two');
+
+promise.then(() => {stages.push('Four'); return {num: 'Five'}})
+.then(obj => {stages.push(obj.num); return {num: 'Six'}})
+.then(obj => {stages.push(obj.num)})
+.then(() => assert.compareArray(stages, ["One", "Two", "Three", 123, "Four", "Five", "Six"]))
+.then($DONE, $DONE);
+
+stages.push('Three');
--- /dev/null
+/*---
+includes: [compareArray.js]
+flags: [async]
+---*/
+
+let stages = [];
+
+var promise = new Promise(function(resolve, reject) {
+ stages.push('One');
+
+ reject(123);
+})
+
+stages.push('Two');
+
+promise.then(() => {stages.push('Four'); return {num: 'Five'}})
+.then(obj => {stages.push(obj.num); return {num: 'Six'}})
+.then(obj => {stages.push(obj.num)})
+.catch(v => assert.sameValue(v, 123))
+.then(() => assert.compareArray(stages, ["One", "Two", "Three"]))
+.then($DONE, $DONE);
+
+stages.push('Three');
--- /dev/null
+/*---
+includes: [compareArray.js]
+flags: [async]
+---*/
+
+let stages = [];
+
+var promise = new Promise(function(resolve, reject) {
+ stages.push('One');
+ reject(42);
+});
+
+stages.push('Two');
+
+promise.then(
+ v => $DONOTEVALUATE(),
+ v => assert.sameValue(v, 42))
+.then(() => assert.compareArray(stages, ['One', 'Two', 'Three']))
+.then($DONE, $DONE);
+
+stages.push('Three');
--- /dev/null
+/*---
+includes: []
+flags: []
+negative:
+ phase: runtime
+---*/
+
+Promise.reject(new Error('Oh my'))
+.then(
+ function(success) {},
+ function(error) { throw error;}
+);
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+let called = false;
+
+Promise.resolve('Success')
+.then(
+ function(value) {
+ assert.sameValue(value, 'Success');
+ called = true;
+ },
+ function(value) {
+ $DONOTEVALUATE()
+})
+.then(() => assert.sameValue(called, true))
+.then($DONE, $DONE);
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+var p = Promise.resolve([1,2,3]);
+p.then(function(v) {
+ assert.sameValue(v[0], 1);
+})
+.then($DONE, $DONE);
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+var p1 = Promise.resolve({
+ then: function(onFulfill, onReject) { onFulfill('fulfilled!'); }
+});
+
+p1.then(
+ function(v) { assert.sameValue(v, 'fulfilled!'); },
+ function(e) { $DONOTEVALUATE() },
+)
+.then(() => assert.sameValue(p1 instanceof Promise, true))
+.then($DONE, $DONE);
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+let called = false;
+
+var thenable = {
+ then: function(resolve) {
+ called = true;
+ resolve();
+ }
+};
+
+function executor(resolve, reject) {
+ resolve(thenable);
+ throw new Error('ignored');
+}
+
+new Promise(executor)
+.then(() => assert.sameValue(called, true))
+.then($DONE, $DONE);
--- /dev/null
+/*---
+includes: [compareArray.js]
+flags: []
+---*/
+
+let calls = [];
+
+function NotPromise(executor) {
+ assert.sameValue(Object.isExtensible(executor), true);
+ executor(function() {calls.push('S')}, function() {calls.push('R')});
+}
+
+Promise.resolve.call(NotPromise);
+
+assert.compareArray(calls, ['S']);
+++ /dev/null
-var promise = new Promise(function(resolve, reject) {
- console.log('One');
-
- reject(123);
-}).catch((v) => {console.log(v)});
-
-console.log('Two');
-
-promise.then(() => {console.log('Four'); return {num: 'Five'}})
-.then((obj) => {console.log(obj.num); return {num: 'Six'}})
-.then((obj) => {console.log(obj.num); return {num: 'Seven'}})
-.then((obj) => {console.log(obj.num); return {num: 'Eight'}})
-.then((obj) => {console.log(obj.num)});
-
-console.log('Three');
\ No newline at end of file
+++ /dev/null
-var promise = new Promise(function(resolve, reject) {
- console.log('One');
- reject('Oh no');
-});
-
-console.log('Two');
-
-promise.then(() => {console.log('Three')})
-.catch((v) => {console.log(v)});
-
-console.log('Three');
\ No newline at end of file
--- /dev/null
+/*---
+includes: [compareArray.js]
+flags: [async]
+---*/
+
+let stages = [];
+
+var promise = new Promise(function(resolve, reject) {
+ stages.push('One');
+ reject('Oh no');
+});
+
+stages.push('Two');
+
+promise.then(() => {stages.push('Three')})
+.catch((v) => {stages.push(v)})
+.then(() => assert.compareArray(stages, ['One', 'Two', 'Three', 'Oh no']))
+.then($DONE, $DONE);
+
+stages.push('Three');
+++ /dev/null
-var promise = new Promise((resolve, reject) => resolve('all'));
-
-promise.then( function f1(result) {
- console.log('S: ' + result);
- return 'f1';
-});
-
-promise.then( function f2(result) {
- console.log('R: ' + result);
- return 'f2';
-});
-
-console.log('end')
\ No newline at end of file
--- /dev/null
+/*---
+includes: [compareArray.js]
+flags: [async]
+---*/
+
+let stages = [];
+
+var promise = new Promise((resolve, reject) => resolve('all'));
+
+promise.then( function f1(result) {
+ stages.push('S: ' + result);
+ return 'f1';
+});
+
+promise.then( function f2(result) {
+ stages.push('R: ' + result);
+ return 'f2';
+})
+.then(() => assert.compareArray(stages, ['end', 'S: all', 'R: all']))
+.then($DONE, $DONE);
+
+stages.push('end');
+++ /dev/null
-var thenable = new Promise(function() {});
-
-var p = new Promise(function(resolve) {
- resolve();
- throw thenable;
-});
-
-p.then(function() {
- console.log('Done');
-});
\ No newline at end of file
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+let called = false;
+
+var thenable = new Promise(function() {});
+
+var p = new Promise(function(resolve) {
+ resolve();
+ throw thenable;
+});
+
+p.then(function() {
+ called = true;
+})
+.then(() => assert.sameValue(called, true))
+.then($DONE, $DONE);
+++ /dev/null
-var thenable = Promise.resolve();
-var p = new Promise(function(a,b) {
- throw thenable;
-});
-
-p.then(function() {
- console.log('The promise should not be fulfilled.');
-})
-.then(
- function() {
- console.log('The promise should not be fulfilled.');
- },
- function(x) {
- if (x !== thenable) {
- console.log('The promise should be rejected with the resolution value.');
- return;
- }
-
- console.log('Done');
- }
-);
\ No newline at end of file
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+let called = false;
+
+var thenable = Promise.resolve();
+var p = new Promise(function(a,b) {
+ throw thenable;
+});
+
+p
+.then(v => $DONOTEVALUATE())
+.then(
+ v => $DONOTEVALUATE(),
+ function(x) {
+ assert.sameValue(x, thenable, 'The promise should be rejected with the resolution value.');
+ called = true;
+ }
+)
+.then(() => assert.sameValue(called, true))
+.then($DONE, $DONE);
+++ /dev/null
-var isLoading = true;
-var promise = new Promise((a, b) => {a()} );
-
-promise.then(function(response) {
- throw new TypeError('oops');
-})
-.then(function(json) { })
-.catch(function(error) { console.log(error); })
-.finally(function() { console.log('Done') });
\ No newline at end of file
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+let stages = [];
+
+var isLoading = true;
+var promise = new Promise((a, b) => {a()} );
+
+promise.then(function(response) {
+ throw new TypeError('oops');
+})
+.then(function(json) { })
+.catch(e => stages.push(e))
+.finally(() => stages.push('Done'))
+.then(() => {
+ assert.sameValue(stages[0] instanceof TypeError, true);
+ assert.sameValue(stages[1], 'Done');
+})
+.then($DONE, $DONE);
+++ /dev/null
-var obj = {};
-var p = Promise.resolve(obj);
-
-p.then(undefined, undefined)
-.then(function(arg) {
- if (arg !== obj) {
- console.log('Expected resolution object to be passed through, got ' + arg);
- }
-})
-.then(() => {console.log('Done')}, () => {console.log('Error')});
\ No newline at end of file
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+var obj = {};
+var p = Promise.resolve(obj);
+
+p.then(undefined, undefined)
+.then(
+ v => {
+ assert.sameValue(v, obj,
+ 'Expected resolution object to be passed through, got ' + v);
+ },
+ e => $DONOTEVALUATE())
+.then($DONE, $DONE);
+++ /dev/null
-var obj = {};
-var p = Promise.reject(obj);
-
-p.then(undefined, undefined).then(function() {
- console.log('Should not be called -- promise was rejected.');
-}, function(arg) {
- if (arg !== obj) {
- console.log('Expected resolution object to be passed through, got ' + arg);
- }
-}).then(() => {console.log('Done')}, () => {console.log('Error')});
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+var obj = {};
+var p = Promise.reject(obj);
+
+p.then(undefined, undefined)
+.then(
+ v => DONOTEVALUATE(),
+ e => {
+ assert.sameValue(e, obj,
+ 'Expected resolution object to be passed through, got ' + e);
+})
+.then($DONE, $DONE);
+++ /dev/null
-var obj = {};
-var p = Promise.reject(obj);
-
-p.then(undefined, undefined).then(function() {
- console.log('Should not be called -- promise was rejected.');
-}, function(arg) {
- if (arg !== obj) {
- console.log('Expected resolution object to be passed through, got ' + arg);
- }
-}).then(() => {console.log('Done')}, () => {console.log('Error')});
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+/* Duplicate of s16. */
+
+var obj = {};
+var p = Promise.reject(obj);
+
+p.then(undefined, undefined)
+.then(
+ v => DONOTEVALUATE(),
+ e => {
+ assert.sameValue(e, obj,
+ 'Expected resolution object to be passed through, got ' + e);
+})
+.then($DONE, $DONE);
+/*---
+includes: [compareArray.js]
+flags: [async]
+---*/
+
+let stages = [];
+
var thenable = {
then: function(resolve) {
resolve();
- console.log('State 5');
+ stages.push(5);
}
};
var thenableWithError = {
then: function(resolve) {
- console.log('State 3');
+ stages.push(3);
resolve(thenable);
- console.log('State 4');
+ stages.push(4);
throw new Error('ignored exception');
}
};
function executor(resolve, reject) {
- console.log('State 1');
+ stages.push(1);
resolve(thenableWithError);
- console.log('State 2');
+ stages.push(2);
}
-new Promise(executor).then(() => {console.log('Done')}, () => {console.log('Error')});
\ No newline at end of file
+new Promise(executor)
+.then(() => assert.compareArray(stages, [1, 2, 3, 4, 5]))
+.then($DONE, $DONE);
+++ /dev/null
-var returnValue = null;
-var value = {};
-var resolve;
-
-var poisonedThen = Object.defineProperty({}, 'then', {
- get: function() {
- console.log('Throw!');
- throw value;
- }
-});
-
-var promise = new Promise(function(_resolve) {
- resolve = _resolve;
-});
-
-promise.then(
-function() {
- console.log('Resolve!');
- console.log('The promise should not be fulfilled.');
-},
-function(val) {
- console.log('Reject!');
- if (val !== value) {
- console.log('The promise should be fulfilled with the provided value.');
- return;
- }
-
- console.log('Done');
-});
-
-returnValue = resolve(poisonedThen);
-
-console.log(returnValue);
\ No newline at end of file
--- /dev/null
+/*---
+includes: [compareArray.js]
+flags: [async]
+---*/
+
+let stages = [];
+
+var returnValue = null;
+var value = {};
+var resolve;
+
+var poisonedThen = Object.defineProperty({}, 'then', {
+ get: function() {
+ stages.push('Throw!');
+ throw value;
+ }
+});
+
+var promise = new Promise(function(_resolve) {
+ resolve = _resolve;
+});
+
+promise.then(
+ v => $DONOTEVALUATE(),
+ e => {
+ stages.push('Reject!');
+ assert.sameValue(e, value, 'The promise should be fulfilled with the provided value.');
+})
+.then(() => assert.compareArray(stages, ['Throw!', undefined, 'Reject!']))
+.then($DONE, $DONE);
+
+returnValue = resolve(poisonedThen);
+
+stages.push(returnValue);
+++ /dev/null
-var promise = new Promise(function(resolve, reject) {
- console.log('One');
- reject(123);
-});
-
-console.log('Two');
-
-promise.then(() => {console.log('Four'); return {num: 'Five'}})
-.then((obj) => {console.log(obj.num); return {num: 'Six'}})
-.then((obj) => {console.log(obj.num); return {num: 'Seven'}})
-.then((obj) => {console.log(obj.num); return {num: 'Eight'}})
-.then((obj) => {console.log(obj.num)});
-
-console.log('Three');
\ No newline at end of file
+++ /dev/null
-var returnValue = null;
-var value = {};
-var poisonedThen = Object.defineProperty({}, 'then', {
- get: function() {
- throw value;
- }
-});
-var promise = new Promise(function(resolve) {
- returnValue = resolve(poisonedThen);
-});
-
-console.log(returnValue == undefined);
-
-promise.then(function() {
- console.log('The promise should not be fulfilled.');
-}, function(val) {
- if (val !== value) {
- console.log('The promise should be fulfilled with the provided value.');
- return;
- }
-
- console.log('Done');
-});
\ No newline at end of file
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+var returnValue = null;
+var value = {};
+var poisonedThen = Object.defineProperty({}, 'then', {
+ get: function() {
+ throw value;
+ }
+});
+var promise = new Promise(function(resolve) {
+ returnValue = resolve(poisonedThen);
+});
+
+assert.sameValue(returnValue, undefined);
+
+promise
+.then(
+ v => $DONOTEVALUATE(),
+ e => {
+ assert.sameValue(e, value, 'The promise should be fulfilled with the provided value.');
+})
+.then($DONE, $DONE);
+/*---
+includes: []
+flags: [async]
+---*/
+
var value = {};
var resolve;
var poisonedThen = Object.defineProperty({}, 'then', {
return poisonedThen;
});
-p2.then(function(x) {
- console.log('The promise should not be fulfilled.');
-}, function(x) {
- if (x !== value) {
- console.log('The promise should be rejected with the thrown exception.');
- return;
- }
-
- console.log('Done');
-});
+p2
+.then(
+ v => $DONOTEVALUATE(),
+ e => {
+ assert.sameValue(e, value, 'The promise should be rejected with the thrown exception.');
+})
+.then($DONE, $DONE);
-resolve();
\ No newline at end of file
+resolve();
+++ /dev/null
-var returnValue = null;
-var value = {};
-var resolve;
-
-var thenable = new Promise(function(resolve) {
- resolve();
-});
-
-var promise = new Promise(function(_resolve) {
- resolve = _resolve;
-});
-
-thenable.then = function(resolve) {
- resolve(value);
-};
-
-promise.then(
-function(val) {
- if (val !== value) {
- console.log('The promise should be fulfilled with the provided value.');
- return;
- }
-
- console.log('Done');
-},
-function() {
- console.log('The promise should not be rejected.');
-});
-
-returnValue = resolve(thenable);
-
-console.log(returnValue == undefined);
\ No newline at end of file
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+var returnValue = null;
+var value = {};
+var resolve;
+
+var thenable = new Promise(function(resolve) {
+ resolve();
+});
+
+var promise = new Promise(function(_resolve) {
+ resolve = _resolve;
+});
+
+thenable.then = function(resolve) {
+ resolve(value);
+};
+
+promise
+.then(
+ v => {
+ assert.sameValue(v, value, 'The promise should be fulfilled with the provided value.');
+ },
+ e => $DONOTEVALUATE)
+.then($DONE, $DONE);
+
+returnValue = resolve(thenable);
+
+assert.sameValue(returnValue, undefined);
+++ /dev/null
-var returnValue = null;
-var resolve;
-
-var promise = new Promise(function(_resolve) {
- resolve = _resolve;
-});
-
-promise.then(
-function() {
- console.log('The promise should not be fulfilled.');
-},
-function(reason) {
- if (!reason) {
- console.log('The promise should be rejected with a value.');
- return;
- }
-
- if (reason.constructor !== TypeError) {
- console.log('The promise should be rejected with a TypeError instance.');
- return;
- }
-
- console.log('Done');
-});
-
-returnValue = resolve(promise);
-
-console.log(returnValue == undefined)
\ No newline at end of file
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+var returnValue = null;
+var resolve;
+
+var promise = new Promise(function(_resolve) {
+ resolve = _resolve;
+});
+
+promise
+.then(
+ v => $DONOTEVALUATE(),
+ e => {
+
+ assert.sameValue(e.constructor, TypeError,
+ 'The promise should be rejected with a TypeError instance.');
+})
+.then($DONE, $DONE);
+
+returnValue = resolve(promise);
+
+assert.sameValue(returnValue, undefined);
-var checkPoint = '';
+/*---
+includes: []
+flags: []
+---*/
+
+let checkPoint = '';
Promise.reject.call(function(executor) {
checkPoint += 'a';
checkPoint += 'c';
}, {});
-console.log(checkPoint == 'abc');
\ No newline at end of file
+assert.sameValue(checkPoint, 'abc');
+++ /dev/null
-var resolve, reject;
-var promise = new Promise(function(_resolve, _reject) {
- resolve = _resolve;
- reject = _reject;
-});
-
-var P = function(executor) {
- executor(resolve, reject);
- return promise;
-};
-
-Promise.resolve.call(P, promise)
-.then(
-function() {
- console.log('The promise should not be fulfilled.');
-},
-function(value) {
- if (!value) {
- console.log('The promise should be rejected with a value.');
- return;
- }
-
- if (value.constructor !== TypeError) {
- console.log('The promise should be rejected with a TypeError instance.');
- return;
- }
-
- console.log('Done');
-});
\ No newline at end of file
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+var resolve, reject;
+var promise = new Promise(function(_resolve, _reject) {
+ resolve = _resolve;
+ reject = _reject;
+});
+
+var P = function(executor) {
+ executor(resolve, reject);
+ return promise;
+};
+
+Promise.resolve.call(P, promise)
+.then(
+ v => $DONOTEVALUATE(),
+ e => {
+ assert.sameValue(e.constructor, TypeError,
+ 'The promise should be rejected with a TypeError instance.');
+})
+.then($DONE, $DONE);
+++ /dev/null
-var inherits = (child, parent) => {
- child.prototype = Object.create(parent.prototype, {
- constructor: {
- value: child,
- enumerable: false,
- writable: true,
- configurable: true
- }
- });
- Object.setPrototypeOf(child, parent);
-};
-
-
-var BoxedPromise = (() => {
- function BoxedPromise(executor) {
- console.log('BoxedPromise.constructor');
-
- if (!(this instanceof BoxedPromise)) {
- return Promise(executor);
- }
-
- if (typeof executor !== 'function') {
- return new Promise(executor);
- }
-
- var context, args;
- var promise = new Promise(wrappedExecutor);
- this.boxed = promise;
-
- try {
- executor.apply(context, args);
-
- } catch (e) {
- args[1](e);
- }
-
- function wrappedExecutor(resolve, reject) {
- context = this;
- args = [wrappedResolve, wrappedReject];
- function wrappedResolve(val) {
- return resolve(val);
- }
- function wrappedReject(val) {
- return reject(val);
- }
- }
- }
-
- inherits(BoxedPromise, Promise);
-
- BoxedPromise.prototype.then = function(res, rej) {
- console.log('BoxedPromise.prototype.then');
- var rs = Object.create(Object.getPrototypeOf(this));
- rs.boxed = this.boxed.then(res, rej);
- return rs;
- };
-
- return BoxedPromise;
-})();
-
-
-var PatchedPromise = (() => {
- function PatchedPromise(executor) {
- console.log('PatchedPromise.constructor');
-
- if (!(this instanceof PatchedPromise)) {
- return Promise(executor);
- }
-
- if (typeof executor !== 'function') {
- return new Promise(executor);
- }
-
- var context, args;
- var promise = new Promise(wrappedExecutor);
- Object.setPrototypeOf(promise, PatchedPromise.prototype);
-
- try {
- executor.apply(context, args);
-
- } catch (e) {
- args[1](e);
- }
-
- return promise;
-
- function wrappedExecutor(resolve, reject) {
- context = this;
- args = [wrappedResolve, wrappedReject];
- function wrappedResolve(val) {
- return resolve(val);
- }
- function wrappedReject(val) {
- return reject(val);
- }
- }
- }
-
- inherits(PatchedPromise, Promise);
-
- return PatchedPromise;
-})();
-
-
-var testSubclass = (Class, name) => {
- return new Promise((resolve) => {
- var resolved = Class.resolve(name)
- .then((x) => console.log('resolved', name));
-
- console.log(name, 'resolve', resolved instanceof Class ? 'OK' : 'failed');
-
-
- var rejected = Class.reject(name)
- .catch((x) => console.log('rejected', name));
-
- console.log(name, 'reject', rejected instanceof Class ? 'OK' : 'failed');
-
-
- var instance = new Class((resolve) => {
- setImmediate(() => resolve(name));
- });
-
- var chain = instance
- .then((x) => { console.log('then', x); return x; })
- .then((x) => { console.log('then', x); return x; });
-
- console.log(name, 'chain', chain instanceof Class ? 'OK' : 'failed');
-
- var fin = chain
- .finally(() => console.log('finally', name));
-
- console.log(name, 'finally', fin instanceof Class ? 'OK' : 'failed');
-
- console.log(name, 'sync done\n');
-
- fin
- .then(() => console.log(name, 'async done\n'))
- .then(resolve);
- });
-};
-
-Promise.resolve()
- .then(() => testSubclass(BoxedPromise, 'BoxedPromise'))
- .then(() => testSubclass(PatchedPromise, 'PatchedPromise'));
--- /dev/null
+/*---
+includes: [compareArray.js]
+flags: [async]
+---*/
+
+let stages = [];
+
+var inherits = (child, parent) => {
+ child.prototype = Object.create(parent.prototype, {
+ constructor: {
+ value: child,
+ enumerable: false,
+ writable: true,
+ configurable: true
+ }
+ });
+ Object.setPrototypeOf(child, parent);
+};
+
+
+var BoxedPromise = (() => {
+ function BoxedPromise(executor) {
+ stages.push('BoxedPromise.constructor');
+
+ if (!(this instanceof BoxedPromise)) {
+ return Promise(executor);
+ }
+
+ if (typeof executor !== 'function') {
+ return new Promise(executor);
+ }
+
+ var context, args;
+ var promise = new Promise(wrappedExecutor);
+ this.boxed = promise;
+
+ try {
+ executor.apply(context, args);
+
+ } catch (e) {
+ args[1](e);
+ }
+
+ function wrappedExecutor(resolve, reject) {
+ context = this;
+ args = [wrappedResolve, wrappedReject];
+ function wrappedResolve(val) {
+ return resolve(val);
+ }
+ function wrappedReject(val) {
+ return reject(val);
+ }
+ }
+ }
+
+ inherits(BoxedPromise, Promise);
+
+ BoxedPromise.prototype.then = function(res, rej) {
+ stages.push('BoxedPromise.prototype.then');
+ var rs = Object.create(Object.getPrototypeOf(this));
+ rs.boxed = this.boxed.then(res, rej);
+ return rs;
+ };
+
+ return BoxedPromise;
+})();
+
+
+var PatchedPromise = (() => {
+ function PatchedPromise(executor) {
+ stages.push('PatchedPromise.constructor');
+
+ if (!(this instanceof PatchedPromise)) {
+ return Promise(executor);
+ }
+
+ if (typeof executor !== 'function') {
+ return new Promise(executor);
+ }
+
+ var context, args;
+ var promise = new Promise(wrappedExecutor);
+ Object.setPrototypeOf(promise, PatchedPromise.prototype);
+
+ try {
+ executor.apply(context, args);
+
+ } catch (e) {
+ args[1](e);
+ }
+
+ return promise;
+
+ function wrappedExecutor(resolve, reject) {
+ context = this;
+ args = [wrappedResolve, wrappedReject];
+ function wrappedResolve(val) {
+ return resolve(val);
+ }
+ function wrappedReject(val) {
+ return reject(val);
+ }
+ }
+ }
+
+ inherits(PatchedPromise, Promise);
+
+ return PatchedPromise;
+})();
+
+
+var testSubclass = (Class, name) => {
+ return new Promise((resolve) => {
+ var resolved = Class.resolve(name)
+ .then((x) => stages.push(`resolved ${name}`));
+
+ stages.push(`${name} resolve ${resolved instanceof Class ? 'OK' : 'failed'}`);
+
+
+ var rejected = Class.reject(name)
+ .catch((x) => stages.push(`rejected ${name}`));
+
+ stages.push(`${name} reject ${rejected instanceof Class ? 'OK' : 'failed'}`);
+
+ var instance = new Class((resolve) => {
+ setImmediate(() => resolve(name));
+ });
+
+ var chain = instance
+ .then((x) => { stages.push(`then ${x}`); return x; })
+ .then((x) => { stages.push(`then ${x}`); return x; });
+
+ stages.push(`${name} chain ${chain instanceof Class ? 'OK' : 'failed'}`);
+
+ var fin = chain
+ .finally(() => stages.push(`finally ${name}`));
+
+ stages.push(`${name} finally ${fin instanceof Class ? 'OK' : 'failed'}`);
+
+ stages.push(`${name} sync done`);
+
+ fin
+ .then(() => stages.push(`${name} async done`))
+ .then(resolve);
+ });
+};
+
+Promise.resolve()
+.then(() => testSubclass(BoxedPromise, 'BoxedPromise'))
+.then(() => {
+ assert.compareArray(stages, [
+ "BoxedPromise.constructor",
+ "BoxedPromise.prototype.then",
+ "BoxedPromise resolve OK",
+ "BoxedPromise.constructor",
+ "BoxedPromise.prototype.then",
+ "BoxedPromise reject OK",
+ "BoxedPromise.constructor",
+ "BoxedPromise.prototype.then",
+ "BoxedPromise.prototype.then",
+ "BoxedPromise chain OK",
+ "BoxedPromise.prototype.then",
+ "BoxedPromise finally OK",
+ "BoxedPromise sync done",
+
+ "BoxedPromise.prototype.then",
+ "BoxedPromise.prototype.then",
+ "resolved BoxedPromise",
+ "rejected BoxedPromise",
+ "then BoxedPromise",
+ "then BoxedPromise",
+ "finally BoxedPromise",
+ "BoxedPromise.constructor",
+ "BoxedPromise.prototype.then",
+ "BoxedPromise.prototype.then",
+ "BoxedPromise async done",
+ ]);
+ stages = [];
+})
+.then(() => testSubclass(PatchedPromise, 'PatchedPromise'))
+.then(() => {
+ assert.compareArray(stages, [
+ "PatchedPromise.constructor",
+ "PatchedPromise.constructor",
+ "PatchedPromise resolve OK",
+ "PatchedPromise.constructor",
+ "PatchedPromise.constructor",
+ "PatchedPromise reject OK",
+ "PatchedPromise.constructor",
+ "PatchedPromise.constructor",
+ "PatchedPromise.constructor",
+ "PatchedPromise chain OK",
+ "PatchedPromise.constructor",
+ "PatchedPromise finally OK",
+ "PatchedPromise sync done",
+
+ "PatchedPromise.constructor",
+ "PatchedPromise.constructor",
+ "resolved PatchedPromise",
+ "rejected PatchedPromise",
+ "then PatchedPromise",
+ "then PatchedPromise",
+ "finally PatchedPromise",
+ "PatchedPromise.constructor",
+ "PatchedPromise.constructor",
+ "PatchedPromise.constructor",
+ "PatchedPromise async done",
+ ]);
+ stages = [];
+})
+.then($DONE, $DONE);
+++ /dev/null
-
-var promise = new Promise(function(resolve, reject) {
- console.log('One');
- reject(new Error('Blah'));
-});
-
-console.log('Two');
-
-promise.then((response) => console.log(`Fulfilled: ${response}`), (error) => console.log(`Rejected: ${error}`));
-
-console.log('Three');
\ No newline at end of file
+++ /dev/null
-Promise.reject(new Error('Oh my')).then(function(success) {
-},
-function(error) {
- console.log(error);
- throw error;
-});
\ No newline at end of file
+++ /dev/null
-
-Promise.resolve('Success').then(function(value) {
- console.log(value);
-},
-function(value) {
- console.log('ignored');
-});
\ No newline at end of file
+++ /dev/null
-var p = Promise.resolve([1,2,3]);
-p.then(function(v) {
- console.log(v[0]);
-});
\ No newline at end of file
+++ /dev/null
-var p1 = Promise.resolve({
- then: function(onFulfill, onReject) { onFulfill('fulfilled!'); }
-});
-
-console.log(p1 instanceof Promise);
-
-p1.then(function(v) {
- console.log(v);
-},
-function(e) {
- console.log('ignored');
-});
\ No newline at end of file
+++ /dev/null
-var thenable = {
- then: function(resolve) {
- console.log('Ok')
- resolve();
- }
-};
-
-function executor(resolve, reject) {
- resolve(thenable);
- throw new Error('ignored');
-}
-
-new Promise(executor).then(() => {});
\ No newline at end of file
+++ /dev/null
-var executorFunction;
-
-function NotPromise(executor) {
- executorFunction = executor;
- executor(function() {console.log('S')}, function() {console.log('R')});
-}
-
-Promise.resolve.call(NotPromise);
-
-console.log(Object.isExtensible(executorFunction));
\ No newline at end of file
+/*---
+includes: [compareArray.js]
+flags: []
+---*/
+
var res = [];
function abc() {
var promise = new Promise(function(resolve, reject) {
res.push('Two');
promise.then(() => {res.push('Four'); return {num: 'Five'}})
.then((obj) => {res.push(obj.num); return {num: 'Six'}})
- .then((obj) => {res.push(obj.num); return {num: 'Seven'}})
- .then((obj) => {res.push(obj.num); return {num: 'Eight'}})
.then((obj) => {res.push(obj.num)});
res.push('Three');
}
+
abc();
-console.log(res.join(','));
-setTimeout(() => console.log(res.join(',')), 0);
+assert.compareArray(res, ['One', 'Two', 'Three']);
+setTimeout(() => assert.compareArray(res, ['One', 'Two', 'Three', 'Four', 'Five', 'Six']), 0);
+++ /dev/null
-Promise.resolve()
-.then(() => {nonExsisting()});
\ No newline at end of file
--- /dev/null
+/*---
+includes: []
+flags: []
+negative:
+ phase: runtime
+---*/
+
+Promise.resolve()
+.then(() => {nonExsisting()});
+++ /dev/null
-Promise.resolve()
-.then(() => {nonExsisting()})
-.catch(() => {console.log("Done")});
\ No newline at end of file
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+let called = false;
+
+Promise.resolve()
+.then(() => {nonExsisting()})
+.catch(() => {called = true;})
+.then(v => assert.sameValue(called, true))
+.then($DONE, $DONE);
+++ /dev/null
-Promise.resolve()
-.then(() => {nonExsisting()})
-.finally(() => {})
-.catch(() => {console.log("Done")});
\ No newline at end of file
--- /dev/null
+/*---
+includes: []
+flags: [async]
+---*/
+
+let called = false;
+
+Promise.resolve()
+.then(() => {nonExsisting()})
+.finally(() => {})
+.catch(() => {called = true;})
+.then(v => assert.sameValue(called, true))
+.then($DONE, $DONE);
+/*---
+includes: []
+flags: []
+negative:
+ phase: runtime
+---*/
+
Promise.resolve()
.then(() => {nonExsistingOne()});
+++ /dev/null
-Promise.resolve()
-.then(() => {nonExsistingOne()});
-
-Promise.resolve()
-.then(() => {nonExsistingTwo()});
\ No newline at end of file
--- /dev/null
+/*---
+includes: []
+flags: []
+negative:
+ phase: runtime
+---*/
+
+Promise.resolve()
+.then(() => {nonExsistingOne()});
+
+Promise.resolve()
+.then(() => {nonExsistingTwo()});
# version
njs_run {"-v"} "\\d+\.\\d+\.\\d+"
-
-# Promise
-
-njs_run {"./test/js/promise_set_timeout.js"} \
-"One,Two,Three
-One,Two,Three,Four,Five,Six,Seven,Eight"
-
-njs_run {"./test/js/promise_s1.js"} \
-"One
-Two
-Three
-123
-Four
-Five
-Six
-Seven
-Eight"
-
-njs_run {"./test/js/promise_s2.js"} \
-"One
-Two
-Three"
-
-njs_run {"./test/js/promise_s3.js"} \
-"One
-Two
-Three
-Rejected: Error: Blah"
-
-njs_run {"./test/js/promise_s4.js"} \
-"Error: Oh my"
-
-njs_run {"./test/js/promise_s5.js"} \
-"Success"
-
-njs_run {"./test/js/promise_s6.js"} \
-"1"
-
-njs_run {"./test/js/promise_s7.js"} \
-"true
-fulfilled!"
-
-njs_run {"./test/js/promise_s8.js"} \
-"Ok"
-
-njs_run {"./test/js/promise_s9.js"} \
-"S
-true"
-
-njs_run {"./test/js/promise_s10.js"} \
-"One
-Two
-Three
-Oh no"
-
-njs_run {"./test/js/promise_s11.js"} \
-"end
-S: all
-R: all"
-
-njs_run {"./test/js/promise_s12.js"} \
-"Done"
-
-njs_run {"./test/js/promise_s13.js"} \
-"Done"
-
-njs_run {"./test/js/promise_s14.js"} \
-"TypeError: oops
- at anonymous \\\(promise_s14.js:5\\\)
- at native \\\(native\\\)
- at main \\\(promise_s14.js:9\\\)
-
-Done"
-
-njs_run {"./test/js/promise_s15.js"} \
-"Done"
-
-njs_run {"./test/js/promise_s16.js"} \
-"Done"
-
-njs_run {"./test/js/promise_s17.js"} \
-"Done"
-
-njs_run {"./test/js/promise_s18.js"} \
-"State 1
-State 2
-State 3
-State 4
-State 5
-Done"
-
-njs_run {"./test/js/promise_s19.js"} \
-"Throw!
-undefined
-Reject!
-Done"
-
-njs_run {"./test/js/promise_s20.js"} \
-"true
-Done"
-
-njs_run {"./test/js/promise_s21.js"} \
-"Done"
-
-njs_run {"./test/js/promise_s22.js"} \
-"true
-Done"
-
-njs_run {"./test/js/promise_s23.js"} \
-"true
-Done"
-
-njs_run {"./test/js/promise_s24.js"} \
-"true"
-
-njs_run {"./test/js/promise_s25.js"} \
-"Done"
-
-njs_run {"./test/js/promise_s26.js"} \
-"BoxedPromise.constructor
-BoxedPromise.prototype.then
-BoxedPromise resolve OK
-BoxedPromise.constructor
-BoxedPromise.prototype.then
-BoxedPromise reject OK
-BoxedPromise.constructor
-BoxedPromise.prototype.then
-BoxedPromise.prototype.then
-BoxedPromise chain OK
-BoxedPromise.prototype.then
-BoxedPromise finally OK
-BoxedPromise sync done
-
-BoxedPromise.prototype.then
-BoxedPromise.prototype.then
-resolved BoxedPromise
-rejected BoxedPromise
-then BoxedPromise
-then BoxedPromise
-finally BoxedPromise
-BoxedPromise.constructor
-BoxedPromise.prototype.then
-BoxedPromise.prototype.then
-BoxedPromise async done
-
-PatchedPromise.constructor
-PatchedPromise.constructor
-PatchedPromise resolve OK
-PatchedPromise.constructor
-PatchedPromise.constructor
-PatchedPromise reject OK
-PatchedPromise.constructor
-PatchedPromise.constructor
-PatchedPromise.constructor
-PatchedPromise chain OK
-PatchedPromise.constructor
-PatchedPromise finally OK
-PatchedPromise sync done
-
-PatchedPromise.constructor
-PatchedPromise.constructor
-resolved PatchedPromise
-rejected PatchedPromise
-then PatchedPromise
-then PatchedPromise
-finally PatchedPromise
-PatchedPromise.constructor
-PatchedPromise.constructor
-PatchedPromise.constructor
-PatchedPromise async done"
-
-# fs
-
-njs_run {"./test/fs/methods.js" "--match-exception-text"} \
-"fs readFile SUCCESS
-fs readFileSync SUCCESS
-fsp readFile SUCCESS
-fs writeFile SUCCESS
-fs writeFileSync SUCCESS
-fsp writeFile SUCCESS
-fs appendFile SUCCESS
-fs appendFileSync SUCCESS
-fsp appendFile SUCCESS
-fs realpath SUCCESS
-fs realpathSync SUCCESS
-fsp realpath SUCCESS
-fs stat SUCCESS
-fs statSync SUCCESS
-fsp stat SUCCESS
-fs lstat SUCCESS
-fs lstatSync SUCCESS
-fsp lstat SUCCESS"
-
-njs_run {"./test/js/fs_promises_001.js"} \
-"init ok true
-short circut ok true
-chain ok true
-error 1 ok true
-error 2 ok true
-errors ok"
-
-njs_run {"./test/js/fs_promises_002.js"} \
-"testSync ok true
-testCallback ok true
-testPromise ok true"
-
-njs_run {"./test/js/fs_promises_003.js"} \
-"test fs.unlinkSync
-test fs.unlink
-test fsp.unlink"
-
-njs_run {"./test/js/fs_promises_004.js"} \
-"test fs.symlinkSync
-test fs.symlink
-test fsp.symlink"
-
-njs_run {"./test/js/fs_promises_005.js"} \
-"test fs.mkdirSync
-test fs.mkdir
-test fsp.mkdir"
-
-njs_run {"./test/js/fs_promises_006.js"} \
-"test fs.renameSync
-test fs.rename
-test fsp.rename"
-
-njs_run {"./test/js/fs_promises_007.js"} \
-"test fs.readdirSync
-test fs.readdir
-test fsp.readdir"
-
-njs_run {"./test/js/fs_promises_008.js"} \
-"test recursive fs.mkdirSync"
-
-njs_run {"./test/js/fs_promises_009.js"} \
-"test recursive fs.rmdirSync"
-
-njs_run {"./test/js/promise_then_throw_finally_catch.js"} \
-"Done"
-
-njs_run {"./test/js/promise_catch_throw.js"} \
-"Error: unhandled promise rejection: ReferenceError: \"nonExsistingInCatch\" is not defined"
-
-njs_run {"./test/js/promise_then_throw.js"} \
-"Error: unhandled promise rejection: ReferenceError: \"nonExsisting\" is not defined"
-
-njs_run {"./test/js/promise_then_throw_catch.js"} \
-"Done"
-
-njs_run {"./test/js/promise_catch_then_throw_catch.js"} \
-"Done"
-
-njs_run {"./test/js/promise_finally.js"} \
-"here
-Thrown:
-Error: unhandled promise rejection: nope"
-
-njs_run {"./test/js/promise_finally_throw.js"} \
-"Error: unhandled promise rejection: ReferenceError: \"nonExsistingInFinally\" is not defined"
-
-njs_run {"./test/js/promise_finally_throw_catch.js"} \
-"Done"
-
-njs_run {"./test/js/promise_two_then_throw.js"} \
-"Error: unhandled promise rejection: ReferenceError: \"nonExsistingOne\" is not defined"
-
-njs_run {"./test/js/promise_two_first_then_throw.js"} \
-"Error: unhandled promise rejection: ReferenceError: \"nonExsistingOne\" is not defined"
-
-njs_run {"./test/js/promise_reject_catch.js"} \
-"rejected test"
-
-njs_run {"./test/js/promise_reject_post_catch.js"} \
-"Error: unhandled promise rejection: undefined"
-
-njs_run {"./test/js/promise_rejection_tracker.js"} \
-"Thrown:
-Error: unhandled promise rejection: 1"
-
-njs_run {"./test/js/promise_all.js"} \
-"resolved:\\\[\\\['one','two'],\\\['three','four']]"
-
-njs_run {"./test/js/promise_all_throw.js"} \
-"rejected:foo"
-
-njs_run {"./test/js/promise_allSettled.js"} \
-"resolved:resolved:F:0,3,42,here|R:finally,finally after rejected,foo,here too,yes"
-
-njs_run {"./test/js/promise_allSettled_string.js"} \
-"resolved:F:a,b,c|R:"
-
-njs_run {"./test/js/promise_any.js"} \
-"resolved:4"
-
-njs_run {"./test/js/promise_any_all_rejected.js"} \
-"reject:AggregateError: All promises were rejected"
-
-njs_run {"./test/js/promise_race.js"} \
-"resolved:one"
-
-njs_run {"./test/js/promise_race_throw.js"} \
-"rejected:one"
-
-# Webcrypto
-
-njs_run {"./test/webcrypto/rsa_decoding.js" "--match-exception-text"} \
-"RSA-OAEP decoding SUCCESS"
-
-njs_run {"./test/webcrypto/rsa.js" "--match-exception-text"} \
-"RSA-OAEP encoding/decoding SUCCESS"
-
-njs_run {"./test/webcrypto/aes_decoding.js" "--match-exception-text"} \
-"AES decoding SUCCESS"
-
-njs_run {"./test/webcrypto/aes.js" "--match-exception-text"} \
-"AES encoding/decoding SUCCESS"
-
-njs_run {"./test/webcrypto/derive.js" "--match-exception-text"} \
-"derive SUCCESS"
-
-njs_run {"./test/webcrypto/digest.js" "--match-exception-text"} \
-"SHA digest SUCCESS"
-
-njs_run {"./test/webcrypto/sign.js" "--match-exception-text"} \
-"HMAC sign SUCCESS
-RSASSA-PKCS1-v1_5 sign SUCCESS
-RSA-PSS sign SUCCESS
-ECDSA sign SUCCESS"
-
-njs_run {"./test/webcrypto/verify.js" "--match-exception-text"} \
-"HMAC verify SUCCESS
-RSASSA-PKCS1-v1_5 verify SUCCESS
-RSA-PSS verify SUCCESS
-ECDSA verify SUCCESS"
-
-# Async/Await
-
-njs_run {"./test/js/async_await_inline.js"} \
-"70"
-
-njs_run {"./test/js/async_await_add.js"} \
-"110"
-
-njs_run {"./test/js/async_await_stages.js"} \
-"30 1, 2, 3, 4, 5"
-
-njs_run {"./test/js/async_await_for.js"} \
-"85 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, end"
-
-njs_run {"./test/js/async_await_blank.js"} \
-"12345"
-
-njs_run {"./test/js/async_await_reject.js"} \
-"Thrown:
-Error: unhandled promise rejection: 50"
-
-njs_run {"./test/js/async_await_catch.js"} \
-"51"
-
-njs_run {"./test/js/async_await_finally.js"} \
-"51
-Thrown:
-Error: unhandled promise rejection: 50"
-
-njs_run {"./test/js/async_await_throw.js"} \
-"Thrown:
-Error: unhandled promise rejection: 50"
-
-njs_run {"./test/js/async_await_throw_catch.js"} \
-"110"
-
-njs_run {"./test/js/async_await_throw_async.js"} \
-"Thrown:
-Error: unhandled promise rejection: 51"
-
-njs_run {"./test/js/async_await_throw_catch_async.js"} \
-"51"
-
-njs_run {"./test/js/async_await_try_catch.js"} \
-"reject
-finally
-end"
-
-njs_run {"./test/js/async_await_try_finally.js"} \
-"Thrown:
-Error: unhandled promise rejection: finally reject"
-
-njs_run {"./test/js/async_await_try_throw.js"} \
-"finally
-Thrown:
-Error: unhandled promise rejection: try"
-
-njs_run {"./test/js/async_await_try_throw_catch.js"} \
-"try
-finally
-end"
-
-njs_run {"./test/js/async_await_try_resolve.js"} \
-"key: resolve"
-
-njs_run {"./test/js/async_await_many_call.js"} \
-"\\\['First: SUN MOON','Second: CAT MOUSE','Third: MAN WOMAN']"
--- /dev/null
+#!/bin/sh
+
+# Copyright (C) Dmitry Volyntsev
+# Copyright (C) NGINX, Inc.
+
+NJS_TEST_DIR=`mktemp -d /tmp/njs_test.XXX`
+NJS_TEST_LOG_DEFAULT="$NJS_TEST_DIR/log.log"
+
+NJS_TEST_VERBOSE=${NJS_TEST_VERBOSE:-}
+NJS_TEST_BINARY=${NJS_TEST_BINARY:-build/njs}
+NJS_TEST_LOG=${NJS_TEST_LOG:-${NJS_TEST_LOG_DEFAULT}}
+
+for njs_option
+do
+ case "$njs_option" in
+ -*=*) value=`echo "$njs_option" | sed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) value="" ;;
+ esac
+
+ case "$njs_option" in
+ --binary=*)
+ NJS_TEST_BINARY="$value"
+ shift
+ ;;
+
+ --log=*)
+ NJS_TEST_LOG="$value"
+ shift
+ ;;
+
+ --test-dir=*)
+ NJS_TEST_DIR="$value"
+ shift
+ ;;
+
+ --verbose=*)
+ NJS_TEST_VERBOSE="$value"
+ shift
+ ;;
+
+ --help)
+ . test/help
+ exit 0
+ ;;
+
+ --*)
+ echo
+ echo $0: error: invalid option \"$njs_option\".
+ echo Run \"$0 --help\" to see available options.
+ echo
+ exit 1
+ ;;
+
+ *)
+ break
+ ;;
+ esac
+
+done
+
+NJS_TEST_PATHS=${@:-test}
--- /dev/null
+#!/bin/sh
+
+# Copyright (C) Dmitry Volyntsev
+# Copyright (C) NGINX, Inc.
+
+njs_includes=`grep 'includes: \[[^]]*]' $njs_test \
+ | sed -e 's/includes: \[//' | sed -e 's/,/ /g' | sed -e 's/\]//'`
+njs_includes="assert.js sta.js $njs_includes"
+
+njs_flags=`grep 'flags: \[[^]]*]' $njs_test \
+ | sed -e 's/flags: \[//' | sed -e 's/,/ /g' | sed -e 's/\]//'`
+
+njs_negative=`grep 'negative:' $njs_test > /dev/null \
+ && grep 'phase: ' $njs_test | sed -e 's/ *phase: //' || true`
+
+njs_async=no
+for flag in $njs_flags; do
+ case $flag in
+ async)
+ njs_async=yes
+ njs_includes="compatPrint.js doneprintHandle.js $njs_includes"
+
+ ;;
+ esac
+done
+
+njs_inc=
+for file in $njs_includes; do
+ njs_inc="$njs_inc test/harness/$file"
+done
+
+mkdir -p `dirname $NJS_TEST_DIR/$njs_test`
+
+cat $njs_inc $njs_test > $NJS_TEST_DIR/$njs_test
+
+njs_total=$((njs_total+1))
--- /dev/null
+#!/bin/sh
+
+# Copyright (C) Dmitry Volyntsev
+# Copyright (C) NGINX, Inc.
+
+NJS_STATUS="PASSED"
+if [ $njs_passed -ne $njs_total ]; then
+ NJS_STATUS="FAILED"
+fi
+
+if [ -n "$njs_failed_list" ]; then
+ for t in $njs_failed_list; do
+ printf "$t FAILED\n"
+ done
+fi
+
+printf "TOTAL: $NJS_STATUS [$njs_passed/$njs_total]\n"
+exit $(($njs_passed != $njs_total))
--- /dev/null
+#!/bin/sh
+
+# Copyright (C) Dmitry Volyntsev
+# Copyright (C) NGINX, Inc.
+
+verbose() {
+ if [ -n "$NJS_TEST_VERBOSE" ]; then
+ printf "$1"
+ fi
+}
+
+passed() {
+ verbose " PASSED\n"
+ njs_passed=$((njs_passed+1))
+}
+
+failed() {
+ njs_failed_list="$njs_failed_list $1"
+ verbose " FAILED\n"
+}
+
+verbose "Test dir: $NJS_TEST_DIR\n"
+verbose "Log file: $NJS_TEST_LOG\n"
+verbose "\n"
+
+njs_passed=0
+njs_total=0
+njs_failed_list=""
+
+NJS_TESTS=""
+for arg in $NJS_TEST_PATHS; do
+ if [ -d $arg ]; then
+ NJS_TESTS="$NJS_TESTS $(find $arg -name '*\.t\.js')"
+ else
+ NJS_TESTS="$NJS_TESTS $arg"
+ fi
+done
+
+NJS_TESTS=`printf "%s\n" $NJS_TESTS | sort`
--- /dev/null
+#!/bin/sh
+
+# Copyright (C) Dmitry Volyntsev
+# Copyright (C) NGINX, Inc.
+
+set -e
+
+. test/options
+. test/setup
+
+for njs_test in $NJS_TESTS; do
+ . test/prepare
+
+ njs_log="$NJS_TEST_DIR/${njs_test%.*}.log"
+
+ verbose "$njs_test $njs_log"
+ cat << END >> $NJS_TEST_LOG
+----------------------------------------
+running $njs_test $njs_log
+END
+
+ if /bin/sh -c "($NJS_TEST_BINARY $NJS_TEST_DIR/$njs_test)" > $njs_log 2>&1; then
+ njs_success=yes
+ else
+ njs_success=no
+ fi
+
+ cat $njs_log >> $NJS_TEST_LOG
+ njs_out=`cat $njs_log`
+
+ if [ $njs_success = yes ]; then
+ if [ -n "$njs_negative" ]; then
+ failed $njs_test
+
+ elif [ $njs_async = yes ]; then
+ if [ "$njs_out" != 'Test262:AsyncTestComplete' ]; then
+ failed $njs_test
+
+ else
+ passed $njs_test
+ fi
+
+ else
+ if [ -n "$njs_out" ]; then
+ failed $njs_test
+
+ else
+ passed $njs_test
+ fi
+ fi
+
+ else
+ if [ -n "$njs_negative" ]; then
+ passed $njs_test
+
+ else
+ failed $njs_test
+ fi
+ fi
+
+done
+
+. test/finalize
+. test/report
-if (typeof crypto == 'undefined') {
- crypto = require('crypto').webcrypto;
-}
+/*---
+includes: [compatFs.js, compatBuffer.js, compatWebcrypto.js, runTsuite.js, webCryptoUtils.js]
+flags: [async]
+---*/
-async function run(tlist) {
- function validate(t, r, i) {
- if (r.status == "fulfilled" && !t[i].exception) {
- return r.value === "SUCCESS";
- }
+async function test(params) {
+ let dkey = await crypto.subtle.importKey("raw", params.key,
+ {name: params.name},
+ false, ["decrypt"]);
- if (r.status == "rejected" && t[i].exception) {
- if (process.argv[2] === '--match-exception-text') {
- /* is not compatible with node.js format */
- return r.reason.toString().startsWith(t[i].exception);
- }
+ let ekey = await crypto.subtle.importKey("raw", params.key,
+ {name: params.name},
+ false, ["encrypt"]);
- return true;
- }
+ let enc = await crypto.subtle.encrypt(params, ekey, params.data);
+ let plaintext = await crypto.subtle.decrypt(params, dkey, enc);
+ plaintext = Buffer.from(plaintext);
- return false;
+ if (params.data.compare(plaintext) != 0) {
+ throw Error(`${params.name} encoding/decoding failed length ${data.length}`);
}
- for (let k = 0; k < tlist.length; k++) {
- let ts = tlist[k];
- let results = await Promise.allSettled(ts.tests.map(t => ts.T(ts.prepare_args(t, ts.opts))));
- let r = results.map((r, i) => validate(ts.tests, r, i));
-
- console.log(`${ts.name} ${r.every(v=>v == true) ? "SUCCESS" : "FAILED"}`);
-
- r.forEach((v, i) => {
- if (!v) {
- console.log(`FAILED ${i}: ${JSON.stringify(ts.tests[i])}\n with reason: ${results[i].reason}`);
- }
- })
- }
+ return 'SUCCESS';
}
function p(args, default_opts) {
return params;
}
-async function test(params) {
- let dkey = await crypto.subtle.importKey("raw", params.key,
- {name: params.name},
- false, ["decrypt"]);
-
- let ekey = await crypto.subtle.importKey("raw", params.key,
- {name: params.name},
- false, ["encrypt"]);
-
- let enc = await crypto.subtle.encrypt(params, ekey, params.data);
- let plaintext = await crypto.subtle.decrypt(params, dkey, enc);
- plaintext = Buffer.from(plaintext);
-
- if (params.data.compare(plaintext) != 0) {
- throw Error(`${params.name} encoding/decoding failed length ${data.length}`);
- }
-
- return 'SUCCESS';
-}
let aes_tsuite = {
name: "AES encoding/decoding",
+ skip: () => (!has_fs() || !has_buffer() || !has_webcrypto()),
T: test,
prepare_args: p,
opts: {
{ name: "AES-CBC", data: "aabbccdd".repeat(5), iv: "ffffffffffffffffffffffffffffffff" },
]};
-run([aes_tsuite]);
+run([aes_tsuite])
+.then($DONE, $DONE);
-const fs = require('fs');
+/*---
+includes: [compatFs.js, compatBuffer.js, compatWebcrypto.js, runTsuite.js, webCryptoUtils.js]
+flags: [async]
+---*/
-if (typeof crypto == 'undefined') {
- crypto = require('crypto').webcrypto;
-}
-
-async function run(tlist) {
- function validate(t, r, i) {
- if (r.status == "fulfilled" && !t[i].exception) {
- return r.value === "SUCCESS";
- }
-
- if (r.status == "rejected" && t[i].exception) {
- if (process.argv[2] === '--match-exception-text') {
- /* is not compatible with node.js format */
- return r.reason.toString().startsWith(t[i].exception);
- }
-
- return true;
- }
-
- return false;
- }
-
- for (let k = 0; k < tlist.length; k++) {
- let ts = tlist[k];
- let results = await Promise.allSettled(ts.tests.map(t => ts.T(ts.prepare_args(t, ts.opts))));
- let r = results.map((r, i) => validate(ts.tests, r, i));
+async function test(params) {
+ let enc = base64decode(fs.readFileSync(`test/webcrypto/${params.file}`));
+ let key = await crypto.subtle.importKey("raw", params.key,
+ {name: params.name},
+ false, ["decrypt"]);
- console.log(`${ts.name} ${r.every(v=>v == true) ? "SUCCESS" : "FAILED"}`);
+ let plaintext = await crypto.subtle.decrypt(params, key, enc);
+ plaintext = new TextDecoder().decode(plaintext);
- r.forEach((v, i) => {
- if (!v) {
- console.log(`FAILED ${i}: ${JSON.stringify(ts.tests[i])}\n with reason: ${results[i].reason}`);
- }
- })
+ if (params.expected != plaintext) {
+ throw Error(`${params.name} decoding failed expected: "${params.expected}" vs "${plaintext}"`);
}
-}
-function base64decode(b64) {
- const joined = b64.toString().split('\n').join('');
- return Buffer.from(joined, 'base64');
+ return 'SUCCESS';
}
function p(args, default_opts) {
return params;
}
-async function test(params) {
- let enc = base64decode(fs.readFileSync(`test/webcrypto/${params.file}`));
- let key = await crypto.subtle.importKey("raw", params.key,
- {name: params.name},
- false, ["decrypt"]);
-
- let plaintext = await crypto.subtle.decrypt(params, key, enc);
- plaintext = new TextDecoder().decode(plaintext);
-
- if (params.expected != plaintext) {
- throw Error(`${params.name} decoding failed expected: "${params.expected}" vs "${plaintext}"`);
- }
-
- return 'SUCCESS';
-}
-
let aes_tsuite = {
name: "AES decoding",
+ skip: () => (!has_fs() || !has_buffer() || !has_webcrypto()),
T: test,
prepare_args: p,
opts: {
expected: "AES-CBC-256-SECRET-TEXT" },
]};
-run([aes_tsuite]);
+run([aes_tsuite])
+.then($DONE, $DONE);
-if (typeof crypto == 'undefined') {
- crypto = require('crypto').webcrypto;
-}
-
-async function run(tlist) {
- function validate(t, r, i) {
- if (r.status == "fulfilled" && !t[i].exception) {
- return r.value === "SUCCESS";
- }
-
- if (r.status == "rejected" && t[i].exception) {
- if (process.argv[2] === '--match-exception-text') {
- /* is not compatible with node.js format */
- return r.reason.toString().startsWith(t[i].exception);
- }
-
- return true;
- }
-
- if (r.status == "rejected" && t[i].optional) {
- return r.reason.toString().startsWith("InternalError: not implemented");
- }
-
- return false;
- }
-
- for (let k = 0; k < tlist.length; k++) {
- let ts = tlist[k];
- let results = await Promise.allSettled(ts.tests.map(t => ts.T(ts.prepare_args(t, ts.opts))));
- let r = results.map((r, i) => validate(ts.tests, r, i));
-
- console.log(`${ts.name} ${r.every(v=>v == true) ? "SUCCESS" : "FAILED"}`);
-
- r.forEach((v, i) => {
- if (!v) {
- console.log(`FAILED ${i}: ${JSON.stringify(ts.tests[i])}\n with reason: ${results[i].reason}`);
- }
- })
- }
-}
-
-function merge(to, from) {
- let r = Object.assign({}, to);
- Object.keys(from).forEach(v => {
- if (typeof r[v] == 'object' && typeof from[v] == 'object') {
- r[v] = merge(r[v], from[v]);
-
- } else if (typeof from[v] == 'object') {
- r[v] = Object.assign({}, from[v]);
-
- } else {
- r[v] = from[v];
- }
- })
-
- return r;
-};
-
-function p(args, default_opts) {
- let params = Object.assign({}, default_opts);
- params = merge(params, args);
-
- params.algorithm.salt = Buffer.from(params.algorithm.salt, "hex");
- params.algorithm.info = Buffer.from(params.algorithm.info, "hex");
- params.derivedAlgorithm.iv = Buffer.from(params.derivedAlgorithm.iv, "hex");
-
- return params;
-}
+/*---
+includes: [compatFs.js, compatBuffer.js, compatWebcrypto.js, runTsuite.js, webCryptoUtils.js]
+flags: [async]
+---*/
async function test(params) {
let r;
return "SUCCESS";
}
+function p(args, default_opts) {
+ let params = Object.assign({}, default_opts);
+ params = merge(params, args);
+
+ params.algorithm.salt = Buffer.from(params.algorithm.salt, "hex");
+ params.algorithm.info = Buffer.from(params.algorithm.info, "hex");
+ params.derivedAlgorithm.iv = Buffer.from(params.derivedAlgorithm.iv, "hex");
+
+ return params;
+}
+
let derive_tsuite = {
name: "derive",
+ skip: () => (!has_fs() || !has_buffer() || !has_webcrypto()),
T: test,
prepare_args: p,
opts: {
expected: "e089c7491711306c69e077aa19fae6bfd2d4a6d240b0d37317d50472d7291a3e" },
]};
-run([derive_tsuite]);
+run([derive_tsuite])
+.then($DONE, $DONE);
-if (typeof crypto == 'undefined') {
- crypto = require('crypto').webcrypto;
-}
-
-async function run(tlist) {
- function validate(t, r, i) {
- if (r.status == "fulfilled" && !t[i].exception) {
- return r.value === "SUCCESS";
- }
-
- if (r.status == "rejected" && t[i].exception) {
- if (process.argv[2] === '--match-exception-text') {
- /* is not compatible with node.js format */
- return r.reason.toString().startsWith(t[i].exception);
- }
-
- return true;
- }
-
- return false;
- }
-
- for (let k = 0; k < tlist.length; k++) {
- let ts = tlist[k];
- let results = await Promise.allSettled(ts.tests.map(t => ts.T(ts.prepare_args(t, ts.opts))));
- let r = results.map((r, i) => validate(ts.tests, r, i));
-
- console.log(`${ts.name} ${r.every(v=>v == true) ? "SUCCESS" : "FAILED"}`);
-
- r.forEach((v, i) => {
- if (!v) {
- console.log(`FAILED ${i}: ${JSON.stringify(ts.tests[i])}\n with reason: ${results[i].reason}`);
- }
- })
- }
-}
-
-function p(args) {
- let params = Object.assign({}, args);
- params.data = Buffer.from(params.data, "hex");
- return params;
-}
+/*---
+includes: [compatFs.js, compatBuffer.js, compatWebcrypto.js, runTsuite.js, webCryptoUtils.js]
+flags: [async]
+---*/
async function test(params) {
let digest = await crypto.subtle.digest(params.name, params.data);
return 'SUCCESS';
}
+function p(args) {
+ let params = Object.assign({}, args);
+ params.data = Buffer.from(params.data, "hex");
+ return params;
+}
+
let digest_tsuite = {
name: "SHA digest",
+ skip: () => (!has_fs() || !has_buffer() || !has_webcrypto()),
T: test,
prepare_args: p,
opts: { },
expected: "cdea58919606ea9ae078f7595b192b84446f2189" },
]};
-run([digest_tsuite]);
+run([digest_tsuite])
+.then($DONE, $DONE);
-const fs = require('fs');
-
-if (typeof crypto == 'undefined') {
- crypto = require('crypto').webcrypto;
-}
-
-async function run(tlist) {
- function validate(t, r, i) {
- if (r.status == "fulfilled" && !t[i].exception) {
- return r.value === "SUCCESS";
- }
-
- if (r.status == "rejected" && t[i].exception) {
- if (process.argv[2] === '--match-exception-text') {
- /* is not compatible with node.js format */
- return r.reason.toString().startsWith(t[i].exception);
- }
-
- return true;
- }
-
- return false;
- }
-
- for (let k = 0; k < tlist.length; k++) {
- let ts = tlist[k];
- let results = await Promise.allSettled(ts.tests.map(t => ts.T(ts.prepare_args(t, ts.opts))));
- let r = results.map((r, i) => validate(ts.tests, r, i));
-
- console.log(`${ts.name} ${r.every(v=>v == true) ? "SUCCESS" : "FAILED"}`);
-
- r.forEach((v, i) => {
- if (!v) {
- console.log(`FAILED ${i}: ${JSON.stringify(ts.tests[i])}\n with reason: ${results[i].reason}`);
- }
- })
- }
-}
-
-function pem_to_der(pem, type) {
- const pemJoined = pem.toString().split('\n').join('');
- const pemHeader = `-----BEGIN ${type} KEY-----`;
- const pemFooter = `-----END ${type} KEY-----`;
- const pemContents = pemJoined.substring(pemHeader.length, pemJoined.length - pemFooter.length);
- return Buffer.from(pemContents, 'base64');
-}
-
-function p(args, default_opts) {
- let params = Object.assign({}, default_opts, args);
-
- params.data = Buffer.from(params.data, "hex");
-
- return params;
-}
+/*---
+includes: [compatFs.js, compatBuffer.js, compatWebcrypto.js, runTsuite.js, webCryptoUtils.js]
+flags: [async]
+---*/
async function test(params) {
let spki = await crypto.subtle.importKey("spki",
}
return 'SUCCESS';
-};
+}
+
+function p(args, default_opts) {
+ let params = Object.assign({}, default_opts, args);
+
+ params.data = Buffer.from(params.data, "hex");
+
+ return params;
+}
let rsa_tsuite = {
name: "RSA-OAEP encoding/decoding",
+ skip: () => (!has_fs() || !has_buffer() || !has_webcrypto()),
T: test,
prepare_args: p,
opts: {
{ data: "aabbcc", spki: "rsa2.spki", exception: "Error: EVP_PKEY_decrypt() failed" },
]};
-run([rsa_tsuite]);
+run([rsa_tsuite])
+.then($DONE, $DONE);
+++ /dev/null
-const fs = require('fs');
-
-if (typeof crypto == 'undefined') {
- crypto = require('crypto').webcrypto;
-}
-
-async function run(tlist) {
- function validate(t, r, i) {
- if (r.status == "fulfilled" && !t[i].exception) {
- return r.value === "SUCCESS";
- }
-
- if (r.status == "rejected" && t[i].exception) {
- if (process.argv[2] === '--match-exception-text') {
- /* is not compatible with node.js format */
- return r.reason.toString().startsWith(t[i].exception);
- }
-
- return true;
- }
-
- return false;
- }
-
- for (let k = 0; k < tlist.length; k++) {
- let ts = tlist[k];
- let results = await Promise.allSettled(ts.tests.map(t => ts.T(ts.prepare_args(t, ts.opts))));
- let r = results.map((r, i) => validate(ts.tests, r, i));
-
- console.log(`${ts.name} ${r.every(v=>v == true) ? "SUCCESS" : "FAILED"}`);
-
- r.forEach((v, i) => {
- if (!v) {
- console.log(`FAILED ${i}: ${JSON.stringify(ts.tests[i])}\n with reason: ${results[i].reason}`);
- }
- })
- }
-}
-
-function pem_to_der(pem) {
- const pemJoined = pem.toString().split('\n').join('');
- const pemHeader = '-----BEGIN PRIVATE KEY-----';
- const pemFooter = '-----END PRIVATE KEY-----';
- const pemContents = pemJoined.substring(pemHeader.length, pemJoined.length - pemFooter.length);
- return Buffer.from(pemContents, 'base64');
-}
-
-function base64decode(b64) {
- const joined = b64.toString().split('\n').join('');
- return Buffer.from(joined, 'base64');
-}
-
-async function test(params) {
- let pem = fs.readFileSync(`test/webcrypto/${params.pem}`);
- let enc = base64decode(fs.readFileSync(`test/webcrypto/${params.src}`));
-
- let key = await crypto.subtle.importKey("pkcs8", pem_to_der(pem),
- {name:"RSA-OAEP", hash:"SHA-1"},
- false, ["decrypt"]);
-
- let plaintext = await crypto.subtle.decrypt({name: "RSA-OAEP"}, key, enc);
- plaintext = new TextDecoder().decode(plaintext);
-
- if (params.expected != plaintext) {
- throw Error(`RSA-OAEP decoding failed expected: "${params.expected}" vs "${plaintext}"`);
- }
-
- return "SUCCESS";
-}
-
-let rsa_tsuite = {
- name: "RSA-OAEP decoding",
- T: test,
- prepare_args: (v) => v,
- opts: { },
-
- tests: [
- { pem: "rsa.pkcs8", src: "text.base64.rsa-oaep.enc", expected: "WAKAWAKA" },
- { pem: "ec.pkcs8", src: "text.base64.rsa-oaep.enc", exception: "Error: RSA key is not found" },
- { pem: "rsa.pkcs8.broken", src: "text.base64.rsa-oaep.enc", exception: "Error: d2i_PKCS8_PRIV_KEY_INFO_bio() failed" },
-]};
-
-run([rsa_tsuite]);
--- /dev/null
+/*---
+includes: [compatFs.js, compatBuffer.js, compatWebcrypto.js, runTsuite.js, webCryptoUtils.js]
+flags: [async]
+---*/
+
+async function test(params) {
+ if (!has_fs() || !has_buffer() || !has_webcrypto()) {
+ return 'SKIPPED';
+ }
+
+ let pem = fs.readFileSync(`test/webcrypto/${params.pem}`);
+ let enc = base64decode(fs.readFileSync(`test/webcrypto/${params.src}`));
+
+ let key = await crypto.subtle.importKey("pkcs8", pem_to_der(pem, "PRIVATE"),
+ {name:"RSA-OAEP", hash:"SHA-1"},
+ false, ["decrypt"]);
+
+ let plaintext = await crypto.subtle.decrypt({name: "RSA-OAEP"}, key, enc);
+ plaintext = new TextDecoder().decode(plaintext);
+
+ if (params.expected != plaintext) {
+ throw Error(`RSA-OAEP decoding failed expected: "${params.expected}" vs "${plaintext}"`);
+ }
+
+ return "SUCCESS";
+}
+
+let rsa_tsuite = {
+ name: "RSA-OAEP decoding",
+ T: test,
+ prepare_args: (v) => v,
+ opts: { },
+
+ tests: [
+ { pem: "rsa.pkcs8", src: "text.base64.rsa-oaep.enc", expected: "WAKAWAKA" },
+ { pem: "ec.pkcs8", src: "text.base64.rsa-oaep.enc", exception: "Error: RSA key is not found" },
+ { pem: "rsa.pkcs8.broken", src: "text.base64.rsa-oaep.enc", exception: "Error: d2i_PKCS8_PRIV_KEY_INFO_bio() failed" },
+]};
+
+run([rsa_tsuite])
+.then($DONE, $DONE);
-const fs = require('fs');
-if (typeof crypto == 'undefined') {
- crypto = require('crypto').webcrypto;
-}
-
-async function run(tlist) {
- function validate(t, r, i) {
- if (r.status == "fulfilled" && !t[i].exception) {
- return r.value === "SUCCESS";
- }
-
- if (r.status == "rejected" && t[i].exception) {
- if (process.argv[2] === '--match-exception-text') {
- /* is not compatible with node.js format */
- return r.reason.toString().startsWith(t[i].exception);
- }
-
- return true;
- }
-
- return false;
- }
-
- for (let k = 0; k < tlist.length; k++) {
- let ts = tlist[k];
- let results = await Promise.allSettled(ts.tests.map(t => ts.T(ts.prepare_args(t, ts.opts))));
- let r = results.map((r, i) => validate(ts.tests, r, i));
-
- console.log(`${ts.name} ${r.every(v=>v == true) ? "SUCCESS" : "FAILED"}`);
-
- r.forEach((v, i) => {
- if (!v) {
- console.log(`FAILED ${i}: ${JSON.stringify(ts.tests[i])}\n with reason: ${results[i].reason}`);
- }
- })
- }
-}
-
-function merge(to, from) {
- let r = Object.assign({}, to);
- Object.keys(from).forEach(v => {
- if (typeof r[v] == 'object' && typeof from[v] == 'object') {
- r[v] = merge(r[v], from[v]);
-
- } else if (typeof from[v] == 'object') {
- r[v] = Object.assign({}, from[v]);
-
- } else {
- r[v] = from[v];
- }
- })
-
- return r;
-};
-
-function pem_to_der(pem, type) {
- const pemJoined = pem.toString().split('\n').join('');
- const pemHeader = `-----BEGIN ${type} KEY-----`;
- const pemFooter = `-----END ${type} KEY-----`;
- const pemContents = pemJoined.substring(pemHeader.length, pemJoined.length - pemFooter.length);
- return Buffer.from(pemContents, 'base64');
-}
-
-function base64decode(b64) {
- const joined = b64.toString().split('\n').join('');
- return Buffer.from(joined, 'base64');
-}
-
-function p(args, default_opts) {
- let key;
- let encoder = new TextEncoder();
- let params = merge({}, default_opts);
- params = merge(params, args);
-
- switch (params.sign_key.fmt) {
- case "pkcs8":
- let pem = fs.readFileSync(`test/webcrypto/${params.sign_key.key}`);
- key = pem_to_der(pem, "PRIVATE");
- break;
- case "raw":
- key = encoder.encode(params.sign_key.key);
- break;
- default:
- throw Error("Unknown sign key format");
- }
-
- params.sign_key.key = key;
-
- switch (params.verify_key.fmt) {
- case "spki":
- let pem = fs.readFileSync(`test/webcrypto/${params.verify_key.key}`);
- key = pem_to_der(pem, "PUBLIC");
- break;
- case "raw":
- key = encoder.encode(params.verify_key.key);
- break;
- default:
- throw Error("Unknown verify key format");
- }
-
- params.verify_key.key = key;
-
- return params;
-}
+/*---
+includes: [compatFs.js, compatBuffer.js, compatWebcrypto.js, runTsuite.js, webCryptoUtils.js]
+flags: [async]
+---*/
async function test(params) {
let encoder = new TextEncoder();
return "SUCCESS";
}
+function p(args, default_opts) {
+ let key;
+ let encoder = new TextEncoder();
+ let params = merge({}, default_opts);
+ params = merge(params, args);
+
+ switch (params.sign_key.fmt) {
+ case "pkcs8":
+ let pem = fs.readFileSync(`test/webcrypto/${params.sign_key.key}`);
+ key = pem_to_der(pem, "PRIVATE");
+ break;
+ case "raw":
+ key = encoder.encode(params.sign_key.key);
+ break;
+ default:
+ throw Error("Unknown sign key format");
+ }
+
+ params.sign_key.key = key;
+
+ switch (params.verify_key.fmt) {
+ case "spki":
+ let pem = fs.readFileSync(`test/webcrypto/${params.verify_key.key}`);
+ key = pem_to_der(pem, "PUBLIC");
+ break;
+ case "raw":
+ key = encoder.encode(params.verify_key.key);
+ break;
+ default:
+ throw Error("Unknown verify key format");
+ }
+
+ params.verify_key.key = key;
+
+ return params;
+}
+
let hmac_tsuite = {
name: "HMAC sign",
+ skip: () => (!has_fs() || !has_buffer() || !has_webcrypto()),
T: test,
prepare_args: p,
opts: {
let rsassa_pkcs1_v1_5_tsuite = {
name: "RSASSA-PKCS1-v1_5 sign",
+ skip: () => (!has_fs() || !has_buffer() || !has_webcrypto()),
T: test,
prepare_args: p,
opts: {
let rsa_pss_tsuite = {
name: "RSA-PSS sign",
+ skip: () => (!has_fs() || !has_buffer() || !has_webcrypto()),
T: test,
prepare_args: p,
opts: {
let ecdsa_tsuite = {
name: "ECDSA sign",
+ skip: () => (!has_fs() || !has_buffer() || !has_webcrypto()),
T: test,
prepare_args: p,
opts: {
rsassa_pkcs1_v1_5_tsuite,
rsa_pss_tsuite,
ecdsa_tsuite
-]);
+])
+.then($DONE, $DONE);
-const fs = require('fs');
+/*---
+includes: [compatFs.js, compatBuffer.js, compatWebcrypto.js, runTsuite.js, webCryptoUtils.js]
+flags: [async]
+---*/
-if (typeof crypto == 'undefined') {
- crypto = require('crypto').webcrypto;
-}
-
-async function run(tlist) {
- function validate(t, r, i) {
- if (r.status == "fulfilled" && !t[i].exception) {
- return r.value === "SUCCESS";
- }
-
- if (r.status == "rejected" && t[i].exception) {
- if (process.argv[2] === '--match-exception-text') {
- /* is not compatible with node.js format */
- return r.reason.toString().startsWith(t[i].exception);
- }
-
- return true;
- }
-
- return false;
- }
-
- for (let k = 0; k < tlist.length; k++) {
- let ts = tlist[k];
- let results = await Promise.allSettled(ts.tests.map(t => ts.T(ts.prepare_args(t, ts.opts))));
- let r = results.map((r, i) => validate(ts.tests, r, i));
+async function test(params) {
+ let key = await crypto.subtle.importKey(params.key.fmt,
+ params.key.file,
+ params.import_alg,
+ false, ["verify"]);
- console.log(`${ts.name} ${r.every(v=>v == true) ? "SUCCESS" : "FAILED"}`);
+ let r = await crypto.subtle.verify(params.verify_alg,
+ key, params.signature,
+ params.text);
- r.forEach((v, i) => {
- if (!v) {
- console.log(`FAILED ${i}: ${JSON.stringify(ts.tests[i])}\n with reason: ${results[i].reason}`);
- }
- })
+ if (params.expected !== r) {
+ throw Error(`${params.import_alg.name} failed expected: "${params.expected}" vs "${r}"`);
}
-}
-
-function merge(to, from) {
- let r = Object.assign({}, to);
- Object.keys(from).forEach(v => {
- if (typeof r[v] == 'object' && typeof from[v] == 'object') {
- r[v] = merge(r[v], from[v]);
-
- } else if (typeof from[v] == 'object') {
- r[v] = Object.assign({}, from[v]);
-
- } else {
- r[v] = from[v];
- }
- })
-
- return r;
-};
-function base64decode(b64) {
- const joined = b64.toString().split('\n').join('');
- return Buffer.from(joined, 'base64');
-}
-
-function pem_to_der(pem, type) {
- const pemJoined = pem.toString().split('\n').join('');
- const pemHeader = `-----BEGIN ${type} KEY-----`;
- const pemFooter = `-----END ${type} KEY-----`;
- const pemContents = pemJoined.substring(pemHeader.length, pemJoined.length - pemFooter.length);
- return Buffer.from(pemContents, 'base64');
+ return 'SUCCESS';
}
function p(args, default_opts) {
return params;
}
-
-async function test(params) {
- let key = await crypto.subtle.importKey(params.key.fmt,
- params.key.file,
- params.import_alg,
- false, ["verify"]);
-
- let r = await crypto.subtle.verify(params.verify_alg,
- key, params.signature,
- params.text);
-
- if (params.expected !== r) {
- throw Error(`${params.import_alg.name} failed expected: "${params.expected}" vs "${r}"`);
- }
-
- return 'SUCCESS';
-}
-
let hmac_tsuite = {
name: "HMAC verify",
+ skip: () => (!has_fs() || !has_buffer() || !has_webcrypto()),
T: test,
prepare_args: p,
opts: {
let rsassa_pkcs1_v1_5_tsuite = {
name: "RSASSA-PKCS1-v1_5 verify",
+ skip: () => (!has_fs() || !has_buffer() || !has_webcrypto()),
T: test,
prepare_args: p,
opts: {
let rsa_pss_tsuite = {
name: "RSA-PSS verify",
+ skip: () => (!has_fs() || !has_buffer() || !has_webcrypto()),
T: test,
prepare_args: p,
opts: {
let ecdsa_tsuite = {
name: "ECDSA verify",
+ skip: () => (!has_fs() || !has_buffer() || !has_webcrypto()),
T: test,
prepare_args: p,
opts: {
rsassa_pkcs1_v1_5_tsuite,
rsa_pss_tsuite,
ecdsa_tsuite,
-]);
+])
+.then($DONE, $DONE);