-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: tests and general structure (#7)
* refactor: naming * refactor(FML): mega refactor * refactor(handlers): logics and more handlers * fix(primitives): throw an error when type mismatch * fix(circularity): remove ciruclarity protection because reflect-metadata protection * test(handlers): added unit test for callback handler * test(handlers): add enum unit test and fix callback one * test(handlers): add some more tests for handlers * refactor(naming): changed some names * test: more coverage and renaming * chore(release-settings): change startegy to work with v-* and not with master * test(reflector): add class reflector test coverage * test: added integration test, increased coverage
- Loading branch information
Showing
46 changed files
with
1,077 additions
and
649 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { ClassReflector } from './class-reflector'; | ||
import { CallbackValueHandler } from './handlers/callback-value-handler'; | ||
import { ObjectLiteralValueHandler } from './handlers/object-literal-value-handler'; | ||
import { EnumValueHandler } from './handlers/enum-value-handler'; | ||
import { MultiClassValueHandler } from './handlers/multi-class-value-handler'; | ||
import { SingleClassValueHandler } from './handlers/single-class-value-handler'; | ||
import { PrimitiveValueHandler } from './handlers/primitive-value-handler'; | ||
import { ClassLiteral, ClassType, FixtureOptions } from './types/fixture-options.type'; | ||
import { PropertyDto } from './types/property-dto.interface'; | ||
import { ValueHandler } from './types/value-handler.interface'; | ||
import { IClassProcessor } from './types/iclass-processor.interface'; | ||
|
||
import FakerStatic = Faker.FakerStatic; | ||
|
||
export class ClassProcessor<T> implements IClassProcessor<T> { | ||
private static readonly VALUE_INSPECTORS: ClassType<ValueHandler<FixtureOptions>>[] = [ | ||
EnumValueHandler, | ||
MultiClassValueHandler, | ||
SingleClassValueHandler, | ||
CallbackValueHandler, | ||
ObjectLiteralValueHandler, | ||
PrimitiveValueHandler, | ||
]; | ||
|
||
public static readonly DEFAULT_LOCALE = 'en'; | ||
|
||
public constructor(private readonly faker: FakerStatic, private readonly reflector: ClassReflector, locale: string) { | ||
this.faker.setLocale(locale); | ||
} | ||
|
||
private handlePropertyValue(propertyDto: PropertyDto<FixtureOptions>): T | T[] { | ||
for (const inspectorClass of ClassProcessor.VALUE_INSPECTORS) { | ||
const inspector = new inspectorClass(this.faker, this) as ValueHandler<FixtureOptions>; | ||
|
||
if (inspector.shouldHandle(propertyDto)) { | ||
return inspector.produceValue<T>(propertyDto); | ||
} | ||
} | ||
|
||
return null; | ||
} | ||
|
||
/** | ||
* Return an object from the target class with all the properties | ||
* decorated by the 'Fixture' Decorator | ||
* | ||
* @param target | ||
*/ | ||
public process(target: ClassType<T>): ClassLiteral<T> { | ||
if (!target) { | ||
throw new Error(`Target class '${target}' is 'undefined'`); | ||
} | ||
|
||
const classReflection = this.reflector.reflectClass(target); | ||
|
||
return classReflection.reduce((acc, val) => { | ||
return { ...acc, [val.name]: this.handlePropertyValue(val) }; | ||
}, {}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { ClassReflector } from './class-reflector'; | ||
import { Fixture } from './decorators/fixture.decorator'; | ||
import { ClassReflectionDto } from './types/class-reflection-dto.type'; | ||
|
||
describe('ClassReflector', () => { | ||
let reflector: ClassReflector; | ||
|
||
class EmptyClass {} | ||
|
||
class TestClass { | ||
@Fixture('Foo') | ||
fooer: string; | ||
|
||
@Fixture('Bar') | ||
barer: string; | ||
} | ||
|
||
describe('Given a ClassReflector', () => { | ||
beforeAll(() => { | ||
reflector = new ClassReflector(); | ||
}); | ||
|
||
describe("when calling 'reflectClass'", () => { | ||
describe('and there are no related decorators on any of the properties', () => { | ||
test('then return empty array of properties', () => { | ||
expect(reflector.reflectClass(EmptyClass)).toHaveLength(0); | ||
}); | ||
}); | ||
|
||
describe('and there are some related decorators in the class', () => { | ||
let classReflection: ClassReflectionDto; | ||
|
||
beforeAll(() => { | ||
classReflection = reflector.reflectClass(TestClass); | ||
}); | ||
|
||
test('then return an array of properties which the length is the number of decorators', () => { | ||
expect(classReflection).toBeInstanceOf(Array); | ||
expect(classReflection).toHaveLength(2); | ||
}); | ||
|
||
test('then create a property dto for each of the properties', () => { | ||
expect(Object.keys(classReflection[0])).toEqual(['type', 'value', 'name', 'constructorName']); | ||
}); | ||
|
||
test('then register the class in the reflected classes storage', () => { | ||
expect(ClassReflector.REFLECTED_CLASSES).toHaveProperty(TestClass.name); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import reflect, { ClassReflection, PropertyReflection } from '@plumier/reflect'; | ||
import { ClassType } from './types/fixture-options.type'; | ||
import { FixtureOptions } from './types/fixture-options.type'; | ||
import { FIXTURE_DECORATOR_NAME } from './decorators/fixture.decorator'; | ||
import { PropertyDto } from './types/property-dto.interface'; | ||
import { ClassReflectionDto } from './types/class-reflection-dto.type'; | ||
|
||
export class ClassReflector { | ||
public static readonly REFLECTED_CLASSES: Record<string, ClassReflectionDto> = {}; | ||
|
||
private extractDecoratedProperties(classReflection: ClassReflection): PropertyDto<FixtureOptions>[] { | ||
return classReflection.properties?.map((property) => { | ||
const value = ClassReflector.extractFixtureDecoratorValue(property); | ||
return ClassReflector.createPropertyDto(property, value); | ||
}); | ||
} | ||
|
||
private static createPropertyDto( | ||
property: PropertyReflection, | ||
fixtureDecoratorValue: FixtureOptions | null | ||
): PropertyDto<FixtureOptions> { | ||
const { name, type: { name: constructorName } = {} } = property; | ||
|
||
return { | ||
type: typeof fixtureDecoratorValue, | ||
value: fixtureDecoratorValue, | ||
name, | ||
constructorName, | ||
}; | ||
} | ||
|
||
private static extractFixtureDecoratorValue(property: PropertyReflection): FixtureOptions | null { | ||
const { decorators = [] } = property; | ||
const fixtureDecorator = decorators.find((decorator) => decorator.type === FIXTURE_DECORATOR_NAME); | ||
|
||
return fixtureDecorator ? fixtureDecorator.value : null; | ||
} | ||
|
||
public reflectClass(target: ClassType<unknown>): ClassReflectionDto { | ||
if (!ClassReflector.REFLECTED_CLASSES.hasOwnProperty(target.name)) { | ||
ClassReflector.REFLECTED_CLASSES[target.name] = this.extractDecoratedProperties(reflect(target)); | ||
} | ||
|
||
return ClassReflector.REFLECTED_CLASSES[target.name]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.