Skip to content

Commit

Permalink
[#12697] Create generic builder (#12698)
Browse files Browse the repository at this point in the history
* create generic builder
  • Loading branch information
cedricongjh authored Feb 9, 2024
1 parent 887af1c commit 1b4ed92
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { ViewRolePrivilegesModalComponent } from './view-role-privileges-modal/v
import { CourseService } from '../../../services/course.service';
import { InstructorService } from '../../../services/instructor.service';
import { SimpleModalService } from '../../../services/simple-modal.service';
import { instructorBuilder } from '../../../test-helpers/generic-builder';
import { createMockNgbModalRef } from '../../../test-helpers/mock-ngb-modal-ref';
import { Course, Instructor, InstructorPermissionRole, JoinState } from '../../../types/api-output';
import { InstructorCreateRequest } from '../../../types/api-request';
Expand All @@ -41,26 +42,19 @@ const testCourse: Course = {
deletionTimestamp: 1000,
};

const testInstructor1: Instructor = {
courseId: 'exampleId',
email: '[email protected]',
joinState: JoinState.JOINED,
name: 'Instructor 1',
};
const testInstructor1: Instructor = instructorBuilder.email('[email protected]').name('Instructor 1').build();

const testInstructor2: Instructor = {
courseId: 'exampleId',
email: '[email protected]',
joinState: JoinState.NOT_JOINED,
name: 'Instructor 2',
};
const testInstructor2 = instructorBuilder
.email('[email protected]')
.joinState(JoinState.NOT_JOINED)
.name('Instructor 2')
.build();

const testInstructor3: Instructor = {
courseId: 'exampleId',
email: '[email protected]',
joinState: JoinState.NOT_JOINED,
name: 'Instructor 3',
};
const testInstructor3 = instructorBuilder
.email('[email protected]')
.joinState(JoinState.NOT_JOINED)
.name('Instructor 3')
.build();

const emptyInstructorPanel: InstructorEditPanel = {
googleId: '',
Expand Down
61 changes: 61 additions & 0 deletions src/web/test-helpers/generic-builder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { Course, Instructor, JoinState } from '../types/api-output';

type GenericBuilder<T> = {
[K in keyof T]: (value: T[K]) => GenericBuilder<T>;
} & { build(): T };

/**
* A generic builder function that creates a builder object for constructing objects with specified initial values.
*
* @template T - The type of object being constructed.
* @param initialValues - The initial values for the object being constructed.
* @returns A generic builder object.
* @example
* // Create a course builder with initial values.
* const courseBuilder = createBuilder<Course>({
* courseId: 'exampleId',
* courseName: '',
* timeZone: '',
* institute: '',
* creationTimestamp: 0,
* deletionTimestamp: 0,
* });
*
* // Usage of builder:
* const myCourse = courseBuilder
* .courseName('Introduction to TypeScript')
* .timeZone('UTC+0')
* .institute('My University')
* .creationTimestamp(Date.now())
* .build();
*/
export function createBuilder<T extends object>(initialValues: T): GenericBuilder<T> {
const builder: any = {};

(Object.keys(initialValues) as (keyof T)[]).forEach((key) => {
builder[key] = (value: T[keyof T]) => {
initialValues[key] = value;
return builder;
};
});

builder.build = () => ({ ...initialValues });

return builder;
}

export const courseBuilder = createBuilder<Course>({
courseId: 'exampleId',
courseName: '',
timeZone: '',
institute: '',
creationTimestamp: 0,
deletionTimestamp: 0,
});

export const instructorBuilder = createBuilder<Instructor>({
courseId: 'exampleId',
email: '',
name: '',
joinState: JoinState.JOINED,
});

0 comments on commit 1b4ed92

Please sign in to comment.