Skip to content

Commit

Permalink
feat: πŸ”₯ Allow devs to pass in comparison functions
Browse files Browse the repository at this point in the history
Add default comparison functions for most likely use cases. Implimented
them

βœ… Closes: #220
  • Loading branch information
theryansmee committed Mar 23, 2022
1 parent bbe7b0b commit 7f69bad
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 30 deletions.
24 changes: 18 additions & 6 deletions packages/falso/src/lib/core/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,22 @@ type Return<T, O extends FakeOptions> = [O] extends [never]

export function fake<T, Options extends FakeOptions>(
data: T[] | (() => T),
options?: Options
options?: Options,
comparisonFunction: (
item: T,
items: T[]
) => boolean = primitiveComparisonFunction
): Return<T, Options> {
if (Array.isArray(data)) {
return fakeFromArray(data, options) as any;
}

return fakeFromFunction(data, options) as any;
return fakeFromFunction(data, comparisonFunction, options) as any;
}

export function fakeFromFunction<T, Options extends FakeOptions>(
data: () => T,
comparisonFunction: (item: T, items: T[]) => boolean,
options?: Options
) {
if (!options?.length) {
Expand All @@ -44,7 +49,7 @@ export function fakeFromFunction<T, Options extends FakeOptions>(
while (items.length < options.length && attempts < maxAttempts) {
const item = data();

if (!items.includes(item)) {
if (!comparisonFunction(item, items)) {
items.push(item);
}

Expand All @@ -65,9 +70,7 @@ export function fakeFromArray<T, Options extends FakeOptions>(
const priority = options?.priority ?? 'length';

if (priority === 'length') {
return Array.from({ length: options.length }, (_, index) =>
randElement(data)
);
return Array.from({ length: options.length }, () => randElement(data));
}

const clonedData: T[] = JSON.parse(JSON.stringify(data));
Expand All @@ -84,6 +87,15 @@ export function fakeFromArray<T, Options extends FakeOptions>(
return newArray;
}

export const primitiveComparisonFunction: <T>(item: T, items: T[]) => boolean =
(item, items) => items.includes(item);
export const objectWithIdComparisonFunction: <T extends { id: string }>(
item: T,
items: T[]
) => boolean = (item, items) => {
return items.some((i) => i.id === item.id);
};

export function randElement<T>(arr: T[]): T {
return arr[Math.floor(random() * arr.length)];
}
Expand Down
8 changes: 5 additions & 3 deletions packages/falso/src/lib/post.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FakeOptions, fake } from './core/core';
import { FakeOptions, fake, objectWithIdComparisonFunction } from './core/core';
import { randUser, User } from './user';
import { randUuid } from './uuid';
import { randText } from './text';
Expand Down Expand Up @@ -28,7 +28,7 @@ export interface Post {
export function randPost<Options extends FakeOptions = never>(
options?: Options
) {
return fake(() => {
const factory = () => {
const post: Post = {
id: randUuid(),
title: randText({ charCount: 40 }),
Expand All @@ -43,5 +43,7 @@ export function randPost<Options extends FakeOptions = never>(
};

return post;
}, options);
};

return fake(factory, options, objectWithIdComparisonFunction);
}
36 changes: 20 additions & 16 deletions packages/falso/src/lib/product.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { FakeOptions, fake, getRandomInRange } from './core/core';
import {
FakeOptions,
fake,
getRandomInRange,
objectWithIdComparisonFunction,
} from './core/core';
import { randUuid } from './uuid';
import { randProductName } from './product-name';
import { randProductDescription } from './product-description';
Expand Down Expand Up @@ -35,19 +40,18 @@ export interface Product {
export function randProduct<Options extends FakeOptions = never>(
options?: Options
) {
return fake(
() => ({
id: randUuid(),
title: randProductName(),
description: randProductDescription(),
price: getRandomInRange({ fraction: 2 }).toString(),
category: randProductCategory(),
image: randImg(),
rating: {
rate: getRandomInRange({ min: 0.1, max: 5.0, fraction: 1 }).toString(),
count: getRandomInRange({ min: 0, max: 10000 }).toString(),
},
}),
options
);
const factory = () => ({
id: randUuid(),
title: randProductName(),
description: randProductDescription(),
price: getRandomInRange({ fraction: 2 }).toString(),
category: randProductCategory(),
image: randImg(),
rating: {
rate: getRandomInRange({ min: 0.1, max: 5.0, fraction: 1 }).toString(),
count: getRandomInRange({ min: 0, max: 10000 }).toString(),
},
});

return fake(factory, options, objectWithIdComparisonFunction);
}
9 changes: 7 additions & 2 deletions packages/falso/src/lib/superhero.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { fake, FakeOptions, randElement } from './core/core';
import {
fake,
FakeOptions,
objectWithIdComparisonFunction,
randElement,
} from './core/core';
import { data } from './superhero.json';
import { randUuid } from './uuid';

Expand Down Expand Up @@ -50,5 +55,5 @@ export function randSuperhero<Options extends SuperheroOptions = never>(
};
};

return fake(factory, options);
return fake(factory, options, objectWithIdComparisonFunction);
}
8 changes: 5 additions & 3 deletions packages/falso/src/lib/user.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { fake, FakeOptions } from './core/core';
import { fake, FakeOptions, objectWithIdComparisonFunction } from './core/core';
import { randUuid } from './uuid';
import { randEmail } from './email';
import { randFirstName } from './first-name';
Expand Down Expand Up @@ -40,7 +40,7 @@ export interface User {
export function randUser<Options extends FakeOptions = never>(
options?: Options
) {
return fake(() => {
const factory = () => {
const firstName = randFirstName({ withAccents: false });
const lastName = randLastName({ withAccents: false });

Expand All @@ -56,5 +56,7 @@ export function randUser<Options extends FakeOptions = never>(
};

return user;
}, options);
};

return fake(factory, options, objectWithIdComparisonFunction);
}

0 comments on commit 7f69bad

Please sign in to comment.