From 8bde60825b820848fce97b76ad946bdff3d81b79 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Thu, 9 Nov 2023 23:05:38 +0100 Subject: [PATCH 01/15] test(date): additional birthday tests --- src/modules/date/index.ts | 26 +++++------ test/modules/date.spec.ts | 97 ++++++++++++++++++++++++++------------- 2 files changed, 77 insertions(+), 46 deletions(-) diff --git a/src/modules/date/index.ts b/src/modules/date/index.ts index 2729c8496a3..318d5d58055 100644 --- a/src/modules/date/index.ts +++ b/src/modules/date/index.ts @@ -415,7 +415,7 @@ export class SimpleDateModule extends SimpleModuleBase { refDate?: string | Date | number; } = {} ): Date { - const mode = options.mode === 'age' ? 'age' : 'year'; + const { min, max, mode = 'year' } = options; const refDate = toDate(options.refDate, this.faker.defaultRefDate); const refYear = refDate.getUTCFullYear(); @@ -423,29 +423,25 @@ export class SimpleDateModule extends SimpleModuleBase { // So that people can still be considered as adults in most cases // Convert to epoch timestamps - let min: number; - let max: number; + let from: number; + let to: number; if (mode === 'age') { - min = new Date(refDate).setUTCFullYear(refYear - (options.max ?? 80) - 1); - max = new Date(refDate).setUTCFullYear(refYear - (options.min ?? 18)); + from = new Date(refDate).setUTCFullYear(refYear - (max ?? 80) - 1); + to = new Date(refDate).setUTCFullYear(refYear - (min ?? 18)); } else { - // Avoid generating dates the first and last date of the year + // Avoid generating dates on the first and last date of the year // to avoid running into other years depending on the timezone. - min = new Date(Date.UTC(0, 0, 2)).setUTCFullYear( - options.min ?? refYear - 80 - ); - max = new Date(Date.UTC(0, 11, 30)).setUTCFullYear( - options.max ?? refYear - 19 - ); + from = new Date(Date.UTC(0, 0, 2)).setUTCFullYear(min ?? refYear - 80); + to = new Date(Date.UTC(0, 11, 30)).setUTCFullYear(max ?? refYear - 19); } - if (max < min) { + if (from > to) { throw new FakerError( - `Max ${options.max} should be larger than or equal to min ${options.min}.` + `Max ${mode} ${max} (${to}) should be greater than or equal to min ${mode} ${min} (${from}).` ); } - return new Date(this.faker.number.int({ min, max })); + return this.between({ from, to }); } } diff --git a/test/modules/date.spec.ts b/test/modules/date.spec.ts index 303dc407524..bab750b6778 100644 --- a/test/modules/date.spec.ts +++ b/test/modules/date.spec.ts @@ -477,65 +477,86 @@ describe('date', () => { expect(birthdate).toBeInstanceOf(Date); }); - it('returns a random birthdate between two years', () => { + it.each(['year', 'age', undefined] as const)( + 'returns a random birthdate that is 18+ by default (%s mode)', + (mode) => { + // Generate the latest possible value => youngest + faker.seed(2855577693); + + const refDate = new Date(); + const birthdate = faker.date.birthdate({ refDate, mode }); + expect(birthdate).toBeInstanceOf(Date); + const value = birthdate.valueOf(); + const refDateValue = refDate.valueOf(); + expect(value).toBeLessThanOrEqual(refDateValue); + const deltaDate = new Date(refDateValue - value); + expect(deltaDate.getUTCFullYear() - 1970).toBe(18); + } + ); + + it('returns a random birthdate in one year', () => { const min = 1990; - const max = 2000; + const max = 1990; const birthdate = faker.date.birthdate({ min, max, mode: 'year' }); // birthdate is a date object expect(birthdate).toBeInstanceOf(Date); + expect(birthdate.toISOString()).not.toMatch(/T00:00:00.000Z/); // Generated date is between min and max expect(birthdate.getUTCFullYear()).toBeGreaterThanOrEqual(min); expect(birthdate.getUTCFullYear()).toBeLessThanOrEqual(max); }); - it('returns a random birthdate that is 18+ by default', () => { - // Generate the latest possible value => youngest - faker.seed(2855577693); - - const refDate = new Date(); - const birthdate = faker.date.birthdate({ refDate }); - expect(birthdate).toBeInstanceOf(Date); - const value = birthdate.valueOf(); - const refDateValue = refDate.valueOf(); - expect(value).toBeLessThanOrEqual(refDateValue); - const deltaDate = new Date(refDateValue - value); - expect(deltaDate.getUTCFullYear() - 1970).toBeGreaterThanOrEqual(18); - }); - - it('returns a random birthdate in one year', () => { + it('returns a random birthdate between two years', () => { const min = 1990; - const max = 1990; + const max = 2000; const birthdate = faker.date.birthdate({ min, max, mode: 'year' }); // birthdate is a date object expect(birthdate).toBeInstanceOf(Date); - expect(birthdate.toISOString()).not.toMatch(/T00:00:00.000Z/); // Generated date is between min and max expect(birthdate.getUTCFullYear()).toBeGreaterThanOrEqual(min); expect(birthdate.getUTCFullYear()).toBeLessThanOrEqual(max); }); + it('returns a random birthdate for specific age', () => { + const min = 21; + const max = 21; + const refDate = new Date(); + + const birthdate = faker.date.birthdate({ + min, + max, + refDate, + mode: 'age', + }); + + expect(birthdate).toBeInstanceOf(Date); + const value = birthdate.valueOf(); + const refDateValue = refDate.valueOf(); + expect(value).toBeLessThanOrEqual(refDateValue); + const deltaDate = new Date(refDateValue - value); + expect(deltaDate.getUTCFullYear() - 1970).toBe(21); + }); + it('returns a random birthdate between two ages', () => { - const min = 4; - const max = 5; + const min = 21; + const max = 22; + const refDate = new Date(); const birthdate = faker.date.birthdate({ min, max, mode: 'age' }); - // birthdate is a date object expect(birthdate).toBeInstanceOf(Date); - - // Generated date is between min and max - expect(birthdate.getUTCFullYear()).toBeGreaterThanOrEqual( - new Date().getUTCFullYear() - max - 1 - ); - expect(birthdate.getUTCFullYear()).toBeLessThanOrEqual( - new Date().getUTCFullYear() - min - ); + const value = birthdate.valueOf(); + const refDateValue = refDate.valueOf(); + expect(value).toBeLessThanOrEqual(refDateValue); + const deltaDate = new Date(refDateValue - value); + expect(deltaDate.getUTCFullYear() - 1970).toBeGreaterThanOrEqual(21); + expect(deltaDate.getUTCFullYear() - 1970).toBeLessThanOrEqual(22); }); it('should throw an error when the min > max year', () => { @@ -546,7 +567,21 @@ describe('date', () => { faker.date.birthdate({ min, max, mode: 'year' }) ).toThrow( new FakerError( - `Max 1990 should be larger than or equal to min 2000.` + `Max year 1990 (662515200000) should be greater than or equal to min year 2000 (946771200000).` + ) + ); + }); + + it('should throw an error when the min > max age', () => { + const min = 31; + const max = 25; + const refDate = Date.UTC(2020, 0, 1); + + expect(() => + faker.date.birthdate({ min, max, refDate, mode: 'age' }) + ).toThrow( + new FakerError( + `Max age 25 (599616000000) should be greater than or equal to min age 31 (757382400000).` ) ); }); From 7d7a65456fccc69f2eabc5bf05a7ff31f0f3c510 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Sat, 16 Mar 2024 18:02:21 +0100 Subject: [PATCH 02/15] chore: apply suggestions --- src/modules/date/index.ts | 38 ++++++++++++++++++-------- test/modules/date.spec.ts | 57 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 81 insertions(+), 14 deletions(-) diff --git a/src/modules/date/index.ts b/src/modules/date/index.ts index 318d5d58055..ceb92521291 100644 --- a/src/modules/date/index.ts +++ b/src/modules/date/index.ts @@ -425,20 +425,36 @@ export class SimpleDateModule extends SimpleModuleBase { // Convert to epoch timestamps let from: number; let to: number; - if (mode === 'age') { - from = new Date(refDate).setUTCFullYear(refYear - (max ?? 80) - 1); - to = new Date(refDate).setUTCFullYear(refYear - (min ?? 18)); - } else { - // Avoid generating dates on the first and last date of the year - // to avoid running into other years depending on the timezone. - from = new Date(Date.UTC(0, 0, 2)).setUTCFullYear(min ?? refYear - 80); - to = new Date(Date.UTC(0, 11, 30)).setUTCFullYear(max ?? refYear - 19); + switch (mode) { + case 'age': { + from = new Date(refDate).setUTCFullYear(refYear - (max ?? 80) - 1); + to = new Date(refDate).setUTCFullYear(refYear - (min ?? 18)); + break; + } + + case 'year': { + // Avoid generating dates on the first and last date of the year + // to avoid running into other years depending on the timezone. + from = new Date(Date.UTC(0, 0, 2)).setUTCFullYear(min ?? refYear - 80); + to = new Date(Date.UTC(0, 11, 30)).setUTCFullYear(max ?? refYear - 19); + break; + } } if (from > to) { - throw new FakerError( - `Max ${mode} ${max} (${to}) should be greater than or equal to min ${mode} ${min} (${from}).` - ); + switch (mode) { + case 'age': { + throw new FakerError( + `Max age ${max ?? 80} should be greater than or equal to min age ${min ?? 18}.` + ); + } + + case 'year': { + throw new FakerError( + `Max year ${max ?? refYear - 19} should be greater than or equal to min year ${min ?? refYear - 80}.` + ); + } + } } return this.between({ from, to }); diff --git a/test/modules/date.spec.ts b/test/modules/date.spec.ts index bab750b6778..1717f526bd3 100644 --- a/test/modules/date.spec.ts +++ b/test/modules/date.spec.ts @@ -502,7 +502,6 @@ describe('date', () => { // birthdate is a date object expect(birthdate).toBeInstanceOf(Date); - expect(birthdate.toISOString()).not.toMatch(/T00:00:00.000Z/); // Generated date is between min and max expect(birthdate.getUTCFullYear()).toBeGreaterThanOrEqual(min); @@ -567,7 +566,33 @@ describe('date', () => { faker.date.birthdate({ min, max, mode: 'year' }) ).toThrow( new FakerError( - `Max year 1990 (662515200000) should be greater than or equal to min year 2000 (946771200000).` + `Max year 1990 should be greater than or equal to min year 2000.` + ) + ); + }); + + it('should throw an error when the min > undefined max year', () => { + const min = 2010; + const refDate = Date.UTC(2020, 0, 1); + + expect(() => + faker.date.birthdate({ min, refDate, mode: 'year' }) + ).toThrow( + new FakerError( + `Max year 2001 should be greater than or equal to min year 2010.` + ) + ); + }); + + it('should throw an error when the undefined min > max year', () => { + const max = 1900; + const refDate = Date.UTC(2020, 0, 1); + + expect(() => + faker.date.birthdate({ max, refDate, mode: 'year' }) + ).toThrow( + new FakerError( + `Max year 1900 should be greater than or equal to min year 1940.` ) ); }); @@ -581,7 +606,33 @@ describe('date', () => { faker.date.birthdate({ min, max, refDate, mode: 'age' }) ).toThrow( new FakerError( - `Max age 25 (599616000000) should be greater than or equal to min age 31 (757382400000).` + `Max age 25 should be greater than or equal to min age 31.` + ) + ); + }); + + it('should throw an error when the min > undefined max age', () => { + const min = 100; + const refDate = Date.UTC(2020, 0, 1); + + expect(() => + faker.date.birthdate({ min, refDate, mode: 'age' }) + ).toThrow( + new FakerError( + `Max age 80 should be greater than or equal to min age 100.` + ) + ); + }); + + it('should throw an error when the undefined min > max age', () => { + const max = 10; + const refDate = Date.UTC(2020, 0, 1); + + expect(() => + faker.date.birthdate({ max, refDate, mode: 'age' }) + ).toThrow( + new FakerError( + `Max age 10 should be greater than or equal to min age 18.` ) ); }); From 92a79586a1a4f4fbd12aab630847b633b295e451 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Sat, 16 Mar 2024 18:13:38 +0100 Subject: [PATCH 03/15] refactor(date)!: change birthdate default mode to age --- docs/guide/upgrading_v9/2756.md | 6 ++++++ src/modules/date/index.ts | 10 +++++----- test/modules/__snapshots__/date.spec.ts.snap | 6 +++--- 3 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 docs/guide/upgrading_v9/2756.md diff --git a/docs/guide/upgrading_v9/2756.md b/docs/guide/upgrading_v9/2756.md new file mode 100644 index 00000000000..e63eb098330 --- /dev/null +++ b/docs/guide/upgrading_v9/2756.md @@ -0,0 +1,6 @@ +### Changed default mode from birthdate + +Previously, the method defaulted to `year` mode, however the other defaults refer to ages. +For that reason, we switched to `age` mode by default. + +We also improved the error messages in case of invalid min/max age/year ranges. diff --git a/src/modules/date/index.ts b/src/modules/date/index.ts index ceb92521291..4b80707f4e3 100644 --- a/src/modules/date/index.ts +++ b/src/modules/date/index.ts @@ -374,7 +374,7 @@ export class SimpleDateModule extends SimpleModuleBase { * - `'age'`: The min and max options define the age of the person (e.g. `18` - `42`). * - `'year'`: The min and max options define the range the birthdate may be in (e.g. `1900` - `2000`). * - * Defaults to `year`. + * Defaults to `age`. * * @example * faker.date.birthdate() // 1977-07-10T01:37:30.719Z @@ -388,13 +388,13 @@ export class SimpleDateModule extends SimpleModuleBase { /** * The minimum age or year to generate a birthdate. * - * @default 18 + * @default 18 (age) */ min?: number; /** * The maximum age or year to generate a birthdate. * - * @default 80 + * @default 80 (age) */ max?: number; /** @@ -404,7 +404,7 @@ export class SimpleDateModule extends SimpleModuleBase { * - `'age'`: The min and max options define the age of the person (e.g. `18` - `42`). * - `'year'`: The min and max options define the range the birthdate may be in (e.g. `1900` - `2000`). * - * @default 'year' + * @default 'age' */ mode?: 'age' | 'year'; /** @@ -415,7 +415,7 @@ export class SimpleDateModule extends SimpleModuleBase { refDate?: string | Date | number; } = {} ): Date { - const { min, max, mode = 'year' } = options; + const { min, max, mode = 'age' } = options; const refDate = toDate(options.refDate, this.faker.defaultRefDate); const refYear = refDate.getUTCFullYear(); diff --git a/test/modules/__snapshots__/date.spec.ts.snap b/test/modules/__snapshots__/date.spec.ts.snap index 9b3c3d7659b..0ecce4960ca 100644 --- a/test/modules/__snapshots__/date.spec.ts.snap +++ b/test/modules/__snapshots__/date.spec.ts.snap @@ -71,7 +71,7 @@ exports[`date > 42 > birthdate > with age mode and refDate 1`] = `1963-09-27T06: exports[`date > 42 > birthdate > with age range and refDate 1`] = `1962-12-27T20:14:08.437Z`; -exports[`date > 42 > birthdate > with only refDate 1`] = `1964-03-22T08:05:48.849Z`; +exports[`date > 42 > birthdate > with only refDate 1`] = `1963-09-27T06:10:42.813Z`; exports[`date > 42 > birthdate > with year and refDate 1`] = `0020-07-07T19:06:53.165Z`; @@ -199,7 +199,7 @@ exports[`date > 1211 > birthdate > with age mode and refDate 1`] = `1998-08-21T2 exports[`date > 1211 > birthdate > with age range and refDate 1`] = `1996-10-13T01:44:07.954Z`; -exports[`date > 1211 > birthdate > with only refDate 1`] = `1998-07-25T13:16:47.251Z`; +exports[`date > 1211 > birthdate > with only refDate 1`] = `1998-08-21T21:24:31.101Z`; exports[`date > 1211 > birthdate > with year and refDate 1`] = `0021-01-26T13:16:31.426Z`; @@ -325,7 +325,7 @@ exports[`date > 1337 > birthdate > with age mode and refDate 1`] = `1956-08-25T0 exports[`date > 1337 > birthdate > with age range and refDate 1`] = `1956-02-15T21:16:37.850Z`; -exports[`date > 1337 > birthdate > with only refDate 1`] = `1957-03-31T18:18:16.563Z`; +exports[`date > 1337 > birthdate > with only refDate 1`] = `1956-08-25T03:56:58.153Z`; exports[`date > 1337 > birthdate > with year and refDate 1`] = `0020-05-27T14:46:44.794Z`; From d573935d2de7b7e471ed673b9bf39e4e1e012912 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Sun, 17 Mar 2024 02:01:33 +0100 Subject: [PATCH 04/15] chore: add error attempting to prevent migration errors --- src/modules/date/index.ts | 9 ++++++++- test/modules/date.spec.ts | 30 ++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/modules/date/index.ts b/src/modules/date/index.ts index 4b80707f4e3..9973b61429e 100644 --- a/src/modules/date/index.ts +++ b/src/modules/date/index.ts @@ -415,10 +415,17 @@ export class SimpleDateModule extends SimpleModuleBase { refDate?: string | Date | number; } = {} ): Date { - const { min, max, mode = 'age' } = options; + const { min, max, mode = 'age', mode: originalMode } = options; const refDate = toDate(options.refDate, this.faker.defaultRefDate); const refYear = refDate.getUTCFullYear(); + // TODO @ST-DDT 2024-03-17: Remove this check in v10 + if (originalMode == null && min != null && min >= 1000) { + throw new FakerError( + `The min option is greater than 1000, which likely refers to a 'year'. The new default mode is 'age'. To prevent this error, set the mode option explicitly.` + ); + } + // If no min or max is specified, generate a random date between (now - 80) years and (now - 18) years respectively // So that people can still be considered as adults in most cases diff --git a/test/modules/date.spec.ts b/test/modules/date.spec.ts index 1717f526bd3..4783255e7e4 100644 --- a/test/modules/date.spec.ts +++ b/test/modules/date.spec.ts @@ -636,6 +636,36 @@ describe('date', () => { ) ); }); + + // TODO @ST-DDT 2024-03-17: Remove these in v10 + it('should throw an error when the min is very high with default mode', () => { + const min = 2000; + const max = 5000; + + expect(() => faker.date.birthdate({ min, max })).toThrow( + new FakerError( + `The min option is greater than 1000, which likely refers to a 'year'. The new default mode is 'age'. To prevent this error, set the mode option explicitly.` + ) + ); + }); + + it('should not throw an error when the min is very high with age mode', () => { + const min = 2000; + const max = 5000; + + const actual = faker.date.birthdate({ min, max, mode: 'age' }); + + expect(actual).toBeInstanceOf(Date); + }); + + it('should not throw an error when the min is very high with year mode', () => { + const min = 2000; + const max = 5000; + + const actual = faker.date.birthdate({ min, max, mode: 'year' }); + + expect(actual).toBeInstanceOf(Date); + }); }); } ); From fb4fbf14f8e389a991159f90b30aa03cf4515c95 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Sun, 17 Mar 2024 14:30:48 +0100 Subject: [PATCH 05/15] refactor: signature improvements --- src/modules/date/index.ts | 123 +++++++++++++++++++++----------------- test/modules/date.spec.ts | 8 ++- 2 files changed, 75 insertions(+), 56 deletions(-) diff --git a/src/modules/date/index.ts b/src/modules/date/index.ts index 9973b61429e..567cb47c460 100644 --- a/src/modules/date/index.ts +++ b/src/modules/date/index.ts @@ -383,35 +383,52 @@ export class SimpleDateModule extends SimpleModuleBase { * * @since 7.0.0 */ + birthdate( + options?: + | { + /** + * The date to use as reference point for the newly generated date. + * + * @default faker.defaultRefDate() + */ + refDate?: string | Date | number; + } + | { + /** + * The minimum age or year to generate a birthdate. + * + * @default 18 (age) / refDate - 80 years (year) + */ + min: number; + /** + * The maximum age or year to generate a birthdate. + * + * @default 80 (age) / refDate - 19 years (year) + */ + max: number; + /** + * The mode to generate the birthdate. Supported modes are `'age'` and `'year'` . + * + * There are two modes available `'age'` and `'year'`: + * - `'age'`: The min and max options define the age of the person (e.g. `18` - `42`). + * - `'year'`: The min and max options define the range the birthdate may be in (e.g. `1900` - `2000`). + * + * @default 'age' + */ + mode: 'age' | 'year'; + /** + * The date to use as reference point for the newly generated date. + * + * @default faker.defaultRefDate() + */ + refDate?: string | Date | number; + } + ): Date; birthdate( options: { - /** - * The minimum age or year to generate a birthdate. - * - * @default 18 (age) - */ min?: number; - /** - * The maximum age or year to generate a birthdate. - * - * @default 80 (age) - */ max?: number; - /** - * The mode to generate the birthdate. Supported modes are `'age'` and `'year'` . - * - * There are two modes available `'age'` and `'year'`: - * - `'age'`: The min and max options define the age of the person (e.g. `18` - `42`). - * - `'year'`: The min and max options define the range the birthdate may be in (e.g. `1900` - `2000`). - * - * @default 'age' - */ mode?: 'age' | 'year'; - /** - * The date to use as reference point for the newly generated date. - * - * @default faker.defaultRefDate() - */ refDate?: string | Date | number; } = {} ): Date { @@ -419,52 +436,48 @@ export class SimpleDateModule extends SimpleModuleBase { const refDate = toDate(options.refDate, this.faker.defaultRefDate); const refYear = refDate.getUTCFullYear(); - // TODO @ST-DDT 2024-03-17: Remove this check in v10 - if (originalMode == null && min != null && min >= 1000) { - throw new FakerError( - `The min option is greater than 1000, which likely refers to a 'year'. The new default mode is 'age'. To prevent this error, set the mode option explicitly.` - ); - } - - // If no min or max is specified, generate a random date between (now - 80) years and (now - 18) years respectively - // So that people can still be considered as adults in most cases - - // Convert to epoch timestamps - let from: number; - let to: number; switch (mode) { case 'age': { - from = new Date(refDate).setUTCFullYear(refYear - (max ?? 80) - 1); - to = new Date(refDate).setUTCFullYear(refYear - (min ?? 18)); - break; - } + // TODO @ST-DDT 2024-03-17: Remove this check in v10 + if (originalMode == null && min != null && min >= 1000) { + throw new FakerError( + `The min option is greater than 1000, which likely refers to a 'year'. The new default mode is 'age'. To prevent this error, set the mode option explicitly.` + ); + } - case 'year': { - // Avoid generating dates on the first and last date of the year - // to avoid running into other years depending on the timezone. - from = new Date(Date.UTC(0, 0, 2)).setUTCFullYear(min ?? refYear - 80); - to = new Date(Date.UTC(0, 11, 30)).setUTCFullYear(max ?? refYear - 19); - break; - } - } + const from = new Date(refDate).setUTCFullYear( + refYear - (max ?? 80) - 1 + ); + const to = new Date(refDate).setUTCFullYear(refYear - (min ?? 18)); - if (from > to) { - switch (mode) { - case 'age': { + if (from > to) { throw new FakerError( `Max age ${max ?? 80} should be greater than or equal to min age ${min ?? 18}.` ); } - case 'year': { + return this.between({ from, to }); + } + + case 'year': { + // Avoid generating dates on the first and last date of the year + // to avoid running into other years depending on the timezone. + const from = new Date(Date.UTC(0, 0, 2)).setUTCFullYear( + min ?? refYear - 80 + ); + const to = new Date(Date.UTC(0, 11, 30)).setUTCFullYear( + max ?? refYear - 19 + ); + + if (from > to) { throw new FakerError( `Max year ${max ?? refYear - 19} should be greater than or equal to min year ${min ?? refYear - 80}.` ); } + + return this.between({ from, to }); } } - - return this.between({ from, to }); } } diff --git a/test/modules/date.spec.ts b/test/modules/date.spec.ts index 4783255e7e4..da7a4b2a358 100644 --- a/test/modules/date.spec.ts +++ b/test/modules/date.spec.ts @@ -642,7 +642,13 @@ describe('date', () => { const min = 2000; const max = 5000; - expect(() => faker.date.birthdate({ min, max })).toThrow( + expect(() => + faker.date.birthdate({ + min, + max, + mode: undefined as unknown as 'age', + }) + ).toThrow( new FakerError( `The min option is greater than 1000, which likely refers to a 'year'. The new default mode is 'age'. To prevent this error, set the mode option explicitly.` ) From d1956adca44570654dbe2fbf5aae6bd1847b8c71 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Sun, 17 Mar 2024 14:33:31 +0100 Subject: [PATCH 06/15] docs: remove defaults --- src/modules/date/index.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/modules/date/index.ts b/src/modules/date/index.ts index 567cb47c460..e6d561d00e0 100644 --- a/src/modules/date/index.ts +++ b/src/modules/date/index.ts @@ -396,14 +396,10 @@ export class SimpleDateModule extends SimpleModuleBase { | { /** * The minimum age or year to generate a birthdate. - * - * @default 18 (age) / refDate - 80 years (year) */ min: number; /** * The maximum age or year to generate a birthdate. - * - * @default 80 (age) / refDate - 19 years (year) */ max: number; /** From e4747e32cd9541d72915024cf815d03436a7ac2a Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Sun, 17 Mar 2024 14:44:38 +0100 Subject: [PATCH 07/15] adjust backwards compatibility and migration guide --- docs/guide/upgrading_v9/2756.md | 4 ++-- src/modules/date/index.ts | 20 +++++++++--------- test/modules/date.spec.ts | 36 --------------------------------- 3 files changed, 13 insertions(+), 47 deletions(-) diff --git a/docs/guide/upgrading_v9/2756.md b/docs/guide/upgrading_v9/2756.md index e63eb098330..da0be8ebba5 100644 --- a/docs/guide/upgrading_v9/2756.md +++ b/docs/guide/upgrading_v9/2756.md @@ -1,6 +1,6 @@ ### Changed default mode from birthdate -Previously, the method defaulted to `year` mode, however the other defaults refer to ages. -For that reason, we switched to `age` mode by default. +Previously, the method had defaults that were unclear in their specific impact. +Now, the method requires either none or all of the `min`, `max` and `mode` options. We also improved the error messages in case of invalid min/max age/year ranges. diff --git a/src/modules/date/index.ts b/src/modules/date/index.ts index e6d561d00e0..8abf85c3bd5 100644 --- a/src/modules/date/index.ts +++ b/src/modules/date/index.ts @@ -1,6 +1,7 @@ import type { Faker } from '../..'; import type { DateEntryDefinition } from '../../definitions'; import { FakerError } from '../../errors/faker-error'; +import { deprecated } from '../../internal/deprecated'; import { SimpleModuleBase } from '../../internal/module-base'; import { assertLocaleData } from '../../locale-proxy'; @@ -408,8 +409,6 @@ export class SimpleDateModule extends SimpleModuleBase { * There are two modes available `'age'` and `'year'`: * - `'age'`: The min and max options define the age of the person (e.g. `18` - `42`). * - `'year'`: The min and max options define the range the birthdate may be in (e.g. `1900` - `2000`). - * - * @default 'age' */ mode: 'age' | 'year'; /** @@ -431,16 +430,19 @@ export class SimpleDateModule extends SimpleModuleBase { const { min, max, mode = 'age', mode: originalMode } = options; const refDate = toDate(options.refDate, this.faker.defaultRefDate); const refYear = refDate.getUTCFullYear(); + const optionsSet = [min, max, originalMode].filter((x) => x != null).length; + if (optionsSet % 3 !== 0) { + deprecated({ + deprecated: + "faker.date.birthdate({ min: 18, max: 80 }) or faker.date.birthdate({ mode: 'age' })", + proposed: "faker.date.birthdate({ min: 18, max: 80, mode: 'age' })", + since: '9.0', + until: '10.0', + }); + } switch (mode) { case 'age': { - // TODO @ST-DDT 2024-03-17: Remove this check in v10 - if (originalMode == null && min != null && min >= 1000) { - throw new FakerError( - `The min option is greater than 1000, which likely refers to a 'year'. The new default mode is 'age'. To prevent this error, set the mode option explicitly.` - ); - } - const from = new Date(refDate).setUTCFullYear( refYear - (max ?? 80) - 1 ); diff --git a/test/modules/date.spec.ts b/test/modules/date.spec.ts index da7a4b2a358..1717f526bd3 100644 --- a/test/modules/date.spec.ts +++ b/test/modules/date.spec.ts @@ -636,42 +636,6 @@ describe('date', () => { ) ); }); - - // TODO @ST-DDT 2024-03-17: Remove these in v10 - it('should throw an error when the min is very high with default mode', () => { - const min = 2000; - const max = 5000; - - expect(() => - faker.date.birthdate({ - min, - max, - mode: undefined as unknown as 'age', - }) - ).toThrow( - new FakerError( - `The min option is greater than 1000, which likely refers to a 'year'. The new default mode is 'age'. To prevent this error, set the mode option explicitly.` - ) - ); - }); - - it('should not throw an error when the min is very high with age mode', () => { - const min = 2000; - const max = 5000; - - const actual = faker.date.birthdate({ min, max, mode: 'age' }); - - expect(actual).toBeInstanceOf(Date); - }); - - it('should not throw an error when the min is very high with year mode', () => { - const min = 2000; - const max = 5000; - - const actual = faker.date.birthdate({ min, max, mode: 'year' }); - - expect(actual).toBeInstanceOf(Date); - }); }); } ); From bcef41747b14b3d59230447d3051e553ba8c14e4 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Sun, 17 Mar 2024 14:46:46 +0100 Subject: [PATCH 08/15] remove default comment --- src/modules/date/index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/modules/date/index.ts b/src/modules/date/index.ts index 8abf85c3bd5..816aa4b4317 100644 --- a/src/modules/date/index.ts +++ b/src/modules/date/index.ts @@ -375,8 +375,6 @@ export class SimpleDateModule extends SimpleModuleBase { * - `'age'`: The min and max options define the age of the person (e.g. `18` - `42`). * - `'year'`: The min and max options define the range the birthdate may be in (e.g. `1900` - `2000`). * - * Defaults to `age`. - * * @example * faker.date.birthdate() // 1977-07-10T01:37:30.719Z * faker.date.birthdate({ min: 18, max: 65, mode: 'age' }) // 2003-11-02T20:03:20.116Z From 6870d155fdbf106e9a33e28af9bec4575d2bea6d Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Sun, 17 Mar 2024 14:48:24 +0100 Subject: [PATCH 09/15] chore add remove in v10 comment --- src/modules/date/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/date/index.ts b/src/modules/date/index.ts index 816aa4b4317..6baac284dcb 100644 --- a/src/modules/date/index.ts +++ b/src/modules/date/index.ts @@ -428,6 +428,7 @@ export class SimpleDateModule extends SimpleModuleBase { const { min, max, mode = 'age', mode: originalMode } = options; const refDate = toDate(options.refDate, this.faker.defaultRefDate); const refYear = refDate.getUTCFullYear(); + // TODO @ST-DDT 2024-03-17: Remove check in v10 const optionsSet = [min, max, originalMode].filter((x) => x != null).length; if (optionsSet % 3 !== 0) { deprecated({ From 79277eced9e39b43af35d151924355e0b1972bb6 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Sun, 24 Mar 2024 16:12:15 +0100 Subject: [PATCH 10/15] refactor: throw errors and add distinct signatures --- src/modules/date/index.ts | 134 +++++++++++++++---- test/modules/__snapshots__/date.spec.ts.snap | 12 -- test/modules/date.spec.ts | 93 +++---------- 3 files changed, 121 insertions(+), 118 deletions(-) diff --git a/src/modules/date/index.ts b/src/modules/date/index.ts index 3970ba31f5a..47a1984676d 100644 --- a/src/modules/date/index.ts +++ b/src/modules/date/index.ts @@ -1,7 +1,6 @@ import type { Faker } from '../..'; import type { DateEntryDefinition } from '../../definitions'; import { FakerError } from '../../errors/faker-error'; -import { deprecated } from '../../internal/deprecated'; import { SimpleModuleBase } from '../../internal/module-base'; import { assertLocaleData } from '../../locale-proxy'; @@ -336,22 +335,107 @@ export class SimpleDateModule extends SimpleModuleBase { } /** - * Returns a random birthdate. + * Returns a random birthdate. By default, the birthdate is generated for an adult between 18 and 80 years old. + * But you can customize the `'age'` range or the `'year'` range to generate a birthdate. * - * @param options The options to use to generate the birthdate. If no options are set, an age between 18 and 80 (inclusive) is generated. - * @param options.min The minimum age or year to generate a birthdate. - * @param options.max The maximum age or year to generate a birthdate. - * @param options.refDate The date to use as reference point for the newly generated date. Defaults to `now`. - * @param options.mode The mode to generate the birthdate. Supported modes are `'age'` and `'year'` . + * @param options The options to use to generate the birthdate. + * @param options.refDate The date to use as reference point for the newly generated date. Defaults to `faker.defaultRefDate()`. + * + * @example + * faker.date.birthdate() // 1977-07-10T01:37:30.719Z + * + * @since 7.0.0 + */ + birthdate(options?: { + /** + * The date to use as reference point for the newly generated date. + * + * @default faker.defaultRefDate() + */ + refDate?: string | Date | number; + }): Date; + /** + * Returns a random birthdate for a given age range. * - * There are two modes available `'age'` and `'year'`: - * - `'age'`: The min and max options define the age of the person (e.g. `18` - `42`). - * - `'year'`: The min and max options define the range the birthdate may be in (e.g. `1900` - `2000`). + * @param options The options to use to generate the birthdate. + * @param options.mode `'age'` to generate a birthdate based on the age range. It is also possible to generate a birthdate based on a `'year'` range. + * @param options.min The minimum age to generate a birthdate for. + * @param options.max The maximum age to generate a birthdate for. + * @param options.refDate The date to use as reference point for the newly generated date. Defaults to `faker.defaultRefDate()`. + * + * @example + * faker.date.birthdate({ mode: 'age', min: 18, max: 65 }) // 2003-11-02T20:03:20.116Z + * + * @since 7.0.0 + */ + birthdate(options: { + /** + * `'age'` to generate a birthdate based on the age range. + * It is also possible to generate a birthdate based on a `'year'` range. + */ + mode: 'age'; + /** + * The minimum age to generate a birthdate for. + */ + min: number; + /** + * The maximum age to generate a birthdate for. + */ + max: number; + /** + * The date to use as reference point for the newly generated date. + * + * @default faker.defaultRefDate() + */ + refDate?: string | Date | number; + }): Date; + /** + * Returns a random birthdate in the given range of years. + * + * @param options The options to use to generate the birthdate. + * @param options.mode `'year'` to generate a birthdate based on the year range. It is also possible to generate a birthdate based on a `'age'` range. + * @param options.min The minimum year to generate a birthdate in. + * @param options.max The maximum year to generate a birthdate in. + * @param options.refDate The date to use as reference point for the newly generated date. Defaults to `faker.defaultRefDate()`. + * + * @example + * faker.date.birthdate({ mode: 'year', min: 1900, max: 2000 }) // 1940-08-20T08:53:07.538Z + * + * @since 7.0.0 + */ + birthdate(options: { + /** + * `'year'` to generate a birthdate based on the year range. It is also possible to generate a birthdate based on an `'age'` range. + */ + mode: 'year'; + /** + * The minimum year to generate a birthdate in. + */ + min: number; + /** + * The maximum year to generate a birthdate in. + */ + max: number; + /** + * The date to use as reference point for the newly generated date. + * + * @default faker.defaultRefDate() + */ + refDate?: string | Date | number; + }): Date; + /** + * Returns a random birthdate in the given range of years. + * + * @param options The options to use to generate the birthdate. + * @param options.mode Either `'age'` or `'year'` to generate a birthdate based on the age or year range. + * @param options.min The minimum age or year to generate a birthdate in. + * @param options.max The maximum age or year to generate a birthdate in. + * @param options.refDate The date to use as reference point for the newly generated date. Defaults to `faker.defaultRefDate()`. * * @example * faker.date.birthdate() // 1977-07-10T01:37:30.719Z - * faker.date.birthdate({ min: 18, max: 65, mode: 'age' }) // 2003-11-02T20:03:20.116Z - * faker.date.birthdate({ min: 1900, max: 2000, mode: 'year' }) // 1940-08-20T08:53:07.538Z + * faker.date.birthdate({ mode: 'age', min: 18, max: 65 }) // 2003-11-02T20:03:20.116Z + * faker.date.birthdate({ mode: 'year', min: 1900, max: 2000 }) // 1940-08-20T08:53:07.538Z * * @since 7.0.0 */ @@ -367,21 +451,17 @@ export class SimpleDateModule extends SimpleModuleBase { } | { /** - * The minimum age or year to generate a birthdate. + * Either `'age'` or `'year'` to generate a birthdate based on the age or year range. */ - min: number; + mode: 'age' | 'year'; /** - * The maximum age or year to generate a birthdate. + * The minimum year to generate a birthdate in. */ - max: number; + min: number; /** - * The mode to generate the birthdate. Supported modes are `'age'` and `'year'` . - * - * There are two modes available `'age'` and `'year'`: - * - `'age'`: The min and max options define the age of the person (e.g. `18` - `42`). - * - `'year'`: The min and max options define the range the birthdate may be in (e.g. `1900` - `2000`). + * The maximum year to generate a birthdate in. */ - mode: 'age' | 'year'; + max: number; /** * The date to use as reference point for the newly generated date. * @@ -411,13 +491,9 @@ export class SimpleDateModule extends SimpleModuleBase { (x) => x != null ).length; if (optionsSet % 3 !== 0) { - deprecated({ - deprecated: - "faker.date.birthdate({ min: 18, max: 80 }) or faker.date.birthdate({ mode: 'age' })", - proposed: "faker.date.birthdate({ min: 18, max: 80, mode: 'age' })", - since: '9.0', - until: '10.0', - }); + throw new FakerError( + "The 'min', 'max', and 'mode' options must be set together." + ); } const date = toDate(refDate); diff --git a/test/modules/__snapshots__/date.spec.ts.snap b/test/modules/__snapshots__/date.spec.ts.snap index adf094939af..0b0c66a013b 100644 --- a/test/modules/__snapshots__/date.spec.ts.snap +++ b/test/modules/__snapshots__/date.spec.ts.snap @@ -67,16 +67,12 @@ exports[`date > 42 > betweens > with string dates and count 1`] = ` exports[`date > 42 > birthdate > with age and refDate 1`] = `1980-07-07T19:06:53.165Z`; -exports[`date > 42 > birthdate > with age mode and refDate 1`] = `1963-09-27T06:10:42.813Z`; - exports[`date > 42 > birthdate > with age range and refDate 1`] = `1962-12-27T20:14:08.437Z`; exports[`date > 42 > birthdate > with only refDate 1`] = `1963-09-27T06:10:42.813Z`; exports[`date > 42 > birthdate > with year and refDate 1`] = `0020-07-07T19:06:53.165Z`; -exports[`date > 42 > birthdate > with year mode and refDate 1`] = `1964-03-22T08:05:48.849Z`; - exports[`date > 42 > birthdate > with year range and refDate 1`] = `0057-12-20T11:59:38.353Z`; exports[`date > 42 > future > with only Date refDate 1`] = `2021-07-08T10:07:33.524Z`; @@ -195,16 +191,12 @@ exports[`date > 1211 > betweens > with string dates and count 1`] = ` exports[`date > 1211 > birthdate > with age and refDate 1`] = `1981-01-26T13:16:31.426Z`; -exports[`date > 1211 > birthdate > with age mode and refDate 1`] = `1998-08-21T21:24:31.101Z`; - exports[`date > 1211 > birthdate > with age range and refDate 1`] = `1996-10-13T01:44:07.954Z`; exports[`date > 1211 > birthdate > with only refDate 1`] = `1998-08-21T21:24:31.101Z`; exports[`date > 1211 > birthdate > with year and refDate 1`] = `0021-01-26T13:16:31.426Z`; -exports[`date > 1211 > birthdate > with year mode and refDate 1`] = `1998-07-25T13:16:47.251Z`; - exports[`date > 1211 > birthdate > with year range and refDate 1`] = `0113-12-03T19:45:28.165Z`; exports[`date > 1211 > future > with only Date refDate 1`] = `2022-01-26T14:59:27.356Z`; @@ -321,16 +313,12 @@ exports[`date > 1337 > betweens > with string dates and count 1`] = ` exports[`date > 1337 > birthdate > with age and refDate 1`] = `1980-05-27T14:46:44.794Z`; -exports[`date > 1337 > birthdate > with age mode and refDate 1`] = `1956-08-25T03:56:58.153Z`; - exports[`date > 1337 > birthdate > with age range and refDate 1`] = `1956-02-15T21:16:37.850Z`; exports[`date > 1337 > birthdate > with only refDate 1`] = `1956-08-25T03:56:58.153Z`; exports[`date > 1337 > birthdate > with year and refDate 1`] = `0020-05-27T14:46:44.794Z`; -exports[`date > 1337 > birthdate > with year mode and refDate 1`] = `1957-03-31T18:18:16.563Z`; - exports[`date > 1337 > birthdate > with year range and refDate 1`] = `0046-08-09T19:19:14.289Z`; exports[`date > 1337 > future > with only Date refDate 1`] = `2021-05-28T08:29:26.600Z`; diff --git a/test/modules/date.spec.ts b/test/modules/date.spec.ts index 9f19b82f636..a4f1c1c603b 100644 --- a/test/modules/date.spec.ts +++ b/test/modules/date.spec.ts @@ -106,10 +106,6 @@ describe('date', () => { t.describe('birthdate', (t) => { t.it('with only refDate', { refDate }) - .it('with age mode and refDate', { - mode: 'age', - refDate, - }) .it('with age and refDate', { min: 40, max: 40, @@ -122,10 +118,6 @@ describe('date', () => { mode: 'age', refDate, }) - .it('with year mode and refDate', { - mode: 'year', - refDate, - }) .it('with year and refDate', { min: 2000, max: 2000, @@ -497,23 +489,6 @@ describe('date', () => { expect(birthdate).toBeInstanceOf(Date); }); - it.each(['year', 'age', undefined] as const)( - 'returns a random birthdate that is 18+ by default (%s mode)', - (mode) => { - // Generate the latest possible value => youngest - faker.seed(2855577693); - - const refDate = new Date(); - const birthdate = faker.date.birthdate({ refDate, mode }); - expect(birthdate).toBeInstanceOf(Date); - const value = birthdate.valueOf(); - const refDateValue = refDate.valueOf(); - expect(value).toBeLessThanOrEqual(refDateValue); - const deltaDate = new Date(refDateValue - value); - expect(deltaDate.getUTCFullYear() - 1970).toBe(18); - } - ); - it('returns a random birthdate in one year', () => { const min = 1990; const max = 1990; @@ -578,6 +553,22 @@ describe('date', () => { expect(deltaDate.getUTCFullYear() - 1970).toBeLessThanOrEqual(22); }); + it.each(['min', 'max', 'mode'] as const)( + "should throw an error when '%s' is not provided", + (key) => { + const options = { min: 18, max: 80, mode: 'age' } as const; + + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete + delete options[key]; + + expect(() => faker.date.birthdate(options)).toThrow( + new FakerError( + `The 'min', 'max', and 'mode' options must be set together.` + ) + ); + } + ); + it('should throw an error when the min > max year', () => { const min = 2000; const max = 1990; @@ -591,32 +582,6 @@ describe('date', () => { ); }); - it('should throw an error when the min > undefined max year', () => { - const min = 2010; - const refDate = Date.UTC(2020, 0, 1); - - expect(() => - faker.date.birthdate({ min, refDate, mode: 'year' }) - ).toThrow( - new FakerError( - `Max year 2001 should be greater than or equal to min year 2010.` - ) - ); - }); - - it('should throw an error when the undefined min > max year', () => { - const max = 1900; - const refDate = Date.UTC(2020, 0, 1); - - expect(() => - faker.date.birthdate({ max, refDate, mode: 'year' }) - ).toThrow( - new FakerError( - `Max year 1900 should be greater than or equal to min year 1940.` - ) - ); - }); - it('should throw an error when the min > max age', () => { const min = 31; const max = 25; @@ -630,32 +595,6 @@ describe('date', () => { ) ); }); - - it('should throw an error when the min > undefined max age', () => { - const min = 100; - const refDate = Date.UTC(2020, 0, 1); - - expect(() => - faker.date.birthdate({ min, refDate, mode: 'age' }) - ).toThrow( - new FakerError( - `Max age 80 should be greater than or equal to min age 100.` - ) - ); - }); - - it('should throw an error when the undefined min > max age', () => { - const max = 10; - const refDate = Date.UTC(2020, 0, 1); - - expect(() => - faker.date.birthdate({ max, refDate, mode: 'age' }) - ).toThrow( - new FakerError( - `Max age 10 should be greater than or equal to min age 18.` - ) - ); - }); }); } ); From 59426d5ec44201a246f4bb04a901ce90cd214fc7 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Wed, 27 Mar 2024 11:30:24 +0100 Subject: [PATCH 11/15] chore: apply review suggestions --- src/modules/date/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/date/index.ts b/src/modules/date/index.ts index 47a1984676d..6497ec2e09a 100644 --- a/src/modules/date/index.ts +++ b/src/modules/date/index.ts @@ -472,9 +472,9 @@ export class SimpleDateModule extends SimpleModuleBase { ): Date; birthdate( options: { + mode?: 'age' | 'year'; min?: number; max?: number; - mode?: 'age' | 'year'; refDate?: string | Date | number; } = {} ): Date { From 3fd134d311df6ff50761af832924dd11e77e6c54 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Thu, 28 Mar 2024 19:29:27 +0100 Subject: [PATCH 12/15] docs: fix jsdocs --- src/modules/date/index.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/modules/date/index.ts b/src/modules/date/index.ts index d0779d6663d..5ccd5ccd686 100644 --- a/src/modules/date/index.ts +++ b/src/modules/date/index.ts @@ -358,7 +358,7 @@ export class SimpleDateModule extends SimpleModuleBase { /** * Returns a random birthdate. By default, the birthdate is generated for an adult between 18 and 80 years old. - * But you can customize the `'age'` range or the `'year'` range to generate a birthdate. + * But you can customize the `'age'` range or the `'year'` range to generate a more specific birthdate. * * @param options The options to use to generate the birthdate. * @param options.refDate The date to use as reference point for the newly generated date. Defaults to `faker.defaultRefDate()`. @@ -427,7 +427,8 @@ export class SimpleDateModule extends SimpleModuleBase { */ birthdate(options: { /** - * `'year'` to generate a birthdate based on the year range. It is also possible to generate a birthdate based on an `'age'` range. + * `'year'` to generate a birthdate based on the year range. + * It is also possible to generate a birthdate based on an `'age'` range. */ mode: 'year'; /** @@ -446,7 +447,8 @@ export class SimpleDateModule extends SimpleModuleBase { refDate?: string | Date | number; }): Date; /** - * Returns a random birthdate in the given range of years. + * Returns a random birthdate. By default, the birthdate is generated for an adult between 18 and 80 years old. + * But you can customize the `'age'` range or the `'year'` range to generate a more specific birthdate. * * @param options The options to use to generate the birthdate. * @param options.mode Either `'age'` or `'year'` to generate a birthdate based on the age or year range. @@ -477,11 +479,11 @@ export class SimpleDateModule extends SimpleModuleBase { */ mode: 'age' | 'year'; /** - * The minimum year to generate a birthdate in. + * The minimum age/year to generate a birthdate for/in. */ min: number; /** - * The maximum year to generate a birthdate in. + * The maximum age/year to generate a birthdate for/in. */ max: number; /** From fb023aacec31a4be3ae358b007367536d02c7ce3 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Fri, 29 Mar 2024 20:30:27 +0100 Subject: [PATCH 13/15] chore: cleanup and simplifications --- src/modules/date/index.ts | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/modules/date/index.ts b/src/modules/date/index.ts index 5ccd5ccd686..aa364924925 100644 --- a/src/modules/date/index.ts +++ b/src/modules/date/index.ts @@ -418,7 +418,6 @@ export class SimpleDateModule extends SimpleModuleBase { * @param options.mode `'year'` to generate a birthdate based on the year range. It is also possible to generate a birthdate based on a `'age'` range. * @param options.min The minimum year to generate a birthdate in. * @param options.max The maximum year to generate a birthdate in. - * @param options.refDate The date to use as reference point for the newly generated date. Defaults to `faker.defaultRefDate()`. * * @example * faker.date.birthdate({ mode: 'year', min: 1900, max: 2000 }) // 1940-08-20T08:53:07.538Z @@ -439,12 +438,6 @@ export class SimpleDateModule extends SimpleModuleBase { * The maximum year to generate a birthdate in. */ max: number; - /** - * The date to use as reference point for the newly generated date. - * - * @default faker.defaultRefDate() - */ - refDate?: string | Date | number; }): Date; /** * Returns a random birthdate. By default, the birthdate is generated for an adult between 18 and 80 years old. @@ -504,7 +497,7 @@ export class SimpleDateModule extends SimpleModuleBase { ): Date { const { mode = 'age', - refDate = this.faker.defaultRefDate(), + refDate: rawRefDate = this.faker.defaultRefDate(), min: originalMin, max: originalMax, mode: originalMode, @@ -520,8 +513,8 @@ export class SimpleDateModule extends SimpleModuleBase { ); } - const date = toDate(refDate); - const refYear = date.getUTCFullYear(); + const refDate = toDate(rawRefDate); + const refYear = refDate.getUTCFullYear(); switch (mode) { case 'age': { @@ -547,7 +540,7 @@ export class SimpleDateModule extends SimpleModuleBase { if (from > to) { throw new FakerError( - `Max year ${max ?? refYear - 19} should be greater than or equal to min year ${min ?? refYear - 80}.` + `Max year ${max} should be greater than or equal to min year ${min}.` ); } From 737e2d754aa42d4ce6afe4b2af79d85712302caa Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Sat, 30 Mar 2024 00:31:15 +0100 Subject: [PATCH 14/15] test: fix seeded tests --- test/modules/__snapshots__/date.spec.ts.snap | 12 ++++++------ test/modules/date.spec.ts | 14 ++++++-------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/test/modules/__snapshots__/date.spec.ts.snap b/test/modules/__snapshots__/date.spec.ts.snap index 0b0c66a013b..d73d48cd6e7 100644 --- a/test/modules/__snapshots__/date.spec.ts.snap +++ b/test/modules/__snapshots__/date.spec.ts.snap @@ -71,9 +71,9 @@ exports[`date > 42 > birthdate > with age range and refDate 1`] = `1962-12-27T20 exports[`date > 42 > birthdate > with only refDate 1`] = `1963-09-27T06:10:42.813Z`; -exports[`date > 42 > birthdate > with year and refDate 1`] = `0020-07-07T19:06:53.165Z`; +exports[`date > 42 > birthdate > with year 1`] = `2000-05-16T22:59:36.655Z`; -exports[`date > 42 > birthdate > with year range and refDate 1`] = `0057-12-20T11:59:38.353Z`; +exports[`date > 42 > birthdate > with year range 1`] = `1937-10-30T15:52:21.843Z`; exports[`date > 42 > future > with only Date refDate 1`] = `2021-07-08T10:07:33.524Z`; @@ -195,9 +195,9 @@ exports[`date > 1211 > birthdate > with age range and refDate 1`] = `1996-10-13T exports[`date > 1211 > birthdate > with only refDate 1`] = `1998-08-21T21:24:31.101Z`; -exports[`date > 1211 > birthdate > with year and refDate 1`] = `0021-01-26T13:16:31.426Z`; +exports[`date > 1211 > birthdate > with year 1`] = `2000-12-04T01:16:03.291Z`; -exports[`date > 1211 > birthdate > with year range and refDate 1`] = `0113-12-03T19:45:28.165Z`; +exports[`date > 1211 > birthdate > with year range 1`] = `1993-10-11T07:45:00.030Z`; exports[`date > 1211 > future > with only Date refDate 1`] = `2022-01-26T14:59:27.356Z`; @@ -317,9 +317,9 @@ exports[`date > 1337 > birthdate > with age range and refDate 1`] = `1956-02-15T exports[`date > 1337 > birthdate > with only refDate 1`] = `1956-08-25T03:56:58.153Z`; -exports[`date > 1337 > birthdate > with year and refDate 1`] = `0020-05-27T14:46:44.794Z`; +exports[`date > 1337 > birthdate > with year 1`] = `2000-04-06T02:45:32.287Z`; -exports[`date > 1337 > birthdate > with year range and refDate 1`] = `0046-08-09T19:19:14.289Z`; +exports[`date > 1337 > birthdate > with year range 1`] = `1926-06-20T07:18:01.782Z`; exports[`date > 1337 > future > with only Date refDate 1`] = `2021-05-28T08:29:26.600Z`; diff --git a/test/modules/date.spec.ts b/test/modules/date.spec.ts index 61c17e98a63..d459db337e4 100644 --- a/test/modules/date.spec.ts +++ b/test/modules/date.spec.ts @@ -107,28 +107,26 @@ describe('date', () => { t.describe('birthdate', (t) => { t.it('with only refDate', { refDate }) .it('with age and refDate', { + mode: 'age', min: 40, max: 40, - mode: 'age', refDate, }) .it('with age range and refDate', { + mode: 'age', min: 20, max: 80, - mode: 'age', refDate, }) - .it('with year and refDate', { + .it('with year', { + mode: 'year', min: 2000, max: 2000, - mode: 'age', - refDate, }) - .it('with year range and refDate', { + .it('with year range', { + mode: 'year', min: 1900, max: 2000, - mode: 'age', - refDate, }); }); }); From 083a059e09a55bd004509b42501003ff002b2ab8 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Sat, 30 Mar 2024 18:05:37 +0100 Subject: [PATCH 15/15] chore: apply suggestions --- src/modules/date/index.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/modules/date/index.ts b/src/modules/date/index.ts index aa364924925..f851c62e624 100644 --- a/src/modules/date/index.ts +++ b/src/modules/date/index.ts @@ -447,7 +447,9 @@ export class SimpleDateModule extends SimpleModuleBase { * @param options.mode Either `'age'` or `'year'` to generate a birthdate based on the age or year range. * @param options.min The minimum age or year to generate a birthdate in. * @param options.max The maximum age or year to generate a birthdate in. - * @param options.refDate The date to use as reference point for the newly generated date. Defaults to `faker.defaultRefDate()`. + * @param options.refDate The date to use as reference point for the newly generated date. + * Only used when `mode` is `'age'`. + * Defaults to `faker.defaultRefDate()`. * * @example * faker.date.birthdate() // 1977-07-10T01:37:30.719Z @@ -481,6 +483,7 @@ export class SimpleDateModule extends SimpleModuleBase { max: number; /** * The date to use as reference point for the newly generated date. + * Only used when `mode` is `'age'`. * * @default faker.defaultRefDate() */ @@ -497,10 +500,12 @@ export class SimpleDateModule extends SimpleModuleBase { ): Date { const { mode = 'age', + min = 18, + max = 80, refDate: rawRefDate = this.faker.defaultRefDate(), + mode: originalMode, min: originalMin, max: originalMax, - mode: originalMode, } = options; // TODO @ST-DDT 2024-03-17: Remove check in v10 @@ -518,7 +523,6 @@ export class SimpleDateModule extends SimpleModuleBase { switch (mode) { case 'age': { - const { min = 18, max = 80 } = options; const from = new Date(refDate).setUTCFullYear(refYear - max - 1); const to = new Date(refDate).setUTCFullYear(refYear - min); @@ -532,7 +536,6 @@ export class SimpleDateModule extends SimpleModuleBase { } case 'year': { - const { min = refYear - 80, max = refYear - 19 } = options; // Avoid generating dates on the first and last date of the year // to avoid running into other years depending on the timezone. const from = new Date(Date.UTC(0, 0, 2)).setUTCFullYear(min);