Skip to content

Commit

Permalink
Replace chai with node:assert
Browse files Browse the repository at this point in the history
  • Loading branch information
voxpelli committed Jul 25, 2023
1 parent d0e59d9 commit c3cacdc
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 109 deletions.
9 changes: 1 addition & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,12 @@
"globby": "^13.2.2"
},
"devDependencies": {
"@types/chai": "^4.3.5",
"@types/chai-as-promised": "^7.1.5",
"@types/node": "^18.17.0",
"@types/sinon": "^10.0.15",
"@types/sinon-chai": "^3.2.9",
"@voxpelli/eslint-config": "^19.0.0",
"@voxpelli/node-test-pretty-reporter": "^1.0.1",
"@voxpelli/node-test-pretty-reporter": "^1.0.2",
"@voxpelli/tsconfig": "^8.0.0",
"c8": "^8.0.0",
"chai": "^4.3.7",
"chai-as-promised": "^7.1.1",
"chai-posix-path": "^1.0.0",
"desm": "^1.3.0",
"eslint": "^8.45.0",
"eslint-plugin-es-x": "^7.2.0",
Expand All @@ -86,7 +80,6 @@
"knip": "^2.17.0",
"npm-run-all2": "^6.0.6",
"sinon": "^15.2.0",
"sinon-chai": "^3.7.0",
"type-coverage": "^2.26.0",
"typescript": "~5.1.6",
"umzug": "^3.2.1"
Expand Down
61 changes: 41 additions & 20 deletions test/dependencies.spec.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,60 @@
import { describe, it } from 'node:test';

import chai from 'chai';
import assert from 'node:assert/strict';

import { processDefinition } from '../lib/dependencies.js';

const should = chai.should();

const context = Object.freeze({ filePath: 'bar/foo.js', normalizedPluginName: 'foo' });

describe('Dependencies', () => {
describe('processDefinition()', () => {
it('should throw on a non-object definition', () => {
should.Throw(() => { processDefinition(undefined, context); }, Error, 'Invalid umzeption definition, expected an object');
assert.throws(() => { processDefinition(undefined, context); }, {
name: 'TypeError',
message: 'Invalid umzeption definition, expected an object',
});
// eslint-disable-next-line unicorn/no-null
should.Throw(() => { processDefinition(null, context); }, Error, 'Invalid umzeption definition, expected an object');
should.Throw(() => { processDefinition('test', context); }, Error, 'Invalid umzeption definition, expected an object');
should.Throw(() => { processDefinition(() => 'test', context); }, Error, 'Invalid umzeption definition, expected an object');
assert.throws(() => { processDefinition(null, context); }, {
name: 'TypeError',
message: 'Invalid umzeption definition, expected an object',
});
assert.throws(() => { processDefinition('test', context); }, {
name: 'TypeError',
message: 'Invalid umzeption definition, expected an object',
});
assert.throws(() => { processDefinition(() => 'test', context); }, {
name: 'TypeError',
message: 'Invalid umzeption definition, expected an object',
});
});

it('should throw on an invalid object definition', () => {
should.Throw(() => { processDefinition({ name: 123 }, context); }, Error, 'Invalid umzeption definition');
should.Throw(() => { processDefinition({ dependencies: 123 }, context); }, Error, 'Invalid umzeption definition');
should.Throw(() => { processDefinition({ name: undefined }, context); }, Error, 'Invalid umzeption definition');
should.Throw(() => { processDefinition({ dependencies: undefined }, context); }, Error, 'Invalid umzeption definition');
assert.throws(() => { processDefinition({ name: 123 }, context); }, {
name: 'Error',
message: 'Invalid umzeption definition',
});
assert.throws(() => { processDefinition({ dependencies: 123 }, context); }, {
name: 'Error',
message: 'Invalid umzeption definition',
});
assert.throws(() => { processDefinition({ name: undefined }, context); }, {
name: 'Error',
message: 'Invalid umzeption definition',
});
assert.throws(() => { processDefinition({ dependencies: undefined }, context); }, {
name: 'Error',
message: 'Invalid umzeption definition',
});
});

it('should return an object', () => {
const result = processDefinition({}, context);
should.exist(result);
result.should.be.an('object');
assert.ok(result);
assert(typeof result === 'object', 'processDefinition returns an object');
});

it('should add a name if one is missing', () => {
const result = processDefinition({}, context);
result.should.deep.equal({
assert.deepStrictEqual(result, {
filePath: context.filePath,
name: context.normalizedPluginName,
});
Expand All @@ -44,15 +65,15 @@ describe('Dependencies', () => {
filePath: 'foo',
normalizedPluginName: './foo/bar.js',
});
result.should.deep.equal({ filePath: 'foo', name: 'bar' });
assert.deepStrictEqual(result, { filePath: 'foo', name: 'bar' });
});

it('should leave an already set name alone but shallow clone the definition', () => {
const input = { filePath: 'foo', name: 'abc123' };
const result = processDefinition(input, context);

result.should.deep.equal({ filePath: 'foo', name: 'abc123' });
result.should.not.equal(input);
assert.deepStrictEqual(result, { filePath: 'foo', name: 'abc123' });
assert.notStrictEqual(result, input);
});

it('should leave additional properties on the definition but shallow clone it', () => {
Expand All @@ -65,13 +86,13 @@ describe('Dependencies', () => {

const result = processDefinition(input, context);

result.should.deep.equal({
assert.deepStrictEqual(result, {
filePath: 'foo',
name: 'abc123',
dependencies: ['foo'],
abc: 123,
});
result.should.not.equal(input);
assert.notStrictEqual(result, input);
});
});
});
11 changes: 2 additions & 9 deletions test/integration.spec.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
import { describe, it, afterEach } from 'node:test';
import assert from 'node:assert/strict';

import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import sinon from 'sinon';
import sinonChai from 'sinon-chai';

import { filename } from 'desm';
import { Umzug, memoryStorage } from 'umzug';

import { umzeption } from '../index.js';

chai.use(chaiAsPromised);
chai.use(sinonChai);

chai.should();

describe('Integration', () => {
afterEach(() => {
sinon.restore();
Expand Down Expand Up @@ -43,7 +36,7 @@ describe('Integration', () => {

const executed = await storage.executed({ context });

executed.should.deep.equal([
assert.deepStrictEqual(executed, [
'test-dependency|foo-01.js',
'main|foo-01.js',
]);
Expand Down
102 changes: 72 additions & 30 deletions test/normalize-plugin-name.spec.js
Original file line number Diff line number Diff line change
@@ -1,68 +1,110 @@
import { describe, it } from 'node:test';

import chai from 'chai';
import chaiPosixPath from 'chai-posix-path';
import assert, { AssertionError } from 'node:assert/strict';

import { normalizePluginName } from '../lib/plugin-importer/normalize-plugin-name.js';

chai.use(chaiPosixPath);
/**
* @param {string} sourcePath
* @param {string} targetPath
* @returns {void}
*/
function assertPosixPath (sourcePath, targetPath) {
const posixPath = sourcePath.split('\\').join('/');

const should = chai.should();
if (posixPath !== targetPath) {
throw new AssertionError({
message: `expected ${sourcePath} to translate to posix path ${targetPath} but translated to ${posixPath}`,
actual: posixPath,
expected: targetPath,
});
}
}

describe('Normalize Plugin Name', () => {
describe('normalizePluginName()', () => {
it('should require a substantive string pluginName argument', () => {
// @ts-ignore
should.Throw(() => { normalizePluginName(); }, TypeError, 'Invalid pluginName, expected a string');
assert.throws(() => { normalizePluginName(); }, {
name: 'TypeError',
message: 'Invalid pluginName, expected a string',
});
// @ts-ignore
should.Throw(() => { normalizePluginName(123); }, TypeError, 'Invalid pluginName, expected a string');
assert.throws(() => { normalizePluginName(123); }, {
name: 'TypeError',
message: 'Invalid pluginName, expected a string',
});

should.Throw(() => { normalizePluginName(''); }, Error, 'Invalid pluginName, expected the string to be non-empty');
assert.throws(() => { normalizePluginName(''); }, {
name: 'Error',
message: 'Invalid pluginName, expected the string to be non-empty',
});

should.Throw(() => { normalizePluginName(' '); }, Error, 'Invalid pluginName, expected the string to not begin or end with whitespace');
should.Throw(() => { normalizePluginName('foo '); }, Error, 'Invalid pluginName, expected the string to not begin or end with whitespace');
should.Throw(() => { normalizePluginName(' foo'); }, Error, 'Invalid pluginName, expected the string to not begin or end with whitespace');
should.Throw(() => { normalizePluginName(' foo '); }, Error, 'Invalid pluginName, expected the string to not begin or end with whitespace');
assert.throws(() => { normalizePluginName(' '); }, {
name: 'Error',
message: 'Invalid pluginName, expected the string to not begin or end with whitespace',
});
assert.throws(() => { normalizePluginName('foo '); }, {
name: 'Error',
message: 'Invalid pluginName, expected the string to not begin or end with whitespace',
});
assert.throws(() => { normalizePluginName(' foo'); }, {
name: 'Error',
message: 'Invalid pluginName, expected the string to not begin or end with whitespace',
});
assert.throws(() => { normalizePluginName(' foo '); }, {
name: 'Error',
message: 'Invalid pluginName, expected the string to not begin or end with whitespace',
});
});

it('should throw on upwards directory traversing', () => {
should.not.Throw(() => { normalizePluginName('./foo/../bar/'); });
should.Throw(() => { normalizePluginName('./foo/../../bar/'); }, 'Plugin name attempts directory traversal: "./foo/../../bar/"');
assert.doesNotThrow(() => { normalizePluginName('./foo/../bar/'); });
assert.throws(() => { normalizePluginName('./foo/../../bar/'); }, {
message: 'Plugin name attempts directory traversal: "./foo/../../bar/"',
});
});

it('should return simple plugin name unaltered', () => {
const result = normalizePluginName('foo');
should.exist(result);
result.should.equal('foo');
assert.ok(result);
assert.strictEqual(result, 'foo');
});

it('should add prefix when one is set', () => {
const result = normalizePluginName('foo', 'example-prefix');
should.exist(result);
result.should.equal('example-prefix-foo');
assert.ok(result);
assert.strictEqual(result, 'example-prefix-foo');
});

it('should add prefix as suffix to plain scopes', () => {
const result = normalizePluginName('@foo', 'example-prefix');
should.exist(result);
result.should.equal('@foo/example-prefix');
assert.ok(result);
assert.strictEqual(result, '@foo/example-prefix');
});

it('should not add prefix if already prefixed', () => {
const result = normalizePluginName('example-prefix-foo', 'example-prefix');
should.exist(result);
result.should.equal('example-prefix-foo');
assert.ok(result);
assert.strictEqual(result, 'example-prefix-foo');
});

it('should return local path without prefix but normalized', () => {
normalizePluginName('./foo/../bar/', 'example-prefix')
.should.be.posixPath('./bar/');
normalizePluginName('./foo', 'example-prefix')
.should.be.posixPath('./foo');
normalizePluginName('./foo/../bar/')
.should.be.posixPath('./bar/');
normalizePluginName('./foo')
.should.be.posixPath('./foo');
assertPosixPath(
normalizePluginName('./foo/../bar/', 'example-prefix'),
'./bar/'
);
assertPosixPath(
normalizePluginName('./foo', 'example-prefix'),
'./foo'
);
assertPosixPath(
normalizePluginName('./foo/../bar/'),
'./bar/'
);
assertPosixPath(
normalizePluginName('./foo'),
'./foo'
);
});
});
});
Loading

0 comments on commit c3cacdc

Please sign in to comment.