From a467cf23a3c6818f33439c3f26b5c96974a76191 Mon Sep 17 00:00:00 2001 From: E1ecti <67551086+E1ecti@users.noreply.github.com> Date: Sun, 5 Apr 2026 06:16:54 +0200 Subject: [PATCH 1/5] feat: add `step` property for `number` rule --- README.md | 1 + index.d.ts | 8 ++++++++ lib/messages.js | 1 + lib/rules/number.js | 9 +++++++++ test/messages.spec.js | 1 + test/rules/number.spec.js | 13 +++++++++++++ test/typescript/messages.spec.ts | 1 + test/typescript/rules/number.spec.ts | 13 +++++++++++++ 8 files changed, 47 insertions(+) diff --git a/README.md b/README.md index 4a395198..d78b82a3 100644 --- a/README.md +++ b/README.md @@ -1671,6 +1671,7 @@ Name | Default text `numberEqual` | The '{field}' field must be equal to {expected}. `numberNotEqual` | The '{field}' field can't be equal to {expected}. `numberInteger` | The '{field}' field must be an integer. +`numberStep` | The '{field}' field must be a multiple of {expected}. `numberPositive` | The '{field}' field must be a positive number. `numberNegative` | The '{field}' field must be a negative number. `array` | The '{field}' field must be an array. diff --git a/index.d.ts b/index.d.ts index 19fbe6f4..f9e9b697 100644 --- a/index.d.ts +++ b/index.d.ts @@ -351,6 +351,10 @@ export interface RuleNumber extends RuleCustom { * @default false */ integer?: boolean; + /** + * The stepping interval for the input value + */ + step?: number; /** * The value must be greater than zero * @default false @@ -731,6 +735,10 @@ export interface BuiltInMessages { * The '{field}' field must be an integer. */ numberInteger?: string; + /** + * The '{field}' field must be a multiple of {expected}. + */ + numberStep?: string; /** * The '{field}' field must be a positive number. */ diff --git a/lib/messages.js b/lib/messages.js index bb2d672a..29321ae6 100644 --- a/lib/messages.js +++ b/lib/messages.js @@ -25,6 +25,7 @@ module.exports = { numberEqual: "The '{field}' field must be equal to {expected}.", numberNotEqual: "The '{field}' field can't be equal to {expected}.", numberInteger: "The '{field}' field must be an integer.", + numberStep: "The '{field}' field must be a multiple of {expected}.", numberPositive: "The '{field}' field must be a positive number.", numberNegative: "The '{field}' field must be a negative number.", diff --git a/lib/rules/number.js b/lib/rules/number.js index 5ac898c0..4065b175 100644 --- a/lib/rules/number.js +++ b/lib/rules/number.js @@ -69,6 +69,15 @@ module.exports = function({ schema, messages }, path, context) { `); } + // Check step + if (schema.step != null) { + src.push(` + if (value % ${schema.step} !== 0) { + ${this.makeError({ type: "numberStep", expected: schema.step, actual: "origValue", messages })} + } + `); + } + // Check positive if (schema.positive === true) { src.push(` diff --git a/test/messages.spec.js b/test/messages.spec.js index 5f2048d8..3a523253 100644 --- a/test/messages.spec.js +++ b/test/messages.spec.js @@ -22,6 +22,7 @@ describe("Test Messages", () => { expect(msg.numberEqual).toBeDefined(); expect(msg.numberNotEqual).toBeDefined(); expect(msg.numberInteger).toBeDefined(); + expect(msg.numberStep).toBeDefined(); expect(msg.numberPositive).toBeDefined(); expect(msg.numberNegative).toBeDefined(); expect(msg.array).toBeDefined(); diff --git a/test/rules/number.spec.js b/test/rules/number.spec.js index c46a3884..a1665da3 100644 --- a/test/rules/number.spec.js +++ b/test/rules/number.spec.js @@ -82,6 +82,19 @@ describe("Test rule: number", () => { expect(check(20)).toEqual(true); }); + it("check step", () => { + const check = v.compile({ $$root: true, type: "number", step: 10 }); + const message = "The '' field must be a multiple of 10."; + + expect(check(8.5)).toEqual([{ type: "numberStep", expected: 10, actual: 8.5, message }]); + expect(check(-5.5)).toEqual([{ type: "numberStep", expected: 10, actual: -5.5, message }]); + expect(check(15)).toEqual([{ type: "numberStep", expected: 10, actual: 15, message }]); + expect(check(0)).toEqual(true); + expect(check(-20)).toEqual(true); + expect(check(20)).toEqual(true); + expect(check(100)).toEqual(true); + }); + it("check positive number", () => { const check = v.compile({ $$root: true, type: "number", positive: true }); const message = "The '' field must be a positive number."; diff --git a/test/typescript/messages.spec.ts b/test/typescript/messages.spec.ts index aee94d8e..ef274194 100644 --- a/test/typescript/messages.spec.ts +++ b/test/typescript/messages.spec.ts @@ -22,6 +22,7 @@ describe("TypeScript Definitions", () => { expect(msg.numberEqual).toBeDefined(); expect(msg.numberNotEqual).toBeDefined(); expect(msg.numberInteger).toBeDefined(); + expect(msg.numberStep).toBeDefined(); expect(msg.numberPositive).toBeDefined(); expect(msg.numberNegative).toBeDefined(); expect(msg.array).toBeDefined(); diff --git a/test/typescript/rules/number.spec.ts b/test/typescript/rules/number.spec.ts index 877ee4a2..bb604f98 100644 --- a/test/typescript/rules/number.spec.ts +++ b/test/typescript/rules/number.spec.ts @@ -78,6 +78,19 @@ describe('TypeScript Definitions', () => { expect(check(20)).toEqual(true); }); + it('check step', () => { + const check = v.compile({ $$root: true, type: 'number', step: 10 } as RuleNumber); + const message = 'The \'\' field must be a multiple of 10.'; + + expect(check(8.5)).toEqual([{ type: "numberStep", expected: 10, actual: 8.5, message }]); + expect(check(-5.5)).toEqual([{ type: "numberStep", expected: 10, actual: -5.5, message }]); + expect(check(15)).toEqual([{ type: "numberStep", expected: 10, actual: 15, message }]); + expect(check(0)).toEqual(true); + expect(check(-20)).toEqual(true); + expect(check(20)).toEqual(true); + expect(check(100)).toEqual(true); + }); + it('check positive number', () => { const check = v.compile({ $$root: true, type: 'number', positive: true } as RuleNumber); const message = 'The \'\' field must be a positive number.'; From f49abcd67ad7ea4d68a144565af0125843e9f323 Mon Sep 17 00:00:00 2001 From: E1ecti <67551086+E1ecti@users.noreply.github.com> Date: Tue, 7 Apr 2026 13:21:09 +0200 Subject: [PATCH 2/5] fix: handle floating point precision, non-positive/NaN steps --- lib/rules/number.js | 6 +++++- test/rules/number.spec.js | 28 ++++++++++++++++++++++++++-- test/typescript/rules/number.spec.ts | 25 ++++++++++++++++++++++++- 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/lib/rules/number.js b/lib/rules/number.js index 4065b175..5019fe04 100644 --- a/lib/rules/number.js +++ b/lib/rules/number.js @@ -71,8 +71,12 @@ module.exports = function({ schema, messages }, path, context) { // Check step if (schema.step != null) { + if (!(schema.step > 0)) + throw new Error(`Invalid '${schema.type}' schema. The 'step' field must be a positive number.`); + src.push(` - if (value % ${schema.step} !== 0) { + const ratio = value / ${schema.step}; + if (Math.abs(Math.round(ratio) - ratio) > 1e-10) { ${this.makeError({ type: "numberStep", expected: schema.step, actual: "origValue", messages })} } `); diff --git a/test/rules/number.spec.js b/test/rules/number.spec.js index a1665da3..3c68617c 100644 --- a/test/rules/number.spec.js +++ b/test/rules/number.spec.js @@ -82,19 +82,43 @@ describe("Test rule: number", () => { expect(check(20)).toEqual(true); }); + it("check schema's 'step' field type", () => { + const message = "Invalid 'number' schema. The 'step' field must be a positive number."; + + expect(() => v.compile({ $$root: true, type: "number", step: 0 })).toThrow(message); + }); + it("check step", () => { const check = v.compile({ $$root: true, type: "number", step: 10 }); const message = "The '' field must be a multiple of 10."; + expect(check(15)).toEqual([{ type: "numberStep", expected: 10, actual: 15, message }]); expect(check(8.5)).toEqual([{ type: "numberStep", expected: 10, actual: 8.5, message }]); expect(check(-5.5)).toEqual([{ type: "numberStep", expected: 10, actual: -5.5, message }]); - expect(check(15)).toEqual([{ type: "numberStep", expected: 10, actual: 15, message }]); + expect(check(0)).toEqual(true); - expect(check(-20)).toEqual(true); expect(check(20)).toEqual(true); + expect(check(-20)).toEqual(true); expect(check(100)).toEqual(true); }); + it("check step (float)", () => { + const check = v.compile({ $$root: true, type: "number", step: 0.2 }); + const message = "The '' field must be a multiple of 0.2."; + + expect(check(1.1)).toEqual([{ type: "numberStep", expected: 0.2, actual: 1.1, message }]); + expect(check(-5.5)).toEqual([{ type: "numberStep", expected: 0.2, actual: -5.5, message }]); + expect(check(0.20001)).toEqual([{ type: "numberStep", expected: 0.2, actual: 0.20001, message }]); + + expect(check(0)).toEqual(true); + expect(check(2)).toEqual(true); + expect(check(1.4)).toEqual(true); + expect(check(-20.2)).toEqual(true); + + expect(check(1.4000000001)).toEqual([{ type: "numberStep", expected: 0.2, actual: 1.4000000001, message }]); + expect(check(1.40000000001)).toEqual(true); // will pass due to precision tolerance + }); + it("check positive number", () => { const check = v.compile({ $$root: true, type: "number", positive: true }); const message = "The '' field must be a positive number."; diff --git a/test/typescript/rules/number.spec.ts b/test/typescript/rules/number.spec.ts index bb604f98..7a57897c 100644 --- a/test/typescript/rules/number.spec.ts +++ b/test/typescript/rules/number.spec.ts @@ -78,9 +78,15 @@ describe('TypeScript Definitions', () => { expect(check(20)).toEqual(true); }); + it("check schema's 'step' field type", () => { + const message = "Invalid 'number' schema. The 'step' field must be a positive number."; + + expect(() => v.compile({ $$root: true, type: "number", step: 0 })).toThrow(message); + }); + it('check step', () => { const check = v.compile({ $$root: true, type: 'number', step: 10 } as RuleNumber); - const message = 'The \'\' field must be a multiple of 10.'; + const message = "The '' field must be a multiple of 10."; expect(check(8.5)).toEqual([{ type: "numberStep", expected: 10, actual: 8.5, message }]); expect(check(-5.5)).toEqual([{ type: "numberStep", expected: 10, actual: -5.5, message }]); @@ -91,6 +97,23 @@ describe('TypeScript Definitions', () => { expect(check(100)).toEqual(true); }); + it("check step (float)", () => { + const check = v.compile({ $$root: true, type: "number", step: 0.2 } as RuleNumber); + const message = "The '' field must be a multiple of 0.2."; + + expect(check(1.1)).toEqual([{ type: "numberStep", expected: 0.2, actual: 1.1, message }]); + expect(check(-5.5)).toEqual([{ type: "numberStep", expected: 0.2, actual: -5.5, message }]); + expect(check(0.20001)).toEqual([{ type: "numberStep", expected: 0.2, actual: 0.20001, message }]); + + expect(check(0)).toEqual(true); + expect(check(2)).toEqual(true); + expect(check(1.4)).toEqual(true); + expect(check(-20.2)).toEqual(true); + + expect(check(1.4000000001)).toEqual([{ type: "numberStep", expected: 0.2, actual: 1.4000000001, message }]); + expect(check(1.40000000001)).toEqual(true); // will pass due to precision tolerance + }); + it('check positive number', () => { const check = v.compile({ $$root: true, type: 'number', positive: true } as RuleNumber); const message = 'The \'\' field must be a positive number.'; From fafdec666c99a782660a62fec8afc20f4d839f9d Mon Sep 17 00:00:00 2001 From: E1ecti <67551086+E1ecti@users.noreply.github.com> Date: Tue, 7 Apr 2026 13:30:00 +0200 Subject: [PATCH 3/5] test: added negative/NaN tests for `step` property --- test/rules/number.spec.js | 2 ++ test/typescript/rules/number.spec.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/test/rules/number.spec.js b/test/rules/number.spec.js index 3c68617c..ca8e9d2a 100644 --- a/test/rules/number.spec.js +++ b/test/rules/number.spec.js @@ -86,6 +86,8 @@ describe("Test rule: number", () => { const message = "Invalid 'number' schema. The 'step' field must be a positive number."; expect(() => v.compile({ $$root: true, type: "number", step: 0 })).toThrow(message); + expect(() => v.compile({ $$root: true, type: "number", step: -1 })).toThrow(message); + expect(() => v.compile({ $$root: true, type: "number", step: NaN })).toThrow(message); }); it("check step", () => { diff --git a/test/typescript/rules/number.spec.ts b/test/typescript/rules/number.spec.ts index 7a57897c..ea7bdad1 100644 --- a/test/typescript/rules/number.spec.ts +++ b/test/typescript/rules/number.spec.ts @@ -82,6 +82,8 @@ describe('TypeScript Definitions', () => { const message = "Invalid 'number' schema. The 'step' field must be a positive number."; expect(() => v.compile({ $$root: true, type: "number", step: 0 })).toThrow(message); + expect(() => v.compile({ $$root: true, type: "number", step: -1 })).toThrow(message); + expect(() => v.compile({ $$root: true, type: "number", step: NaN })).toThrow(message); }); it('check step', () => { From 6cce700340bbdcc872e8cb71b0d1e758e4842b5f Mon Sep 17 00:00:00 2001 From: E1ecti <67551086+E1ecti@users.noreply.github.com> Date: Thu, 9 Apr 2026 03:36:21 +0200 Subject: [PATCH 4/5] refactor: improve float `step` validation logic --- lib/rules/number.js | 49 +++++++++++++++++++++------- test/rules/number.spec.js | 6 +++- test/typescript/rules/number.spec.ts | 6 +++- 3 files changed, 48 insertions(+), 13 deletions(-) diff --git a/lib/rules/number.js b/lib/rules/number.js index 5019fe04..589371fb 100644 --- a/lib/rules/number.js +++ b/lib/rules/number.js @@ -21,7 +21,7 @@ module.exports = function({ schema, messages }, path, context) { src.push(` if (typeof value !== "number" || isNaN(value) || !isFinite(value)) { - ${this.makeError({ type: "number", actual: "origValue", messages })} + ${this.makeError({ type: "number", actual: "origValue", messages })} return value; } `); @@ -64,29 +64,56 @@ module.exports = function({ schema, messages }, path, context) { if (schema.integer === true) { src.push(` if (value % 1 !== 0) { - ${this.makeError({ type: "numberInteger", actual: "origValue", messages })} + ${this.makeError({ type: "numberInteger", actual: "origValue", messages })} } `); } // Check step if (schema.step != null) { - if (!(schema.step > 0)) + if (schema.step <= 0 || !Number.isFinite(schema.step)) throw new Error(`Invalid '${schema.type}' schema. The 'step' field must be a positive number.`); + + const errorSrc = this.makeError({ type: "numberStep", expected: schema.step, actual: "origValue", messages }); - src.push(` - const ratio = value / ${schema.step}; - if (Math.abs(Math.round(ratio) - ratio) > 1e-10) { - ${this.makeError({ type: "numberStep", expected: schema.step, actual: "origValue", messages })} - } - `); + if (Number.isInteger(schema.step)) + src.push(` + if (value % ${schema.step} !== 0) { + ${errorSrc} + } + `) + else { + const stepDecimals = schema.step.toString().split('.')[1].length + const multiplier = Math.pow(10, stepDecimals); + const stepInt = Math.round(schema.step * multiplier); + + src.push(` + if (!Number.isFinite(value)) { + ${errorSrc} + } else { + const valStr = value.toString(); + const valDotIdx = valStr.indexOf('.'); + const valDecimals = valDotIdx !== -1 ? valStr.length - valDotIdx - 1 : 0; + + if (valDecimals > ${stepDecimals}) { + ${errorSrc} + } else { + const valInt = Math.round(value * ${multiplier}); + + if (valInt % ${stepInt} !== 0) { + ${errorSrc} + } + } + } + `); + } } // Check positive if (schema.positive === true) { src.push(` if (value <= 0) { - ${this.makeError({ type: "numberPositive", actual: "origValue", messages })} + ${this.makeError({ type: "numberPositive", actual: "origValue", messages })} } `); } @@ -95,7 +122,7 @@ module.exports = function({ schema, messages }, path, context) { if (schema.negative === true) { src.push(` if (value >= 0) { - ${this.makeError({ type: "numberNegative", actual: "origValue", messages })} + ${this.makeError({ type: "numberNegative", actual: "origValue", messages })} } `); } diff --git a/test/rules/number.spec.js b/test/rules/number.spec.js index ca8e9d2a..b9ab5e40 100644 --- a/test/rules/number.spec.js +++ b/test/rules/number.spec.js @@ -88,6 +88,7 @@ describe("Test rule: number", () => { expect(() => v.compile({ $$root: true, type: "number", step: 0 })).toThrow(message); expect(() => v.compile({ $$root: true, type: "number", step: -1 })).toThrow(message); expect(() => v.compile({ $$root: true, type: "number", step: NaN })).toThrow(message); + expect(() => v.compile({ $$root: true, type: "number", step: Infinity })).toThrow(message); }); it("check step", () => { @@ -97,6 +98,8 @@ describe("Test rule: number", () => { expect(check(15)).toEqual([{ type: "numberStep", expected: 10, actual: 15, message }]); expect(check(8.5)).toEqual([{ type: "numberStep", expected: 10, actual: 8.5, message }]); expect(check(-5.5)).toEqual([{ type: "numberStep", expected: 10, actual: -5.5, message }]); + expect(check(NaN)).toEqual([{ type: "numberStep", expected: 10, actual: NaN, message }]); + expect(check(Infinity)).toEqual([{ type: "numberStep", expected: 10, actual: Infinity, message }]); expect(check(0)).toEqual(true); expect(check(20)).toEqual(true); @@ -111,6 +114,8 @@ describe("Test rule: number", () => { expect(check(1.1)).toEqual([{ type: "numberStep", expected: 0.2, actual: 1.1, message }]); expect(check(-5.5)).toEqual([{ type: "numberStep", expected: 0.2, actual: -5.5, message }]); expect(check(0.20001)).toEqual([{ type: "numberStep", expected: 0.2, actual: 0.20001, message }]); + expect(check(NaN)).toEqual([{ type: "numberStep", expected: 0.2, actual: NaN, message }]); + expect(check(Infinity)).toEqual([{ type: "numberStep", expected: 0.2, actual: Infinity, message }]); expect(check(0)).toEqual(true); expect(check(2)).toEqual(true); @@ -118,7 +123,6 @@ describe("Test rule: number", () => { expect(check(-20.2)).toEqual(true); expect(check(1.4000000001)).toEqual([{ type: "numberStep", expected: 0.2, actual: 1.4000000001, message }]); - expect(check(1.40000000001)).toEqual(true); // will pass due to precision tolerance }); it("check positive number", () => { diff --git a/test/typescript/rules/number.spec.ts b/test/typescript/rules/number.spec.ts index ea7bdad1..6ffecdfb 100644 --- a/test/typescript/rules/number.spec.ts +++ b/test/typescript/rules/number.spec.ts @@ -93,6 +93,9 @@ describe('TypeScript Definitions', () => { expect(check(8.5)).toEqual([{ type: "numberStep", expected: 10, actual: 8.5, message }]); expect(check(-5.5)).toEqual([{ type: "numberStep", expected: 10, actual: -5.5, message }]); expect(check(15)).toEqual([{ type: "numberStep", expected: 10, actual: 15, message }]); + expect(check(NaN)).toEqual([{ type: "numberStep", expected: 10, actual: NaN, message }]); + expect(check(Infinity)).toEqual([{ type: "numberStep", expected: 10, actual: Infinity, message }]); + expect(check(0)).toEqual(true); expect(check(-20)).toEqual(true); expect(check(20)).toEqual(true); @@ -106,6 +109,8 @@ describe('TypeScript Definitions', () => { expect(check(1.1)).toEqual([{ type: "numberStep", expected: 0.2, actual: 1.1, message }]); expect(check(-5.5)).toEqual([{ type: "numberStep", expected: 0.2, actual: -5.5, message }]); expect(check(0.20001)).toEqual([{ type: "numberStep", expected: 0.2, actual: 0.20001, message }]); + expect(check(NaN)).toEqual([{ type: "numberStep", expected: 0.2, actual: NaN, message }]); + expect(check(Infinity)).toEqual([{ type: "numberStep", expected: 0.2, actual: Infinity, message }]); expect(check(0)).toEqual(true); expect(check(2)).toEqual(true); @@ -113,7 +118,6 @@ describe('TypeScript Definitions', () => { expect(check(-20.2)).toEqual(true); expect(check(1.4000000001)).toEqual([{ type: "numberStep", expected: 0.2, actual: 1.4000000001, message }]); - expect(check(1.40000000001)).toEqual(true); // will pass due to precision tolerance }); it('check positive number', () => { From 42d7668952695bcd7401b0514e89ebbc07a3b651 Mon Sep 17 00:00:00 2001 From: E1ecti <67551086+E1ecti@users.noreply.github.com> Date: Thu, 9 Apr 2026 03:43:43 +0200 Subject: [PATCH 5/5] fix: remove rudimental test cases --- test/rules/number.spec.js | 4 ---- test/typescript/rules/number.spec.ts | 4 ---- 2 files changed, 8 deletions(-) diff --git a/test/rules/number.spec.js b/test/rules/number.spec.js index b9ab5e40..3b020e79 100644 --- a/test/rules/number.spec.js +++ b/test/rules/number.spec.js @@ -98,8 +98,6 @@ describe("Test rule: number", () => { expect(check(15)).toEqual([{ type: "numberStep", expected: 10, actual: 15, message }]); expect(check(8.5)).toEqual([{ type: "numberStep", expected: 10, actual: 8.5, message }]); expect(check(-5.5)).toEqual([{ type: "numberStep", expected: 10, actual: -5.5, message }]); - expect(check(NaN)).toEqual([{ type: "numberStep", expected: 10, actual: NaN, message }]); - expect(check(Infinity)).toEqual([{ type: "numberStep", expected: 10, actual: Infinity, message }]); expect(check(0)).toEqual(true); expect(check(20)).toEqual(true); @@ -114,8 +112,6 @@ describe("Test rule: number", () => { expect(check(1.1)).toEqual([{ type: "numberStep", expected: 0.2, actual: 1.1, message }]); expect(check(-5.5)).toEqual([{ type: "numberStep", expected: 0.2, actual: -5.5, message }]); expect(check(0.20001)).toEqual([{ type: "numberStep", expected: 0.2, actual: 0.20001, message }]); - expect(check(NaN)).toEqual([{ type: "numberStep", expected: 0.2, actual: NaN, message }]); - expect(check(Infinity)).toEqual([{ type: "numberStep", expected: 0.2, actual: Infinity, message }]); expect(check(0)).toEqual(true); expect(check(2)).toEqual(true); diff --git a/test/typescript/rules/number.spec.ts b/test/typescript/rules/number.spec.ts index 6ffecdfb..3bc5d5b0 100644 --- a/test/typescript/rules/number.spec.ts +++ b/test/typescript/rules/number.spec.ts @@ -93,8 +93,6 @@ describe('TypeScript Definitions', () => { expect(check(8.5)).toEqual([{ type: "numberStep", expected: 10, actual: 8.5, message }]); expect(check(-5.5)).toEqual([{ type: "numberStep", expected: 10, actual: -5.5, message }]); expect(check(15)).toEqual([{ type: "numberStep", expected: 10, actual: 15, message }]); - expect(check(NaN)).toEqual([{ type: "numberStep", expected: 10, actual: NaN, message }]); - expect(check(Infinity)).toEqual([{ type: "numberStep", expected: 10, actual: Infinity, message }]); expect(check(0)).toEqual(true); expect(check(-20)).toEqual(true); @@ -109,8 +107,6 @@ describe('TypeScript Definitions', () => { expect(check(1.1)).toEqual([{ type: "numberStep", expected: 0.2, actual: 1.1, message }]); expect(check(-5.5)).toEqual([{ type: "numberStep", expected: 0.2, actual: -5.5, message }]); expect(check(0.20001)).toEqual([{ type: "numberStep", expected: 0.2, actual: 0.20001, message }]); - expect(check(NaN)).toEqual([{ type: "numberStep", expected: 0.2, actual: NaN, message }]); - expect(check(Infinity)).toEqual([{ type: "numberStep", expected: 0.2, actual: Infinity, message }]); expect(check(0)).toEqual(true); expect(check(2)).toEqual(true);