From 425f27060afa01e5cf623b2a068efbf0961c307e Mon Sep 17 00:00:00 2001 From: Kouadio Fabrice Nguessan <72697416+fabnguess@users.noreply.github.com> Date: Mon, 19 Feb 2024 12:51:46 +0000 Subject: [PATCH] refactor(sec-literal/test): use the Node.js native test runner (#242) --- workspaces/estree-ast-utils/LICENSE | 2 +- workspaces/sec-literal/LICENSE | 2 +- workspaces/sec-literal/package.json | 2 +- workspaces/sec-literal/test/hex.spec.js | 99 +++++++++----------- workspaces/sec-literal/test/literal.spec.js | 58 +++++------- workspaces/sec-literal/test/patterns.spec.js | 94 ++++++++++--------- workspaces/sec-literal/test/utils.spec.js | 66 ++++++------- 7 files changed, 149 insertions(+), 174 deletions(-) diff --git a/workspaces/estree-ast-utils/LICENSE b/workspaces/estree-ast-utils/LICENSE index 346097d..53f7d65 100644 --- a/workspaces/estree-ast-utils/LICENSE +++ b/workspaces/estree-ast-utils/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 NodeSecure +Copyright (c) 2023-2024 NodeSecure Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/workspaces/sec-literal/LICENSE b/workspaces/sec-literal/LICENSE index 346097d..53f7d65 100644 --- a/workspaces/sec-literal/LICENSE +++ b/workspaces/sec-literal/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 NodeSecure +Copyright (c) 2023-2024 NodeSecure Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/workspaces/sec-literal/package.json b/workspaces/sec-literal/package.json index 92b7c25..ce786fd 100644 --- a/workspaces/sec-literal/package.json +++ b/workspaces/sec-literal/package.json @@ -7,7 +7,7 @@ "type": "module", "scripts": { "lint": "eslint --ext .js", - "test-only": "cross-env esm-tape-runner 'test/*.spec.js' | tap-monkey", + "test-only": "node --test", "test": "cross-env npm run lint && npm run test-only" }, "repository": { diff --git a/workspaces/sec-literal/test/hex.spec.js b/workspaces/sec-literal/test/hex.spec.js index fb1b4e9..5e627a4 100644 --- a/workspaces/sec-literal/test/hex.spec.js +++ b/workspaces/sec-literal/test/hex.spec.js @@ -1,77 +1,70 @@ // Import Node.js Dependencies import { randomBytes } from "node:crypto"; - -// Import Third-party Dependencies -import test from "tape"; +import { describe, test } from "node:test"; +import assert from "node:assert"; // Import Internal Dependencies import { isHex, isSafe, CONSTANTS } from "../src/hex.js"; import { createLiteral } from "./utils/index.js"; -test("isHex() of a random Hexadecimal value must return true", (tape) => { - const hexValue = randomBytes(4).toString("hex"); +describe("isHex()", () => { + test("must return true for random 4 character hexadecimal values", () => { + const hexValue = randomBytes(4).toString("hex"); - tape.strictEqual(isHex(hexValue), true, `Hexadecimal value '${hexValue}' must return true`); - tape.end(); -}); + assert.strictEqual(isHex(hexValue), true, `Hexadecimal value '${hexValue}' must return true`); + }); -test("isHex() of an ESTree Literal containing a random Hexadecimal value must return true", (tape) => { - const hexValue = createLiteral(randomBytes(4).toString("hex")); + test("must return true for ESTree Literals containing random 4 character hexadecimal values", () => { + const hexValue = createLiteral(randomBytes(4).toString("hex")); - tape.strictEqual(isHex(hexValue), true, `Hexadecimal value '${hexValue.value}' must return true`); - tape.end(); -}); + assert.strictEqual(isHex(hexValue), true, `Hexadecimal value '${hexValue.value}' must return true`); + }); -test("An hexadecimal value must be at least 4 chars long", (tape) => { - const hexValue = randomBytes(1).toString("hex"); + test("An hexadecimal value must be at least 4 chars long", () => { + const hexValue = randomBytes(1).toString("hex"); - tape.strictEqual(isHex(hexValue), false, `Hexadecimal value '${hexValue}' must return false`); - tape.end(); -}); + assert.strictEqual(isHex(hexValue), false, `Hexadecimal value '${hexValue}' must return false`); + }); -test("isHex() of a value that is not a string or an ESTree Literal must return false", (tape) => { - const hexValue = 100; + test("should return false for non-string/ESTree Literal values", () => { + const hexValue = 100; - tape.strictEqual(isHex(hexValue), false, "100 is typeof number so it must always return false"); - tape.end(); + assert.strictEqual(isHex(hexValue), false, "100 is typeof number so it must always return false"); + }); }); -test("isSafe must return true for a value with a length lower or equal five characters", (tape) => { - tape.ok(isSafe("h2l5x")); - tape.end(); -}); +describe("isSafe()", () => { + test("must return true for a value with a length lower or equal five characters", () => { + assert.ok(isSafe("h2l5x")); + }); -test("isSafe must return true if the string diversity is only two characters or lower", (tape) => { - tape.ok(isSafe("aaaaaaaaaaaaaabbbbbbbbbbbbb")); - tape.end(); -}); + test("must return true if the string diversity is only two characters or lower", () => { + assert.ok(isSafe("aaaaaaaaaaaaaabbbbbbbbbbbbb")); + }); -test("isSafe must always return true if argument is only number, lower or upper letters", (tape) => { - const values = ["00000000", "aaaaaaaa", "AAAAAAAAA"]; + test("must always return true if argument is only number, lower or upper letters", () => { + const values = ["00000000", "aaaaaaaa", "AAAAAAAAA"]; - for (const hexValue of values) { - tape.ok(isSafe(hexValue)); - } - tape.end(); -}); + for (const hexValue of values) { + assert.ok(isSafe(hexValue)); + } + }); -test("isSafe() must always return true if the value start with one of the 'safe' values", (tape) => { - for (const safeValue of CONSTANTS.SAFE_HEXA_VALUES) { - const hexValue = safeValue + randomBytes(4).toString("hex"); + test("must always return true if the value start with one of the 'safe' values", () => { + for (const safeValue of CONSTANTS.SAFE_HEXA_VALUES) { + const hexValue = safeValue + randomBytes(4).toString("hex"); - tape.ok(isSafe(hexValue)); - } - tape.end(); -}); + assert.ok(isSafe(hexValue)); + } + }); -test("isSafe must return true because it start with a safe pattern (and it must lowerCase the string)", (tape) => { - tape.ok(isSafe("ABCDEF1234567890")); - tape.end(); -}); + test("must return true because it start with a safe pattern (and it must lowerCase the string)", () => { + assert.ok(isSafe("ABCDEF1234567890")); + }); -test("isSafe() must always return false if the value start with one of the 'unsafe' values", (tape) => { - for (const unsafeValue of CONSTANTS.UNSAFE_HEXA_VALUES) { - tape.strictEqual(isSafe(unsafeValue), false); - } - tape.end(); + test("must always return false if the value start with one of the 'unsafe' values", () => { + for (const unsafeValue of CONSTANTS.UNSAFE_HEXA_VALUES) { + assert.strictEqual(isSafe(unsafeValue), false); + } + }); }); diff --git a/workspaces/sec-literal/test/literal.spec.js b/workspaces/sec-literal/test/literal.spec.js index b47df12..a9d8205 100644 --- a/workspaces/sec-literal/test/literal.spec.js +++ b/workspaces/sec-literal/test/literal.spec.js @@ -1,44 +1,39 @@ // Import Node.js Dependencies import { randomBytes } from "node:crypto"; - -// Import Third-party Dependencies -import test from "tape"; +import { test } from "node:test"; +import assert from "node:assert"; // Import Internal Dependencies import { isLiteral, toValue, toRaw, defaultAnalysis } from "../src/literal.js"; import { createLiteral } from "./utils/index.js"; -test("isLiteral must return true for a valid ESTree Literal Node", (tape) => { +test("isLiteral must return true for a valid ESTree Literal Node", () => { const literalSample = createLiteral("boo"); - tape.strictEqual(isLiteral(literalSample), true); - tape.strictEqual(isLiteral("hey"), false); - tape.strictEqual(isLiteral({ type: "fake", value: "boo" }), false); - tape.end(); + assert.strictEqual(isLiteral(literalSample), true); + assert.strictEqual(isLiteral("hey"), false); + assert.strictEqual(isLiteral({ type: "fake", value: "boo" }), false); }); -test("toValue must return a string when we give a valid EStree Literal", (tape) => { +test("toValue must return a string when we give a valid EStree Literal", () => { const literalSample = createLiteral("boo"); - tape.strictEqual(toValue(literalSample), "boo"); - tape.strictEqual(toValue("hey"), "hey"); - tape.end(); + assert.strictEqual(toValue(literalSample), "boo"); + assert.strictEqual(toValue("hey"), "hey"); }); -test("toRaw must return a string when we give a valid EStree Literal", (tape) => { +test("toRaw must return a string when we give a valid EStree Literal", () => { const literalSample = createLiteral("boo", true); - tape.strictEqual(toRaw(literalSample), "boo"); - tape.strictEqual(toRaw("hey"), "hey"); - tape.end(); + assert.strictEqual(toRaw(literalSample), "boo"); + assert.strictEqual(toRaw("hey"), "hey"); }); -test("defaultAnalysis() of something else than a Literal must always return null", (tape) => { - tape.strictEqual(defaultAnalysis(10), null); - tape.end(); +test("defaultAnalysis() of something else than a Literal must always return null", () => { + assert.strictEqual(defaultAnalysis(10), null); }); -test("defaultAnalysis() of an Hexadecimal value", (tape) => { +test("defaultAnalysis() of an Hexadecimal value", () => { const hexValue = randomBytes(10).toString("hex"); const result = defaultAnalysis(createLiteral(hexValue, true)); @@ -46,11 +41,10 @@ test("defaultAnalysis() of an Hexadecimal value", (tape) => { isBase64: true, hasHexadecimalSequence: false, hasUnicodeSequence: false }; - tape.deepEqual(result, expected); - tape.end(); + assert.deepEqual(result, expected); }); -test("defaultAnalysis() of an Base64 value", (tape) => { +test("defaultAnalysis() of an Base64 value", () => { const hexValue = randomBytes(10).toString("base64"); const result = defaultAnalysis(createLiteral(hexValue, true)); @@ -58,11 +52,10 @@ test("defaultAnalysis() of an Base64 value", (tape) => { isBase64: true, hasHexadecimalSequence: false, hasUnicodeSequence: false }; - tape.deepEqual(result, expected); - tape.end(); + assert.deepEqual(result, expected); }); -test("defaultAnalysis() of an Unicode Sequence", (tape) => { +test("defaultAnalysis() of an Unicode Sequence", () => { const unicodeSequence = createLiteral("'\\u0024\\u0024'", true); const result = defaultAnalysis(unicodeSequence); @@ -70,11 +63,10 @@ test("defaultAnalysis() of an Unicode Sequence", (tape) => { isBase64: false, hasHexadecimalSequence: false, hasUnicodeSequence: true }; - tape.deepEqual(result, expected); - tape.end(); + assert.deepEqual(result, expected); }); -test("defaultAnalysis() of an Unicode Sequence", (tape) => { +test("defaultAnalysis() of an Unicode Sequence", () => { const hexSequence = createLiteral("'\\x64\\x61\\x74\\x61'", true); const result = defaultAnalysis(hexSequence); @@ -82,11 +74,10 @@ test("defaultAnalysis() of an Unicode Sequence", (tape) => { isBase64: false, hasHexadecimalSequence: true, hasUnicodeSequence: false }; - tape.deepEqual(result, expected); - tape.end(); + assert.deepEqual(result, expected); }); -test("defaultAnalysis() with a Literal with no 'raw' property must return two null values", (tape) => { +test("defaultAnalysis() with a Literal with no 'raw' property must return two null values", () => { const hexValue = randomBytes(10).toString("base64"); const result = defaultAnalysis(createLiteral(hexValue)); @@ -94,6 +85,5 @@ test("defaultAnalysis() with a Literal with no 'raw' property must return two nu isBase64: true, hasHexadecimalSequence: null, hasUnicodeSequence: null }; - tape.deepEqual(result, expected); - tape.end(); + assert.deepEqual(result, expected); }); diff --git a/workspaces/sec-literal/test/patterns.spec.js b/workspaces/sec-literal/test/patterns.spec.js index 89db85b..748dc4f 100644 --- a/workspaces/sec-literal/test/patterns.spec.js +++ b/workspaces/sec-literal/test/patterns.spec.js @@ -1,3 +1,7 @@ +// Import Node.js Dependencies +import { describe, test } from "node:test"; +import assert from "node:assert"; + // Import Internal Dependencies import { commonStringPrefix, @@ -5,60 +9,60 @@ import { commonHexadecimalPrefix } from "../src/patterns.js"; -// Import Third-party Dependencies -import test from "tape"; -test("commonStringPrefix of two strings that does not start with the same set of characters must return null", (tape) => { - tape.strictEqual(commonStringPrefix("boo", "foo"), null, - "there is no common prefix between 'boo' and 'foo' so the result must be null"); - tape.end(); -}); +describe("commonStringPrefix()", () => { + test("must return null for two strings that have no common prefix", () => { + assert.strictEqual(commonStringPrefix("boo", "foo"), null, + "there is no common prefix between 'boo' and 'foo' so the result must be null"); + }); -test("commonStringPrefix of two strings that start with the same set of characters must return it as result", (tape) => { - tape.strictEqual(commonStringPrefix("bromance", "brother"), "bro", - "the common prefix between bromance and brother must be 'bro'."); - tape.end(); + test("should return the common prefix for strings with a shared prefix", () => { + assert.strictEqual(commonStringPrefix("bromance", "brother"), "bro", + "the common prefix between bromance and brother must be 'bro'."); + }); }); -test("commonStringSuffix of two strings that end with the same set of characters must return it as result", (tape) => { - tape.strictEqual(commonStringSuffix("boo", "foo"), "oo", - "the common suffix between boo and foo must be 'oo'"); - tape.end(); -}); +describe("commonStringSuffix()", () => { + test("must return the common suffix for the two strings with a shared suffix", () => { + assert.strictEqual(commonStringSuffix("boo", "foo"), "oo", + "the common suffix between boo and foo must be 'oo'"); + }); -test("commonStringSuffix of two strings that does not end with the same set of characters must return null", (tape) => { - tape.strictEqual(commonStringSuffix("bromance", "brother"), null, - "there is no common suffix between 'bromance' and 'brother' so the result must be null"); - tape.end(); + test("must return null for two strings with no common suffix", () => { + assert.strictEqual(commonStringSuffix("bromance", "brother"), null, + "there is no common suffix between 'bromance' and 'brother' so the result must be null"); + }); }); -test("commonHexadecimalPrefix - throw a TypeError if identifiersArray is not an Array", (tape) => { - tape.throws(() => commonHexadecimalPrefix(10), "identifiersArray must be an Array"); - tape.end(); -}); +describe("commonHexadecimalPrefix()", () => { + test("should throw a TypeError if identifiersArray is not an Array", () => { + assert.throws(() => commonHexadecimalPrefix(10), { + name: "TypeError", + message: "identifiersArray must be an Array" + }); + }); -test("commonHexadecimalPrefix - only hexadecimal identifiers", (tape) => { - const data = [ - "_0x3c0c55", "_0x1185d5", "_0x160fc8", "_0x18a66f", "_0x18a835", "_0x1a8356", - "_0x1adf3b", "_0x1e4510", "_0x1e9a2a", "_0x215558", "_0x2b0194", "_0x2fffe5", - "_0x32c822", "_0x33bb79" - ]; - const result = commonHexadecimalPrefix(data); + test("should handle only hexadecimal identifiers", () => { + const data = [ + "_0x3c0c55", "_0x1185d5", "_0x160fc8", "_0x18a66f", "_0x18a835", "_0x1a8356", + "_0x1adf3b", "_0x1e4510", "_0x1e9a2a", "_0x215558", "_0x2b0194", "_0x2fffe5", + "_0x32c822", "_0x33bb79" + ]; + const result = commonHexadecimalPrefix(data); - tape.strictEqual(result.oneTimeOccurence, 0); - tape.strictEqual(result.prefix._0x, data.length); - tape.end(); -}); + assert.strictEqual(result.oneTimeOccurence, 0); + assert.strictEqual(result.prefix._0x, data.length); + }); -test("commonHexadecimalPrefix - add one non-hexadecimal identifier", (tape) => { - const data = [ - "_0x3c0c55", "_0x1185d5", "_0x160fc8", "_0x18a66f", "_0x18a835", "_0x1a8356", - "_0x1adf3b", "_0x1e4510", "_0x1e9a2a", "_0x215558", "_0x2b0194", "_0x2fffe5", - "_0x32c822", "_0x33bb79", "foo" - ]; - const result = commonHexadecimalPrefix(data); + test("should add one non-hexadecimal identifier", () => { + const data = [ + "_0x3c0c55", "_0x1185d5", "_0x160fc8", "_0x18a66f", "_0x18a835", "_0x1a8356", + "_0x1adf3b", "_0x1e4510", "_0x1e9a2a", "_0x215558", "_0x2b0194", "_0x2fffe5", + "_0x32c822", "_0x33bb79", "foo" + ]; + const result = commonHexadecimalPrefix(data); - tape.strictEqual(result.oneTimeOccurence, 1); - tape.strictEqual(result.prefix._0x, data.length - 1); - tape.end(); + assert.strictEqual(result.oneTimeOccurence, 1); + assert.strictEqual(result.prefix._0x, data.length - 1); + }); }); diff --git a/workspaces/sec-literal/test/utils.spec.js b/workspaces/sec-literal/test/utils.spec.js index 830dfe4..dc0d3b6 100644 --- a/workspaces/sec-literal/test/utils.spec.js +++ b/workspaces/sec-literal/test/utils.spec.js @@ -2,25 +2,22 @@ // Import Node.js Dependencies import { randomBytes } from "node:crypto"; - -// Import Third-party Dependencies -import test from "tape"; +import { test } from "node:test"; +import assert from "node:assert"; // Import Internal Dependencies import { stringCharDiversity, isSvg, isSvgPath, stringSuspicionScore } from "../src/utils.js"; -test("stringCharDiversity must return the number of unique chars in a given string", (tape) => { - tape.strictEqual(stringCharDiversity("helloo!"), 5, +test("stringCharDiversity must return the number of unique chars in a given string", () => { + assert.strictEqual(stringCharDiversity("helloo!"), 5, "the following string 'helloo!' contains five unique chars: h, e, l, o and !"); - tape.end(); }); -test("stringCharDiversity must return the number of unique chars in a given string (but with exclusions of given chars)", (tape) => { - tape.strictEqual(stringCharDiversity("- - -\n", ["\n"]), 2); - tape.end(); +test("stringCharDiversity must return the number of unique chars in a given string (but with exclusions of given chars)", () => { + assert.strictEqual(stringCharDiversity("- - -\n", ["\n"]), 2); }); -test("isSvg must return true for an HTML svg balise", (tape) => { +test("isSvg must return true for an HTML svg balise", () => { const SVGHTML = ` @@ -28,62 +25,53 @@ test("isSvg must return true for an HTML svg balise", (tape) => { `; - tape.strictEqual(isSvg(SVGHTML), true); - tape.end(); + assert.strictEqual(isSvg(SVGHTML), true); }); -test("isSvg of a SVG Path must return true", (tape) => { - tape.strictEqual(isSvg("M150 0 L75 200 L225 200 Z"), true); - tape.end(); +test("isSvg of a SVG Path must return true", () => { + assert.strictEqual(isSvg("M150 0 L75 200 L225 200 Z"), true); }); -test("isSvg must return false for invalid XML string", (tape) => { - tape.strictEqual(isSvg(""), false); - tape.end(); +test("isSvg must return false for invalid XML string", () => { + assert.strictEqual(isSvg(""), false); }); -test("isSvgPath must return true when we give a valid svg path and false when the string is not valid", (tape) => { - tape.strictEqual(isSvgPath("M150 0 L75 200 L225 200 Z"), true); - tape.strictEqual(isSvgPath("M150"), false, "the length of an svg path must be always higher than four characters"); - tape.strictEqual(isSvgPath("hello world!"), false); - tape.strictEqual(isSvgPath(10), false, "isSvgPath argument must always return false for anything that is not a string primitive"); - tape.end(); +test("isSvgPath must return true when we give a valid svg path and false when the string is not valid", () => { + assert.strictEqual(isSvgPath("M150 0 L75 200 L225 200 Z"), true); + assert.strictEqual(isSvgPath("M150"), false, "the length of an svg path must be always higher than four characters"); + assert.strictEqual(isSvgPath("hello world!"), false); + assert.strictEqual(isSvgPath(10), false, "isSvgPath argument must always return false for anything that is not a string primitive"); }); -test("stringSuspicionScore must always return 0 if the string length if below 45", (tape) => { +test("stringSuspicionScore must always return 0 if the string length if below 45", () => { for (let strSize = 1; strSize < 45; strSize++) { // We generate a random String (with slice it in two because a size of 20 for hex is 40 bytes). const randomStr = randomBytes(strSize).toString("hex").slice(strSize); - tape.strictEqual(stringSuspicionScore(randomStr), 0); + assert.strictEqual(stringSuspicionScore(randomStr), 0); } - tape.end(); }); -test("stringSuspicionScore must return one if the str is between 45 and 200 chars and had no space in the first 45 chars", (tape) => { +test("stringSuspicionScore must return one if the str is between 45 and 200 chars and had no space in the first 45 chars", () => { const randomStrWithNoSpaces = randomBytes(25).toString("hex"); - tape.strictEqual(stringSuspicionScore(randomStrWithNoSpaces), 1); - tape.end(); + assert.strictEqual(stringSuspicionScore(randomStrWithNoSpaces), 1); }); -test("stringSuspicionScore must return zero if the str is between 45 and 200 chars and has at least one space in the first 45 chars", (tape) => { +test("stringSuspicionScore must return zero if the str is between 45 and 200 chars and has at least one space in the first 45 chars", () => { const randomStrWithSpaces = randomBytes(10).toString("hex") + " -_- " + randomBytes(30).toString("hex"); - tape.strictEqual(stringSuspicionScore(randomStrWithSpaces), 0); - tape.end(); + assert.strictEqual(stringSuspicionScore(randomStrWithSpaces), 0); }); -test("stringSuspicionScore must return a score of two for a string with more than 200 chars and no spaces", (tape) => { +test("stringSuspicionScore must return a score of two for a string with more than 200 chars and no spaces", () => { const randomStr = randomBytes(200).toString("hex"); - tape.strictEqual(stringSuspicionScore(randomStr), 2); - tape.end(); + assert.strictEqual(stringSuspicionScore(randomStr), 2); }); -test("stringSuspicionScore must add two to the final score when the string has more than 70 uniques chars", (tape) => { +test("stringSuspicionScore must add two to the final score when the string has more than 70 uniques chars", () => { const randomStr = "૱꠸┯┰┱┲❗►◄Ăă0123456789ᶀᶁᶂᶃᶄᶆᶇᶈᶉᶊᶋᶌᶍᶎᶏᶐᶑᶒᶓᶔᶕᶖᶗᶘᶙᶚᶸᵯᵰᵴᵶᵹᵼᵽᵾᵿ⤢⤣⤤⤥⥆⥇™°×π±√ "; - tape.strictEqual(stringSuspicionScore(randomStr), 3); - tape.end(); + assert.strictEqual(stringSuspicionScore(randomStr), 3); });