Skip to content

Commit bd2725f

Browse files
committed
Merge branch 'master' of github.com:streamich/json-joy
2 parents 3cfeccc + ed523e1 commit bd2725f

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

packages/json-type/src/random/Random.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,13 @@ export class Random {
114114
let max = Number.MAX_SAFE_INTEGER;
115115
const schema = type.getSchema();
116116
const {lt, lte, gt, gte} = schema;
117+
const isIntegerFormat = schema.format && ['i8', 'i16', 'i32', 'i64', 'i', 'u8', 'u16', 'u32', 'u64', 'u'].includes(schema.format);
117118
if (gt !== undefined) min = gt;
118119
if (gte !== undefined)
119120
if (gte === lte) return gte;
120-
else min = gte + 0.000000000000001;
121+
else min = isIntegerFormat ? gte : gte + 0.000000000000001;
121122
if (lt !== undefined) max = lt;
122-
if (lte !== undefined) max = lte - 0.000000000000001;
123+
if (lte !== undefined) max = isIntegerFormat ? lte : lte - 0.000000000000001;
123124
if (min >= max) return max;
124125
if (schema.format) {
125126
switch (schema.format) {

packages/json-type/src/random/__tests__/random.spec.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,34 @@ describe('Random', () => {
5858
}
5959
});
6060

61+
test('num with integer format and gte/lte always produces clean integers', () => {
62+
// Test u16 format with gte/lte constraints (the configuration that was failing)
63+
const type = t.Number({format: 'u16', gte: 1, lte: 65535});
64+
for (let i = 0; i < 100; i++) {
65+
const value = Random.gen(type);
66+
expect(typeof value).toBe('number');
67+
expect(Number.isInteger(value)).toBe(true);
68+
expect(value).toBeGreaterThanOrEqual(1);
69+
expect(value).toBeLessThanOrEqual(65535);
70+
// Verify no floating-point artifacts
71+
expect(value).toBe(Math.floor(value));
72+
validate(type, value);
73+
}
74+
});
75+
76+
test('num with all integer formats produces clean integers', () => {
77+
const integerFormats = ['i8', 'i16', 'i32', 'u8', 'u16', 'u32'] as const;
78+
for (const format of integerFormats) {
79+
const type = t.Number({format, gte: 1, lte: 100});
80+
for (let i = 0; i < 50; i++) {
81+
const value = Random.gen(type);
82+
expect(Number.isInteger(value)).toBe(true);
83+
expect(value).toBe(Math.floor(value));
84+
validate(type, value);
85+
}
86+
}
87+
});
88+
6189
test('bool generates valid booleans', () => {
6290
const type = t.Boolean();
6391
for (let i = 0; i < 10; i++) {

0 commit comments

Comments
 (0)