Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve compatibility tests #1253

Merged
merged 6 commits into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions test/compat/_.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* @overview Provides testing utilities.
* @license MIT
*/

import * as arbitrary from "../_arbitraries.js";

export { arbitrary };
191 changes: 138 additions & 53 deletions test/compat/index.test.js
Original file line number Diff line number Diff line change
@@ -1,61 +1,146 @@
/**
* @overview Contains smoke tests for Shescape to verify compatibility with Node
* versions.
* @overview Contains smoke tests for the main shescape module to verify
* compatibility with Node.js versions.
* @license MIT
*/

import test from "ava";
import { testProp } from "@fast-check/ava";
import * as fc from "fast-check";

import * as constants from "../_constants.js";
import { arbitrary } from "./_.js";

import { Shescape } from "../../index.js";

test.before((t) => {
t.context.quoteShell = constants.isWindows
? constants.binCmd
: constants.binBash;
});

test("has a working `escape` function", (t) => {
const shescape = new Shescape({ shell: false });

t.true(typeof shescape.escape === "function");

const input = "Hello world!";
const result = shescape.escape(input);
t.is(typeof result, "string");
});

test("has a working `escapeAll` function", (t) => {
const shescape = new Shescape({ shell: false });

t.true(typeof shescape.escapeAll === "function");

const inputs = ["foo", "bar"];
const result = shescape.escapeAll(inputs);
for (const output of result) {
t.is(typeof output, "string");
}
});

test("has a working `quote` function", (t) => {
const shescape = new Shescape({ shell: t.context.quoteShell });

t.true(typeof shescape.quote === "function");

const input = "Hello world!";
const result = shescape.quote(input);
t.is(typeof result, "string");
});

test("has a working `quoteAll` function", (t) => {
const shescape = new Shescape({ shell: t.context.quoteShell });

t.true(typeof shescape.quoteAll === "function");

const inputs = ["foo", "bar"];
const result = shescape.quoteAll(inputs);
for (const output of result) {
t.is(typeof output, "string");
}
});
testProp(
"Shescape#escape",
[arbitrary.shescapeOptions(), arbitrary.shescapeArg()],
(t, options, arg) => {
let shescape;

try {
shescape = new Shescape(options);
} catch (error) {
const known = ["No executable could be found for "];

if (!known.some((knownError) => error.message.includes(knownError))) {
t.fail(`Unexpected error:\n${error}`);
}
}

try {
shescape.escape(arg);
} catch (error) {
const known = [
"Cannot read property 'escape' of undefined",
"Cannot read properties of undefined (reading 'escape')",
];

if (!known.some((knownError) => error.message.includes(knownError))) {
t.fail(`Unexpected error:\n${error}`);
}
}

t.pass();
},
);

testProp(
"Shescape#escapeAll",
[arbitrary.shescapeOptions(), fc.array(arbitrary.shescapeArg())],
(t, options, args) => {
let shescape;

try {
shescape = new Shescape(options);
} catch (error) {
const known = ["No executable could be found for "];

if (!known.some((knownError) => error.message.includes(knownError))) {
t.fail(`Unexpected error:\n${error}`);
}
}

try {
shescape.escapeAll(args);
} catch (error) {
const known = [
"Cannot read property 'escapeAll' of undefined",
"Cannot read properties of undefined (reading 'escapeAll')",
];

if (!known.some((knownError) => error.message.includes(knownError))) {
t.fail(`Unexpected error:\n${error}`);
}
}

t.pass();
},
);

testProp(
"Shescape#quote",
[arbitrary.shescapeOptions(), arbitrary.shescapeArg()],
(t, options, arg) => {
let shescape;

try {
shescape = new Shescape(options);
} catch (error) {
const known = ["No executable could be found for "];

if (!known.some((knownError) => error.message.includes(knownError))) {
t.fail(`Unexpected error:\n${error}`);
}
}

try {
shescape.quote(arg);
} catch (error) {
const known = [
"Cannot read property 'quote' of undefined",
"Cannot read properties of undefined (reading 'quote')",
"Quoting is not supported when no shell is used",
];

if (!known.some((knownError) => error.message.includes(knownError))) {
t.fail(`Unexpected error:\n${error}`);
}
}

t.pass();
},
);

testProp(
"Shescape#quoteAll",
[arbitrary.shescapeOptions(), fc.array(arbitrary.shescapeArg())],
(t, options, args) => {
let shescape;

try {
shescape = new Shescape(options);
} catch (error) {
const known = ["No executable could be found for "];

if (!known.some((knownError) => error.message.includes(knownError))) {
t.fail(`Unexpected error:\n${error}`);
}
}

try {
shescape.quoteAll(args);
} catch (error) {
const known = [
"Cannot read property 'quoteAll' of undefined",
"Cannot read properties of undefined (reading 'quoteAll')",
"Quoting is not supported when no shell is used",
];

if (!known.some((knownError) => error.message.includes(knownError))) {
t.fail(`Unexpected error:\n${error}`);
}
}

t.pass();
},
);
126 changes: 126 additions & 0 deletions test/compat/testing.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/**
* @overview Contains smoke tests for the shescape testing module to verify
* compatibility with Node.js versions.
* @license MIT
*/

import { testProp } from "@fast-check/ava";
import * as fc from "fast-check";

import { arbitrary } from "./_.js";

import { Shescape as Stubscape, Throwscape } from "../../testing.js";

testProp(
"Stubscape#escape",
[arbitrary.shescapeOptions(), arbitrary.shescapeArg()],
(t, options, arg) => {
let stubscape;

try {
stubscape = new Stubscape(options);
} catch (error) {
t.fail(`Unexpected error:\n${error}`);
}

try {
stubscape.escape(arg);
} catch (error) {
t.fail(`Unexpected error:\n${error}`);
}

t.pass();
},
);

testProp(
"Stubscape#escapeAll",
[arbitrary.shescapeOptions(), fc.array(arbitrary.shescapeArg())],
(t, options, args) => {
let stubscape;

try {
stubscape = new Stubscape(options);
} catch (error) {
t.fail(`Unexpected error:\n${error}`);
}

try {
stubscape.escapeAll(args);
} catch (error) {
t.fail(`Unexpected error:\n${error}`);
}

t.pass();
},
);

testProp(
"Stubscape#quote",
[arbitrary.shescapeOptions(), arbitrary.shescapeArg()],
(t, options, arg) => {
let stubscape;

try {
stubscape = new Stubscape(options);
} catch (error) {
t.fail(`Unexpected error:\n${error}`);
}

try {
stubscape.quote(arg);
} catch (error) {
const knownErrors = [""];

if (!knownErrors.includes(error.message)) {
t.fail(`Unexpected error:\n${error}`);
}
}

t.pass();
},
);

testProp(
"Stubscape#quoteAll",
[arbitrary.shescapeOptions(), fc.array(arbitrary.shescapeArg())],
(t, options, args) => {
let stubscape;

try {
stubscape = new Stubscape(options);
} catch (error) {
t.fail(`Unexpected error:\n${error}`);
}

try {
stubscape.quoteAll(args);
} catch (error) {
const knownErrors = [""];

if (!knownErrors.includes(error.message)) {
t.fail(`Unexpected error:\n${error}`);
}
}

t.pass();
},
);

testProp(
"Throwscape#constructor",
[arbitrary.shescapeOptions()],
(t, options) => {
try {
new Throwscape(options);
} catch (error) {
const knownErrors = ["Can't be instantiated"];

if (!knownErrors.includes(error.message)) {
t.fail(`Unexpected error:\n${error}`);
}
}

t.pass();
},
);