interface-forge
Version:
A TypeScript library for creating strongly typed mock data factories using Faker.js for test data generation
151 lines (128 loc) • 4.08 kB
text/typescript
/**
* Circular References Example
*
* This example demonstrates how to handle circular references
* using the use() method for lazy evaluation.
*/
import { Factory } from 'interface-forge';
interface Department {
employees: Employee[];
id: string;
manager: Employee;
name: string;
}
interface Employee {
department: Department;
id: string;
name: string;
subordinates: Employee[];
supervisor?: Employee;
}
interface Post {
author: User;
content: string;
id: string;
relatedPosts: Post[];
title: string;
}
interface User {
favoritePost?: Post;
id: string;
name: string;
posts: Post[];
}
const UserFactory: Factory<User> = new Factory<User>((faker) => ({
favoritePost: faker.use(() => PostFactory.build()),
id: faker.string.uuid(),
name: faker.person.fullName(),
posts: faker.use(() => PostFactory.batch(3)),
}));
const PostFactory: Factory<Post> = new Factory<Post>((faker) => ({
author: faker.use(() => UserFactory.build()),
content: faker.lorem.paragraphs(2),
id: faker.string.uuid(),
relatedPosts: faker.use(() => PostFactory.batch(2)),
title: faker.lorem.sentence(),
}));
const user = UserFactory.build();
console.log('User:', user.name);
console.log('Posts by user:', user.posts.length);
console.log('Favorite post:', user.favoritePost?.title);
const DepartmentFactory: Factory<Department> = new Factory<Department>(
(faker) => ({
employees: faker.use(() => EmployeeFactory.batch(5)),
id: faker.string.uuid(),
manager: faker.use(() => EmployeeFactory.build()),
name: faker.commerce.department(),
}),
);
const EmployeeFactory: Factory<Employee> = new Factory<Employee>((faker) => ({
department: faker.use(() => DepartmentFactory.build()),
id: faker.string.uuid(),
name: faker.person.fullName(),
subordinates: faker.use(() =>
EmployeeFactory.batch(faker.number.int({ max: 3, min: 0 })),
),
supervisor: faker.datatype.boolean({ probability: 0.8 })
? faker.use(() => EmployeeFactory.build())
: undefined,
}));
const LimitedUserFactory: Factory<User> = new Factory<User>(
(faker) => ({
favoritePost: undefined,
id: faker.string.uuid(),
name: faker.person.fullName(),
posts: faker.use(() => LimitedPostFactory.batch(2)),
}),
{ maxDepth: 3 },
);
const LimitedPostFactory: Factory<Post> = new Factory<Post>(
(faker) => ({
author: faker.use(() => LimitedUserFactory.build()),
content: faker.lorem.paragraphs(2),
id: faker.string.uuid(),
relatedPosts: faker.use(() => LimitedPostFactory.batch(1)),
title: faker.lorem.sentence(),
}),
{ maxDepth: 3 },
);
const limitedUser = LimitedUserFactory.build();
console.log('Limited depth user:', limitedUser);
const createUserWithOwnPosts = () => {
const user = UserFactory.build({ favoritePost: undefined, posts: [] });
const posts = PostFactory.batch(3, { author: user });
user.posts = posts;
[user.favoritePost] = posts;
return user;
};
const userWithOwnPosts = createUserWithOwnPosts();
console.log(
'User owns all posts:',
userWithOwnPosts.posts.every(
(post: Post) => post.author.id === userWithOwnPosts.id,
),
);
interface GraphNode {
connections: GraphNode[];
id: string;
value: number;
}
const GraphNodeFactory: Factory<GraphNode> = new Factory<GraphNode>(
(faker) => ({
connections: faker.use(() =>
GraphNodeFactory.batch(faker.number.int({ max: 3, min: 0 })),
),
id: faker.string.uuid(),
value: faker.number.int({ max: 100, min: 1 }),
}),
);
const graphRoot = new Factory<GraphNode>(
(faker) => ({
connections: faker.use(() => GraphNodeFactory.batch(3)),
id: faker.string.uuid(),
value: faker.number.int({ max: 100, min: 1 }),
}),
{ maxDepth: 2 },
).build();
console.log('Graph root node:', graphRoot.id);
console.log('Direct connections:', graphRoot.connections.length);