Skip to content

Commit

Permalink
fix(automapper.ts): add more tests and fix get bug
Browse files Browse the repository at this point in the history
  • Loading branch information
nartc committed Mar 24, 2020
1 parent c66cbb5 commit bdab072
Show file tree
Hide file tree
Showing 12 changed files with 367 additions and 7 deletions.
60 changes: 60 additions & 0 deletions src/member-functions/specs/condition.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import {
MemberMapFunctionReturnClassId,
TransformationType,
} from '../../types';
import { condition } from '../condition';

describe('ConditionFunction', () => {
const source = {
truthy: true,
falsy: false,
};

it('should return correctly', () => {
const conditionFn = condition<typeof source>(s => s.truthy);
expect(conditionFn).toBeTruthy();
expect(conditionFn[MemberMapFunctionReturnClassId.type]).toBe(
TransformationType.Condition
);
expect(conditionFn[MemberMapFunctionReturnClassId.misc]).toBe(null);
expect(conditionFn[MemberMapFunctionReturnClassId.fn]).toBeInstanceOf(
Function
);
});

it('should map to truthy when true', () => {
const conditionFn = condition<typeof source>(s => s.truthy);
const result = conditionFn[MemberMapFunctionReturnClassId.fn](
source,
'truthy'
);
expect(result).toBe(true);
});

it('should still map to truthy when true and defaultValue is provided', () => {
const conditionFn = condition<typeof source>(s => s.truthy, 'defaultValue');
const result = conditionFn[MemberMapFunctionReturnClassId.fn](
source,
'truthy'
);
expect(result).toBe(true);
});

it('should map to null when false', () => {
const conditionFn = condition<typeof source>(s => s.falsy);
const result = conditionFn[MemberMapFunctionReturnClassId.fn](
source,
'falsy'
);
expect(result).toBe(null);
});

it('should map to defaultValue when false and provided', () => {
const conditionFn = condition<typeof source>(s => s.falsy, 'defaultValue');
const result = conditionFn[MemberMapFunctionReturnClassId.fn](
source,
'falsy'
);
expect(result).toBe('defaultValue');
});
});
42 changes: 42 additions & 0 deletions src/member-functions/specs/convert-using.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import {
Converter,
MemberMapFunctionReturnClassId,
TransformationType,
} from '../../types';
import { convertUsing } from '../convert-using';

describe('ConvertUsingFunction', () => {
class DateTimeConverter implements Converter<Date, string> {
convert(source: Date): string {
return source.toDateString();
}
}

const source = {
birthday: new Date('10/14/1991'),
};

it('should return correctly', () => {
const convertUsingFn = convertUsing(
new DateTimeConverter(),
s => s.birthday
);
expect(convertUsingFn).toBeTruthy();
expect(convertUsingFn[MemberMapFunctionReturnClassId.type]).toBe(
TransformationType.ConvertUsing
);
expect(convertUsingFn[MemberMapFunctionReturnClassId.misc]).toBe(null);
expect(convertUsingFn[MemberMapFunctionReturnClassId.fn]).toBeInstanceOf(
Function
);
});

it('should map correctly', () => {
const convertUsingFn = convertUsing(
new DateTimeConverter(),
s => s.birthday
);
const result = convertUsingFn[MemberMapFunctionReturnClassId.fn](source);
expect(result).toBe(new Date('10/14/1991').toDateString());
});
});
25 changes: 25 additions & 0 deletions src/member-functions/specs/from-value.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {
MemberMapFunctionReturnClassId,
TransformationType,
} from '../../types';
import { fromValue } from '../from-value';

describe('FromValueFunction', () => {
it('should return correctly', () => {
const fromValueFunction = fromValue(10);
expect(fromValueFunction).toBeTruthy();
expect(fromValueFunction[MemberMapFunctionReturnClassId.type]).toBe(
TransformationType.FromValue
);
expect(fromValueFunction[MemberMapFunctionReturnClassId.misc]).toBe(null);
expect(fromValueFunction[MemberMapFunctionReturnClassId.fn]).toBeInstanceOf(
Function
);
});

it('should map correctly', () => {
const fromValueFunction = fromValue(10);
const result = fromValueFunction[MemberMapFunctionReturnClassId.fn]();
expect(result).toBe(10);
});
});
24 changes: 24 additions & 0 deletions src/member-functions/specs/ignore.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {
MemberMapFunctionReturnClassId,
TransformationType,
} from '../../types';
import { ignore } from '../ignore';

