From 238afa76bf8d1417792965b853e2f8f9ed18ea6b Mon Sep 17 00:00:00 2001 From: Shinigami92 Date: Tue, 25 Jan 2022 14:31:11 +0100 Subject: [PATCH 1/4] test: rewrite commerce tests --- test/commerce.spec.ts | 332 +++++++++++++++++++++++------------------- 1 file changed, 183 insertions(+), 149 deletions(-) diff --git a/test/commerce.spec.ts b/test/commerce.spec.ts index e03b3bb7e2d..1f6710785a9 100644 --- a/test/commerce.spec.ts +++ b/test/commerce.spec.ts @@ -1,158 +1,192 @@ -import { describe, expect, it, vi } from 'vitest'; +import { afterEach, describe, expect, it, vi } from 'vitest'; import { faker } from '../dist/cjs'; -describe('commerce', () => { - describe('color()', () => { - it('returns random value from commerce.color array', () => { - const color = faker.commerce.color(); - expect(faker.definitions.commerce.color).toContain(color); - }); - }); - - describe('department(max, fixedValue)', () => { - it('should use the default amounts when not passing arguments', () => { - const department = faker.commerce.department(); - expect(department.split(' ')).toHaveLength(1); - }); - - /* - - it("should return only one value if we specify a maximum of one", function() { - sinon.spy(faker.random, 'arrayElement'); - - const department = faker.commerce.department(1); - - assert.strictEqual(department.split(" ").length, 1); - assert.ok(faker.random.arrayElement.calledOnce); - - faker.random.arrayElement.restore(); - }); - - it("should return the maximum value if we specify the fixed value", function() { - sinon.spy(faker.random, 'arrayElement'); - - const department = faker.commerce.department(5, true); - - console.log(department); - - // account for the separator - assert.strictEqual(department.split(" ").length, 6); - // Sometimes it will generate duplicates that aren't used in the final string, - // so we check if arrayElement has been called exactly or more than 5 times - assert.ok(faker.random.arrayElement.callCount >= 5); - - faker.random.arrayElement.restore(); - }); - */ - }); - - describe('productName()', () => { - it('returns name comprising of an adjective, material and product', () => { - const spy_random_arrayElement = vi.spyOn(faker.random, 'arrayElement'); - const spy_commerce_productAdjective = vi.spyOn( - faker.commerce, - 'productAdjective' - ); - const spy_commerce_productMaterial = vi.spyOn( - faker.commerce, - 'productMaterial' - ); - const spy_commerce_product = vi.spyOn(faker.commerce, 'product'); - - const name = faker.commerce.productName(); - - expect(name.split(' ').length).greaterThanOrEqual(3); - - expect(spy_random_arrayElement).toHaveBeenCalledTimes(3); - expect(spy_commerce_productAdjective).toHaveBeenCalledOnce(); - expect(spy_commerce_productMaterial).toHaveBeenCalledOnce(); - expect(spy_commerce_product).toHaveBeenCalledOnce(); - - spy_random_arrayElement.mockRestore(); - spy_commerce_productAdjective.mockRestore(); - spy_commerce_productMaterial.mockRestore(); - spy_commerce_product.mockRestore(); - }); - }); +const seededRuns = [ + { + seed: 42, + expectations: { + color: 'grey', + department: 'Tools', + productName: 'Fantastic Soft Sausages', + price: '375.00', + productAdjective: 'Fantastic', + productMaterial: 'Cotton', + product: 'Pants', + productDescription: + 'The Apollotech B340 is an affordable wireless mouse with reliable connectivity, 12 months battery life and modern design', + }, + }, + { + seed: 1337, + expectations: { + color: 'black', + department: 'Computers', + productName: 'Gorgeous Rubber Keyboard', + price: '263.00', + productAdjective: 'Gorgeous', + productMaterial: 'Concrete', + product: 'Ball', + productDescription: + 'The slim & simple Maple Gaming Keyboard from Dev Byte comes with a sleek body and 7- Color RGB LED Back-lighting for smart functionality', + }, + }, + { + seed: 1211, + expectations: { + color: 'azure', + department: 'Automotive', + productName: 'Unbranded Granite Salad', + price: '929.00', + productAdjective: 'Unbranded', + productMaterial: 'Frozen', + product: 'Sausages', + productDescription: + 'Andy shoes are designed to keeping in mind durability as well as trends, the most stylish range of shoes & sandals', + }, + }, +]; + +const NON_SEEDED_BASED_RUN = 5; + +const functionNames = [ + 'color', + 'department', + 'productName', + 'price', + 'productAdjective', + 'productMaterial', + 'product', + 'productDescription', +]; - describe('price(min, max, dec, symbol)', () => { - it('should use the default amounts when not passing arguments', () => { - const price = faker.commerce.price(); - - expect(price).toBeTruthy(); - // TODO @Shinigami92 2022-01-20: I converted the price string to number to satisfy TS - expect(+price > 0, 'the amount should be greater than 0').toBe(true); - expect(+price < 1001, 'the amount should be less than 1000').toBe(true); - }); - - it('should use the default decimal location when not passing arguments', () => { - const price = faker.commerce.price(); - - const decimal = '.'; - const expected = price.length - 3; - const actual = price.indexOf(decimal); - - expect( - actual, - 'The expected location of the decimal is ' + - expected + - ' but it was ' + - actual + - ' amount ' + - price - ).toBe(expected); - }); - - it('should not include a currency symbol by default', () => { - const amount = faker.commerce.price(); - - const regexp = new RegExp(/[0-9.]/); - - const expected = true; - const actual = regexp.test(amount); - - expect( - actual, - 'The expected match should not include a currency symbol' - ).toBe(expected); - }); - - it('it should handle negative amounts, but return 0', () => { - const amount = faker.commerce.price(-200, -1); - - expect(amount).toBeTruthy(); - // TODO @Shinigami92 2022-01-20: I converted the price string to number to satisfy TS - expect(+amount === 0.0, 'the amount should equal 0').toBe(true); - }); - - it('it should handle argument dec', () => { - const price = faker.commerce.price(100, 100, 1); - - expect(price).toBeTruthy(); - expect(price, 'the price should be equal 100.0').toStrictEqual('100.0'); - }); - - it('it should handle argument dec = 0', () => { - const price = faker.commerce.price(100, 100, 0); - - expect(price).toBeTruthy(); - expect(price, 'the price should be equal 100').toStrictEqual('100'); - }); +describe('commerce', () => { + afterEach(() => { + faker.locale = 'en'; }); - describe('productDescription()', () => { - it('returns a random product description', () => { - const spy_commerce_productDescription = vi.spyOn( - faker.commerce, - 'productDescription' - ); - - const description = faker.commerce.productDescription(); - - expect(typeof description).toBe('string'); - expect(spy_commerce_productDescription).toHaveBeenCalledOnce(); + for (let { seed, expectations } of seededRuns) { + describe(`seed: ${seed}`, () => { + for (const functionName of functionNames) { + it(`${functionName}()`, () => { + faker.seed(seed); - spy_commerce_productDescription.mockRestore(); + const actual = faker.commerce[functionName](); + expect(actual).toEqual(expectations[functionName]); + }); + } }); + } + + describe('non seed-based tests', () => { + for (let i = 1; i <= NON_SEEDED_BASED_RUN; i++) { + describe(`color()`, () => { + it('should return random value from color array', () => { + const actual = faker.commerce.color(); + expect(faker.definitions.commerce.color).toContain(actual); + }); + }); + + describe(`department()`, () => { + it('', () => { + const department = faker.commerce.department(); + expect(department.split(' ')).toHaveLength(1); + }); + }); + + describe(`productName()`, () => { + it('', () => { + const name = faker.commerce.productName(); + expect(name.split(' ').length).greaterThanOrEqual(3); + }); + }); + + describe(`price()`, () => { + it('should use the default amounts when not passing arguments', () => { + const price = faker.commerce.price(); + + expect(price).toBeTruthy(); + // TODO @Shinigami92 2022-01-20: I converted the price string to number to satisfy TS + expect(+price > 0, 'the amount should be greater than 0').toBe(true); + expect(+price < 1001, 'the amount should be less than 1000').toBe( + true + ); + }); + + it('should use the default decimal location when not passing arguments', () => { + const price = faker.commerce.price(); + + const decimal = '.'; + const expected = price.length - 3; + const actual = price.indexOf(decimal); + + expect( + actual, + 'The expected location of the decimal is ' + + expected + + ' but it was ' + + actual + + ' amount ' + + price + ).toBe(expected); + }); + + it('should not include a currency symbol by default', () => { + const amount = faker.commerce.price(); + + const regexp = new RegExp(/[0-9.]/); + + const expected = true; + const actual = regexp.test(amount); + + expect( + actual, + 'The expected match should not include a currency symbol' + ).toBe(expected); + }); + + it('it should handle negative amounts, but return 0', () => { + const amount = faker.commerce.price(-200, -1); + + expect(amount).toBeTruthy(); + // TODO @Shinigami92 2022-01-20: I converted the price string to number to satisfy TS + expect(+amount === 0.0, 'the amount should equal 0').toBe(true); + }); + + it('it should handle argument dec', () => { + const price = faker.commerce.price(100, 100, 1); + + expect(price).toBeTruthy(); + expect(price, 'the price should be equal 100.0').toStrictEqual( + '100.0' + ); + }); + + it('it should handle argument dec = 0', () => { + const price = faker.commerce.price(100, 100, 0); + + expect(price).toBeTruthy(); + expect(price, 'the price should be equal 100').toStrictEqual('100'); + }); + }); + + describe(`productAdjective()`, () => { + it('', () => {}); + }); + + describe(`productMaterial()`, () => { + it('', () => {}); + }); + + describe(`product()`, () => { + it('', () => {}); + }); + + describe(`productDescription()`, () => { + it('should return a random product description', () => { + const description = faker.commerce.productDescription(); + expect(typeof description).toBe('string'); + }); + }); + } }); }); From e87415ea581bc1962303caa6814abf66189dbb7b Mon Sep 17 00:00:00 2001 From: Shinigami92 Date: Tue, 25 Jan 2022 14:50:28 +0100 Subject: [PATCH 2/4] test: improve --- test/commerce.spec.ts | 76 ++++++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 29 deletions(-) diff --git a/test/commerce.spec.ts b/test/commerce.spec.ts index 1f6710785a9..f1e4135f2e8 100644 --- a/test/commerce.spec.ts +++ b/test/commerce.spec.ts @@ -87,16 +87,27 @@ describe('commerce', () => { }); describe(`department()`, () => { - it('', () => { + it('should return random value from department array', () => { const department = faker.commerce.department(); - expect(department.split(' ')).toHaveLength(1); + expect(faker.definitions.commerce.department).toContain(department); }); }); describe(`productName()`, () => { - it('', () => { + it('should return random values from product arrays', () => { const name = faker.commerce.productName(); expect(name.split(' ').length).greaterThanOrEqual(3); + + const parts = name.split(' '); + expect(faker.definitions.commerce.product_name.adjective).toContain( + parts[0] + ); + expect(faker.definitions.commerce.product_name.material).toContain( + parts[1] + ); + expect(faker.definitions.commerce.product_name.product).toContain( + parts[2] + ); }); }); @@ -105,11 +116,10 @@ describe('commerce', () => { const price = faker.commerce.price(); expect(price).toBeTruthy(); + // TODO @Shinigami92 2022-01-20: I converted the price string to number to satisfy TS - expect(+price > 0, 'the amount should be greater than 0').toBe(true); - expect(+price < 1001, 'the amount should be less than 1000').toBe( - true - ); + expect(+price).greaterThan(0); + expect(+price).lessThanOrEqual(1000); }); it('should use the default decimal location when not passing arguments', () => { @@ -117,34 +127,25 @@ describe('commerce', () => { const decimal = '.'; const expected = price.length - 3; + const actual = price.indexOf(decimal); expect( actual, - 'The expected location of the decimal is ' + - expected + - ' but it was ' + - actual + - ' amount ' + - price + `The expected location of the decimal is ${expected} but it was ${actual} amount ${price}` ).toBe(expected); }); it('should not include a currency symbol by default', () => { const amount = faker.commerce.price(); - const regexp = new RegExp(/[0-9.]/); - - const expected = true; - const actual = regexp.test(amount); - expect( - actual, + amount, 'The expected match should not include a currency symbol' - ).toBe(expected); + ).match(/[0-9.]/); }); - it('it should handle negative amounts, but return 0', () => { + it('should handle negative amounts, but return 0', () => { const amount = faker.commerce.price(-200, -1); expect(amount).toBeTruthy(); @@ -152,7 +153,7 @@ describe('commerce', () => { expect(+amount === 0.0, 'the amount should equal 0').toBe(true); }); - it('it should handle argument dec', () => { + it('should handle argument dec', () => { const price = faker.commerce.price(100, 100, 1); expect(price).toBeTruthy(); @@ -161,7 +162,7 @@ describe('commerce', () => { ); }); - it('it should handle argument dec = 0', () => { + it('should handle argument dec = 0', () => { const price = faker.commerce.price(100, 100, 0); expect(price).toBeTruthy(); @@ -170,21 +171,38 @@ describe('commerce', () => { }); describe(`productAdjective()`, () => { - it('', () => {}); + it('should return random value from product adjective array', () => { + const actual = faker.commerce.productAdjective(); + expect(faker.definitions.commerce.product_name.adjective).toContain( + actual + ); + }); }); describe(`productMaterial()`, () => { - it('', () => {}); + it('should return random value from product material array', () => { + const actual = faker.commerce.productMaterial(); + expect(faker.definitions.commerce.product_name.material).toContain( + actual + ); + }); }); describe(`product()`, () => { - it('', () => {}); + it('should return random value from product array', () => { + const actual = faker.commerce.product(); + expect(faker.definitions.commerce.product_name.product).toContain( + actual + ); + }); }); describe(`productDescription()`, () => { - it('should return a random product description', () => { - const description = faker.commerce.productDescription(); - expect(typeof description).toBe('string'); + it('should return random value from product description array', () => { + const actual = faker.commerce.productDescription(); + expect(faker.definitions.commerce.product_description).toContain( + actual + ); }); }); } From 5db164dfea16b819b0d61aa8f2d62649224ee6e2 Mon Sep 17 00:00:00 2001 From: Shinigami92 Date: Tue, 25 Jan 2022 14:53:00 +0100 Subject: [PATCH 3/4] chore: format --- test/commerce.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/commerce.spec.ts b/test/commerce.spec.ts index f1e4135f2e8..e339d011260 100644 --- a/test/commerce.spec.ts +++ b/test/commerce.spec.ts @@ -1,4 +1,4 @@ -import { afterEach, describe, expect, it, vi } from 'vitest'; +import { afterEach, describe, expect, it } from 'vitest'; import { faker } from '../dist/cjs'; const seededRuns = [ From 9eb93f14a808690df2f02b60d6be91119d167589 Mon Sep 17 00:00:00 2001 From: Shinigami92 Date: Tue, 25 Jan 2022 18:11:49 +0100 Subject: [PATCH 4/4] test: use a random generated seed for random-tests --- test/commerce.spec.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/commerce.spec.ts b/test/commerce.spec.ts index e339d011260..8041982a690 100644 --- a/test/commerce.spec.ts +++ b/test/commerce.spec.ts @@ -77,7 +77,10 @@ describe('commerce', () => { }); } - describe('non seed-based tests', () => { + // 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(`color()`, () => { it('should return random value from color array', () => {