This is an automated email from the ASF dual-hosted git repository.

wangweipeng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory.git


The following commit(s) were added to refs/heads/main by this push:
     new 228d6811d feat(JavaScript): Align testcase (#3320)
228d6811d is described below

commit 228d6811d3306282d049d30cea9899f633129202
Author: weipeng <[email protected]>
AuthorDate: Tue Feb 10 22:33:47 2026 +0800

    feat(JavaScript): Align testcase (#3320)
    
    ## Why?
    
    
    
    ## What does this PR do?
    1. Impl dynamic field annotation
    2. More testcases were passed. current progress is 33/39
    3. Replace `mode` config by `compatible: boolean`
    
    
    
    ## Related issues
    #3133
    
    
    ## Does this PR introduce any user-facing change?
    
    
    
    - [ ] Does this PR introduce any public API change?
    - [ ] Does this PR introduce any binary protocol compatibility change?
    
    ## Benchmark
---
 javascript/packages/fory/index.ts              |   2 +
 javascript/packages/fory/lib/fory.ts           |   7 +-
 javascript/packages/fory/lib/gen/any.ts        |   4 +-
 javascript/packages/fory/lib/gen/ext.ts        |   4 +-
 javascript/packages/fory/lib/gen/serializer.ts |  42 ++++++--
 javascript/packages/fory/lib/gen/struct.ts     |  19 ++--
 javascript/packages/fory/lib/meta/TypeMeta.ts  |   2 +-
 javascript/packages/fory/lib/type.ts           |   3 +-
 javascript/packages/fory/lib/typeInfo.ts       |  18 ++--
 javascript/packages/fory/lib/typeResolver.ts   |   3 +
 javascript/test/crossLanguage.test.ts          | 131 ++++++++++++-------------
 javascript/test/protocol/struct.test.ts        |   2 +-
 javascript/test/typemeta.test.ts               |   6 +-
 13 files changed, 142 insertions(+), 101 deletions(-)

diff --git a/javascript/packages/fory/index.ts 
b/javascript/packages/fory/index.ts
index 00ea9b978..36c73ac82 100644
--- a/javascript/packages/fory/index.ts
+++ b/javascript/packages/fory/index.ts
@@ -23,6 +23,7 @@ import {
   ArrayTypeInfo,
   Type,
   ForyField,
+  Dynamic,
 } from "./lib/typeInfo";
 import { Serializer, Mode } from "./lib/type";
 import Fory from "./lib/fory";
@@ -38,6 +39,7 @@ export {
   Mode,
   BinaryWriter,
   ForyField,
+  Dynamic,
   BinaryReader,
 };
 
diff --git a/javascript/packages/fory/lib/fory.ts 
b/javascript/packages/fory/lib/fory.ts
index 18ea876bb..141749525 100644
--- a/javascript/packages/fory/lib/fory.ts
+++ b/javascript/packages/fory/lib/fory.ts
@@ -21,7 +21,7 @@ import TypeResolver from "./typeResolver";
 import { BinaryWriter } from "./writer";
 import { BinaryReader } from "./reader";
 import { ReferenceResolver } from "./referenceResolver";
-import { ConfigFlags, Serializer, Config, Mode, ForyTypeInfoSymbol, 
WithForyClsInfo, TypeId, CustomSerializer } from "./type";
+import { ConfigFlags, Serializer, Config, ForyTypeInfoSymbol, WithForyClsInfo, 
TypeId, CustomSerializer } from "./type";
 import { OwnershipError } from "./error";
 import { InputType, ResultType, StructTypeInfo, TypeInfo } from "./typeInfo";
 import { Gen } from "./gen";
@@ -58,12 +58,12 @@ export default class {
       refTracking: config?.refTracking !== null ? Boolean(config?.refTracking) 
: null,
       useSliceString: Boolean(config?.useSliceString),
       hooks: config?.hooks || {},
-      mode: config?.mode || Mode.SchemaConsistent,
+      compatible: Boolean(config?.compatible),
     };
   }
 
   isCompatible() {
-    return this.config.mode === Mode.Compatible;
+    return this.config.compatible === true;
   }
 
   registerSerializer<T>(constructor: new () => T, customSerializer: 
CustomSerializer<T>): {
@@ -132,6 +132,7 @@ export default class {
       readNoRef: serializer.readNoRef,
       readRef: serializer.readRef,
       readTypeInfo: serializer.readTypeInfo,
+      readRefWithoutTypeInfo: serializer.readRefWithoutTypeInfo,
     } as any)!;
     TypeInfo.detach();
     return result;
diff --git a/javascript/packages/fory/lib/gen/any.ts 
b/javascript/packages/fory/lib/gen/any.ts
index 805cd9e28..b3dd6aa88 100644
--- a/javascript/packages/fory/lib/gen/any.ts
+++ b/javascript/packages/fory/lib/gen/any.ts
@@ -21,7 +21,7 @@ import { TypeInfo } from "../typeInfo";
 import { CodecBuilder } from "./builder";
 import { BaseSerializerGenerator } from "./serializer";
 import { CodegenRegistry } from "./router";
-import { Mode, Serializer, TypeId } from "../type";
+import { Serializer, TypeId } from "../type";
 import { Scope } from "./scope";
 import Fory from "../fory";
 import { TypeMeta } from "../meta/TypeMeta";
@@ -59,7 +59,7 @@ export class AnyHelper {
       case TypeId.NAMED_EXT:
       case TypeId.NAMED_UNION:
       case TypeId.NAMED_COMPATIBLE_STRUCT:
-        if (fory.config.mode === Mode.Compatible || typeId === 
TypeId.NAMED_COMPATIBLE_STRUCT) {
+        if (fory.isCompatible() || typeId === TypeId.NAMED_COMPATIBLE_STRUCT) {
           const typeMeta = 
fory.typeMetaResolver.readTypeMeta(fory.binaryReader);
           const ns = typeMeta.getNs();
           const typeName = typeMeta.getTypeName();
diff --git a/javascript/packages/fory/lib/gen/ext.ts 
b/javascript/packages/fory/lib/gen/ext.ts
index 835e1f525..72081a10d 100644
--- a/javascript/packages/fory/lib/gen/ext.ts
+++ b/javascript/packages/fory/lib/gen/ext.ts
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-import { TypeId, Mode } from "../type";
+import { TypeId } from "../type";
 import { Scope } from "./scope";
 import { CodecBuilder } from "./builder";
 import { StructTypeInfo, TypeInfo } from "../typeInfo";
@@ -149,7 +149,7 @@ class ExtSerializerGenerator extends 
BaseSerializerGenerator {
         writeUserTypeIdStmt = 
this.builder.writer.writeVarUint32Small7(this.typeInfo.userTypeId);
         break;
       case TypeId.NAMED_EXT:
-        if (this.builder.fory.config.mode !== Mode.Compatible) {
+        if (!this.builder.fory.isCompatible()) {
           const typeInfo = this.typeInfo;
           const nsBytes = this.scope.declare("nsBytes", 
this.builder.metaStringResolver.encodeNamespace(CodecBuilder.replaceBackslashAndQuote(typeInfo.namespace)));
           const typeNameBytes = this.scope.declare("typeNameBytes", 
this.builder.metaStringResolver.encodeTypeName(CodecBuilder.replaceBackslashAndQuote(typeInfo.typeName)));
diff --git a/javascript/packages/fory/lib/gen/serializer.ts 
b/javascript/packages/fory/lib/gen/serializer.ts
index 986f2a35f..0923fddaa 100644
--- a/javascript/packages/fory/lib/gen/serializer.ts
+++ b/javascript/packages/fory/lib/gen/serializer.ts
@@ -21,7 +21,7 @@ import { CodecBuilder } from "./builder";
 import { RefFlags, TypeId } from "../type";
 import { Scope } from "./scope";
 import { TypeInfo } from "../typeInfo";
-import { refTrackingAbleTypeId } from "../meta/TypeMeta";
+import { refTrackingUnableTypeId } from "../meta/TypeMeta";
 import { BinaryWriter } from "../writer";
 
 export const makeHead = (flag: RefFlags, typeId: number) => {
@@ -35,7 +35,7 @@ export const makeHead = (flag: RefFlags, typeId: number) => {
 export interface SerializerGenerator {
   writeRef(accessor: string): string;
   writeNoRef(accessor: string): string;
-  writeRefOrNull(assignStmt: (v: string) => string, accessor: string): string;
+  writeRefOrNull(accessor: string, assignStmt: (v: string) => string): string;
   writeTypeInfo(accessor: string): string;
   write(accessor: string): string;
   writeEmbed(): any;
@@ -44,7 +44,8 @@ export interface SerializerGenerator {
   getFixedSize(): number;
   needToWriteRef(): boolean;
 
-  readRef(assignStmt: (v: string) => string, withoutTypeInfo?: boolean): 
string;
+  readRef(assignStmt: (v: string) => string): string;
+  readRefWithoutTypeInfo(assignStmt: (v: string) => string): string;
   readNoRef(assignStmt: (v: string) => string, refState: string): string;
   readTypeInfo(): string;
   read(assignStmt: (v: string) => string, refState: string): string;
@@ -72,7 +73,7 @@ export abstract class BaseSerializerGenerator implements 
SerializerGenerator {
   abstract getFixedSize(): number;
 
   needToWriteRef(): boolean {
-    if (refTrackingAbleTypeId(this.typeInfo.typeId)) {
+    if (refTrackingUnableTypeId(this.typeInfo.typeId)) {
       return false;
     }
     return this.builder.fory.config.refTracking === true;
@@ -106,7 +107,7 @@ export abstract class BaseSerializerGenerator implements 
SerializerGenerator {
     const noneedWrite = this.scope.uniqueName("noneedWrite");
     return `
       let ${noneedWrite} = false;
-      ${this.writeRefOrNull(expr => `${noneedWrite} = ${expr}`, accessor)}
+      ${this.writeRefOrNull(accessor, expr => `${noneedWrite} = ${expr}`)}
       if (!${noneedWrite}) {
         ${this.writeNoRef(accessor)}
       }
@@ -120,7 +121,7 @@ export abstract class BaseSerializerGenerator implements 
SerializerGenerator {
     `;
   }
 
-  writeRefOrNull(assignStmt: (expr: string) => string, accessor: string) {
+  writeRefOrNull(accessor: string, assignStmt: (expr: string) => string) {
     let refFlagStmt = "";
     if (this.needToWriteRef()) {
       const existsId = this.scope.uniqueName("existsId");
@@ -197,14 +198,33 @@ export abstract class BaseSerializerGenerator implements 
SerializerGenerator {
     `;
   }
 
-  readRef(assignStmt: (v: string) => string, withoutTypeInfo = false): string {
+  readRefWithoutTypeInfo(assignStmt: (v: string) => string): string {
     const refFlag = this.scope.uniqueName("refFlag");
     return `
         const ${refFlag} = ${this.builder.reader.int8()};
         switch (${refFlag}) {
             case ${RefFlags.NotNullValueFlag}:
             case ${RefFlags.RefValueFlag}:
-                ${!withoutTypeInfo ? this.readNoRef(assignStmt, `${refFlag} 
=== ${RefFlags.RefValueFlag}`) : this.read(assignStmt, `${refFlag} === 
${RefFlags.RefValueFlag}`)}
+                ${this.read(assignStmt, `${refFlag} === 
${RefFlags.RefValueFlag}`)}
+                break;
+            case ${RefFlags.RefFlag}:
+                
${assignStmt(this.builder.referenceResolver.getReadObject(this.builder.reader.varUInt32()))}
+                break;
+            case ${RefFlags.NullFlag}:
+                ${assignStmt("null")}
+                break;
+        }
+    `;
+  }
+
+  readRef(assignStmt: (v: string) => string): string {
+    const refFlag = this.scope.uniqueName("refFlag");
+    return `
+        const ${refFlag} = ${this.builder.reader.int8()};
+        switch (${refFlag}) {
+            case ${RefFlags.NotNullValueFlag}:
+            case ${RefFlags.RefValueFlag}:
+                ${this.readNoRef(assignStmt, `${refFlag} === 
${RefFlags.RefValueFlag}`)}
                 break;
             case ${RefFlags.RefFlag}:
                 
${assignStmt(this.builder.referenceResolver.getReadObject(this.builder.reader.varUInt32()))}
@@ -258,7 +278,7 @@ export abstract class BaseSerializerGenerator implements 
SerializerGenerator {
         ${this.writeNoRef("v")}
       };
       const writeRefOrNull = (v) => {
-        ${this.writeRefOrNull(expr => `return ${expr};`, "v")}
+        ${this.writeRefOrNull("v", expr => `return ${expr};`)}
       };
       const writeTypeInfo = (v) => {
         ${this.writeTypeInfo("v")}
@@ -269,6 +289,9 @@ export abstract class BaseSerializerGenerator implements 
SerializerGenerator {
       const readRef = () => {
         ${this.readRef(assignStmt => `return ${assignStmt}`)}
       };
+      const readRefWithoutTypeInfo = () => {
+        ${this.readRefWithoutTypeInfo(assignStmt => `return ${assignStmt}`)}
+      };
       const readNoRef = (fromRef) => {
         ${this.readNoRef(assignStmt => `return ${assignStmt}`, "fromRef")}
       };
@@ -295,6 +318,7 @@ export abstract class BaseSerializerGenerator implements 
SerializerGenerator {
 
               read,
               readRef,
+              readRefWithoutTypeInfo,
               readNoRef,
               readTypeInfo,
             };
diff --git a/javascript/packages/fory/lib/gen/struct.ts 
b/javascript/packages/fory/lib/gen/struct.ts
index 6f8627442..e715f7f73 100644
--- a/javascript/packages/fory/lib/gen/struct.ts
+++ b/javascript/packages/fory/lib/gen/struct.ts
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-import { TypeId, Mode, RefFlags } from "../type";
+import { TypeId, RefFlags } from "../type";
 import { Scope } from "./scope";
 import { CodecBuilder } from "./builder";
 import { StructTypeInfo, TypeInfo } from "../typeInfo";
@@ -75,16 +75,17 @@ class StructSerializerGenerator extends 
BaseSerializerGenerator {
   readField(fieldName: string, fieldTypeInfo: TypeInfo, assignStmt: (expr: 
string) => string, embedGenerator: SerializerGenerator, needToWriteRef: 
boolean) {
     const { nullable = false } = this.typeInfo.options.fieldInfo?.[fieldName] 
|| {};
     let { trackingRef } = this.typeInfo.options.fieldInfo?.[fieldName] || {};
+    const { dynamic } = this.typeInfo.options.fieldInfo?.[fieldName] || {};
     if (typeof trackingRef !== "boolean") {
       trackingRef = needToWriteRef;
     }
     const refMode = toRefMode(trackingRef, nullable);
     let stmt = "";
     // polymorphic type
-    if (fieldTypeInfo.isMonomorphic()) {
+    if (fieldTypeInfo.isMonomorphic(dynamic)) {
       if (refMode == RefMode.TRACKING || refMode === RefMode.NULL_ONLY) {
         stmt = `
-            ${embedGenerator.readRef(assignStmt, true)}
+          ${embedGenerator.readRefWithoutTypeInfo(assignStmt)}
         `;
       } else {
         stmt = embedGenerator.read(assignStmt, "false");
@@ -102,18 +103,19 @@ class StructSerializerGenerator extends 
BaseSerializerGenerator {
   writeField(fieldName: string, fieldTypeInfo: TypeInfo, fieldAccessor: 
string, embedGenerator: SerializerGenerator, needToWriteRef: boolean) {
     const { nullable = false } = this.typeInfo.options.fieldInfo?.[fieldName] 
|| {};
     let { trackingRef } = this.typeInfo.options.fieldInfo?.[fieldName] || {};
+    const { dynamic } = this.typeInfo.options.fieldInfo?.[fieldName] || {};
     if (typeof trackingRef !== "boolean") {
       trackingRef = needToWriteRef;
     }
     const refMode = toRefMode(trackingRef, nullable);
     let stmt = "";
     // polymorphic type
-    if (fieldTypeInfo.isMonomorphic()) {
+    if (fieldTypeInfo.isMonomorphic(dynamic)) {
       if (refMode == RefMode.TRACKING) {
         const noneedWrite = this.scope.uniqueName("noneedWrite");
         stmt = `
             let ${noneedWrite} = false;
-            ${embedGenerator.writeRefOrNull(expr => `${noneedWrite} = 
${expr}`, fieldAccessor)}
+            ${embedGenerator.writeRefOrNull(fieldAccessor, expr => 
`${noneedWrite} = ${expr}`)}
             if (!${noneedWrite}) {
               ${embedGenerator.write(fieldAccessor)}
             }
@@ -308,13 +310,16 @@ class StructSerializerGenerator extends 
BaseSerializerGenerator {
   writeEmbed() {
     return new Proxy({}, {
       get: (target, prop: string) => {
-        return (accessor: string) => {
+        return (accessor: string, ...args: any) => {
           const name = this.scope.declare(
             "tag_ser",
             TypeId.isNamedType(this.typeInfo.typeId)
               ? 
this.builder.typeResolver.getSerializerByName(CodecBuilder.replaceBackslashAndQuote(this.typeInfo.named!))
               : 
this.builder.typeResolver.getSerializerById(this.typeInfo.typeId, 
this.typeInfo.userTypeId)
           );
+          if (prop === "writeRefOrNull") {
+            return args[0](`${name}.${prop}(${accessor})`);
+          }
           return `${name}.${prop}(${accessor})`;
         };
       },
@@ -337,7 +342,7 @@ class StructSerializerGenerator extends 
BaseSerializerGenerator {
         }
         break;
       case TypeId.NAMED_STRUCT:
-        if (this.builder.fory.config.mode !== Mode.Compatible) {
+        if (!this.builder.fory.isCompatible()) {
           const typeInfo = this.typeInfo.castToStruct();
           const nsBytes = this.scope.declare("nsBytes", 
this.builder.metaStringResolver.encodeNamespace(CodecBuilder.replaceBackslashAndQuote(typeInfo.namespace)));
           const typeNameBytes = this.scope.declare("typeNameBytes", 
this.builder.metaStringResolver.encodeTypeName(CodecBuilder.replaceBackslashAndQuote(typeInfo.typeName)));
diff --git a/javascript/packages/fory/lib/meta/TypeMeta.ts 
b/javascript/packages/fory/lib/meta/TypeMeta.ts
index 63fbf99c3..6ade956fc 100644
--- a/javascript/packages/fory/lib/meta/TypeMeta.ts
+++ b/javascript/packages/fory/lib/meta/TypeMeta.ts
@@ -51,7 +51,7 @@ export const isPrimitiveTypeId = (typeId: number): boolean => 
{
   return PRIMITIVE_TYPE_IDS.includes(typeId as any);
 };
 
-export const refTrackingAbleTypeId = (typeId: number): boolean => {
+export const refTrackingUnableTypeId = (typeId: number): boolean => {
   return PRIMITIVE_TYPE_IDS.includes(typeId as any) || [TypeId.DURATION, 
TypeId.DATE, TypeId.TIMESTAMP, TypeId.STRING].includes(typeId as any);
 };
 
diff --git a/javascript/packages/fory/lib/type.ts 
b/javascript/packages/fory/lib/type.ts
index 549f972e8..8141b20fa 100644
--- a/javascript/packages/fory/lib/type.ts
+++ b/javascript/packages/fory/lib/type.ts
@@ -224,6 +224,7 @@ export type Serializer<T = any> = {
 
   read: (fromRef: boolean) => T;
   readRef: () => T;
+  readRefWithoutTypeInfo: () => T;
   readNoRef: (fromRef: boolean) => T;
   readTypeInfo: () => void;
 };
@@ -265,7 +266,7 @@ export interface Config {
   hooks: {
     afterCodeGenerated?: (code: string) => string;
   };
-  mode: Mode;
+  compatible?: boolean;
 }
 
 export interface WithForyClsInfo {
diff --git a/javascript/packages/fory/lib/typeInfo.ts 
b/javascript/packages/fory/lib/typeInfo.ts
index 88696b15f..c5c3ac368 100644
--- a/javascript/packages/fory/lib/typeInfo.ts
+++ b/javascript/packages/fory/lib/typeInfo.ts
@@ -26,6 +26,7 @@ export const ForyField = (fieldInfo: {
   nullable?: boolean,
   trackingRef?: boolean,
   id?: number,
+  dynamic?: Dynamic,
 }) => {
   return (target: any, key: string | {name?: string}) => {
     const creator = target.constructor;
@@ -104,7 +105,6 @@ export class TypeInfo<T = unknown> extends 
ExtensibleFunction {
   // Stored as unsigned 32-bit; -1 (0xffffffff) means "unset".
   userTypeId = -1;
   options?: any;
-  dynamic: "TRUE" | "FALSE" | "AUTO" = "AUTO";
   static fory: WeakRef<Fory> | null = null;
 
   static attach(fory: Fory) {
@@ -145,10 +145,10 @@ export class TypeInfo<T = unknown> extends 
ExtensibleFunction {
     if (!fory) {
       throw new Error("fory is not attached")
     }
-    if (internalTypeId === TypeId.NAMED_STRUCT && fory.config.mode === 
Mode.Compatible) {
+    if (internalTypeId === TypeId.NAMED_STRUCT && fory.isCompatible()) {
       return TypeId.NAMED_COMPATIBLE_STRUCT;
     }
-    if (internalTypeId === TypeId.STRUCT && fory.config.mode === 
Mode.Compatible) {
+    if (internalTypeId === TypeId.STRUCT && fory.isCompatible()) {
       return TypeId.COMPATIBLE_STRUCT;
     }
     return this._typeId;
@@ -158,8 +158,8 @@ export class TypeInfo<T = unknown> extends 
ExtensibleFunction {
     return this.computeTypeId(TypeInfo.fory?.deref());
   }
 
-  isMonomorphic() {
-    switch (this.dynamic) {
+  isMonomorphic(dynamic: Dynamic = Dynamic.AUTO) {
+    switch (dynamic) {
       case "TRUE":
         return false;
       case "FALSE":
@@ -367,7 +367,13 @@ export class TypeInfo<T = unknown> extends 
ExtensibleFunction {
   }
 }
 
-type StructFieldInfo = {nullable?: boolean, trackingRef?: boolean, id?: number}
+export enum Dynamic {
+  TRUE = "TRUE",
+  FALSE = "FALSE",
+  AUTO = "AUTO"
+}
+
+type StructFieldInfo = {nullable?: boolean, trackingRef?: boolean, id?: 
number, dynamic?: Dynamic}
 export interface StructTypeInfo extends TypeInfo {
   options: {
     props?: { [key: string]: TypeInfo };
diff --git a/javascript/packages/fory/lib/typeResolver.ts 
b/javascript/packages/fory/lib/typeResolver.ts
index 71a03be25..9dbab56da 100644
--- a/javascript/packages/fory/lib/typeResolver.ts
+++ b/javascript/packages/fory/lib/typeResolver.ts
@@ -64,6 +64,9 @@ const uninitSerialize = {
   readRef: () => {
     throw new Error("uninitSerialize");
   },
+  readRefWithoutTypeInfo: () => {
+    throw new Error("uninitSerialize");
+  },
   readNoRef: (fromRef: boolean) => {
     void fromRef;
     throw new Error("uninitSerialize");
diff --git a/javascript/test/crossLanguage.test.ts 
b/javascript/test/crossLanguage.test.ts
index bd4c5ed5a..6fab9a1ce 100644
--- a/javascript/test/crossLanguage.test.ts
+++ b/javascript/test/crossLanguage.test.ts
@@ -20,9 +20,9 @@
 import Fory, {
   BinaryReader,
   BinaryWriter,
-  Mode,
   ForyField,
   Type,
+  Dynamic,
 } from "../packages/fory/index";
 import { describe, expect, test } from "@jest/globals";
 import * as fs from "node:fs";
@@ -192,7 +192,7 @@ describe("bool", () => {
   });
   test("test_string_serializer", () => {
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true
     });
     // Deserialize strings from Java
     const deserializedStrings = [];
@@ -213,7 +213,7 @@ describe("bool", () => {
   });
   test("test_cross_language_serializer", () => {
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true
     });
 
     // Define and register Color enum
@@ -245,7 +245,7 @@ describe("bool", () => {
   });
   test("test_simple_struct", () => {
     const fory = new Fory({
-      mode: Mode.Compatible,
+      compatible: true,
       hooks: {
         afterCodeGenerated: (code) => {
           return beautify.js(code, { indent_size: 2, space_in_empty_paren: 
true, indent_empty_lines: true });
@@ -310,7 +310,7 @@ describe("bool", () => {
   test("test_named_simple_struct", () => {
     // Same as test_simple_struct but with named registration
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true
     });
 
     // Define Color enum
@@ -365,7 +365,7 @@ describe("bool", () => {
 
   test("test_list", () => {
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true
     });
 
     @Type.struct(102, {
@@ -398,7 +398,7 @@ describe("bool", () => {
 
   test("test_map", () => {
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true
     });
 
     @Type.struct(102, {
@@ -432,7 +432,7 @@ describe("bool", () => {
 
   test("test_integer", () => {
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true
     });
 
     @Type.struct(101, {
@@ -476,7 +476,7 @@ describe("bool", () => {
 
   test("test_item", () => {
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true
     });
 
     @Type.struct(102, {
@@ -511,7 +511,7 @@ describe("bool", () => {
 
   test("test_color", () => {
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true
     });
 
     // Define and register Color enum
@@ -548,7 +548,7 @@ describe("bool", () => {
   });
   test("test_struct_with_list", () => {
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true
     });
 
     @Type.struct(201, {
@@ -585,7 +585,7 @@ describe("bool", () => {
 
   test("test_struct_with_map", () => {
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true
     });
 
     @Type.struct(202, {
@@ -623,7 +623,7 @@ describe("bool", () => {
   test("test_skip_id_custom", () => {
     if (Boolean("1")) { return; }
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true
     });
 
     // Define empty wrapper for deserialization
@@ -647,7 +647,7 @@ describe("bool", () => {
   test("test_skip_name_custom", () => {
     if (Boolean("1")) { return; }
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true
     });
 
     // Define empty wrapper for deserialization
@@ -670,7 +670,7 @@ describe("bool", () => {
 
   test("test_consistent_named", () => {
     const fory = new Fory({
-      mode: Mode.SchemaConsistent,
+      compatible: false,
     });
 
     // Define and register Color enum
@@ -731,7 +731,7 @@ describe("bool", () => {
 
   test("test_struct_version_check", () => {
     const fory = new Fory({
-      mode: Mode.SchemaConsistent,
+      compatible: false,
     });
 
     @Type.struct(201, {
@@ -763,7 +763,7 @@ describe("bool", () => {
   test("test_polymorphic_list", () => {
     if (Boolean("1")) { return; }
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true
     });
 
     // Define Animal interface implementations
@@ -828,7 +828,7 @@ describe("bool", () => {
   test("test_polymorphic_map", () => {
     if (Boolean("1")) { return; }
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true
     });
 
     // Define Animal interface implementations
@@ -891,7 +891,7 @@ describe("bool", () => {
   });
   test("test_one_string_field_schema", () => {
     const fory = new Fory({
-      mode: Mode.SchemaConsistent
+      compatible: false
     });
 
     @Type.struct(200, {
@@ -914,7 +914,7 @@ describe("bool", () => {
   });
   test("test_one_string_field_compatible", () => {
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true
     });
 
     @Type.struct(200, {
@@ -941,7 +941,7 @@ describe("bool", () => {
 
   test("test_two_string_field_compatible", () => {
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true
     });
 
     @Type.struct(201, {
@@ -967,7 +967,7 @@ describe("bool", () => {
   test("test_schema_evolution_compatible", () => {
     if (Boolean("1")) { return; }
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true
     });
 
     @Type.struct(200)
@@ -988,7 +988,7 @@ describe("bool", () => {
   });
   test("test_one_enum_field_schema", () => {
     const fory = new Fory({
-      mode: Mode.SchemaConsistent
+      compatible: false
     });
 
     // Define and register TestEnum
@@ -1022,7 +1022,7 @@ describe("bool", () => {
 
   test("test_one_enum_field_compatible", () => {
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true
     });
 
     // Define and register TestEnum
@@ -1053,7 +1053,7 @@ describe("bool", () => {
 
   test("test_two_enum_field_compatible", () => {
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true
     });
 
     // Define and register TestEnum
@@ -1087,7 +1087,7 @@ describe("bool", () => {
   test("test_enum_schema_evolution_compatible", () => {
     if (Boolean("1")) { return; }
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true
     });
 
     // Register TestEnum
@@ -1270,7 +1270,7 @@ describe("bool", () => {
 
   test("test_nullable_field_schema_consistent_not_null", () => {
     const fory = new Fory({
-      mode: Mode.SchemaConsistent
+      compatible: false
     });
 
     fory.registerSerializer(buildClassConsistent(401));
@@ -1288,7 +1288,7 @@ describe("bool", () => {
 
   test("test_nullable_field_schema_consistent_null", () => {
     const fory = new Fory({
-      mode: Mode.SchemaConsistent
+      compatible: false
     });
     fory.registerSerializer(buildClassConsistent());
 
@@ -1308,7 +1308,7 @@ describe("bool", () => {
 
   test("test_nullable_field_compatible_not_null", () => {
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true
     });
 
     fory.registerSerializer(buildClass());
@@ -1325,7 +1325,7 @@ describe("bool", () => {
 
   test("test_nullable_field_compatible_null", () => {
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true
     });
 
     fory.registerSerializer(buildClass());
@@ -1347,13 +1347,13 @@ describe("bool", () => {
   });
 
   test("test_ref_schema_consistent", () => {
-    if (Boolean("1")) { return; }
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: false,
+      refTracking: true,
     });
 
     @Type.struct(501, {
-      id: Type.int32(),
+      id: Type.varInt32(),
       name: Type.string()
     })
     class RefInner {
@@ -1367,14 +1367,14 @@ describe("bool", () => {
       inner2: Type.struct(501)
     })
     class RefOuter {
+      @ForyField({ trackingRef: true, nullable: true, dynamic: Dynamic.FALSE })
       inner1: RefInner | null = null;
+
+      @ForyField({ trackingRef: true, nullable: true, dynamic: Dynamic.FALSE })
       inner2: RefInner | null = null;
     }
     fory.registerSerializer(RefOuter);
 
-    const reader = new BinaryReader({});
-    reader.reset(content);
-
     // Deserialize outer struct from Java
     let cursor = 0;
     const deserializedOuter = fory.deserialize(content.subarray(cursor));
@@ -1386,13 +1386,13 @@ describe("bool", () => {
   });
 
   test("test_ref_compatible", () => {
-    if (Boolean("1")) { return; }
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true,
+      refTracking: true,
     });
 
     @Type.struct(503, {
-      id: Type.int32(),
+      id: Type.varInt32(),
       name: Type.string()
     })
     class RefInner {
@@ -1406,13 +1406,13 @@ describe("bool", () => {
       inner2: Type.struct(503)
     })
     class RefOuter {
+      @ForyField({ trackingRef: true, nullable: true })
       inner1: RefInner | null = null;
+      @ForyField({ trackingRef: true, nullable: true })
       inner2: RefInner | null = null;
     }
     fory.registerSerializer(RefOuter);
 
-    const reader = new BinaryReader({});
-    reader.reset(content);
 
     // Deserialize outer struct from Java
     let cursor = 0;
@@ -1425,9 +1425,9 @@ describe("bool", () => {
   });
 
   test("test_circular_ref_schema_consistent", () => {
-    if (Boolean("1")) { return; }
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: false,
+      refTracking: true,
     });
 
     @Type.struct(601, {
@@ -1436,6 +1436,7 @@ describe("bool", () => {
     })
     class CircularRefStruct {
       name: string = "";
+      @ForyField({ nullable: true, trackingRef: true })
       selfRef: CircularRefStruct | null = null;
     }
     fory.registerSerializer(CircularRefStruct);
@@ -1454,9 +1455,9 @@ describe("bool", () => {
   });
 
   test("test_circular_ref_compatible", () => {
-    if (Boolean("1")) { return; }
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true,
+      refTracking: true,
     });
 
     @Type.struct(602, {
@@ -1465,13 +1466,11 @@ describe("bool", () => {
     })
     class CircularRefStruct {
       name: string = "";
+      @ForyField({ nullable: true, trackingRef: true })
       selfRef: CircularRefStruct | null = null;
     }
     fory.registerSerializer(CircularRefStruct);
 
-    const reader = new BinaryReader({});
-    reader.reset(content);
-
     // Deserialize circular struct from Java
     let cursor = 0;
     const deserializedStruct = fory.deserialize(content.subarray(cursor));
@@ -1484,7 +1483,7 @@ describe("bool", () => {
 
   test("test_unsigned_schema_consistent_simple", () => {
     const fory = new Fory({
-      mode: Mode.SchemaConsistent
+      compatible: false
     });
 
     @Type.struct(1, {
@@ -1494,7 +1493,7 @@ describe("bool", () => {
     class UnsignedSchemaConsistentSimple {
       u64Tagged: bigint = 0n;
 
-      @ForyField({nullable: true})
+      @ForyField({ nullable: true })
       u64TaggedNullable: bigint | null = null;
     }
     fory.registerSerializer(UnsignedSchemaConsistentSimple);
@@ -1511,7 +1510,7 @@ describe("bool", () => {
 
   test("test_unsigned_schema_consistent", () => {
     const fory = new Fory({
-      mode: Mode.SchemaConsistent
+      compatible: false
     });
 
     @Type.struct(501, {
@@ -1532,31 +1531,31 @@ describe("bool", () => {
       u64FixedField: bigint = 0n;
       u64TaggedField: bigint = 0n;
 
-      @ForyField({nullable: true})
+      @ForyField({ nullable: true })
       @Type.uint8()
       u8NullableField: number = 0;
 
-      @ForyField({nullable: true})
+      @ForyField({ nullable: true })
       @Type.uint16()
       u16NullableField: number = 0;
 
-      @ForyField({nullable: true})
+      @ForyField({ nullable: true })
       @Type.varUInt32()
       u32VarNullableField: number = 0;
 
-      @ForyField({nullable: true})
+      @ForyField({ nullable: true })
       @Type.uint32()
       u32FixedNullableField: number = 0;
 
-      @ForyField({nullable: true})
+      @ForyField({ nullable: true })
       @Type.varUInt64()
       u64VarNullableField: bigint = 0n;
 
-      @ForyField({nullable: true})
+      @ForyField({ nullable: true })
       @Type.uint64()
       u64FixedNullableField: bigint = 0n;
 
-      @ForyField({nullable: true})
+      @ForyField({ nullable: true })
       @Type.taggedUInt64()
       u64TaggedNullableField: bigint = 0n;
     }
@@ -1574,7 +1573,7 @@ describe("bool", () => {
 
   test("test_unsigned_schema_compatible", () => {
     const fory = new Fory({
-      mode: Mode.Compatible
+      compatible: true
     });
 
     @Type.struct(502, {
@@ -1595,31 +1594,31 @@ describe("bool", () => {
       u64FixedField1: bigint = 0n;
       u64TaggedField1: bigint = 0n;
 
-      @ForyField({nullable: true})
+      @ForyField({ nullable: true })
       @Type.uint8()
       u8Field2: number = 0;
 
-      @ForyField({nullable: true})
+      @ForyField({ nullable: true })
       @Type.uint16()
       u16Field2: number = 0;
 
-      @ForyField({nullable: true})
+      @ForyField({ nullable: true })
       @Type.varUInt32()
       u32VarField2: number = 0;
 
-      @ForyField({nullable: true})
+      @ForyField({ nullable: true })
       @Type.uint32()
       u32FixedField2: number = 0;
 
-      @ForyField({nullable: true})
+      @ForyField({ nullable: true })
       @Type.varUInt64()
       u64VarField2: bigint = 0n;
 
-      @ForyField({nullable: true})
+      @ForyField({ nullable: true })
       @Type.uint64()
       u64FixedField2: bigint = 0n;
 
-      @ForyField({nullable: true})
+      @ForyField({ nullable: true })
       @Type.taggedUInt64()
       u64TaggedField2: bigint = 0n;
     }
diff --git a/javascript/test/protocol/struct.test.ts 
b/javascript/test/protocol/struct.test.ts
index e8abde289..a1fb70760 100644
--- a/javascript/test/protocol/struct.test.ts
+++ b/javascript/test/protocol/struct.test.ts
@@ -69,7 +69,7 @@ describe('protocol', () => {
     });
 
     test('should enforce nullable flag in schema-consistent mode', () => {
-        const fory = new Fory({ mode: 'SCHEMA_CONSISTENT' as any });
+        const fory = new Fory({ compatible: false });
 
         const schema = Type.struct(
             { typeName: 'example.schemaConsistentNullable' },
diff --git a/javascript/test/typemeta.test.ts b/javascript/test/typemeta.test.ts
index 29198e628..525ebaeaf 100644
--- a/javascript/test/typemeta.test.ts
+++ b/javascript/test/typemeta.test.ts
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-import Fory, { Type, Mode } from '../packages/fory/index';
+import Fory, { Type } from '../packages/fory/index';
 import {describe, expect, test} from '@jest/globals';
 import * as beautify from 'js-beautify';
 
@@ -26,7 +26,7 @@ describe('typemeta', () => {
   test('should evaluation scheme work', () => {
     
     const fory = new Fory({
-        mode: Mode.Compatible
+        compatible: true
     });    
 
     @Type.struct("example.foo")
@@ -59,7 +59,7 @@ describe('typemeta', () => {
     }
 
     const fory2 = new Fory({
-        mode: Mode.Compatible,
+        compatible: true,
         hooks: {
             afterCodeGenerated: (code: string) => {
                 return beautify.js(code, { indent_size: 2, 
space_in_empty_paren: true, indent_empty_lines: true });


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to