From 933d44aa6f101fd855d9cbeec2f051d656402b25 Mon Sep 17 00:00:00 2001 From: Shinigami Date: Tue, 1 Feb 2022 20:05:14 +0100 Subject: [PATCH] test: rewrite name tests (#372) --- test/name.spec.ts | 725 +++++++++++++++++++++++++++++----------------- 1 file changed, 456 insertions(+), 269 deletions(-) diff --git a/test/name.spec.ts b/test/name.spec.ts index 12baa90eac2..2275dd02667 100644 --- a/test/name.spec.ts +++ b/test/name.spec.ts @@ -1,333 +1,520 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import { faker } from '../dist/cjs'; -function assertInArray(value: T, array: readonly T[]): void { - const idx = array.indexOf(value); - expect(idx).not.toBe(-1); -} +const seededRuns = [ + { + seed: 42, + expectations: { + firstName: { + noArgs: 'Garnett', + }, + lastName: { + noArgs: 'Hintz', + }, + middleName: { + noArgs: 'b', + }, + findName: { + noArgs: 'Lorene Deckow', + }, + jobTitle: { + noArgs: 'Regional Data Representative', + }, + gender: { + noArgs: 'Cis', + }, + prefix: { + noArgs: 'Mrs.', + }, + suffix: { + noArgs: 'III', + }, + title: { + noArgs: 'Regional Data Representative', + }, + jobDescriptor: { + noArgs: 'Regional', + }, + jobArea: { + noArgs: 'Identity', + }, + jobType: { + noArgs: 'Coordinator', + }, + }, + }, + { + seed: 1337, + expectations: { + firstName: { + noArgs: 'Devyn', + }, + lastName: { + noArgs: 'Gibson', + }, + middleName: { + noArgs: 'a', + }, + findName: { + noArgs: 'Marilyn Effertz', + }, + jobTitle: { + noArgs: 'Future Infrastructure Liaison', + }, + gender: { + noArgs: 'Two* person', + }, + prefix: { + noArgs: 'Mrs.', + }, + suffix: { + noArgs: 'I', + }, + title: { + noArgs: 'Future Infrastructure Liaison', + }, + jobDescriptor: { + noArgs: 'Future', + }, + jobArea: { + noArgs: 'Functionality', + }, + jobType: { + noArgs: 'Engineer', + }, + }, + }, + { + seed: 1211, + expectations: { + firstName: { + noArgs: 'Tito', + }, + lastName: { + noArgs: 'Ward', + }, + middleName: { + noArgs: 'c', + }, + findName: { + noArgs: 'Darrel Sanford', + }, + jobTitle: { + noArgs: 'Chief Division Agent', + }, + gender: { + noArgs: 'Transexual Person', + }, + prefix: { + noArgs: 'Dr.', + }, + suffix: { + noArgs: 'DVM', + }, + title: { + noArgs: 'Chief Division Agent', + }, + jobDescriptor: { + noArgs: 'Chief', + }, + jobArea: { + noArgs: 'Factors', + }, + jobType: { + noArgs: 'Representative', + }, + }, + }, +]; + +const NON_SEEDED_BASED_RUN = 5; + +const functionNames = [ + 'firstName', + 'lastName', + 'middleName', + 'findName', + 'jobTitle', + 'gender', + 'prefix', + 'suffix', + 'title', + 'jobDescriptor', + 'jobArea', + 'jobType', +]; describe('name', () => { - describe('firstName()', () => { - it('returns a random name', () => { - const spy_name_firstName = vi - .spyOn(faker.name, 'firstName') - .mockReturnValue('foo'); - - const first_name = faker.name.firstName(); - - expect(first_name).toBe('foo'); + afterEach(() => { + faker.locale = 'en'; + }); - spy_name_firstName.mockRestore(); - }); + for (const { seed, expectations } of seededRuns) { + describe(`seed: ${seed}`, () => { + for (const functionName of functionNames) { + it(`${functionName}()`, () => { + faker.seed(seed); - it('returns a gender-specific name when passed a number', () => { - for (let q = 0; q < 30; q++) { - const gender = Math.floor(Math.random() * 2); - const name = faker.name.firstName(gender); - if (gender === 0) { - assertInArray(name, faker.definitions.name.male_first_name); - } else { - assertInArray(name, faker.definitions.name.female_first_name); - } + const actual = faker.name[functionName](); + expect(actual).toEqual(expectations[functionName].noArgs); + }); } }); - - it('returns a gender-specific name when passed a string', () => { - for (let q = 0; q < 30; q++) { - const gender = Math.floor(Math.random() * 2); - const genderString = gender === 0 ? 'male' : 'female'; - const name = faker.name.firstName(genderString); - assertInArray( - name, - faker.definitions.name[genderString + '_first_name'] + } + + // Create and log-back the seed for debug purposes + faker.seed(Math.ceil(Math.random() * 1_000_000_000)); + + describe(`random seeded tests for seed ${faker.seedValue}`, () => { + for (let i = 1; i <= NON_SEEDED_BASED_RUN; i++) { + describe('firstName()', () => { + beforeEach(() => { + faker.locale = 'en'; + }); + + it('should return a random first name', () => { + const first_name = faker.name.firstName(); + + expect(typeof first_name).toBe('string'); + expect(first_name.length).greaterThan(0); + }); + + it('should return a gender-specific first name when passed a number', () => { + let name = faker.name.firstName(0); + expect(faker.definitions.name.male_first_name).toContain(name); + name = faker.name.firstName(1); + expect(faker.definitions.name.female_first_name).toContain(name); + }); + + // TODO @Shinigami92 2022-01-30: There is a bug: https://github.com/faker-js/faker/issues/373 + it.todo( + 'should return a gender-specific first name when passed a string', + () => { + let name = faker.name.firstName('male'); + expect(faker.definitions.name.male_first_name).toContain(name); + name = faker.name.firstName('female'); + expect(faker.definitions.name.female_first_name).toContain(name); + } ); - } - }); - }); - - describe('lastName()', () => { - it('returns a random name', () => { - const spy_name_lastName = vi - .spyOn(faker.name, 'lastName') - .mockReturnValue('foo'); - - const last_name = faker.name.lastName(); - - expect(last_name).toBe('foo'); - - spy_name_lastName.mockRestore(); - }); - }); - - describe('middleName()', () => { - it('returns a random middle name', () => { - const spy_name_middleName = vi - .spyOn(faker.name, 'middleName') - .mockReturnValue('foo'); - - const middle_name = faker.name.middleName(); - - expect(middle_name).toBe('foo'); - - spy_name_middleName.mockRestore(); - }); - - describe('when using a locale with gender specific middle names', () => { - let oldLocale: string; - - beforeEach(() => { - oldLocale = faker.locale; - faker.locale = 'TEST'; - - // @ts-expect-error - faker.locales.TEST = { - name: { - male_middle_name: ['Genaddiesvich'], - female_middle_name: ['Genaddievna'], - }, - }; }); - afterEach(() => { - faker.locale = oldLocale; - // @ts-expect-error - delete faker.locale.TEST; + describe('lastName()', () => { + beforeEach(() => { + faker.locale = 'en'; + }); + + it('should return a random last name', () => { + const last_name = faker.name.lastName(); + + expect(typeof last_name).toBe('string'); + expect(last_name.length).greaterThan(0); + }); + + it('should return a gender-specific last name when passed a number', () => { + faker.locale = 'az'; + + let name = faker.name.lastName(0); + expect(faker.definitions.name.male_last_name).toContain(name); + name = faker.name.lastName(1); + expect(faker.definitions.name.female_last_name).toContain(name); + }); + + // TODO @Shinigami92 2022-01-30: There is a bug: https://github.com/faker-js/faker/issues/373 + it.todo( + 'should return a gender-specific last name when passed a string', + () => { + faker.locale = 'az'; + + let name = faker.name.lastName('male'); + expect(faker.definitions.name.male_last_name).toContain(name); + name = faker.name.lastName('female'); + expect(faker.definitions.name.female_last_name).toContain(name); + } + ); }); - it('returns male prefix', () => { - const middle_name = faker.name.middleName(0); + describe('middleName()', () => { + beforeEach(() => { + faker.locale = 'en'; + }); + + it('should return a random middle name', () => { + const middle_name = faker.name.middleName(); + + expect(typeof middle_name).toBe('string'); + expect(middle_name.length).greaterThan(0); + }); + + it('should return a gender-specific middle name when passed a number', () => { + faker.locale = 'uk'; + + let name = faker.name.middleName(0); + expect(faker.definitions.name.male_middle_name).toContain(name); + name = faker.name.middleName(1); + expect(faker.definitions.name.female_middle_name).toContain(name); + }); + + // TODO @Shinigami92 2022-01-30: There is a bug: https://github.com/faker-js/faker/issues/373 + it.todo( + 'should return a gender-specific middle name when passed a string', + () => { + faker.locale = 'uk'; + + let name = faker.name.middleName('male'); + expect(faker.definitions.name.male_middle_name).toContain(name); + name = faker.name.middleName('female'); + expect(faker.definitions.name.female_middle_name).toContain(name); + } + ); + }); - expect(middle_name).toBe('Genaddiesvich'); + describe('findName()', () => { + beforeEach(() => { + faker.locale = 'en'; + }); + + it('should return a name with firstName and lastName', () => { + const fullName = faker.name.findName(); + + expect(typeof fullName).toBe('string'); + expect(fullName).toContain(' '); + }); + + it('should return a male gender-specific name with firstName and lastName', () => { + faker.locale = 'mk'; + + const male_specific = [ + ...faker.definitions.name.male_prefix, + ...faker.definitions.name.male_first_name, + ...faker.definitions.name.male_last_name, + ...faker.definitions.name.suffix, + ]; + + const fullName = faker.name.findName(undefined, undefined, 0); + + const parts = fullName.split(' '); + for (const part of parts) { + expect(male_specific).toContain(part); + } + }); + + it('should return a female gender-specific name with firstName and lastName', () => { + faker.locale = 'mk'; + + const female_specific = [ + ...faker.definitions.name.female_prefix, + ...faker.definitions.name.female_first_name, + ...faker.definitions.name.female_last_name, + ...faker.definitions.name.suffix, + ]; + + const fullName = faker.name.findName(undefined, undefined, 1); + + const parts = fullName.split(' '); + for (const part of parts) { + expect(female_specific).toContain(part); + } + }); + + it('should return a male gender-specific name with given firstName and lastName', () => { + faker.locale = 'mk'; + + const male_specific = [ + ...faker.definitions.name.male_prefix, + 'firstName', + 'lastName', + ...faker.definitions.name.suffix, + ]; + + const fullName = faker.name.findName('firstName', 'lastName', 0); + + const parts = fullName.split(' '); + for (const part of parts) { + expect(male_specific).toContain(part); + } + }); + + it('should return a female gender-specific name with given firstName and lastName', () => { + faker.locale = 'mk'; + + const male_specific = [ + ...faker.definitions.name.female_prefix, + 'firstName', + 'lastName', + ...faker.definitions.name.suffix, + ]; + + const fullName = faker.name.findName('firstName', 'lastName', 1); + + const parts = fullName.split(' '); + for (const part of parts) { + expect(male_specific).toContain(part); + } + }); }); - it('returns female prefix', () => { - const middle_name = faker.name.middleName(1); + describe('jobTitle()', () => { + beforeEach(() => { + faker.locale = 'en'; + }); - expect(middle_name).toBe('Genaddievna'); - }); - }); - }); + it('should return a job title consisting of a descriptor, area, and type', () => { + const jobTitle = faker.name.jobTitle(); - describe('findName()', () => { - it('usually returns a first name and last name', () => { - const spy_datatype_number = vi - .spyOn(faker.datatype, 'number') - .mockReturnValue(5); + expect(typeof jobTitle).toBe('string'); - const name = faker.name.findName(); + const [descriptor, level, job] = jobTitle.split(' '); - expect(name).toBeTruthy(); + expect(faker.definitions.name.title.descriptor).toContain(descriptor); + expect(faker.definitions.name.title.level).toContain(level); + expect(faker.definitions.name.title.job).toContain(job); + }); + }); - const parts = name.split(' '); + describe('gender()', () => { + beforeEach(() => { + faker.locale = 'en'; + }); - expect(parts).toHaveLength(2); + it('should return a default gender', () => { + const gender = faker.name.gender(); - spy_datatype_number.mockRestore(); - }); + expect(typeof gender).toBe('string'); + expect(faker.definitions.name.gender).toContain(gender); + }); - it('occasionally returns a first name and last name with a prefix', () => { - const spy_datatype_number = vi - .spyOn(faker.datatype, 'number') - .mockReturnValue(0); + it('should return a binary gender', () => { + const gender = faker.name.gender(true); - const name = faker.name.findName(); - const parts = name.split(' '); + expect(typeof gender).toBe('string'); + expect(faker.definitions.name.binary_gender).toContain(gender); + }); + }); - expect(parts.length).greaterThanOrEqual(3); + describe('prefix()', () => { + beforeEach(() => { + faker.locale = 'en'; + }); - spy_datatype_number.mockRestore(); - }); + it('should return a prefix', () => { + const prefix = faker.name.prefix(); - it('occasionally returns a male full name with a prefix', () => { - const spy_datatype_number = vi - .spyOn(faker.datatype, 'number') - .mockImplementation((opt) => - opt === 8 - ? 0 // with prefix - : opt === 1 - ? 0 // gender male - : undefined - ); + expect(typeof prefix).toBe('string'); + expect(faker.definitions.name.prefix).toContain(prefix); + }); - const spy_name_prefix = vi - .spyOn(faker.name, 'prefix') - .mockImplementation((arg) => (arg === 0 ? 'X' : undefined)); - const spy_name_firstName = vi - .spyOn(faker.name, 'firstName') - .mockImplementation((arg) => (arg === 0 ? 'Y' : undefined)); - const spy_name_lastName = vi - .spyOn(faker.name, 'lastName') - .mockImplementation((arg) => (arg === 0 ? 'Z' : undefined)); + it('should return a male prefix', () => { + faker.locale = 'mk'; - const name = faker.name.findName(); + const prefix = faker.name.prefix(0); - expect(name).toBe('X Y Z'); + expect(typeof prefix).toBe('string'); + expect(faker.definitions.name.male_prefix).toContain(prefix); + }); - spy_datatype_number.mockRestore(); - spy_name_prefix.mockRestore(); - spy_name_firstName.mockRestore(); - spy_name_lastName.mockRestore(); - }); + // TODO @Shinigami92 2022-01-31: There is a bug: https://github.com/faker-js/faker/issues/373 + it.todo('should return a male prefix with given string', () => { + faker.locale = 'mk'; - it('occasionally returns a female full name with a prefix', () => { - const spy_datatype_number = vi - .spyOn(faker.datatype, 'number') - .mockImplementation((opt) => - opt === 8 - ? 0 // with prefix - : opt === 1 - ? 1 // gender female - : undefined - ); + const prefix = faker.name.prefix('male'); - const spy_name_prefix = vi - .spyOn(faker.name, 'prefix') - .mockImplementation((arg) => (arg === 1 ? 'J' : undefined)); - const spy_name_firstName = vi - .spyOn(faker.name, 'firstName') - .mockImplementation((arg) => (arg === 1 ? 'K' : undefined)); - const spy_name_lastName = vi - .spyOn(faker.name, 'lastName') - .mockImplementation((arg) => (arg === 1 ? 'L' : undefined)); + expect(typeof prefix).toBe('string'); + expect(faker.definitions.name.male_prefix).toContain(prefix); + }); - const name = faker.name.findName(); + it('should return a female prefix', () => { + faker.locale = 'mk'; - expect(name).toBe('J K L'); + const prefix = faker.name.prefix(1); - spy_datatype_number.mockRestore(); - spy_name_prefix.mockRestore(); - spy_name_firstName.mockRestore(); - spy_name_lastName.mockRestore(); - }); + expect(typeof prefix).toBe('string'); + expect(faker.definitions.name.female_prefix).toContain(prefix); + }); - it('occasionally returns a first name and last name with a suffix', () => { - const spy_datatype_number = vi - .spyOn(faker.datatype, 'number') - .mockReturnValue(1); - const spy_name_suffix = vi - .spyOn(faker.name, 'suffix') - .mockReturnValue('Jr.'); + // TODO @Shinigami92 2022-01-31: There is a bug: https://github.com/faker-js/faker/issues/373 + it.todo('should return a female prefix with given string', () => { + faker.locale = 'mk'; - const name = faker.name.findName(); - const parts = name.split(' '); + const prefix = faker.name.prefix('female'); - expect(parts.length).greaterThanOrEqual(3); - expect(parts[parts.length - 1]).toBe('Jr.'); + expect(typeof prefix).toBe('string'); + expect(faker.definitions.name.female_prefix).toContain(prefix); + }); + }); - spy_name_suffix.mockRestore(); - spy_datatype_number.mockRestore(); - }); + describe('suffix()', () => { + beforeEach(() => { + faker.locale = 'en'; + }); - it.todo( - 'needs to work with specific locales and respect the fallbacks', - () => { - faker.locale = 'en_US'; - // this will throw if this is broken - const name = faker.name.findName(); - // TODO @Shinigami92 2022-01-20: This test doesn't check anything - } - ); - }); + it('should return a suffix', () => { + const suffix = faker.name.suffix(); - describe('title()', () => { - it('returns a random title', () => { - const spy_name_title = vi - .spyOn(faker.name, 'title') - .mockReturnValue('Lead Solutions Supervisor'); + expect(typeof suffix).toBe('string'); + expect(faker.definitions.name.suffix).toContain(suffix); + }); + }); - const title = faker.name.title(); + describe('title()', () => { + beforeEach(() => { + faker.locale = 'en'; + }); - expect(title).toBe('Lead Solutions Supervisor'); + it('should return a title consisting of a descriptor, area, and type', () => { + const title = faker.name.title(); - spy_name_title.mockRestore(); - }); - }); + expect(typeof title).toBe('string'); - describe('jobTitle()', () => { - it('returns a job title consisting of a descriptor, area, and type', () => { - const spy_random_arrayElement = vi.spyOn(faker.random, 'arrayElement'); - const spy_name_jobDescriptor = vi.spyOn(faker.name, 'jobDescriptor'); - const spy_name_jobArea = vi.spyOn(faker.name, 'jobArea'); - const spy_name_jobType = vi.spyOn(faker.name, 'jobType'); - - const jobTitle = faker.name.jobTitle(); - - expect(typeof jobTitle).toBe('string'); - expect(spy_random_arrayElement).toHaveBeenCalledTimes(3); - expect(spy_name_jobDescriptor).toHaveBeenCalledOnce(); - expect(spy_name_jobArea).toHaveBeenCalledOnce(); - expect(spy_name_jobType).toHaveBeenCalledOnce(); - - spy_random_arrayElement.mockRestore(); - spy_name_jobDescriptor.mockRestore(); - spy_name_jobArea.mockRestore(); - spy_name_jobType.mockRestore(); - }); - }); + const [descriptor, level, job] = title.split(' '); - describe('prefix()', () => { - describe('when using a locale with gender specific name prefixes', () => { - let oldLocale: string; - - beforeEach(() => { - oldLocale = faker.locale; - faker.locale = 'TEST'; - - faker.locales.TEST = { - title: 'Test', - name: { - male_prefix: ['Mp'], - female_prefix: ['Fp'], - }, - }; + // TODO @Shinigami92 2022-01-31: jobTitle and title are the same + expect(faker.definitions.name.title.descriptor).toContain(descriptor); + expect(faker.definitions.name.title.level).toContain(level); + expect(faker.definitions.name.title.job).toContain(job); + }); }); - afterEach(() => { - faker.locale = oldLocale; - delete faker.locales.TEST; - }); + describe('jobDescriptor()', () => { + beforeEach(() => { + faker.locale = 'en'; + }); - it('returns male prefix', () => { - const prefix = faker.name.prefix(0); - expect(prefix).toBe('Mp'); - }); + it('should return a descriptor', () => { + const descriptor = faker.name.jobDescriptor(); - it('returns female prefix', () => { - const prefix = faker.name.prefix(1); - expect(prefix).toBe('Fp'); - }); + expect(typeof descriptor).toBe('string'); - it('returns either prefix', () => { - const prefix = faker.name.prefix(); - expect(['Mp', 'Fp']).toContain(prefix); + expect(faker.definitions.name.title.descriptor).toContain(descriptor); + }); }); - }); - describe('when using a locale without gender specific name prefixes', () => { - let oldLocale: string; + describe('jobArea()', () => { + beforeEach(() => { + faker.locale = 'en'; + }); - beforeEach(() => { - oldLocale = faker.locale; - faker.locale = 'TEST'; + it('should return a level', () => { + const level = faker.name.jobArea(); - faker.locales.TEST = { - title: 'Test', - name: { - prefix: ['P'], - }, - }; - }); + expect(typeof level).toBe('string'); - afterEach(() => { - faker.locale = oldLocale; - delete faker.locales.TEST; + expect(faker.definitions.name.title.level).toContain(level); + }); }); - it('returns a prefix', () => { - const prefix = faker.name.prefix(); + describe('jobType()', () => { + beforeEach(() => { + faker.locale = 'en'; + }); - expect(prefix).toBe('P'); + it('should return a job', () => { + const job = faker.name.jobType(); + + expect(typeof job).toBe('string'); + + expect(faker.definitions.name.title.job).toContain(job); + }); }); - }); + } }); });