Skip to content

Commit da35c51

Browse files
authored
refactor(date)!: stricter error handling of between (#2719)
1 parent 47f008a commit da35c51

File tree

3 files changed

+80
-3
lines changed

3 files changed

+80
-3
lines changed

docs/guide/upgrading_v9/2711.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### Require `from` and `to` in `faker.date.between()` and `betweens()`
2+
3+
Previously, in `faker.date.between()` and `faker.date.betweens()` if the `from` or `to` parameter was omitted (in Javascript) or an invalid date (in Javascript or Typescript), they would default to the current date or reference date. Now, both boundaries must now be given explictly. If you still need the old behavior, you can pass `Date.now()` or the reference date for `from` or `to`.

src/modules/date/index.ts

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,13 @@ export class SimpleDateModule extends SimpleModuleBase {
155155
/**
156156
* Generates a random date between the given boundaries.
157157
*
158-
* @param options The optional options object.
158+
* @param options The options object.
159159
* @param options.from The early date boundary.
160160
* @param options.to The late date boundary.
161161
*
162+
* @throws If `from` or `to` are not provided.
163+
* @throws If `from` is after `to`.
164+
*
162165
* @example
163166
* faker.date.between({ from: '2020-01-01T00:00:00.000Z', to: '2030-01-01T00:00:00.000Z' }) // '2026-05-16T02:22:53.002Z'
164167
*
@@ -174,22 +177,35 @@ export class SimpleDateModule extends SimpleModuleBase {
174177
*/
175178
to: string | Date | number;
176179
}): Date {
180+
// TODO @matthewmayer 2023-03-27: Consider removing in v10 as this check is only needed in JS
181+
if (options == null || options.from == null || options.to == null) {
182+
throw new FakerError(
183+
'Must pass an options object with `from` and `to` values.'
184+
);
185+
}
186+
177187
const { from, to } = options;
178188

179189
const fromMs = toDate(from, 'from').getTime();
180190
const toMs = toDate(to, 'to').getTime();
191+
if (fromMs > toMs) {
192+
throw new FakerError('`from` date must be before `to` date.');
193+
}
181194

182195
return new Date(this.faker.number.int({ min: fromMs, max: toMs }));
183196
}
184197

185198
/**
186199
* Generates random dates between the given boundaries. The dates will be returned in an array sorted in chronological order.
187200
*
188-
* @param options The optional options object.
201+
* @param options The options object.
189202
* @param options.from The early date boundary.
190203
* @param options.to The late date boundary.
191204
* @param options.count The number of dates to generate. Defaults to `3`.
192205
*
206+
* @throws If `from` or `to` are not provided.
207+
* @throws If `from` is after `to`.
208+
*
193209
* @example
194210
* faker.date.betweens({ from: '2020-01-01T00:00:00.000Z', to: '2030-01-01T00:00:00.000Z' })
195211
* // [
@@ -235,8 +251,14 @@ export class SimpleDateModule extends SimpleModuleBase {
235251
max: number;
236252
};
237253
}): Date[] {
238-
const { from, to, count = 3 } = options;
254+
// TODO @matthewmayer 2023-03-27: Consider removing in v10 as this check is only needed in JS
255+
if (options == null || options.from == null || options.to == null) {
256+
throw new FakerError(
257+
'Must pass an options object with `from` and `to` values.'
258+
);
259+
}
239260

261+
const { from, to, count = 3 } = options;
240262
return this.faker.helpers
241263
.multiple(() => this.between({ from, to }), { count })
242264
.sort((a, b) => a.getTime() - b.getTime());
@@ -433,6 +455,12 @@ export class SimpleDateModule extends SimpleModuleBase {
433455
*
434456
* For more control, any of these methods can be customized with further options, or use [`between()`](https://fakerjs.dev/api/date.html#between) to generate a single date between two dates, or [`betweens()`](https://fakerjs.dev/api/date.html#betweens) for multiple dates.
435457
*
458+
* Dates can be specified as Javascript Date objects, strings or UNIX timestamps.
459+
* For example to generate a date between 1st January 2000 and now, use:
460+
* ```ts
461+
* faker.date.between({ from: '2000-01-01', to: Date.now() });
462+
* ```
463+
*
436464
* You can generate random localized month and weekday names using [`month()`](https://fakerjs.dev/api/date.html#month) and [`weekday()`](https://fakerjs.dev/api/date.html#weekday).
437465
*
438466
* These methods have additional concerns about reproducibility, see [Reproducible Results](https://fakerjs.dev/guide/usage.html#reproducible-results).

test/modules/date.spec.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,32 @@ describe('date', () => {
256256
expect(date).lessThan(to);
257257
}
258258
);
259+
260+
it('should throw an error when from is after to', () => {
261+
expect(() =>
262+
faker.date.between({
263+
from: '2000-01-01',
264+
to: '1990-01-01',
265+
})
266+
).toThrow(new FakerError('`from` date must be before `to` date.'));
267+
});
268+
269+
it('should allow date 0 (start of UNIX epoch)', () => {
270+
const date = faker.date.between({
271+
from: 0,
272+
to: '1970-12-31',
273+
});
274+
expect(date).greaterThan(new Date(0));
275+
});
276+
277+
it('should throw an error if to is invalid', () => {
278+
expect(() =>
279+
faker.date.between({
280+
from: '1990-01-01',
281+
to: 'not-a-date',
282+
})
283+
).toThrow(new FakerError('Invalid to date: not-a-date'));
284+
});
259285
});
260286

261287
describe('betweens()', () => {
@@ -325,6 +351,26 @@ describe('date', () => {
325351
expect(dates.at(-1)).lessThan(to);
326352
}
327353
);
354+
355+
it('should throw an error when from is after to', () => {
356+
expect(() =>
357+
faker.date.betweens({
358+
from: '2000-01-01',
359+
to: '1990-01-01',
360+
count: 3,
361+
})
362+
).toThrow(new FakerError('`from` date must be before `to` date.'));
363+
});
364+
365+
it('should throw an error if to is invalid', () => {
366+
expect(() =>
367+
faker.date.betweens({
368+
from: '1990-01-01',
369+
to: 'not-a-date',
370+
count: 3,
371+
})
372+
).toThrow(new FakerError('Invalid to date: not-a-date'));
373+
});
328374
});
329375

330376
describe('recent()', () => {

0 commit comments

Comments
 (0)