Skip to content

Commit 5abcb96

Browse files
committed
fix: make transformers order deterministic
When several trasnformers are applied to the same property the order is reversed every time plainToClass is called. This fix make the transfomers orders consistent across multiple `plainToClass()` calls. Fixes #231
1 parent eaf5412 commit 5abcb96

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

src/metadata/MetadataStorage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ export class MetadataStorage {
215215
}
216216
}
217217
}
218-
return (metadataFromAncestorsTarget).reverse().concat((metadataFromTarget || []).reverse());
218+
return (metadataFromAncestorsTarget).slice().reverse().concat((metadataFromTarget || []).slice().reverse());
219219
}
220220

221221
private getAncestors(target: Function): Function[] {
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import "reflect-metadata";
2+
import { plainToClass } from "../../src/index";
3+
import { defaultMetadataStorage } from "../../src/storage";
4+
import { Expose, Transform } from "../../src/decorators";
5+
6+
describe("applying several transformations", () => {
7+
beforeEach(() => defaultMetadataStorage.clear());
8+
afterEach(() => defaultMetadataStorage.clear());
9+
10+
it("should keep the order of the applied decorators after several plainToClass() calls", () => {
11+
class User {
12+
@Transform(() => "Jonathan")
13+
@Transform(() => "John")
14+
@Expose()
15+
name: string;
16+
}
17+
18+
const firstUser = plainToClass(User, { name: "Joe" });
19+
expect(firstUser.name).toEqual("John");
20+
21+
// Prior to this pull request [#355](https://github.com/typestack/class-transformer/pull/355)
22+
// the order of the transformations was reversed after every `plainToClass()` call
23+
// So after consecutive calls `User#name` would be "John" - "Jonathan" - "John" - "Jonathan"...
24+
// This test ensures the last transformation is always the last one to be applied
25+
const secondUser = plainToClass(User, { name: "Joe" });
26+
expect(secondUser.name).toEqual("John");
27+
});
28+
});

0 commit comments

Comments
 (0)