Skip to content
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
2 changes: 1 addition & 1 deletion guardrails.suppressions.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"typescript/no-unused-vars": 1,
"unicorn/no-thenable": 1
},
"tsExpectError": 2,
"tsExpectError": 0,
"tsIgnore": 0,
"safety": 5,
"config": {},
Expand Down
10 changes: 8 additions & 2 deletions knip.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,15 @@ import { antelopeKnipConfig } from "@antelopejs/tooling-configs/knip";
/**
* `ajs module test` runs these compiled suites and builds its test project from
* `src/antelope.test.ts`. The whole compiled tree ships in the package, and the
* modules implementing this interface run it as their conformance suite.
* modules implementing this interface run it as their conformance suite. The
* `*.untyped.spec.js` suites feed values the types forbid, so they stay
* untyped JavaScript.
*/
const conformanceSuites = ["src/tests/**/*.test.ts", "src/antelope.test.ts"];
const conformanceSuites = [
"src/tests/**/*.test.ts",
"src/tests/**/*.untyped.spec.js",
"src/antelope.test.ts",
];

/**
* No import Knip can follow reaches these files: `datasets/index.ts` is the
Expand Down
24 changes: 0 additions & 24 deletions src/tests/atomic_mutation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,20 +99,6 @@ function ValidateRevision() {
expectedRevision: { kind: "missing" },
}),
).not.to.throw();
for (const expectedRevision of [
null,
undefined,
"",
{ kind: "missing", extra: true },
]) {
expect(() =>
ValidateAtomicMutation("record-a", {
...request,
// @ts-expect-error expectedRevision is null, undefined, "" or a tag with an extra key, off-contract values that ValidateAtomicMutation must refuse with a TypeError
expectedRevision,
}),
).to.throw(TypeError);
}
expect(() =>
table.atomicMutation("record-a", {
...request,
Expand Down Expand Up @@ -198,16 +184,6 @@ function ValidateEquality() {
}),
).not.to.throw();
}
for (const expectedValue of [null, undefined, {}, [], NaN, new Date(NaN)]) {
expect(() =>
ValidateAtomicMutation("record-a", {
type: "deleteIfEqual",
field: "title",
// @ts-expect-error expectedValue is null, undefined, {}, [], NaN or an invalid Date, off-contract values that ValidateAtomicMutation must refuse with a TypeError
expectedValue,
}),
).to.throw(TypeError);
}
}

type StubbedResult =
Expand Down
38 changes: 38 additions & 0 deletions src/tests/atomic_mutation.untyped.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const { expect } = require("chai");

const { ValidateAtomicMutation } = require("../index");

const update = {
type: "update",
revisionField: "revision",
expectedRevision: "observed",
nextRevision: "fresh",
patch: { details: { count: 3 } },
};

describe("Atomic mutation runtime refusal of off-contract values", () => {
it("refuses a null, undefined, empty or extended expected revision", () => {
for (const expectedRevision of [
null,
undefined,
"",
{ kind: "missing", extra: true },
]) {
expect(() =>
ValidateAtomicMutation("record-a", { ...update, expectedRevision }),
).to.throw(TypeError);
}
});

it("refuses a non-scalar or invalid expected value", () => {
for (const expectedValue of [null, undefined, {}, [], NaN, new Date(NaN)]) {
expect(() =>
ValidateAtomicMutation("record-a", {
type: "deleteIfEqual",
field: "title",
expectedValue,
}),
).to.throw(TypeError);
}
});
});
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"types": ["node", "mocha"],
"esModuleInterop": true,
"strict": true,
"allowJs": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"declaration": true,
Expand Down
Loading