[njs] Tests: refactored JavaScript tests.
Dmitry Volyntsev
xeioex at nginx.com
Mon Nov 29 16:52:08 UTC 2021
details: https://hg.nginx.org/njs/rev/3b035831f64a
branches:
changeset: 1753:3b035831f64a
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Mon Nov 29 16:50:41 2021 +0000
description:
Tests: refactored JavaScript tests.
A generic runner test/run is introduced. It runs all available tests
in test/ directory. JavaScript files are expected to be compliant with
Test262.
diffstat:
auto/make | 6 +-
test/finalize | 11 +
test/fs/methods.js | 599 -------------------------
test/fs/methods.t.js | 610 ++++++++++++++++++++++++++
test/fs/promises_01.t.js | 42 +
test/fs/promises_02.t.js | 78 +++
test/fs/promises_03.t.js | 104 ++++
test/fs/promises_04.t.js | 196 ++++++++
test/fs/promises_05.t.js | 141 ++++++
test/fs/promises_06.t.js | 105 ++++
test/fs/promises_07.t.js | 239 ++++++++++
test/fs/promises_08.t.js | 86 +++
test/fs/promises_09.t.js | 109 ++++
test/harness/assert.js | 118 +++++
test/harness/compareArray.js | 42 +
test/harness/compatBuffer.js | 3 +
test/harness/compatFs.js | 11 +
test/harness/compatPrint.js | 3 +
test/harness/compatWebcrypto.js | 8 +
test/harness/doneprintHandle.js | 22 +
test/harness/runTsuite.js | 54 ++
test/harness/sta.js | 27 +
test/harness/webCryptoUtils.js | 13 +
test/js/async_await_add.js | 7 -
test/js/async_await_add.t.js | 15 +
test/js/async_await_blank.js | 5 -
test/js/async_await_blank.t.js | 13 +
test/js/async_await_catch.js | 5 -
test/js/async_await_catch.t.js | 13 +
test/js/async_await_finally.js | 6 -
test/js/async_await_finally.t.js | 15 +
test/js/async_await_for.js | 23 -
test/js/async_await_for.t.js | 31 +
test/js/async_await_inline.js | 11 -
test/js/async_await_inline.t.js | 18 +
test/js/async_await_many_call.js | 30 -
test/js/async_await_many_call.t.js | 35 +
test/js/async_await_reject.js | 5 -
test/js/async_await_reject.t.js | 15 +
test/js/async_await_stages.js | 28 -
test/js/async_await_stages.t.js | 36 +
test/js/async_await_throw.js | 12 -
test/js/async_await_throw.t.js | 22 +
test/js/async_await_throw_async.js | 15 -
test/js/async_await_throw_async.t.js | 25 +
test/js/async_await_throw_catch.js | 12 -
test/js/async_await_throw_catch.t.js | 20 +
test/js/async_await_throw_catch_async.js | 15 -
test/js/async_await_throw_catch_async.t.js | 25 +
test/js/async_await_try_catch.js | 19 -
test/js/async_await_try_catch.t.js | 30 +
test/js/async_await_try_finally.js | 20 -
test/js/async_await_try_finally.t.js | 32 +
test/js/async_await_try_resolve.js | 15 -
test/js/async_await_try_resolve.t.js | 23 +
test/js/async_await_try_throw.js | 14 -
test/js/async_await_try_throw.t.js | 27 +
test/js/async_await_try_throw_catch.js | 17 -
test/js/async_await_try_throw_catch.t.js | 27 +
test/js/fs_promises_001.js | 55 --
test/js/fs_promises_002.js | 72 ---
test/js/fs_promises_003.js | 108 ----
test/js/fs_promises_004.js | 200 --------
test/js/fs_promises_005.js | 143 ------
test/js/fs_promises_006.js | 104 ----
test/js/fs_promises_007.js | 241 ----------
test/js/fs_promises_008.js | 79 ---
test/js/fs_promises_009.js | 106 ----
test/js/promise_all.js | 9 -
test/js/promise_all.t.js | 16 +
test/js/promise_allSettled.js | 20 -
test/js/promise_allSettled.t.js | 26 +
test/js/promise_allSettled_string.js | 10 -
test/js/promise_allSettled_string.t.js | 16 +
test/js/promise_all_throw.js | 9 -
test/js/promise_all_throw.t.js | 15 +
test/js/promise_any.js | 8 -
test/js/promise_any.t.js | 14 +
test/js/promise_any_all_rejected.js | 7 -
test/js/promise_any_all_rejected.t.js | 13 +
test/js/promise_catch_then_throw_catch.js | 5 -
test/js/promise_catch_then_throw_catch.t.js | 14 +
test/js/promise_catch_throw.js | 3 -
test/js/promise_catch_throw.t.js | 10 +
test/js/promise_finally.js | 7 -
test/js/promise_finally.t.js | 14 +
test/js/promise_finally_throw.js | 2 -
test/js/promise_finally_throw.t.js | 9 +
test/js/promise_finally_throw_catch.js | 3 -
test/js/promise_finally_throw_catch.t.js | 9 +
test/js/promise_race.js | 12 -
test/js/promise_race.t.js | 18 +
test/js/promise_race_throw.js | 12 -
test/js/promise_race_throw.t.js | 18 +
test/js/promise_reject_catch.js | 1 -
test/js/promise_reject_catch.t.js | 8 +
test/js/promise_reject_post_catch.js | 2 -
test/js/promise_reject_post_catch.t.js | 9 +
test/js/promise_rejection_tracker.js | 1 -
test/js/promise_rejection_tracker.t.js | 9 +
test/js/promise_s01.t.js | 22 +
test/js/promise_s02.t.js | 23 +
test/js/promise_s03.t.js | 21 +
test/js/promise_s04.t.js | 12 +
test/js/promise_s05.t.js | 18 +
test/js/promise_s06.t.js | 10 +
test/js/promise_s07.t.js | 15 +
test/js/promise_s08.t.js | 22 +
test/js/promise_s09.t.js | 15 +
test/js/promise_s1.js | 15 -
test/js/promise_s10.js | 11 -
test/js/promise_s10.t.js | 20 +
test/js/promise_s11.js | 13 -
test/js/promise_s11.t.js | 22 +
test/js/promise_s12.js | 10 -
test/js/promise_s12.t.js | 19 +
test/js/promise_s13.js | 21 -
test/js/promise_s13.t.js | 23 +
test/js/promise_s14.js | 9 -
test/js/promise_s14.t.js | 21 +
test/js/promise_s15.js | 10 -
test/js/promise_s15.t.js | 16 +
test/js/promise_s16.js | 10 -
test/js/promise_s16.t.js | 16 +
test/js/promise_s17.js | 10 -
test/js/promise_s17.t.js | 18 +
test/js/promise_s18.js | 23 -
test/js/promise_s18.t.js | 32 +
test/js/promise_s19.js | 33 -
test/js/promise_s19.t.js | 34 +
test/js/promise_s2.js | 14 -
test/js/promise_s20.js | 23 -
test/js/promise_s20.t.js | 25 +
test/js/promise_s21.js | 30 -
test/js/promise_s21.t.js | 32 +
test/js/promise_s22.js | 32 -
test/js/promise_s22.t.js | 32 +
test/js/promise_s23.js | 28 -
test/js/promise_s23.t.js | 25 +
test/js/promise_s24.js | 13 -
test/js/promise_s24.t.js | 18 +
test/js/promise_s25.js | 29 -
test/js/promise_s25.t.js | 24 +
test/js/promise_s26.js | 144 ------
test/js/promise_s26.t.js | 211 ++++++++
test/js/promise_s3.js | 11 -
test/js/promise_s4.js | 6 -
test/js/promise_s5.js | 7 -
test/js/promise_s6.js | 4 -
test/js/promise_s7.js | 12 -
test/js/promise_s8.js | 13 -
test/js/promise_s9.js | 10 -
test/js/promise_set_timeout.js | 17 -
test/js/promise_set_timeout.t.js | 21 +
test/js/promise_then_throw.js | 2 -
test/js/promise_then_throw.t.js | 9 +
test/js/promise_then_throw_catch.js | 3 -
test/js/promise_then_throw_catch.t.js | 12 +
test/js/promise_then_throw_finally_catch.js | 4 -
test/js/promise_then_throw_finally_catch.t.js | 13 +
test/js/promise_two_first_then_throw.js | 6 -
test/js/promise_two_first_then_throw.t.js | 13 +
test/js/promise_two_then_throw.js | 5 -
test/js/promise_two_then_throw.t.js | 12 +
test/njs_expect_test.exp | 402 -----------------
test/options | 61 ++
test/prepare | 36 +
test/report | 18 +
test/setup | 39 +
test/test262 | 64 ++
test/webcrypto/aes.js | 125 -----
test/webcrypto/aes.t.js | 96 ++++
test/webcrypto/aes_decoding.js | 118 -----
test/webcrypto/aes_decoding.t.js | 81 +++
test/webcrypto/derive.js | 151 ------
test/webcrypto/derive.t.js | 100 ++++
test/webcrypto/digest.js | 90 ---
test/webcrypto/digest.t.js | 60 ++
test/webcrypto/rsa.js | 108 ----
test/webcrypto/rsa.t.js | 68 ++
test/webcrypto/rsa_decoding.js | 83 ---
test/webcrypto/rsa_decoding.t.js | 41 +
test/webcrypto/sign.js | 290 ------------
test/webcrypto/sign.t.js | 232 +++++++++
test/webcrypto/verify.js | 215 ---------
test/webcrypto/verify.t.js | 155 ++++++
186 files changed, 4544 insertions(+), 4238 deletions(-)
diffs (truncated from 9574 to 1000 lines):
diff -r 144e430d0ed5 -r 3b035831f64a auto/make
--- a/auto/make Mon Nov 29 14:41:09 2021 +0000
+++ b/auto/make Mon Nov 29 16:50:41 2021 +0000
@@ -209,12 +209,16 @@ lib_test: $NJS_BUILD_DIR/njs_auto_config
$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
diff -r 144e430d0ed5 -r 3b035831f64a test/finalize
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/finalize Mon Nov 29 16:50:41 2021 +0000
@@ -0,0 +1,11 @@
+#!/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
diff -r 144e430d0ed5 -r 3b035831f64a test/fs/methods.js
--- a/test/fs/methods.js Mon Nov 29 14:41:09 2021 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,599 +0,0 @@
-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}`);
- }
- })
- }
-}
-
-function p(args, default_opts) {
- let params = Object.assign({}, default_opts, args);
-
- let fname = params.args[0];
-
- if (fname[0] == '@') {
- let gen = `build/test/fs_test_${Math.round(Math.random() * 1000000)}`;
- params.args = params.args.map(v => v);
- params.args[0] = gen + fname.slice(1);
- }
-
- return params;
-}
-
-function promisify(f) {
- return function (...args) {
- return new Promise((resolve, reject) => {
- function callback(err, result) {
- if (err) {
- return reject(err);
- } else {
- resolve(result);
- }
- }
-
- args.push(callback);
- f.apply(this, args);
- });
- };
-}
-
-async function method(name, params) {
- let data = null;
-
- 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));
- }
-
- 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));
- });
-
- 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));
- });
-
- break;
- }
-
- return data;
-}
-
-async function read_test(params) {
- let data = await method("readFile", params);
-
- if (params.slice) {
- data = data.slice.apply(data, params.slice);
- }
-
- 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`);
- }
-
- return 'SUCCESS';
-}
-
-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/non_utf8", "utf8"], expected: "��" },
- { args: ["test/fs/non_utf8", {encoding: "hex"}], expected: "8080" },
- { args: ["test/fs/non_utf8", "base64"], expected: "gIA=" },
- { args: ["test/fs/ascii", "utf8"], expected: "x".repeat(600) },
- { args: ["test/fs/ascii", { encoding:"utf8", flags: "r+"}], expected: "x".repeat(600) },
-
- { 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 },
-];
-
-let readFile_tsuite = {
- name: "fs readFile",
- T: read_test,
- prepare_args: p,
- opts: { type: "callback" },
- tests: read_tests,
-};
-
-let readFileSync_tsuite = {
- name: "fs readFileSync",
- T: read_test,
- prepare_args: p,
- opts: { type: "sync" },
- tests: read_tests,
-};
-
-let readFileP_tsuite = {
- name: "fsp readFile",
- T: read_test,
- prepare_args: p,
- opts: { type: "promise" },
- tests: read_tests,
-};
-
-async function write_test(params) {
- let fname = params.args[0];
-
- try { fs.unlinkSync(fname); } catch (e) {}
-
- let data = await method("writeFile", params).catch(e => ({error:e}));
-
- if (!data) {
- data = fs.readFileSync(fname);
- }
-
- try { fs.unlinkSync(fname); } catch (e) {}
-
- if (params.check) {
- if (!params.check(data, params)) {
- throw Error(`writeFile failed check`);
- }
-
- } else if (params.exception) {
- throw data.error;
-
- } else {
- if (data.compare(params.expected) != 0) {
- throw Error(`writeFile unexpected data`);
- }
- }
-
- return 'SUCCESS';
-}
-
-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") },
- { args: ["@", Buffer.from("XYZ"), {encoding: "utf8", mode: 0o666}],
- expected: Buffer.from("XYZ") },
- { args: ["@", new DataView(Buffer.alloc(3).fill(66).buffer)],
- expected: Buffer.from("BBB") },
- { args: ["@", new Uint8Array(Buffer.from("ABCD"))],
- expected: Buffer.from("ABCD")},
- { args: ["@", "XYZ"], expected: Buffer.from("XYZ")},
- { args: ["@", "78797a", "hex"], expected: Buffer.from("xyz") },
- { args: ["@", "eHl6", "base64"], expected: Buffer.from("xyz") },
- { args: ["@", "eHl6", {encoding: "base64url"}], expected: Buffer.from("xyz"),
- optional: true },
- { args: ["@", Symbol("XYZ")], exception: "TypeError: Cannot convert a Symbol value to a string"},
- { args: ["/invalid_path", "XYZ"],
- check: (err, params) => {
- let e = err.error;
-
- if (e.syscall != 'open') {
- throw Error(`${e.syscall} unexpected syscall`);
- }
-
- if (e.code != "EACCES" && e.code != "EROFS") {
- throw Error(`${e.code} unexpected code`);
- }
-
- return true;
- } },
-];
-
-let writeFile_tsuite = {
- name: "fs writeFile",
- T: write_test,
- prepare_args: p,
- opts: { type: "callback" },
- tests: write_tests,
-};
-
-let writeFileSync_tsuite = {
- name: "fs writeFileSync",
- T: write_test,
- prepare_args: p,
- opts: { type: "sync" },
- tests: write_tests,
-};
-
-let writeFileP_tsuite = {
- name: "fsp writeFile",
- T: write_test,
- prepare_args: p,
- opts: { type: "promise" },
- tests: write_tests,
-};
-
-async function append_test(params) {
- let fname = params.args[0];
-
- try { fs.unlinkSync(fname); } catch (e) {}
-
- let data = await method("appendFile", params).catch(e => ({error:e}));
- data = await method("appendFile", params).catch(e => ({error:e}));
-
- if (!data) {
- data = fs.readFileSync(fname);
- }
-
- try { fs.unlinkSync(fname); } catch (e) {}
-
- if (params.check) {
- if (!params.check(data, params)) {
- throw Error(`appendFile failed check`);
- }
-
- } else if (params.exception) {
- throw data.error;
-
- } else {
- if (data.compare(params.expected) != 0) {
- throw Error(`appendFile unexpected data`);
- }
- }
-
- return 'SUCCESS';
-}
-
-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") },
- { args: ["@", Buffer.from("XYZ"), {encoding: "utf8", mode: 0o666}],
- expected: Buffer.from("XYZXYZ") },
- { args: ["@", new DataView(Buffer.alloc(3).fill(66).buffer)],
- expected: Buffer.from("BBBBBB") },
- { args: ["@", new Uint8Array(Buffer.from("ABCD"))],
- expected: Buffer.from("ABCDABCD")},
- { args: ["@", "XYZ"], expected: Buffer.from("XYZXYZ")},
- { args: ["@", "78797a", "hex"], expected: Buffer.from("xyzxyz") },
- { args: ["@", "eHl6", "base64"], expected: Buffer.from("xyzxyz") },
- { args: ["@", "eHl6", {encoding: "base64url"}], expected: Buffer.from("xyzxyz"),
- optional: true },
- { args: ["@", Symbol("XYZ")], exception: "TypeError: Cannot convert a Symbol value to a string"},
- { args: ["/invalid_path", "XYZ"],
- check: (err, params) => {
- let e = err.error;
-
- if (e.syscall != 'open') {
- throw Error(`${e.syscall} unexpected syscall`);
- }
-
- if (e.code != "EACCES" && e.code != "EROFS") {
- throw Error(`${e.code} unexpected code`);
- }
-
- return true;
- } },
-];
-
-let appendFile_tsuite = {
- name: "fs appendFile",
- T: append_test,
- prepare_args: p,
- opts: { type: "callback" },
- tests: append_tests,
-};
-
-let appendFileSync_tsuite = {
- name: "fs appendFileSync",
- T: append_test,
- prepare_args: p,
- opts: { type: "sync" },
- tests: append_tests,
-};
-
-let appendFileP_tsuite = {
- name: "fsp appendFile",
- T: append_test,
- prepare_args: p,
- opts: { type: "promise" },
- tests: append_tests,
-};
-
-async function realpath_test(params) {
- let data = await method("realpath", params);
-
- if (!params.check(data)) {
- throw Error(`realpath failed check`);
- }
-
- return 'SUCCESS';
-}
-
-let realpath_tests = [
- { args: ["./build/test/.."],
- check: (data) => data.endsWith("build") },
- { args: ["./build/test/", {encoding:'buffer'}],
- check: (data) => data instanceof Buffer },
-];
-
-let realpath_tsuite = {
- name: "fs realpath",
- T: realpath_test,
- prepare_args: p,
- opts: { type: "callback" },
- tests: realpath_tests,
-};
-
-let realpathSync_tsuite = {
- name: "fs realpathSync",
- T: realpath_test,
- prepare_args: p,
- opts: { type: "sync" },
- tests: realpath_tests,
-};
-
-let realpathP_tsuite = {
- name: "fsp realpath",
- T: realpath_test,
- prepare_args: p,
- opts: { type: "promise" },
- tests: realpath_tests,
-};
-
-async function stat_test(params) {
- if (params.init) {
- params.init(params);
- }
-
- let stat = await method(params.method, params).catch(e => ({error:e}));
-
- if (params.check && !params.check(stat, params)) {
- throw Error(`${params.method} failed check`);
- }
-
- return 'SUCCESS';
-}
-
-function contains(arr, elts) {
- return elts.every(el => {
- let r = arr.some(v => el == v);
-
- if (!r) {
- throw Error(`${el} is not found`);
- }
-
- return r;
- });
-}
-
-let stat_tests = [
- { args: ["/invalid_path"],
- check: (err, params) => {
- let e = err.error;
-
- if (e.syscall != params.method) {
- throw Error(`${e.syscall} unexpected syscall`);
- }
-
- if (e.code != "ENOENT") {
- throw Error(`${e.code} unexpected code`);
- }
-
- return true;
- } },
-
- { args: ["@_link"],
- init: (params) => {
- let lname = params.args[0];
- let fname = lname.slice(0, -5);
-
- /* making symbolic link. */
-
- try { fs.unlinkSync(fname); fs.unlinkSync(lname); } catch (e) {}
-
- fs.writeFileSync(fname, fname);
-
- fname = fs.realpathSync(fname);
- fs.symlinkSync(fname, lname);
- },
-
- check: (st, params) => {
- switch (params.method) {
- case "stat":
- if (!st.isFile()) {
- throw Error(`${params.args[0]} is not a file`);
- }
-
- break;
-
- case "lstat":
- if (!st.isSymbolicLink()) {
- throw Error(`${params.args[0]} is not a link`);
- }
-
- break;
- }
-
- return true;
- } },
-
- { 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/"],
- check: (st) => Object.keys(st).every(p => {
- let v = st[p];
- if (p == 'atime' || p == 'ctime' || p == 'mtime' || p == 'birthtime') {
- if (!(v instanceof Date)) {
- throw Error(`${p} is not an instance of Date`);
- }
-
- return true;
- }
-
- if ((typeof v) != 'number') {
- throw Error(`${p} is not an instance of Number`);
- }
-
- return true;
- }) },
-
- { args: ["./build/"],
- check: (st) => ['atime', 'birthtime', 'ctime', 'mtime'].every(p => {
- let date = st[p].valueOf();
- let num = st[p + 'Ms'];
-
- if (Math.abs(date - num) > 1) {
- throw Error(`${p}:${date} != ${p+'Ms'}:${num}`);
- }
-
- return true;
- }) },
-
- { args: ["./build/"],
- check: (st) => ['isBlockDevice',
- 'isCharacterDevice',
- 'isDirectory',
- 'isFIFO',
- 'isFile',
- 'isSocket',
- 'isSymbolicLink'].every(m => {
-
- let r = st[m]();
- if (!(r == (m == 'isDirectory'))) {
- throw Error(`${m} is ${r}`);
- }
-
- return true;
- }) },
-];
-
-let stat_tsuite = {
- name: "fs stat",
- T: stat_test,
- prepare_args: p,
- opts: { type: "callback", method: "stat" },
- tests: stat_tests,
-};
-
-let statSync_tsuite = {
- name: "fs statSync",
- T: stat_test,
- prepare_args: p,
- opts: { type: "sync", method: "stat" },
- tests: stat_tests,
-};
-
-let statP_tsuite = {
- name: "fsp stat",
- T: stat_test,
- prepare_args: p,
- opts: { type: "promise", method: "stat" },
- tests: stat_tests,
-};
-
-let lstat_tsuite = {
- name: "fs lstat",
- T: stat_test,
- prepare_args: p,
- opts: { type: "callback", method: "lstat" },
- tests: stat_tests,
-};
-
-let lstatSync_tsuite = {
- name: "fs lstatSync",
- T: stat_test,
- prepare_args: p,
- opts: { type: "sync", method: "lstat" },
- tests: stat_tests,
-};
-
-let lstatP_tsuite = {
- name: "fsp lstat",
- T: stat_test,
- prepare_args: p,
- opts: { type: "promise", method: "lstat" },
- tests: stat_tests,
-};
-
-run([
- readFile_tsuite,
- readFileSync_tsuite,
- readFileP_tsuite,
- writeFile_tsuite,
- writeFileSync_tsuite,
- writeFileP_tsuite,
- appendFile_tsuite,
- appendFileSync_tsuite,
- appendFileP_tsuite,
- realpath_tsuite,
- realpathSync_tsuite,
- realpathP_tsuite,
- stat_tsuite,
- statSync_tsuite,
- statP_tsuite,
- lstat_tsuite,
- lstatSync_tsuite,
- lstatP_tsuite,
-]);
diff -r 144e430d0ed5 -r 3b035831f64a test/fs/methods.t.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/fs/methods.t.js Mon Nov 29 16:50:41 2021 +0000
@@ -0,0 +1,610 @@
+/*---
+includes: [compatFs.js, compatBuffer.js, runTsuite.js]
+flags: [async]
+---*/
+
+function p(args, default_opts) {
+ let params = Object.assign({}, default_opts, args);
+
+ let fname = params.args[0];
+
+ if (fname[0] == '@') {
+ let gen = `build/test/fs_test_${Math.round(Math.random() * 1000000)}`;
+ params.args = params.args.map(v => v);
+ params.args[0] = gen + fname.slice(1);
+ }
+
+ return params;
+}
+
+function promisify(f) {
+ return function (...args) {
+ return new Promise((resolve, reject) => {
+ function callback(err, result) {
+ if (err) {
+ return reject(err);
+ } else {
+ resolve(result);
+ }
+ }
+
+ args.push(callback);
+ f.apply(this, args);
+ });
+ };
+}
+
+async function method(name, params) {
+ let data = null;
+
+ switch (params.type) {
+ case "sync":
+ data = fs[name + "Sync"].apply(null, params.args);
+ break;
+
+ case "callback":
+ data = await promisify(fs[name]).apply(null, params.args);
+ break;
+
+ case "promise":
+ data = await fs.promises[name].apply(null, params.args);
+ break;
+ }
+
+ return data;
+}
+
+async function read_test(params) {
+ let data = await method("readFile", params).catch(e => ({error:e}));
+
+ if (params.slice && !data.error) {
+ data = data.slice.apply(data, params.slice);
+ }
+
+ if (params.check) {
+ if (!params.check(data, params)) {
+ throw Error(`readFile failed check`);
+ }
+
+ } 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`);
+ }
+ }
+
+ return 'SUCCESS';
+}
+
+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"],
+ 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: ["test/fs/ascii", "utf8"], expected: "x".repeat(600) },
+ { args: ["test/fs/ascii", { encoding:"utf8", flags: "r+"}], expected: "x".repeat(600) },
+
+ { 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"),
+ 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" },
+ 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" },
+ 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" },
+ get tests() { return read_tests() },
+};
+
+async function write_test(params) {
+ let fname = params.args[0];
+
+ try { fs.unlinkSync(fname); } catch (e) {}
+
+ let data = await method("writeFile", params).catch(e => ({error:e}));
+
+ if (!data) {
+ data = fs.readFileSync(fname);
+ }
+
+ try { fs.unlinkSync(fname); } catch (e) {}
+
+ if (params.check) {
+ if (!params.check(data, params)) {
+ throw Error(`writeFile failed check`);
+ }
+
+ } else if (params.exception) {
+ throw data.error;
+
+ } else {
+ if (data.compare(params.expected) != 0) {
+ throw Error(`writeFile unexpected data`);
+ }
+ }
+
+ return 'SUCCESS';
+}
+
+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") },
+ { args: ["@", Buffer.from("XYZ"), {encoding: "utf8", mode: 0o666}],
+ expected: Buffer.from("XYZ") },
+ { args: ["@", new DataView(Buffer.alloc(3).fill(66).buffer)],
+ expected: Buffer.from("BBB") },
+ { args: ["@", new Uint8Array(Buffer.from("ABCD"))],
+ expected: Buffer.from("ABCD")},
+ { args: ["@", "XYZ"], expected: Buffer.from("XYZ")},
+ { args: ["@", "78797a", "hex"], expected: Buffer.from("xyz") },
+ { args: ["@", "eHl6", "base64"], expected: Buffer.from("xyz") },
+ { args: ["@", "eHl6", {encoding: "base64url"}], expected: Buffer.from("xyz"),
+ optional: true },
+ { args: ["@", Symbol("XYZ")], exception: "TypeError: Cannot convert a Symbol value to a string"},
+ { args: ["/invalid_path", "XYZ"],
+ check: (err, params) => {
+ let e = err.error;
+
+ if (e.syscall != 'open') {
+ throw Error(`${e.syscall} unexpected syscall`);
+ }
+
+ if (e.code != "EACCES" && e.code != "EROFS") {
+ throw Error(`${e.code} unexpected code`);
+ }
+
+ return true;
+ } },
+];
+
+let writeFile_tsuite = {
+ name: "fs writeFile",
+ skip: () => (!has_fs() || !has_buffer()),
+ T: write_test,
+ prepare_args: p,
+ opts: { type: "callback" },
+ 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" },
+ 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" },
+ get tests() { return write_tests() },
+};
+
+async function append_test(params) {
+ let fname = params.args[0];
+
+ try { fs.unlinkSync(fname); } catch (e) {}
+
+ let data = await method("appendFile", params).catch(e => ({error:e}));
+ data = await method("appendFile", params).catch(e => ({error:e}));
+
+ if (!data) {
+ data = fs.readFileSync(fname);
+ }
+
+ try { fs.unlinkSync(fname); } catch (e) {}
+
+ if (params.check) {
+ if (!params.check(data, params)) {
+ throw Error(`appendFile failed check`);
+ }
+
+ } else if (params.exception) {
+ throw data.error;
+
+ } else {
+ if (data.compare(params.expected) != 0) {
+ throw Error(`appendFile unexpected data`);
+ }
+ }
+
+ return 'SUCCESS';
+}
+
+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") },
+ { args: ["@", Buffer.from("XYZ"), {encoding: "utf8", mode: 0o666}],
+ expected: Buffer.from("XYZXYZ") },
+ { args: ["@", new DataView(Buffer.alloc(3).fill(66).buffer)],
+ expected: Buffer.from("BBBBBB") },
+ { args: ["@", new Uint8Array(Buffer.from("ABCD"))],
+ expected: Buffer.from("ABCDABCD")},
+ { args: ["@", "XYZ"], expected: Buffer.from("XYZXYZ")},
+ { args: ["@", "78797a", "hex"], expected: Buffer.from("xyzxyz") },
+ { args: ["@", "eHl6", "base64"], expected: Buffer.from("xyzxyz") },
+ { args: ["@", "eHl6", {encoding: "base64url"}], expected: Buffer.from("xyzxyz"),
+ optional: true },
+ { args: ["@", Symbol("XYZ")], exception: "TypeError: Cannot convert a Symbol value to a string"},
+ { args: ["/invalid_path", "XYZ"],
+ check: (err, params) => {
+ let e = err.error;
+
+ if (e.syscall != 'open') {
+ throw Error(`${e.syscall} unexpected syscall`);
+ }
+
+ if (e.code != "EACCES" && e.code != "EROFS") {
+ throw Error(`${e.code} unexpected code`);
+ }
+
+ return true;
+ } },
+];
+
+let appendFile_tsuite = {
+ name: "fs appendFile",
+ skip: () => (!has_fs() || !has_buffer()),
+ T: append_test,
+ prepare_args: p,
+ opts: { type: "callback" },
+ 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" },
+ 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" },
+ get tests() { return append_tests() },
More information about the nginx-devel
mailing list