Skip to content

Commit 2b11c92

Browse files
committed
test(JS): add xlang serialization tests for strings, lists, and maps
1 parent e62df66 commit 2b11c92

32 files changed

Lines changed: 1814 additions & 950 deletions

javascript/jest.config.js

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,35 +21,33 @@
2121

2222
module.exports = {
2323
collectCoverage: true,
24-
preset: 'ts-jest',
25-
testEnvironment: 'node',
24+
preset: "ts-jest",
25+
testEnvironment: "node",
2626
collectCoverageFrom: [
2727
"**/*.ts",
2828
"!**/dist/**",
2929
"!**/build/**",
30-
"!packages/fory/lib/murmurHash3.ts"
30+
"!packages/fory/lib/murmurHash3.ts",
3131
],
3232
testPathIgnorePatterns: [
33-
// Cross-language tests are now enabled for verification
33+
"/node_modules/",
34+
"/dist/",
35+
"/build/",
36+
// Cross-language tests are explicitly enabled by not adding them here
3437
],
3538
transform: {
36-
'\\.ts$': ['ts-jest', {
37-
tsconfig: {
38-
target: "ES2021",
39-
experimentalDecorators: true
39+
"\\.ts$": [
40+
"ts-jest",
41+
{
42+
tsconfig: {
43+
target: "ES2021",
44+
experimentalDecorators: true,
45+
emitDecoratorMetadata: true, // Ensures SimpleStruct decorators work correctly
46+
},
47+
diagnostics: {
48+
ignoreCodes: [151001],
49+
},
4050
},
41-
diagnostics: {
42-
ignoreCodes: [151001]
43-
}
44-
}],
51+
],
4552
},
46-
// todo: JavaScript codebase is iterating rapidly, remove this restriction temporary
47-
// coverageThreshold: {
48-
// global: {
49-
// branches: 91,
50-
// functions: 99,
51-
// lines: 98,
52-
// statements: 98
53-
// }
54-
// }
5553
};

javascript/packages/fory/lib/classResolver.ts

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@
1717
* under the License.
1818
*/
1919

20-
import { ForyTypeInfoSymbol, WithForyClsInfo, Serializer, TypeId } from "./type";
20+
import {
21+
ForyTypeInfoSymbol,
22+
WithForyClsInfo,
23+
Serializer,
24+
TypeId,
25+
} from "./type";
2126
import { Gen } from "./gen";
2227
import { Type, TypeInfo } from "./typeInfo";
2328
import Fory from "./fory";
@@ -75,7 +80,10 @@ export default class ClassResolver {
7580

7681
private initInternalSerializer() {
7782
const registerSerializer = (typeInfo: TypeInfo) => {
78-
return this.registerSerializer(typeInfo, new Gen(this.fory).generateSerializer(typeInfo));
83+
return this.registerSerializer(
84+
typeInfo,
85+
new Gen(this.fory).generateSerializer(typeInfo),
86+
);
7987
};
8088
registerSerializer(Type.string());
8189
registerSerializer(Type.any());
@@ -105,13 +113,13 @@ export default class ClassResolver {
105113
registerSerializer(Type.float64Array());
106114

107115
this.numberSerializer = this.getSerializerById(TypeId.FLOAT64);
108-
this.int64Serializer = this.getSerializerById((TypeId.INT64));
109-
this.boolSerializer = this.getSerializerById((TypeId.BOOL));
110-
this.dateSerializer = this.getSerializerById((TypeId.TIMESTAMP));
111-
this.stringSerializer = this.getSerializerById((TypeId.STRING));
112-
this.setSerializer = this.getSerializerById((TypeId.SET));
113-
this.arraySerializer = this.getSerializerById((TypeId.LIST));
114-
this.mapSerializer = this.getSerializerById((TypeId.MAP));
116+
this.int64Serializer = this.getSerializerById(TypeId.INT64);
117+
this.boolSerializer = this.getSerializerById(TypeId.BOOL);
118+
this.dateSerializer = this.getSerializerById(TypeId.TIMESTAMP);
119+
this.stringSerializer = this.getSerializerById(TypeId.STRING);
120+
this.setSerializer = this.getSerializerById(TypeId.SET);
121+
this.arraySerializer = this.getSerializerById(TypeId.LIST);
122+
this.mapSerializer = this.getSerializerById(TypeId.MAP);
115123
this.uint8ArraySerializer = this.getSerializerById(TypeId.UINT8_ARRAY);
116124
this.uint16ArraySerializer = this.getSerializerById(TypeId.UINT16_ARRAY);
117125
this.uint32ArraySerializer = this.getSerializerById(TypeId.UINT32_ARRAY);
@@ -139,8 +147,7 @@ export default class ClassResolver {
139147
private int32ArraySerializer: null | Serializer = null;
140148
private int64ArraySerializer: null | Serializer = null;
141149

142-
constructor(private fory: Fory) {
143-
}
150+
constructor(private fory: Fory) {}
144151

145152
init() {
146153
this.initInternalSerializer();
@@ -150,11 +157,14 @@ export default class ClassResolver {
150157
return this.typeInfoMap.get(typeIdOrName);
151158
}
152159

153-
registerSerializer(typeInfo: TypeInfo, serializer: Serializer = uninitSerialize) {
160+
registerSerializer(
161+
typeInfo: TypeInfo,
162+
serializer: Serializer = uninitSerialize,
163+
) {
154164
if (!TypeId.isNamedType(typeInfo.typeId)) {
155165
const id = typeInfo.typeId;
156166
this.typeInfoMap.set(id, typeInfo);
157-
if (id <= 0xFF) {
167+
if (id <= 0xff) {
158168
if (this.internalSerializer[id]) {
159169
Object.assign(this.internalSerializer[id], serializer);
160170
} else {
@@ -183,17 +193,16 @@ export default class ClassResolver {
183193
}
184194

185195
typeInfoExists(typeInfo: TypeInfo) {
186-
// Corrected to call the property access properly if isNamedType is a property
187196
if (typeInfo.isNamedType) {
188-
return this.typeInfoMap.has((typeInfo.castToStruct()).named!);
197+
return this.typeInfoMap.has(typeInfo.castToStruct().named!);
189198
}
190199
return this.typeInfoMap.has(typeInfo.typeId);
191200
}
192201

193202
getSerializerByTypeInfo(typeInfo: TypeInfo) {
194203
const typeId = typeInfo.computeTypeId(this.fory);
195204
if (TypeId.isNamedType(typeId)) {
196-
return this.customSerializer.get((typeInfo.castToStruct()).named!);
205+
return this.customSerializer.get(typeInfo.castToStruct().named!);
197206
}
198207
return this.getSerializerById(typeId);
199208
}
@@ -278,10 +287,13 @@ export default class ClassResolver {
278287

279288
// custom types
280289
if (typeof v === "object" && v !== null && ForyTypeInfoSymbol in v) {
281-
const typeInfo = (v[ForyTypeInfoSymbol] as WithForyClsInfo).structTypeInfo;
290+
const typeInfo = (v[ForyTypeInfoSymbol] as WithForyClsInfo)
291+
.structTypeInfo;
282292
return this.getSerializerByTypeInfo(typeInfo);
283293
}
284294

285-
throw new Error(`Failed to detect the Fory type from JavaScript type: ${typeof v}`);
295+
throw new Error(
296+
`Failed to detect the Fory type from JavaScript type: ${typeof v}`,
297+
);
286298
}
287299
}

javascript/packages/fory/lib/fory.ts

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,7 @@ import {
3131
TypeId,
3232
} from "./type";
3333
import { OwnershipError } from "./error";
34-
import {
35-
InputType,
36-
ResultType,
37-
StructTypeInfo,
38-
TypeInfo,
39-
} from "./typeInfo";
34+
import { InputType, ResultType, StructTypeInfo, TypeInfo } from "./typeInfo";
4035
import { Gen } from "./gen";
4136
import { TypeMeta } from "./meta/TypeMeta";
4237
import { PlatformBuffer } from "./platformBuffer";
@@ -82,13 +77,11 @@ export default class {
8277

8378
// Overload: class with decorators
8479
registerSerializer<T extends new () => any>(
85-
constructor: T
80+
constructor: T,
8681
): {
8782
serializer: Serializer;
8883
serialize(data: Partial<InstanceType<T>> | null): PlatformBuffer;
89-
serializeVolatile(
90-
data: Partial<InstanceType<T>>
91-
): {
84+
serializeVolatile(data: Partial<InstanceType<T>>): {
9285
get: () => Uint8Array;
9386
dispose: () => void;
9487
};
@@ -97,13 +90,11 @@ export default class {
9790

9891
// Overload: explicit TypeInfo
9992
registerSerializer<T extends TypeInfo>(
100-
typeInfo: T
93+
typeInfo: T,
10194
): {
10295
serializer: Serializer;
10396
serialize(data: InputType<T> | null): PlatformBuffer;
104-
serializeVolatile(
105-
data: InputType<T>
106-
): {
97+
serializeVolatile(data: InputType<T>): {
10798
get: () => Uint8Array;
10899
dispose: () => void;
109100
};
@@ -119,9 +110,7 @@ export default class {
119110
if (constructorOrType.prototype?.[ForyTypeInfoSymbol]) {
120111
// Case 1: class with decorator metadata
121112
const typeInfo: TypeInfo = (
122-
constructorOrType.prototype[
123-
ForyTypeInfoSymbol
124-
] as WithForyClsInfo
113+
constructorOrType.prototype[ForyTypeInfoSymbol] as WithForyClsInfo
125114
).structTypeInfo;
126115

127116
// For structs we still use codegen via Gen
@@ -185,7 +174,7 @@ export default class {
185174

186175
deserialize<T = any>(
187176
bytes: Uint8Array,
188-
serializer: Serializer = this.anySerializer
177+
serializer: Serializer = this.anySerializer,
189178
): T | null {
190179
this.referenceResolver.reset();
191180
this.binaryReader.reset(bytes);
@@ -205,8 +194,7 @@ export default class {
205194
}
206195

207196
const isOutOfBandEnabled =
208-
(bitmap & ConfigFlags.isOutOfBandFlag) ===
209-
ConfigFlags.isOutOfBandFlag;
197+
(bitmap & ConfigFlags.isOutOfBandFlag) === ConfigFlags.isOutOfBandFlag;
210198
if (isOutOfBandEnabled) {
211199
throw new Error("outofband mode is not supported now");
212200
}
@@ -220,7 +208,7 @@ export default class {
220208
} catch (e) {
221209
if (e instanceof OwnershipError) {
222210
throw new Error(
223-
"Permission denied. To release the serialization ownership, you must call the dispose function returned by serializeVolatile."
211+
"Permission denied. To release the serialization ownership, you must call the dispose function returned by serializeVolatile.",
224212
);
225213
}
226214
throw e;
@@ -248,7 +236,7 @@ export default class {
248236

249237
serializeVolatile<T = any>(
250238
data: T,
251-
serializer: Serializer = this.anySerializer
239+
serializer: Serializer = this.anySerializer,
252240
) {
253241
return this.serializeInternal(data, serializer).dumpAndOwn();
254242
}

javascript/packages/fory/lib/gen/any.ts

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ export class AnyHelper {
3535
}
3636
let serializer: Serializer | undefined;
3737

38-
function tryUpdateSerializer(serializer: Serializer | undefined | null, typeMeta: TypeMeta) {
38+
function tryUpdateSerializer(
39+
serializer: Serializer | undefined | null,
40+
typeMeta: TypeMeta,
41+
) {
3942
if (!serializer) {
4043
throw new Error(`can't find implements of typeId: ${typeId}`);
4144
}
@@ -49,8 +52,13 @@ export class AnyHelper {
4952
switch (typeId) {
5053
case TypeId.COMPATIBLE_STRUCT:
5154
{
52-
const typeMeta = fory.typeMetaResolver.readTypeMeta(fory.binaryReader);
53-
serializer = fory.typeResolver.getSerializerById(typeId, typeMeta.getUserTypeId());
55+
const typeMeta = fory.typeMetaResolver.readTypeMeta(
56+
fory.binaryReader,
57+
);
58+
serializer = fory.typeResolver.getSerializerById(
59+
typeId,
60+
typeMeta.getUserTypeId(),
61+
);
5462
serializer = tryUpdateSerializer(serializer, typeMeta);
5563
}
5664
break;
@@ -59,16 +67,28 @@ export class AnyHelper {
5967
case TypeId.NAMED_EXT:
6068
case TypeId.NAMED_UNION:
6169
case TypeId.NAMED_COMPATIBLE_STRUCT:
62-
if (fory.config.mode === Mode.Compatible || typeId === TypeId.NAMED_COMPATIBLE_STRUCT) {
63-
const typeMeta = fory.typeMetaResolver.readTypeMeta(fory.binaryReader);
70+
if (
71+
fory.config.mode === Mode.Compatible ||
72+
typeId === TypeId.NAMED_COMPATIBLE_STRUCT
73+
) {
74+
const typeMeta = fory.typeMetaResolver.readTypeMeta(
75+
fory.binaryReader,
76+
);
6477
const ns = typeMeta.getNs();
6578
const typeName = typeMeta.getTypeName();
6679
const named = `${ns}$${typeName}`;
67-
serializer = tryUpdateSerializer(fory.typeResolver.getSerializerByName(named), typeMeta);
80+
serializer = tryUpdateSerializer(
81+
fory.typeResolver.getSerializerByName(named),
82+
typeMeta,
83+
);
6884
} else {
6985
const ns = fory.metaStringResolver.readNamespace(fory.binaryReader);
70-
const typeName = fory.metaStringResolver.readTypeName(fory.binaryReader);
71-
serializer = fory.typeResolver.getSerializerByName(`${ns}$${typeName}`);
86+
const typeName = fory.metaStringResolver.readTypeName(
87+
fory.binaryReader,
88+
);
89+
serializer = fory.typeResolver.getSerializerByName(
90+
`${ns}$${typeName}`,
91+
);
7292
}
7393
break;
7494
default:
@@ -88,7 +108,9 @@ export class AnyHelper {
88108

89109
const serializer = fory.typeResolver.getSerializerByData(v);
90110
if (!serializer) {
91-
throw new Error(`Failed to detect the Fory serializer from JavaScript type: ${typeof v}`);
111+
throw new Error(
112+
`Failed to detect the Fory serializer from JavaScript type: ${typeof v}`,
113+
);
92114
}
93115
fory.binaryWriter.reserve(serializer.fixedSize);
94116
return serializer;
@@ -102,7 +124,10 @@ class AnySerializerGenerator extends BaseSerializerGenerator {
102124
constructor(typeInfo: TypeInfo, builder: CodecBuilder, scope: Scope) {
103125
super(typeInfo, builder, scope);
104126
this.typeInfo = typeInfo;
105-
this.detectedSerializer = this.scope.declareVar("detectedSerializer", "null");
127+
this.detectedSerializer = this.scope.declareVar(
128+
"detectedSerializer",
129+
"null",
130+
);
106131
this.writerSerializer = this.scope.declareVar("writerSerializer", "null");
107132
}
108133

0 commit comments

Comments
 (0)