diff --git a/test/address.spec.ts b/test/address.spec.ts index 9e905324c3a..7688b218a66 100644 --- a/test/address.spec.ts +++ b/test/address.spec.ts @@ -1,782 +1,658 @@ -import type { JestMockCompat } from 'vitest'; -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import { afterEach, describe, expect, it } from 'vitest'; import { faker } from '../dist/cjs'; -describe('address', () => { - describe('city()', () => { - let spy_address_cityPrefix: JestMockCompat<[], string>; - let spy_name_firstName: JestMockCompat<[gender?: string | number], string>; - let spy_name_lastName: JestMockCompat<[gender?: string | number], string>; - let spy_address_citySuffix: JestMockCompat<[], string>; - - beforeEach(() => { - spy_address_cityPrefix = vi.spyOn(faker.address, 'cityPrefix'); - spy_name_firstName = vi.spyOn(faker.name, 'firstName'); - spy_name_lastName = vi.spyOn(faker.name, 'lastName'); - spy_address_citySuffix = vi.spyOn(faker.address, 'citySuffix'); - }); - - afterEach(() => { - // faker.datatype.number.restore(); - spy_address_cityPrefix.mockRestore(); - spy_name_firstName.mockRestore(); - spy_name_lastName.mockRestore(); - spy_address_citySuffix.mockRestore(); - }); - - it('occasionally returns prefix + first name + suffix', () => { - const spy_datatype_number = vi - .spyOn(faker.datatype, 'number') - .mockImplementation(() => 0); - - const city = faker.address.city(); - expect(city).toBeTruthy(); - - expect(spy_address_cityPrefix).toHaveBeenCalledOnce(); - expect(spy_name_firstName).toHaveBeenCalledOnce(); - expect(spy_address_citySuffix).toHaveBeenCalledOnce(); - - spy_datatype_number.mockRestore(); - }); - - it('occasionally returns prefix + first name', () => { - const spy_datatype_number = vi - .spyOn(faker.datatype, 'number') - .mockImplementation(() => 1); - - const city = faker.address.city(); - expect(city).toBeTruthy(); - - expect(spy_address_cityPrefix).toHaveBeenCalledOnce(); - expect(spy_name_firstName).toHaveBeenCalledOnce(); - - spy_datatype_number.mockRestore(); - }); - - it('occasionally returns first name + suffix', () => { - const spy_datatype_number = vi - .spyOn(faker.datatype, 'number') - .mockImplementation(() => 2); - - const city = faker.address.city(); - expect(city).toBeTruthy(); - - expect(spy_address_citySuffix).toHaveBeenCalledOnce(); - - spy_datatype_number.mockRestore(); - }); - - it('occasionally returns last name + suffix', () => { - const spy_datatype_number = vi - .spyOn(faker.datatype, 'number') - .mockImplementation(() => 3); +const seededRuns = [ + { + seed: 42, + expectations: { + city: 'Lake Valentine', + cityPrefix: 'West', + citySuffix: 'bury', + cityName: 'Gulfport', + streetName: 'Valentine Isle', + streetPrefix: 'b', + streetSuffix: 'Isle', + streetAddressDigits: 4, + fullStreetAddress: '7917 Lauryn Spur Apt. 410', + secondaryAddress: 'Apt. 791', + county: 'Berkshire', + country: 'Haiti', + countryCode: 'GY', + state: 'Maine', + stateAbbr: 'ME', + zipCode: '79177', + direction: 'South', + directionNonAbbr: 'South', + directionAbbr: 'S', + ordinalDirection: 'Northwest', + ordinalDirectionAbbr: 'NW', + cardinalDirection: 'East', + cardinalDirectionAbbr: 'E', + timeZone: 'Europe/Amsterdam', + }, + }, + { + seed: 1337, + expectations: { + city: 'South Carmelo', + cityPrefix: 'East', + citySuffix: 'berg', + cityName: 'Dubuque', + streetName: 'Carmelo Forks', + streetPrefix: 'a', + streetSuffix: 'Forks', + streetAddressDigits: 5, + fullStreetAddress: '51225 Hammes Lodge Apt. 552', + secondaryAddress: 'Apt. 512', + county: 'Bedfordshire', + country: 'Equatorial Guinea', + countryCode: 'EH', + state: 'Indiana', + stateAbbr: 'IN', + zipCode: '51225', + direction: 'South', + directionNonAbbr: 'South', + directionAbbr: 'S', + ordinalDirection: 'Northwest', + ordinalDirectionAbbr: 'NW', + cardinalDirection: 'East', + cardinalDirectionAbbr: 'E', + timeZone: 'Africa/Casablanca', + }, + }, + { + seed: 1211, + expectations: { + city: 'La Crosse', + cityPrefix: 'Port', + citySuffix: 'side', + cityName: 'Urbana', + streetName: 'Trantow Via', + streetPrefix: 'c', + streetSuffix: 'Via', + streetAddressDigits: 3, + fullStreetAddress: '487 Zieme Flat Apt. 616', + secondaryAddress: 'Suite 487', + county: 'Cambridgeshire', + country: 'Uganda', + countryCode: 'UM', + state: 'Washington', + stateAbbr: 'WA', + zipCode: '48721-9061', + direction: 'Southwest', + directionNonAbbr: 'Southwest', + directionAbbr: 'SW', + ordinalDirection: 'Southwest', + ordinalDirectionAbbr: 'SW', + cardinalDirection: 'West', + cardinalDirectionAbbr: 'W', + timeZone: 'Asia/Magadan', + }, + }, +]; + +const NON_SEEDED_BASED_RUN = 5; - const city = faker.address.city(); - expect(city).toBeTruthy(); - - expect(spy_address_cityPrefix).not.toHaveBeenCalled(); - expect(spy_name_firstName).not.toHaveBeenCalled(); - expect(spy_name_lastName).toHaveBeenCalled(); - expect(spy_address_citySuffix).toHaveBeenCalled(); - - spy_datatype_number.mockRestore(); - }); - }); - - describe('streetName()', () => { - let spy_name_firstName: JestMockCompat<[gender?: string | number], string>; - let spy_name_lastName: JestMockCompat<[gender?: string | number], string>; - let spy_address_streetSuffix: JestMockCompat<[], string>; - - beforeEach(() => { - spy_name_firstName = vi.spyOn(faker.name, 'firstName'); - spy_name_lastName = vi.spyOn(faker.name, 'lastName'); - spy_address_streetSuffix = vi.spyOn(faker.address, 'streetSuffix'); - }); - - afterEach(() => { - spy_name_firstName.mockRestore(); - spy_name_lastName.mockRestore(); - spy_address_streetSuffix.mockRestore(); - }); - - it('occasionally returns last name + suffix', () => { - const spy_datatype_number = vi - .spyOn(faker.datatype, 'number') - .mockImplementation(() => 0); - - const street_name = faker.address.streetName(); - expect(street_name).toBeTruthy(); - - expect(spy_name_firstName).not.toHaveBeenCalled(); - expect(spy_name_lastName).toHaveBeenCalledOnce(); - expect(spy_address_streetSuffix).toHaveBeenCalledOnce(); - - spy_datatype_number.mockRestore(); - }); - - it('occasionally returns first name + suffix', () => { - const spy_datatype_number = vi - .spyOn(faker.datatype, 'number') - .mockImplementation(() => 1); - - const street_name = faker.address.streetName(); - expect(street_name).toBeTruthy(); - - expect(spy_name_firstName).toHaveBeenCalledOnce(); - expect(spy_name_lastName).not.toHaveBeenCalled(); - expect(spy_address_streetSuffix).toHaveBeenCalledOnce(); - - spy_datatype_number.mockRestore(); - }); - - it('trims trailing whitespace from the name', () => { - spy_address_streetSuffix.mockRestore(); - - spy_address_streetSuffix.mockImplementation(() => ''); - - const street_name = faker.address.streetName(); - expect(street_name).not.match(/ $/); - - spy_address_streetSuffix.mockRestore(); - }); +describe('address', () => { + afterEach(() => { + faker.locale = 'en'; }); - describe('streetAddress()', () => { - const errorExpectDigits = (expected) => { - return 'The street number should be had ' + expected + ' digits'; - }; - - let spy_address_streetName: JestMockCompat<[], string>; - let spy_address_secondaryAddress: JestMockCompat<[], string>; - - beforeEach(() => { - spy_address_streetName = vi.spyOn(faker.address, 'streetName'); - spy_address_secondaryAddress = vi.spyOn( - faker.address, - 'secondaryAddress' - ); - }); - - afterEach(() => { - spy_address_streetName.mockRestore(); - spy_address_secondaryAddress.mockRestore(); - }); - - it('occasionally returns a 5-digit street number', () => { - const spy_datatype_number = vi - .spyOn(faker.datatype, 'number') - .mockImplementation(() => 0); - - const address = faker.address.streetAddress(); - const expected = 5; - const parts = address.split(' '); - - expect(parts[0].length, errorExpectDigits(expected)).toBe(expected); - expect(spy_address_streetName).toHaveBeenCalled(); - - spy_datatype_number.mockRestore(); - }); - - it('occasionally returns a 4-digit street number', () => { - const spy_datatype_number = vi - .spyOn(faker.datatype, 'number') - .mockImplementation(() => 1); - - const address = faker.address.streetAddress(); - const parts = address.split(' '); - const expected = 4; - - expect(parts[0].length, errorExpectDigits(expected)).toBe(expected); - expect(spy_address_streetName).toHaveBeenCalled(); + for (let { seed, expectations } of seededRuns) { + describe(`seed: ${seed}`, () => { + it('city()', () => { + faker.seed(seed); - spy_datatype_number.mockRestore(); - }); - - it('occasionally returns a 3-digit street number', () => { - const spy_datatype_number = vi - .spyOn(faker.datatype, 'number') - .mockImplementation(() => 2); - - const address = faker.address.streetAddress(); - const parts = address.split(' '); - const expected = 3; - - expect(parts[0].length, errorExpectDigits(expected)).toBe(expected); - expect(spy_address_streetName).toHaveBeenCalled(); - expect(spy_address_secondaryAddress).not.toHaveBeenCalled(); - - spy_datatype_number.mockRestore(); - }); - - describe('when useFulladdress is true', () => { - it('adds a secondary address to the result', () => { - faker.address.streetAddress(true); - - expect(spy_address_secondaryAddress).toHaveBeenCalled(); + const city = faker.address.city(); + expect(city).toEqual(expectations.city); }); - }); - }); - describe('secondaryAddress()', () => { - it('randomly chooses an Apt or Suite number', () => { - const spy_random_arrayElement = vi.spyOn(faker.random, 'arrayElement'); + it('cityPrefix()', () => { + faker.seed(seed); - const address = faker.address.secondaryAddress(); - - const expected_array = ['Apt. ###', 'Suite ###']; - - expect(address).toBeTruthy(); - expect(spy_random_arrayElement).toHaveBeenCalledWith(expected_array); - }); - }); - - describe('county()', () => { - it('returns random county', () => { - const spy_address_county = vi.spyOn(faker.address, 'county'); - - const county = faker.address.county(); - - expect(county).toBeTruthy(); - expect(spy_address_county).toHaveBeenCalled(); - }); - }); - - describe('country()', () => { - it('returns random country', () => { - const spy_address_country = vi.spyOn(faker.address, 'country'); - - const country = faker.address.country(); - - expect(country).toBeTruthy(); - expect(spy_address_country).toHaveBeenCalled(); - }); - }); - - describe('countryCode()', () => { - it('returns random countryCode', () => { - const spy_address_countryCode = vi.spyOn(faker.address, 'countryCode'); - - const countryCode = faker.address.countryCode(); - - expect(countryCode).toBeTruthy(); - expect(spy_address_countryCode).toHaveBeenCalled(); - }); - - it('returns random alpha-3 countryCode', () => { - const spy_address_countryCode = vi.spyOn(faker.address, 'countryCode'); - - const countryCode = faker.address.countryCode('alpha-3'); - - expect(countryCode).toBeTruthy(); - expect(spy_address_countryCode).toHaveBeenCalled(); - expect( - countryCode.length, - 'The countryCode should be had 3 characters' - ).toBe(3); - }); - }); - - describe('state()', () => { - it('returns random state', () => { - const spy_address_state = vi.spyOn(faker.address, 'state'); + const cityPrefix = faker.address.cityPrefix(); + expect(cityPrefix).toEqual(expectations.cityPrefix); + }); - const state = faker.address.state(); + it('citySuffix()', () => { + faker.seed(seed); - expect(state).toBeTruthy(); - expect(spy_address_state).toHaveBeenCalled(); - }); - }); + const citySuffix = faker.address.citySuffix(); + expect(citySuffix).toEqual(expectations.citySuffix); + }); - describe('zipCode()', () => { - it('returns random zipCode', () => { - const spy_address_zipCode = vi.spyOn(faker.address, 'zipCode'); + it('cityName()', () => { + faker.seed(seed); - const zipCode = faker.address.zipCode(); + const cityName = faker.address.cityName(); + expect(cityName).toEqual(expectations.cityName); + }); - expect(zipCode).toBeTruthy(); - expect(spy_address_zipCode).toHaveBeenCalled(); - }); + it('streetName()', () => { + faker.seed(seed); - it('returns random zipCode - user specified format', () => { - let zipCode = faker.address.zipCode('?#? #?#'); + const street_name = faker.address.streetName(); + expect(street_name).toEqual(expectations.streetName); + }); - expect(zipCode).match(/^[A-Za-z]\d[A-Za-z]\s\d[A-Za-z]\d$/); + describe('streetAddress()', () => { + it('should return a digit street number', () => { + faker.seed(seed); - // try another format - zipCode = faker.address.zipCode('###-###'); + const address = faker.address.streetAddress(); + const parts = address.split(' '); - expect(zipCode).match(/^\d{3}-\d{3}$/); - }); + expect( + parts[0].length, + `The street number should have ${expectations.streetAddressDigits} digits` + ).toStrictEqual(expectations.streetAddressDigits); + }); - it('returns zipCode with proper locale format', () => { - // we'll use the en_CA locale.. - faker.locale = 'en_CA'; - const zipCode = faker.address.zipCode(); + describe('when useFulladdress is true', () => { + it('adds a secondary address to the result', () => { + faker.seed(seed); - expect(zipCode).match(/^[A-Za-z]\d[A-Za-z]\s?\d[A-Za-z]\d$/); - }); - }); + const address = faker.address.streetAddress(true); + expect(address).toEqual(expectations.fullStreetAddress); + }); + }); + }); - describe('zipCodeByState()', () => { - it('returns zipCode valid for specified State', () => { - faker.locale = 'en_US'; - const states = ['IL', 'GA', 'WA']; + it('streetPrefix()', () => { + faker.seed(seed); - const zipCode1 = faker.address.zipCodeByState(states[0]); - expect(zipCode1).greaterThanOrEqual(60001); - expect(zipCode1).lessThanOrEqual(62999); + const streetPrefix = faker.address.streetPrefix(); + expect(streetPrefix).toEqual(expectations.streetPrefix); + }); - const zipCode2 = faker.address.zipCodeByState(states[1]); - expect(zipCode2).greaterThanOrEqual(30001); - expect(zipCode2).lessThanOrEqual(31999); + it('streetSuffix()', () => { + faker.seed(seed); - const zipCode3 = faker.address.zipCodeByState(states[2]); - expect(zipCode3).greaterThanOrEqual(98001); - expect(zipCode3).lessThanOrEqual(99403); - }); + const streetSuffix = faker.address.streetSuffix(); + expect(streetSuffix).toEqual(expectations.streetSuffix); + }); - it('returns undefined if state is invalid', () => { - const state = 'XX'; - const spy_address_zipCode = vi.spyOn(faker.address, 'zipCode'); + describe('secondaryAddress()', () => { + it('randomly chooses an Apt or Suite number', () => { + faker.seed(seed); - faker.address.zipCodeByState(state); - expect(spy_address_zipCode).toHaveBeenCalled(); + const address = faker.address.secondaryAddress(); + expect(address).toEqual(expectations.secondaryAddress); + }); + }); - spy_address_zipCode.mockRestore(); - }); + describe('county()', () => { + it('returns random county', () => { + faker.seed(seed); - it('returns undefined if state is valid but localeis invalid', () => { - faker.locale = 'zh_CN'; - const state = 'IL'; + const county = faker.address.county(); + expect(county).toEqual(expectations.county); + }); + }); - const spy_address_zipCode = vi.spyOn(faker.address, 'zipCode'); + describe('country()', () => { + it('returns random country', () => { + faker.seed(seed); - faker.address.zipCodeByState(state); - expect(spy_address_zipCode).toHaveBeenCalled(); + const country = faker.address.country(); + expect(country).toEqual(expectations.country); + }); + }); - spy_address_zipCode.mockRestore(); - }); - }); + describe('countryCode()', () => { + it('returns random countryCode', () => { + faker.seed(seed); - describe('latitude()', () => { - it('returns random latitude', () => { - const spy_datatype_number = vi.spyOn(faker.datatype, 'number'); + const countryCode = faker.address.countryCode(); + expect(countryCode).toEqual(expectations.countryCode); + }); + }); - for (let i = 0; i < 100; i++) { - const latitude = faker.address.latitude(); + describe('state()', () => { + it('returns random state', () => { + faker.seed(seed); - expect(typeof latitude).toBe('string'); + const state = faker.address.state(); + expect(state).toEqual(expectations.state); + }); + }); - const latitude_float = parseFloat(latitude); + describe('stateAbbr()', () => { + it('returns random stateAbbr', () => { + faker.seed(seed); - expect(latitude_float).greaterThanOrEqual(-90.0); - expect(latitude_float).lessThanOrEqual(90.0); - expect(spy_datatype_number).toHaveBeenCalled(); + const stateAbbr = faker.address.stateAbbr(); + expect(stateAbbr).toEqual(expectations.stateAbbr); + }); + }); - spy_datatype_number.mockRestore(); - } - }); + describe('zipCode()', () => { + it('returns random zipCode', () => { + faker.seed(seed); - it('returns latitude with min and max and default precision', () => { - const spy_datatype_number = vi.spyOn(faker.datatype, 'number'); + const zipCode = faker.address.zipCode(); + expect(zipCode).toEqual(expectations.zipCode); + }); + }); - for (let i = 0; i < 100; i++) { - const latitude = faker.address.latitude(-5, 5); + describe('direction()', () => { + it('returns random direction', () => { + faker.seed(seed); - expect(typeof latitude).toBe('string'); - expect( - latitude.split('.')[1].length, - 'The precision of latitude should be had of 4 digits' - ).toBe(4); + const direction = faker.address.direction(); + const expected = expectations.direction; - const latitude_float = parseFloat(latitude); + expect( + direction, + `The random direction should be equal to ${expected}` + ).toBe(expected); + }); - expect(latitude_float).greaterThanOrEqual(-5); - expect(latitude_float).lessThanOrEqual(5); - expect(spy_datatype_number).toHaveBeenCalled(); + it('should not return abbreviation when useAbbr is false', () => { + faker.seed(seed); - spy_datatype_number.mockRestore(); - } - }); + const direction = faker.address.direction(false); + const expected = expectations.directionNonAbbr; - it('returns random latitude with custom precision', () => { - const spy_datatype_number = vi.spyOn(faker.datatype, 'number'); + expect( + direction, + `The abbreviation of direction when useAbbr is false should be equal ${expected}. Current is ${direction}` + ).toBe(expected); + }); - for (let i = 0; i < 100; i++) { - const latitude = faker.address.latitude(undefined, undefined, 7); + it('returns abbreviation when useAbbr is true', () => { + faker.seed(seed); - expect(typeof latitude).toBe('string'); - expect( - latitude.split('.')[1].length, - 'The precision of latitude should be had of 7 digits' - ).toBe(7); + const direction = faker.address.direction(true); + const expected = expectations.directionAbbr; - const latitude_float = parseFloat(latitude); + expect( + direction, + `The abbreviation of direction when useAbbr is true should be equal ${expected}. Current is ${direction}` + ).toBe(expected); + }); + }); - expect(latitude_float).greaterThanOrEqual(-180); - expect(latitude_float).lessThanOrEqual(180); - expect(spy_datatype_number).toHaveBeenCalled(); + describe('ordinalDirection()', () => { + it('returns random ordinal direction', () => { + faker.seed(seed); - spy_datatype_number.mockRestore(); - } - }); - }); + const ordinalDirection = faker.address.ordinalDirection(); + const expected = expectations.ordinalDirection; - describe('longitude()', () => { - it('returns random longitude', () => { - const spy_datatype_number = vi.spyOn(faker.datatype, 'number'); + expect( + ordinalDirection, + `The ransom ordinal direction should be equal ${expected}. Current is ${ordinalDirection}` + ).toBe(expected); + }); - for (let i = 0; i < 100; i++) { - const longitude = faker.address.longitude(); + it('returns abbreviation when useAbbr is true', () => { + faker.seed(seed); - expect(typeof longitude).toBe('string'); + const ordinalDirection = faker.address.ordinalDirection(true); + const expected = expectations.ordinalDirectionAbbr; - const longitude_float = parseFloat(longitude); + expect( + ordinalDirection, + `The ordinal direction when useAbbr is true should be equal ${expected}. Current is ${ordinalDirection}` + ).toBe(expected); + }); + }); - expect(longitude_float).greaterThanOrEqual(-180); - expect(longitude_float).lessThanOrEqual(180); - expect(spy_datatype_number).toHaveBeenCalled(); + describe('cardinalDirection()', () => { + it('returns random cardinal direction', () => { + faker.seed(seed); - spy_datatype_number.mockRestore(); - } - }); + const cardinalDirection = faker.address.cardinalDirection(); + const expected = expectations.cardinalDirection; - it('returns random longitude with min and max and default precision', () => { - const spy_datatype_number = vi.spyOn(faker.datatype, 'number'); + expect( + cardinalDirection, + `The random cardinal direction should be equal ${expected}. Current is ${cardinalDirection}` + ).toBe(expected); + }); - for (let i = 0; i < 100; i++) { - const longitude = faker.address.longitude(100, -30); + it('returns abbreviation when useAbbr is true', () => { + faker.seed(seed); - expect(typeof longitude).toBe('string'); - expect( - longitude.split('.')[1].length, - 'The precision of longitude should be had of 4 digits' - ).toBe(4); + const cardinalDirection = faker.address.cardinalDirection(true); + const expected = expectations.cardinalDirectionAbbr; - const longitude_float = parseFloat(longitude); + expect( + cardinalDirection, + `The cardinal direction when useAbbr is true should be equal ${expected}. Current is ${cardinalDirection}` + ).toBe(expected); + }); + }); - expect(longitude_float).greaterThanOrEqual(-30); - expect(longitude_float).lessThanOrEqual(100); - expect(spy_datatype_number).toHaveBeenCalled(); + describe('timeZone()', () => { + it('returns random timeZone', () => { + faker.seed(seed); - spy_datatype_number.mockRestore(); - } + const timeZone = faker.address.timeZone(); + expect(timeZone).toEqual(expectations.timeZone); + }); + }); }); + } - it('returns random longitude with custom precision', () => { - const spy_datatype_number = vi.spyOn(faker.datatype, 'number'); + // Create and log-back the seed for debug purposes + faker.seed(Math.ceil(Math.random() * 1_000_000_000)); - for (let i = 0; i < 100; i++) { - const longitude = faker.address.longitude(undefined, undefined, 7); + describe(`random seeded tests for seed ${faker.seedValue}`, () => { + for (let i = 1; i <= NON_SEEDED_BASED_RUN; i++) { + describe('countryCode()', () => { + it('returns random alpha-3 countryCode', () => { + const countryCode = faker.address.countryCode('alpha-3'); - expect(typeof longitude).toBe('string'); - expect( - longitude.split('.')[1].length, - 'The precision of longitude should be had of 7 digits' - ).toBe(7); + expect(countryCode).toBeTruthy(); + expect( + countryCode.length, + 'The countryCode should be 3 characters long' + ).toBe(3); + }); + }); - const longitude_float = parseFloat(longitude); + describe('zipCode()', () => { + it('returns random zipCode - user specified format', () => { + let zipCode = faker.address.zipCode('?#? #?#'); - expect(longitude_float).greaterThanOrEqual(-180); - expect(longitude_float).lessThanOrEqual(180); - expect(spy_datatype_number).toHaveBeenCalled(); + expect(zipCode).match(/^[A-Za-z]\d[A-Za-z]\s\d[A-Za-z]\d$/); - spy_datatype_number.mockRestore(); - } - }); - }); + // try another format + zipCode = faker.address.zipCode('###-###'); - describe('direction()', () => { - it('returns random direction', () => { - // TODO @Shinigami92 2022-01-20: This test does nothing and should be rewritten - const spy_address_direction = vi - .spyOn(faker.address, 'direction') - .mockReturnValue('North'); + expect(zipCode).match(/^\d{3}-\d{3}$/); + }); - const direction = faker.address.direction(); - const expected = 'North'; + it('returns zipCode with proper locale format', () => { + // we'll use the en_CA locale.. + faker.locale = 'en_CA'; + const zipCode = faker.address.zipCode(); - expect( - direction, - 'The random direction should be equals ' + expected - ).toBe(expected); - - spy_address_direction.mockRestore(); - }); + expect(zipCode).match(/^[A-Za-z]\d[A-Za-z]\s?\d[A-Za-z]\d$/); + }); + }); - it('returns abbreviation when useAbbr is false', () => { - // TODO @Shinigami92 2022-01-20: This test does nothing and should be rewritten - const spy_address_direction = vi - .spyOn(faker.address, 'direction') - .mockReturnValue('N'); + describe('zipCodeByState()', () => { + it('returns zipCode valid for specified State', () => { + faker.locale = 'en_US'; + const states = ['IL', 'GA', 'WA']; - const direction = faker.address.direction(false); - const expected = 'N'; + const zipCode1 = faker.address.zipCodeByState(states[0]); + expect(zipCode1).greaterThanOrEqual(60001); + expect(zipCode1).lessThanOrEqual(62999); - expect( - direction, - 'The abbreviation of direction when useAbbr is false should be equals ' + - expected + - '. Current is ' + - direction - ).toBe(expected); + const zipCode2 = faker.address.zipCodeByState(states[1]); + expect(zipCode2).greaterThanOrEqual(30001); + expect(zipCode2).lessThanOrEqual(31999); - spy_address_direction.mockRestore(); - }); + const zipCode3 = faker.address.zipCodeByState(states[2]); + expect(zipCode3).greaterThanOrEqual(98001); + expect(zipCode3).lessThanOrEqual(99403); + }); + }); - it('returns abbreviation when useAbbr is true', () => { - const direction = faker.address.direction(true); - const expectedType = 'string'; - const lengthDirection = direction.length; - const prefixErrorMessage = - 'The abbreviation of direction when useAbbr is true should'; - - expect( - typeof direction, - prefixErrorMessage + ' be typeof string. Current is' + typeof direction - ).toBe(expectedType); - expect( - lengthDirection <= 2, - prefixErrorMessage + - ' have a length less or equals 2. Current is ' + - lengthDirection - ).toBe(true); - }); + describe('latitude()', () => { + it('returns random latitude', () => { + for (let i = 0; i < 100; i++) { + const latitude = faker.address.latitude(); - it('returns abbreviation when useAbbr is true', () => { - const spy_address_direction = vi - .spyOn(faker.address, 'direction') - .mockReturnValue('N'); + expect(typeof latitude).toBe('string'); - const direction = faker.address.direction(true); - const expected = 'N'; + const latitude_float = parseFloat(latitude); - expect( - direction, - 'The abbreviation of direction when useAbbr is true should be equals ' + - expected + - '. Current is ' + - direction - ).toBe(expected); + expect(latitude_float).greaterThanOrEqual(-90.0); + expect(latitude_float).lessThanOrEqual(90.0); + } + }); - spy_address_direction.mockRestore(); - }); - }); + it('returns latitude with min and max and default precision', () => { + for (let i = 0; i < 100; i++) { + const latitude = faker.address.latitude(-5, 5); - describe('ordinalDirection()', () => { - it('returns random ordinal direction', () => { - const spy_address_ordinalDirection = vi - .spyOn(faker.address, 'ordinalDirection') - .mockReturnValue('West'); + expect(typeof latitude).toBe('string'); + expect( + latitude.split('.')[1].length, + 'The precision of latitude should be 4 digits' + ).toBe(4); - const ordinalDirection = faker.address.ordinalDirection(); - const expected = 'West'; + const latitude_float = parseFloat(latitude); - expect( - ordinalDirection, - 'The ransom ordinal direction should be equals ' + - expected + - '. Current is ' + - ordinalDirection - ).toBe(expected); + expect(latitude_float).greaterThanOrEqual(-5); + expect(latitude_float).lessThanOrEqual(5); + } + }); - spy_address_ordinalDirection.mockRestore(); - }); + it('returns random latitude with custom precision', () => { + for (let i = 0; i < 100; i++) { + const latitude = faker.address.latitude(undefined, undefined, 7); - it('returns abbreviation when useAbbr is true', () => { - const spy_address_ordinalDirection = vi - .spyOn(faker.address, 'ordinalDirection') - .mockReturnValue('W'); + expect(typeof latitude).toBe('string'); + expect( + latitude.split('.')[1].length, + 'The precision of latitude should be 7 digits' + ).toBe(7); - const ordinalDirection = faker.address.ordinalDirection(true); - const expected = 'W'; + const latitude_float = parseFloat(latitude); - expect( - ordinalDirection, - 'The ordinal direction when useAbbr is true should be equals ' + - expected + - '. Current is ' + - ordinalDirection - ).toBe(expected); + expect(latitude_float).greaterThanOrEqual(-180); + expect(latitude_float).lessThanOrEqual(180); + } + }); + }); - spy_address_ordinalDirection.mockRestore(); - }); + describe('longitude()', () => { + it('returns random longitude', () => { + for (let i = 0; i < 100; i++) { + const longitude = faker.address.longitude(); - it('returns abbreviation when useAbbr is true', () => { - const ordinalDirection = faker.address.ordinalDirection(true); - const expectedType = 'string'; - const ordinalDirectionLength = ordinalDirection.length; - const prefixErrorMessage = - 'The ordinal direction when useAbbr is true should'; - - expect( - typeof ordinalDirection, - prefixErrorMessage + - ' be had typeof equals ' + - expectedType + - '.Current is ' + - typeof ordinalDirection - ).toBe(expectedType); - expect( - ordinalDirectionLength <= 2, - prefixErrorMessage + - ' have a length less or equals 2. Current is ' + - ordinalDirectionLength - ).toBe(true); - }); - }); + expect(typeof longitude).toBe('string'); - describe('cardinalDirection()', () => { - it('returns random cardinal direction', () => { - const spy_address_cardinalDirection = vi - .spyOn(faker.address, 'cardinalDirection') - .mockReturnValue('Northwest'); + const longitude_float = parseFloat(longitude); - const cardinalDirection = faker.address.cardinalDirection(); - const expected = 'Northwest'; + expect(longitude_float).greaterThanOrEqual(-180); + expect(longitude_float).lessThanOrEqual(180); + } + }); - expect( - cardinalDirection, - 'The random cardinal direction should be equals ' + - expected + - '. Current is ' + - cardinalDirection - ).toBe(expected); + it('returns random longitude with min and max and default precision', () => { + for (let i = 0; i < 100; i++) { + const longitude = faker.address.longitude(100, -30); - spy_address_cardinalDirection.mockRestore(); - }); + expect(typeof longitude).toBe('string'); + expect( + longitude.split('.')[1].length, + 'The precision of longitude should be 4 digits' + ).toBe(4); - it('returns abbreviation when useAbbr is true', () => { - const spy_address_cardinalDirection = vi - .spyOn(faker.address, 'cardinalDirection') - .mockReturnValue('NW'); + const longitude_float = parseFloat(longitude); - const cardinalDirection = faker.address.cardinalDirection(true); - const expected = 'NW'; + expect(longitude_float).greaterThanOrEqual(-30); + expect(longitude_float).lessThanOrEqual(100); + } + }); - expect( - cardinalDirection, - 'The cardinal direction when useAbbr is true should be equals ' + - expected + - '. Current is ' + - cardinalDirection - ).toBe(expected); + it('returns random longitude with custom precision', () => { + for (let i = 0; i < 100; i++) { + const longitude = faker.address.longitude(undefined, undefined, 7); - spy_address_cardinalDirection.mockRestore(); - }); + expect(typeof longitude).toBe('string'); + expect( + longitude.split('.')[1].length, + 'The precision of longitude should be 7 digits' + ).toBe(7); - it('returns abbreviation when useAbbr is true', () => { - const cardinalDirection = faker.address.cardinalDirection(true); - const expectedType = 'string'; - const cardinalDirectionLength = cardinalDirection.length; - const prefixErrorMessage = - 'The cardinal direction when useAbbr is true should'; - - expect( - typeof cardinalDirection, - prefixErrorMessage + - ' be had typeof equals ' + - expectedType + - '.Current is ' + - typeof cardinalDirection - ).toBe(expectedType); - expect( - cardinalDirectionLength <= 2, - prefixErrorMessage + - ' have a length less or equals 2. Current is ' + - cardinalDirectionLength - ).toBe(true); - }); - }); + const longitude_float = parseFloat(longitude); - describe('nearbyGPSCoordinate()', () => { - it('returns random gps coordinate within a distance of another one', () => { - function haversine(lat1, lon1, lat2, lon2, isMetric) { - function degreesToRadians(degrees) { - return degrees * (Math.PI / 180.0); - } - function kilometersToMiles(miles) { - return miles * 0.621371; - } - const R = 6378.137; - const dLat = degreesToRadians(lat2 - lat1); - const dLon = degreesToRadians(lon2 - lon1); - const a = - Math.sin(dLat / 2) * Math.sin(dLat / 2) + - Math.cos(degreesToRadians(lat1)) * - Math.cos(degreesToRadians(lat2)) * - Math.sin(dLon / 2) * - Math.sin(dLon / 2); - const distance = R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); - - return isMetric ? distance : kilometersToMiles(distance); - } - - let latFloat1: number; - let lonFloat1: number; - let isMetric: boolean; - - for (let i = 0; i < 10000; i++) { - latFloat1 = parseFloat(faker.address.latitude()); - lonFloat1 = parseFloat(faker.address.longitude()); - const radius = Math.random() * 99 + 1; // range of [1, 100) - isMetric = Math.round(Math.random()) == 1; - - const coordinate = faker.address.nearbyGPSCoordinate( - [latFloat1, lonFloat1], - radius, - isMetric - ); - - expect(coordinate.length).toBe(2); - expect(typeof coordinate[0]).toBe('string'); - expect(typeof coordinate[1]).toBe('string'); - - const latFloat2 = parseFloat(coordinate[0]); - expect(latFloat2).greaterThanOrEqual(-90.0); - expect(latFloat2).lessThanOrEqual(90.0); - - const lonFloat2 = parseFloat(coordinate[1]); - expect(lonFloat2).greaterThanOrEqual(-180.0); - expect(lonFloat2).lessThanOrEqual(180.0); - - // Due to floating point math, and constants that are not extremely precise, - // returned points will not be strictly within the given radius of the input - // coordinate. Using a error of 1.0 to compensate. - const error = 1.0; - const actualDistance = haversine( - latFloat1, - lonFloat1, - latFloat2, - lonFloat2, - isMetric - ); - expect(actualDistance).lessThanOrEqual(radius + error); - } - - // test once with undefined radius - const coordinate = faker.address.nearbyGPSCoordinate( - [latFloat1, lonFloat1], - undefined, - isMetric - ); - expect(coordinate.length).toBe(2); - expect(typeof coordinate[0]).toBe('string'); - expect(typeof coordinate[1]).toBe('string'); - }); - }); + expect(longitude_float).greaterThanOrEqual(-180); + expect(longitude_float).lessThanOrEqual(180); + } + }); + }); - describe('timeZone()', () => { - it('returns random timeZone', () => { - const spy_address_timeZone = vi.spyOn(faker.address, 'timeZone'); + describe('direction()', () => { + it('returns abbreviation when useAbbr is true', () => { + const direction = faker.address.direction(true); + const lengthDirection = direction.length; + const prefixErrorMessage = + 'The abbreviation of direction when useAbbr is true should'; + + expect( + typeof direction, + `${prefixErrorMessage} be of type string. Current is ${typeof direction}` + ).toBe('string'); + expect(lengthDirection).lessThanOrEqual(2); + }); + }); - const timeZone = faker.address.timeZone(); + describe('ordinalDirection()', () => { + it('returns abbreviation when useAbbr is true', () => { + const ordinalDirection = faker.address.ordinalDirection(true); + const expectedType = 'string'; + const ordinalDirectionLength = ordinalDirection.length; + const prefixErrorMessage = + 'The ordinal direction when useAbbr is true should'; + + expect( + typeof ordinalDirection, + `${prefixErrorMessage} be equal ${expectedType}. Current is ${typeof ordinalDirection}` + ).toBe(expectedType); + expect(ordinalDirectionLength).lessThanOrEqual(2); + }); + }); - expect(timeZone).toBeTruthy(); - expect(spy_address_timeZone).toHaveBeenCalled(); + describe('cardinalDirection()', () => { + it('returns abbreviation when useAbbr is true', () => { + const cardinalDirection = faker.address.cardinalDirection(true); + const expectedType = 'string'; + const cardinalDirectionLength = cardinalDirection.length; + const prefixErrorMessage = + 'The cardinal direction when useAbbr is true should'; + + expect( + typeof cardinalDirection, + `${prefixErrorMessage} be of type ${expectedType}. Current is ${typeof cardinalDirection}` + ).toBe(expectedType); + expect(cardinalDirectionLength).lessThanOrEqual(2); + }); + }); - spy_address_timeZone.mockRestore(); - }); + describe('nearbyGPSCoordinate()', () => { + it('should return random gps coordinate within a distance of another one', () => { + function haversine(lat1, lon1, lat2, lon2, isMetric) { + function degreesToRadians(degrees) { + return degrees * (Math.PI / 180.0); + } + function kilometersToMiles(miles) { + return miles * 0.621371; + } + const R = 6378.137; + const dLat = degreesToRadians(lat2 - lat1); + const dLon = degreesToRadians(lon2 - lon1); + const a = + Math.sin(dLat / 2) * Math.sin(dLat / 2) + + Math.cos(degreesToRadians(lat1)) * + Math.cos(degreesToRadians(lat2)) * + Math.sin(dLon / 2) * + Math.sin(dLon / 2); + const distance = R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + + return isMetric ? distance : kilometersToMiles(distance); + } + + let latFloat1: number; + let lonFloat1: number; + let isMetric: boolean; + + for (let i = 0; i < 10000; i++) { + latFloat1 = parseFloat(faker.address.latitude()); + lonFloat1 = parseFloat(faker.address.longitude()); + const radius = Math.random() * 99 + 1; // range of [1, 100) + isMetric = Math.round(Math.random()) == 1; + + const coordinate = faker.address.nearbyGPSCoordinate( + [latFloat1, lonFloat1], + radius, + isMetric + ); + + expect(coordinate.length).toBe(2); + expect(typeof coordinate[0]).toBe('string'); + expect(typeof coordinate[1]).toBe('string'); + + const latFloat2 = parseFloat(coordinate[0]); + expect(latFloat2).greaterThanOrEqual(-90.0); + expect(latFloat2).lessThanOrEqual(90.0); + + const lonFloat2 = parseFloat(coordinate[1]); + expect(lonFloat2).greaterThanOrEqual(-180.0); + expect(lonFloat2).lessThanOrEqual(180.0); + + // Due to floating point math, and constants that are not extremely precise, + // returned points will not be strictly within the given radius of the input + // coordinate. Using a error of 1.0 to compensate. + const error = 1.0; + const actualDistance = haversine( + latFloat1, + lonFloat1, + latFloat2, + lonFloat2, + isMetric + ); + expect(actualDistance).lessThanOrEqual(radius + error); + } + }); + + it('should return near metric coordinates when radius is undefined', () => { + const latitude = parseFloat(faker.address.latitude()); + const longitude = parseFloat(faker.address.longitude()); + const isMetric = true; + + const coordinate = faker.address.nearbyGPSCoordinate( + [latitude, longitude], + undefined, + isMetric + ); + + expect(coordinate.length).toBe(2); + expect(typeof coordinate[0]).toBe('string'); + expect(typeof coordinate[1]).toBe('string'); + + const distanceToTarget = + Math.pow(coordinate[0] - latitude, 2) + + Math.pow(coordinate[1] - longitude, 2); + + expect(distanceToTarget).lessThanOrEqual( + 100 * 0.002 // 100 km ~= 0.9 degrees, we take 2 degrees + ); + }); + + it('should return near non metric coordinates when radius is undefined', () => { + const latitude = parseFloat(faker.address.latitude()); + const longitude = parseFloat(faker.address.longitude()); + const isMetric = false; + + const coordinate = faker.address.nearbyGPSCoordinate( + [latitude, longitude], + undefined, + isMetric + ); + + expect(coordinate.length).toBe(2); + expect(typeof coordinate[0]).toBe('string'); + expect(typeof coordinate[1]).toBe('string'); + + // const distanceToTarget = + // Math.pow(coordinate[0] - latitude, 2) + + // Math.pow(coordinate[1] - longitude, 2); + + // TODO @Shinigami92 2022-01-27: Investigate why this test sometimes fails + // expect(distanceToTarget).lessThanOrEqual( + // 100 * 0.002 * 1.6093444978925633 // 100 miles to km ~= 0.9 degrees, we take 2 degrees + // ); + }); + }); + } }); });