Skip to content

Commit

Permalink
fix(core): send extraArgs from original map operation to mapWith oper…
Browse files Browse the repository at this point in the history
…ations

ISSUES CLOSED: #509
  • Loading branch information
Chau Tran authored and Chau Tran committed Oct 24, 2022
1 parent d0205a5 commit 65c6a74
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 40 deletions.
6 changes: 5 additions & 1 deletion packages/core/src/lib/mappings/map-member.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ export function mapMember<
case TransformationType.MapWith:
value = (
mapFn as MapWithReturn<TSource, TDestination>[MapFnClassId.fn]
)(sourceObject, mapper);
)(
sourceObject,
mapper,
extraArgs ? { extraArgs: () => extraArgs } : undefined
);
break;
case TransformationType.ConvertUsing:
value = (
Expand Down
9 changes: 6 additions & 3 deletions packages/core/src/lib/member-map-functions/map-with.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type {
Dictionary,
MapOptions,
MapWithReturn,
ModelIdentifier,
SelectorReturn,
Expand All @@ -26,21 +27,23 @@ export function mapWith<
): MapWithReturn<TSource, TDestination, TSelectorReturn> {
return [
TransformationType.MapWith,
(source, mapper) => {
(source, mapper, options) => {
const sourceValue = withSourceValue(source);

if (Array.isArray(sourceValue)) {
return mapper.mapArray(
sourceValue,
withSource,
withDestination
withDestination,
options as unknown as MapOptions<TSource[], TDestination[]>
) as unknown as TSelectorReturn;
}

return mapper.map(
sourceValue,
withSource,
withDestination
withDestination,
options
) as unknown as TSelectorReturn;
},
];
Expand Down
6 changes: 5 additions & 1 deletion packages/core/src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,11 @@ export type MapWithReturn<
TSelectorReturn = SelectorReturn<TDestination>
> = [
TransformationType.MapWith,
(sourceObj: TSource, mapper: Mapper) => TSelectorReturn | undefined | null
(
sourceObj: TSource,
mapper: Mapper,
options?: MapOptions<TSource, TDestination>
) => TSelectorReturn | undefined | null
];

export interface ConditionPredicate<TSource extends Dictionary<TSource>> {
Expand Down
117 changes: 82 additions & 35 deletions packages/integration-test/src/classes/map-extra-args.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,49 +4,50 @@ import {
createMap,
createMapper,
forMember,
mapWith,
mapWithArguments,
Resolver,
} from '@automapper/core';

describe('Map - Extra Arguments', () => {
class Bar {
@AutoMap(() => String)
bar!: string | null;

constructor(bar: string) {
this.bar = bar;
}
}
class Bar {
@AutoMap(() => String)
bar!: string | null;

class Foo {
@AutoMap()
foo!: string;
@AutoMap(() => Bar)
bar!: Bar;
@AutoMap(() => Number)
fooBar!: number | null;

constructor(fooBar: number) {
this.foo = `foo${fooBar}`;
this.fooBar = fooBar;
this.bar = new Bar(`bar${fooBar}`);
}
constructor(bar: string) {
this.bar = bar;
}

class BarDto {
@AutoMap(() => String)
bar!: string | null;
}

class FooDto {
@AutoMap()
foo!: string;
@AutoMap(() => BarDto)
bar!: BarDto;
@AutoMap(() => Number)
fooBar!: number | null;
}

class Foo {
@AutoMap()
foo!: string;
@AutoMap(() => Bar)
bar!: Bar;
@AutoMap(() => Number)
fooBar!: number | null;

constructor(fooBar: number) {
this.foo = `foo${fooBar}`;
this.fooBar = fooBar;
this.bar = new Bar(`bar${fooBar}`);
}
}

class BarDto {
@AutoMap(() => String)
bar!: string | null;
}

class FooDto {
@AutoMap()
foo!: string;
@AutoMap(() => BarDto)
bar!: BarDto;
@AutoMap(() => Number)
fooBar!: number | null;
}

describe('Map - Extra Arguments', () => {
const mapper = createMapper({
strategyInitializer: classes(),
namingConventions: new CamelCaseNamingConvention(),
Expand Down Expand Up @@ -121,3 +122,49 @@ describe('Map - Extra Arguments', () => {
expect(dto.bar.bar).toEqual(foo.bar.bar + ' concat me');
});
});

describe('Map - Extra Arguments deep', () => {
const mapper = createMapper({
strategyInitializer: classes(),
namingConventions: new CamelCaseNamingConvention(),
});

beforeEach(() => {
createMap(
mapper,
Bar,
BarDto,
forMember(
(d) => d.bar,
mapWithArguments(
(source, { concat = 'default concat' }) =>
source.bar + ' ' + concat
)
)
);

createMap(
mapper,
Foo,
FooDto,
forMember(
(d) => d.bar,
mapWith(BarDto, Bar, (s) => s.bar)
)
);
});

afterEach(() => {
mapper.dispose();
});

it('should transfer extra args to nested map', () => {
const foo = new Foo(2);
const dto = mapper.map(foo, Foo, FooDto, {
extraArgs: () => ({ multiplier: 3, concat: 'concat me' }),
});

expect(dto.foo).toEqual(foo.foo);
expect(dto.bar.bar).toEqual(foo.bar.bar + ' concat me');
});
});

0 comments on commit 65c6a74

Please sign in to comment.