Skip to content

Commit 09bf6a1

Browse files
Added assert.number methods to match assert.number.integer methods
1 parent cf21ca7 commit 09bf6a1

File tree

4 files changed

+173
-0
lines changed

4 files changed

+173
-0
lines changed

README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,49 @@ assert.string.enum("", { None: "none", Some: "some" }); // ❌ Invalid
422422
This is an alias for [`assert.type.number()`](#assert-number-value-fieldname-defaultvalue)
423423

424424

425+
### `assert.number.positive(value, [fieldName], [defaultValue])`
426+
Asserts that a value is a positive number (greater than zero).
427+
428+
- **value** - The value to check
429+
- **fieldName** - (optional) The name of the field being assertd. This is used in the error message if the assertion fails.
430+
- **defaultValue** - (optional) The default value to use if `value` is `undefined`.
431+
432+
```javascript
433+
import assert from "@jsdevtools/assert";
434+
435+
assert.number.positive(42); //
436+
assert.number.positive(12345.678); //
437+
assert.number.positive(Infinity); //
438+
assert.number.positive(Math.PI); //
439+
440+
assert.number.positive(0); // ❌ Invalid value: 0. Expected a positive number.
441+
assert.number.positive(-42); // ❌ Invalid value: -42. Expected a positive number.
442+
assert.number.positive(NaN); // ❌ Invalid value: NaN. Expected a number.
443+
```
444+
445+
446+
### `assert.number.nonNegative(value, [fieldName], [defaultValue])`
447+
Asserts that a value is a number that is zero or greater.
448+
449+
- **value** - The value to check
450+
- **fieldName** - (optional) The name of the field being assertd. This is used in the error message if the assertion fails.
451+
- **defaultValue** - (optional) The default value to use if `value` is `undefined`.
452+
453+
```javascript
454+
import assert from "@jsdevtools/assert";
455+
456+
assert.number.nonNegative(0); //
457+
assert.number.nonNegative(42); //
458+
assert.number.nonNegative(12345.6789); //
459+
assert.number.nonNegative(Infinity); //
460+
assert.number.nonNegative(Math.PI); //
461+
462+
assert.number.nonNegative(-42); // ❌ Invalid value: -42. Expected zero or greater.
463+
assert.number.nonNegative(-Infinity); // ❌ Invalid value: -Infinity. Expected zero or greater.
464+
assert.number.nonNegative(NaN); // ❌ Invalid value: NaN. Expected a number.
465+
```
466+
467+
425468
### `assert.number.integer(value, [fieldName], [defaultValue])`
426469
Asserts that a value is an integer value (positive or negative).
427470

src/number.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,26 @@ export interface AssertNumber {
2323
* Asserts that a value is an integer value (positive or negative).
2424
*/
2525
integer: AssertInteger;
26+
27+
/**
28+
* Asserts that a value is a positive number value (greater than zero).
29+
*/
30+
positive<T extends number>(value: T | undefined, fieldName?: string, defaultValue?: T): T;
31+
32+
/**
33+
* Asserts that a value is a positive number value (greater than zero).
34+
*/
35+
positive(value: unknown, fieldName?: string, defaultValue?: unknown): number;
36+
37+
/**
38+
* Asserts that a value is a number value that is zero or greater.
39+
*/
40+
nonNegative<T extends number>(value: T | undefined, fieldName?: string, defaultValue?: T): T;
41+
42+
/**
43+
* Asserts that a value is a number value that is zero or greater.
44+
*/
45+
nonNegative(value: unknown, fieldName?: string, defaultValue?: unknown): number;
2646
}
2747

2848
/**
@@ -67,11 +87,35 @@ export interface AssertInteger {
6787
*/
6888
// tslint:disable-next-line: variable-name
6989
export const number = type.number as AssertNumber;
90+
number.positive = assertPositiveNumber;
91+
number.nonNegative = assertNonNegativeNumber;
7092
number.integer = assertInteger as AssertInteger;
7193
number.integer.positive = assertPositiveInteger;
7294
number.integer.nonNegative = assertNonNegativeInteger;
7395

7496

97+
function assertPositiveNumber(value: number | undefined, fieldName = "value", defaultValue?: number): number {
98+
value = type.number(value, fieldName, defaultValue);
99+
100+
if (value <= 0) {
101+
throw ono.range(`Invalid ${fieldName}: ${humanize(value)}. Expected a positive number.`);
102+
}
103+
104+
return value;
105+
}
106+
107+
108+
function assertNonNegativeNumber(value: number | undefined, fieldName = "value", defaultValue?: number): number {
109+
value = type.number(value, fieldName, defaultValue);
110+
111+
if (value < 0) {
112+
throw ono.range(`Invalid ${fieldName}: ${humanize(value)}. Expected zero or greater.`);
113+
}
114+
115+
return value;
116+
}
117+
118+
75119
function assertInteger(value: number | undefined, fieldName = "value", defaultValue?: number): number {
76120
value = type.number(value, fieldName, defaultValue);
77121

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
"use strict";
2+
3+
const { assert } = require("../../lib");
4+
const { expect } = require("chai");
5+
6+
describe("assert.number.nonNegative()", () => {
7+
8+
it("should assert zero", () => {
9+
expect(assert.number.nonNegative(0)).to.equal(0);
10+
expect(assert.number.nonNegative(0.0)).to.equal(0);
11+
});
12+
13+
it("should assert non-negative numbers", () => {
14+
expect(assert.number.nonNegative(0)).to.equal(0);
15+
expect(assert.number.nonNegative(0.0)).to.equal(0);
16+
expect(assert.number.nonNegative(1.0)).to.equal(1);
17+
expect(assert.number.nonNegative(1.00001)).to.equal(1.00001);
18+
expect(assert.number.nonNegative(4.2)).to.equal(4.2);
19+
expect(assert.number.nonNegative(12345.6789)).to.equal(12345.6789);
20+
expect(assert.number.nonNegative(Number.MAX_VALUE)).to.equal(Number.MAX_VALUE);
21+
expect(assert.number.nonNegative(Math.PI)).to.equal(Math.PI);
22+
});
23+
24+
it("should throw an error for negative numbers", () => {
25+
function negative (value) {
26+
return () => {
27+
assert.number.nonNegative(value);
28+
};
29+
}
30+
31+
expect(negative(-1)).to.throw(RangeError, "Invalid value: -1. Expected zero or greater.");
32+
expect(negative(Number.MIN_SAFE_INTEGER)).to.throw(RangeError, "Invalid value: -9007199254740991. Expected zero or greater.");
33+
});
34+
35+
it("should throw an error for invalid defaults", () => {
36+
function negative (defaultValue) {
37+
return () => {
38+
assert.number.nonNegative(undefined, "age", defaultValue);
39+
};
40+
}
41+
42+
expect(negative(-1)).to.throw(RangeError, "Invalid age: -1. Expected zero or greater.");
43+
expect(negative(Number.MIN_SAFE_INTEGER)).to.throw(RangeError, "Invalid age: -9007199254740991. Expected zero or greater.");
44+
});
45+
46+
});

test/specs/number-positive.spec.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"use strict";
2+
3+
const { assert } = require("../../lib");
4+
const { expect } = require("chai");
5+
6+
describe("assert.number.positive()", () => {
7+
8+
it("should assert positive integers", () => {
9+
expect(assert.number.positive(1)).to.equal(1);
10+
expect(assert.number.positive(4.2)).to.equal(4.2);
11+
expect(assert.number.positive(1234.5678)).to.equal(1234.5678);
12+
expect(assert.number.positive(Number.MAX_VALUE)).to.equal(Number.MAX_VALUE);
13+
expect(assert.number.positive(Math.PI)).to.equal(Math.PI);
14+
});
15+
16+
it("should throw an error for negative numbers", () => {
17+
function negative (value) {
18+
return () => {
19+
assert.number.positive(value);
20+
};
21+
}
22+
23+
expect(negative(0)).to.throw(RangeError, "Invalid value: 0. Expected a positive number.");
24+
expect(negative(-1)).to.throw(RangeError, "Invalid value: -1. Expected a positive number.");
25+
expect(negative(Number.MIN_SAFE_INTEGER)).to.throw(RangeError, "Invalid value: -9007199254740991. Expected a positive number.");
26+
});
27+
28+
it("should throw an error for invalid defaults", () => {
29+
function negative (defaultValue) {
30+
return () => {
31+
assert.number.positive(undefined, "age", defaultValue);
32+
};
33+
}
34+
35+
expect(negative(0)).to.throw(RangeError, "Invalid age: 0. Expected a positive number.");
36+
expect(negative(-1)).to.throw(RangeError, "Invalid age: -1. Expected a positive number.");
37+
expect(negative(Number.MIN_SAFE_INTEGER)).to.throw(RangeError, "Invalid age: -9007199254740991. Expected a positive number.");
38+
});
39+
40+
});

0 commit comments

Comments
 (0)