describe('IgnoreFunction', () => {
it('should return correctly', () => {
const ignoreFn = ignore();
expect(ignoreFn).toBeTruthy();
expect(ignoreFn[MemberMapFunctionReturnClassId.type]).toBe(
TransformationType.Ignore
);
expect(ignoreFn[MemberMapFunctionReturnClassId.misc]).toBe(null);
expect(ignoreFn[MemberMapFunctionReturnClassId.fn]).toBeInstanceOf(
Function
);
});

it('should return undefined when called', () => {
const ignoreFn = ignore();
expect(ignoreFn[MemberMapFunctionReturnClassId.fn]()).toBe(undefined);
});
});
52 changes: 52 additions & 0 deletions src/member-functions/specs/map-from.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import {
MemberMapFunctionReturnClassId,
Resolver,
TransformationType,
} from '../../types';
import { mapFrom } from '../map-from';

describe('MapFromFunction', () => {
const source = {
foo: 'bar',
};

const sourceSelector = (s: typeof source) => s.foo;

it('should return correctly', () => {
const mapFromFn = mapFrom(sourceSelector);
expect(mapFromFn).toBeTruthy();
expect(mapFromFn[MemberMapFunctionReturnClassId.type]).toBe(
TransformationType.MapFrom
);
expect(mapFromFn[MemberMapFunctionReturnClassId.misc]).toBe(sourceSelector);
expect(mapFromFn[MemberMapFunctionReturnClassId.fn]).toBeInstanceOf(
Function
);
});

it('should map to foo correctly', () => {
const mapFromFn = mapFrom(sourceSelector);
const result = mapFromFn[MemberMapFunctionReturnClassId.fn](
source,
null,
null
);
expect(result).toBe('bar');
});

class FooResolver implements Resolver<typeof source, any> {
resolve(source: any) {
return source.foo;
}
}

it('should use resolver correctly', () => {
const mapFromFn = mapFrom(new FooResolver());
const result = mapFromFn[MemberMapFunctionReturnClassId.fn](
source,
null,
null
);
expect(result).toBe('bar');
});
});
31 changes: 31 additions & 0 deletions src/member-functions/specs/map-initialize.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {
MemberMapFunctionReturnClassId,
TransformationType,
} from '../../types';
import { mapInitialize } from '../map-initialize';

describe('MapInitializeFunction', () => {
const source = {
foo: {
bar: 'foo',
},
};

it('should return correctly', () => {
const mapInitFn = mapInitialize();
expect(mapInitFn).toBeTruthy();
expect(mapInitFn[MemberMapFunctionReturnClassId.type]).toBe(
TransformationType.MapInitialize
);
expect(mapInitFn[MemberMapFunctionReturnClassId.misc]).toBe(null);
expect(mapInitFn[MemberMapFunctionReturnClassId.fn]).toBeInstanceOf(
Function
);
});

it('should map correctly', () => {
const mapInitFn = mapInitialize('foo.bar');
const result = mapInitFn[MemberMapFunctionReturnClassId.fn](source);
expect(result).toBe('foo');
});
});
50 changes: 50 additions & 0 deletions src/member-functions/specs/map-with.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Mapper } from '../../automapper';
import {
MemberMapFunctionReturnClassId,
TransformationType,
} from '../../types';
import { mapFrom } from '../map-from';
import { mapWith } from '../map-with';

