Skip to content

Commit

Permalink
Merge pull request #75 from izelnakri/stateful-tests
Browse files Browse the repository at this point in the history
Assert.step, expect & async support
  • Loading branch information
izelnakri authored Jul 29, 2023
2 parents 53a71b1 + 9fd1ee3 commit 7486520
Show file tree
Hide file tree
Showing 17 changed files with 1,523 additions and 385 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:20.4.0-slim
FROM node:20.5.0-slim

RUN apt-get update \
&& apt-get install -y curl unzip wget gnupg \
Expand Down
15 changes: 15 additions & 0 deletions TODO
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
create runtime error for module with no tests, create runtime error for hooks declared in inner modules without hooks reference(typo)

context parameter to module() and test() instead of this

Test left: custom assertions(?)[pushResult], timeout

Add .match() for pattern match

interested in node.js doctool(?)

function innerFail(obj) {
if (obj.message instanceof Error) throw obj.message;

throw new AssertionError(obj);
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
"ts-node": ">=10.7.0"
},
"volta": {
"node": "20.4.0"
"node": "20.5.0"
},
"prettier": {
"printWidth": 100,
Expand Down
142 changes: 98 additions & 44 deletions shims/deno/assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,39 +9,79 @@ export class AssertionError extends DenoAssertionError {
}
}

