Skip to content

Commit 3b44251

Browse files
fix: unable to serialize array with unique items (#98)
* chore: reproduce failure * chore: update unit tests * fix: error in classes with parent BaseModel * chore: fix invalid sub type test --------- Co-authored-by: Eduardo Rodrigues <[email protected]>
1 parent f449617 commit 3b44251

File tree

3 files changed

+38
-4
lines changed

3 files changed

+38
-4
lines changed

src/recast.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { InvalidRequest } from './exceptions';
2-
import { Callable, integer, Integer } from './interface';
2+
import { BaseModel, Callable, integer, Integer } from './interface';
33

44
type primitive = string | number | boolean | bigint | integer | object;
55

@@ -70,7 +70,7 @@ export const transformValue = (
7070
});
7171
} else {
7272
// if type is plain object, we leave it as is
73-
if (Object.is(cls, Object)) {
73+
if (Object.is(cls, Object) || cls.prototype instanceof BaseModel) {
7474
return value;
7575
}
7676
if (

tests/data/sample-model.ts

+19
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,25 @@ export class DeeperDict extends BaseModel {
200200
deepestList?: Optional<Array<integer>>;
201201
}
202202

203+
export class TagsModel extends BaseModel {
204+
['constructor']: typeof TagsModel;
205+
206+
@Expose({ name: 'Tags' })
207+
@Transform((value, obj) => transformValue(Tag, 'tags', value, obj, [Set]), {
208+
toClassOnly: true,
209+
})
210+
tags?: Optional<Set<Tag>>;
211+
}
212+
213+
class Tag extends BaseModel {
214+
['constructor']: typeof Tag;
215+
216+
@Expose({ name: 'Name' })
217+
name: string;
218+
@Expose({ name: 'Value' })
219+
value: string;
220+
}
221+
203222
export class SimpleResourceModel extends BaseModel {
204223
['constructor']: typeof SimpleResourceModel;
205224

tests/lib/recast.test.ts

+17-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { transformValue, recastPrimitive } from '~/recast';
33
import {
44
ResourceModel as ComplexResourceModel,
55
SimpleResourceModel,
6+
TagsModel,
67
} from '../data/sample-model';
78

89
describe('when recasting objects', () => {
@@ -105,15 +106,29 @@ describe('when recasting objects', () => {
105106
);
106107
});
107108

109+
test('recast set type - array with unique items', () => {
110+
const payload = {
111+
Tags: [{ key: 'name', value: 'value' }],
112+
};
113+
const expected = {
114+
Tags: new Set([{ key: 'name', value: 'value' }]),
115+
};
116+
const model = TagsModel.deserialize(payload);
117+
const serialized = JSON.parse(JSON.stringify(model));
118+
expect(serialized).toMatchObject(expected);
119+
expect(TagsModel.deserialize(serialized).serialize()).toMatchObject(expected);
120+
});
121+
108122
test('recast object invalid sub type', () => {
123+
class InvalidClass {}
109124
const k = 'key';
110125
const v = { a: 1, b: 2 };
111126
const recastObject = () => {
112-
transformValue(SimpleResourceModel, k, v, {});
127+
transformValue(InvalidClass, k, v, {});
113128
};
114129
expect(recastObject).toThrow(exceptions.InvalidRequest);
115130
expect(recastObject).toThrow(
116-
`Unsupported type: ${typeof v} [${SimpleResourceModel.name}] for ${k}`
131+
`Unsupported type: ${typeof v} [${InvalidClass.name}] for ${k}`
117132
);
118133
});
119134

0 commit comments

Comments
 (0)