describe('MapWithFunction', () => {
class Bar {
bar!: string;
}

const sourceSelector = (s: any) => s.foo;

it('should return correctly', () => {
const mapWithFn = mapWith(Bar, sourceSelector);
expect(mapWithFn).toBeTruthy();
expect(mapWithFn[MemberMapFunctionReturnClassId.type]).toBe(
TransformationType.MapWith
);
expect(mapWithFn[MemberMapFunctionReturnClassId.misc]).toBe(sourceSelector);
expect(mapWithFn[MemberMapFunctionReturnClassId.fn]).toBeInstanceOf(
Function
);
});

class Foo {
foo!: string;
}

it('should map correctly', () => {
Mapper.createMap(Foo, Bar).forMember(
d => d.bar,
mapFrom(s => s.foo)
);

const mapWithFn = mapWith(Bar, sourceSelector);
const foo = new Foo();
foo.foo = 'bar';
const result = mapWithFn[MemberMapFunctionReturnClassId.fn]({ foo });
expect(result).toBeTruthy();
expect(result).toBeInstanceOf(Bar);
expect(result?.bar).toBe(foo.foo);
});

afterAll(() => {
Mapper.dispose();
});
});
39 changes: 39 additions & 0 deletions src/member-functions/specs/null-substitution.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {
MemberMapFunctionReturnClassId,
TransformationType,
} from '../../types';
import { nullSubstitution } from '../null-substitution';

describe('NullSubstitutionFunction', () => {
it('should return correctly', () => {
const nullSubFn = nullSubstitution('');
expect(nullSubFn).toBeTruthy();
expect(nullSubFn[MemberMapFunctionReturnClassId.type]).toBe(
TransformationType.NullSubstitution
);
expect(nullSubFn[MemberMapFunctionReturnClassId.misc]).toBe(null);
expect(nullSubFn[MemberMapFunctionReturnClassId.fn]).toBeInstanceOf(
Function
);
});

it('should return source if source is not null', () => {
const nullSubFn = nullSubstitution('subbed');
const result = nullSubFn[MemberMapFunctionReturnClassId.fn](
{ foo: 'bar' },
'foo'
);
expect(result).toBe('bar');
expect(result).not.toBe('subbed');
});

it('should return subbed if source is null', () => {
const nullSubFn = nullSubstitution('subbed');
const result = nullSubFn[MemberMapFunctionReturnClassId.fn](
{ foo: null },
'foo'
);
expect(result).toBe('subbed');
expect(result).not.toBe(null);
});
});
25 changes: 25 additions & 0 deletions src/member-functions/specs/pre-condition.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { preCondition } from '../pre-condition';

describe('PreConditionFunction', () => {
it('should return correctly', () => {
let preCondFn = preCondition(s => s.truthy);
expect(preCondFn).toBeTruthy();
expect(preCondFn[0]).toBeInstanceOf(Function);
expect(preCondFn[1]).toBe(undefined);

preCondFn = preCondition(s => s.truthy, 'default');
expect(preCondFn[1]).toBe('default');
});

it('should return truthy when true', () => {
const preCond = preCondition(s => s.truthy);
const result = preCond[0]({ truthy: true });
expect(result).toBe(true);
});

it('should return falsy when false', () => {
const preCond = preCondition(s => s.falsy);
const result = preCond[0]({ falsy: false });
expect(result).toBe(false);
});
});
20 changes: 15 additions & 5 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ export interface NamingConvention {
}

export interface Resolver<
TSource extends Dict<TSource> = any,
TDestination extends Dict<TDestination> = any,
TSource extends Dict<TSource>,
TDestination extends Dict<TDestination>,
TReturnType = SelectorReturn<TDestination>
> {
resolve(
Expand Down Expand Up @@ -246,8 +246,18 @@ export interface MapFromFunction<
ValueSelector<TSource, TDestination, TSelectorReturn>,
(
source: TSource,
destination: typeof from extends Resolver ? TDestination : any,
transformation: typeof from extends Resolver
destination: typeof from extends Resolver<
TSource,
TDestination,
TSelectorReturn
>
? TDestination
: any,
transformation: typeof from extends Resolver<
TSource,
TDestination,
TSelectorReturn
>
? MappingTransformation<TSource, TDestination, TSelectorReturn>
: any
) => TSelectorReturn
Expand Down Expand Up @@ -289,7 +299,7 @@ export interface FromValueFunction<
(rawValue: TSelectorReturn): [
TransformationType.FromValue,
null,
(source: TSource) => TSelectorReturn
() => TSelectorReturn
];
}

Expand Down
Loading

0 comments on commit bdab072

Please sign in to comment.