// NOTE: Maybe do the expect, steps in some object, and also do timeout and async(?)
export default {
_steps: [],
timeout() {
return true; // NOTE: NOT implemented
},
step(value = '') {
this._steps.push(value);
},
verifySteps(steps, message = 'Verify steps failed!') {
const result = this.deepEqual(this._steps, steps, message);
export default class Assert {
AssertionError = AssertionError

#asyncOps = [];

constructor(module, test) {
this.test = test || module;
}
_incrementAssertionCount() {
this.test.totalExecutedAssertions++;
}
timeout(number) {
if (!Number.isInteger(number) || number < 0) {
throw new Error('assert.timeout() expects a positive integer.');
}

this.test.timeout = number;
}
step(message) {
let assertionMessage = message;
let result = !!message;

this.test.steps.push(message);

if (typeof message === 'undefined' || message === '') {
assertionMessage = 'You must provide a message to assert.step';
} else if (typeof message !== 'string') {
assertionMessage = 'You must provide a string value to assert.step';
result = false;
}

this._steps.length = 0;
this.pushResult({
result,
message: assertionMessage
});
}
verifySteps(steps, message = 'Verify steps failed!') {
this.deepEqual(this.test.steps, steps, message);
this.test.steps.length = 0;
}
expect(number) {
if (!Number.isInteger(number) || number < 0) {
throw new Error('assert.expect() expects a positive integer.');
}

return result;
},
expect() {
return () => {}; // NOTE: NOT implemented
},
this.test.expectedAssertionCount = number;
}
async() {
return () => {}; // NOTE: noop, node should have sanitizeResources
},
let resolveFn;
let done = new Promise(resolve => { resolveFn = resolve; });

this.#asyncOps.push(done);

return () => { resolveFn(); };
}
async waitForAsyncOps() {
return Promise.all(this.#asyncOps);
}
pushResult(resultInfo = {}) {
if (!result) {
this._incrementAssertionCount();
if (!resultInfo.result) {
throw new AssertionError({
actual: resultInfo.actual,
expected: resultInfo.expected,
message: result.Infomessage || 'Custom assertion failed!',
message: resultInfo.message || 'Custom assertion failed!',
stackStartFn: this.pushResult,
});
}
},

return this;
}
ok(state, message) {
this._incrementAssertionCount();
if (!state) {
throw new AssertionError({
actual: state,
Expand All @@ -50,8 +90,9 @@ export default {
stackStartFn: this.ok,
});
}
},
}
notOk(state, message) {
this._incrementAssertionCount();
if (state) {
throw new AssertionError({
actual: state,
Expand All @@ -60,8 +101,9 @@ export default {
stackStartFn: this.notOk,
});
}
},
}
true(state, message) {
this._incrementAssertionCount();
if (state !== true) {
throw new AssertionError({
actual: state,
Expand All @@ -70,8 +112,9 @@ export default {
stackStartFn: this.true,
});
}
},
}
false(state, message) {
this._incrementAssertionCount();
if (state !== false) {
throw new AssertionError({
actual: state,
Expand All @@ -80,8 +123,9 @@ export default {
stackStartFn: this.false,
});
}
},
}
equal(actual, expected, message) {
this._incrementAssertionCount();
if (actual != expected) {
throw new AssertionError({
actual,
Expand All @@ -91,8 +135,9 @@ export default {
stackStartFn: this.equal,
});
}
},
}
notEqual(actual, expected, message) {
this._incrementAssertionCount();
if (actual == expected) {
throw new AssertionError({
actual,
Expand All @@ -102,57 +147,62 @@ export default {
stackStartFn: this.notEqual,
});
}
},
}
propEqual(actual, expected, message) {
this._incrementAssertionCount();
let targetActual = objectValues(actual);
let targetExpected = objectValues(expected);
if (!window.QUnit.equiv(targetActual, targetExpected)) {
if (!QUnit.equiv(targetActual, targetExpected)) {
throw new AssertionError({
actual: targetActual,
expected: targetExpected,
message: message || `Expected properties to be propEqual: ${defaultMessage(targetActual, 'should propEqual to:', targetExpected)}`,
stackStartFn: this.propEqual,
});
}
},
}
notPropEqual(actual, expected, message) {
this._incrementAssertionCount();
let targetActual = objectValues(actual);
let targetExpected = objectValues(expected);
if (window.QUnit.equiv(targetActual, targetExpected)) {
if (QUnit.equiv(targetActual, targetExpected)) {
throw new AssertionError({
actual: targetActual,
expected: targetExpected,
message: message || `Expected properties to NOT be propEqual: ${defaultMessage(targetActual, 'should notPropEqual to:', targetExpected)}`,
stackStartFn: this.notPropEqual,
});
}
},
}
propContains(actual, expected, message) {
this._incrementAssertionCount();
let targetActual = objectValuesSubset(actual, expected);
let targetExpected = objectValues(expected, false);
if (!window.QUnit.equiv(targetActual, targetExpected)) {
if (!QUnit.equiv(targetActual, targetExpected)) {
throw new AssertionError({
actual: targetActual,
expected: targetExpected,
message: message || `propContains assertion fail on: ${defaultMessage(targetActual, 'should propContains to:', targetExpected)}`,
stackStartFn: this.propContains,
});
}
},
}
notPropContains(actual, expected, message) {
this._incrementAssertionCount();
let targetActual = objectValuesSubset(actual, expected);
let targetExpected = objectValues(expected);
if (window.QUnit.equiv(targetActual, targetExpected)) {
if (QUnit.equiv(targetActual, targetExpected)) {
throw new AssertionError({
actual: targetActual,
expected: targetExpected,
message: message || `notPropContains assertion fail on: ${defaultMessage(targetActual, 'should notPropContains of:', targetExpected)}`,
stackStartFn: this.notPropContains,
});
}
},
}
deepEqual(actual, expected, message) {
if (!window.QUnit.equiv(actual, expected)) {
this._incrementAssertionCount();
if (!QUnit.equiv(actual, expected)) {
throw new AssertionError({
actual,
expected,
Expand All @@ -161,9 +211,10 @@ export default {
stackStartFn: this.deepEqual,
});
}
},
}
notDeepEqual(actual, expected, message) {
if (window.QUnit.equiv(actual, expected)) {
this._incrementAssertionCount();
if (QUnit.equiv(actual, expected)) {
throw new AssertionError({
actual,
expected,
Expand All @@ -172,8 +223,9 @@ export default {
stackStartFn: this.notDeepEqual,
});
}
},
}
strictEqual(actual, expected, message) {
this._incrementAssertionCount();
if (actual !== expected) {
throw new AssertionError({
actual,
Expand All @@ -183,8 +235,9 @@ export default {
stackStartFn: this.strictEqual,
});
}
},
}
notStrictEqual(actual, expected, message) {
this._incrementAssertionCount();
if (actual === expected) {
throw new AssertionError({
actual,
Expand All @@ -194,8 +247,9 @@ export default {
stackStartFn: this.notStrictEqual,
});
}
},
}
throws(blockFn, expectedInput, assertionMessage) {
this?._incrementAssertionCount();
let [expected, message] = validateExpectedExceptionArgs(expectedInput, assertionMessage, 'rejects');
if (typeof blockFn !== 'function') {
throw new AssertionError({
Expand Down Expand Up @@ -228,8 +282,9 @@ export default {
message: 'Function passed to `assert.throws` did not throw an exception!',
stackStartFn: this.throws,
});
},
}
async rejects(promise, expectedInput, assertionMessage) {
this._incrementAssertionCount();
let [expected, message] = validateExpectedExceptionArgs(expectedInput, assertionMessage, 'rejects');
let then = promise && promise.then;
if (typeof then !== 'function') {
Expand Down Expand Up @@ -276,4 +331,3 @@ ${inspect(expected)}`
function inspect(value) {
return util.inspect(value, { depth: 10, colors: true, compact: false });
}

Loading

0 comments on commit 7486520

Please sign in to comment.