Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions java/fory-core/src/test/java/org/apache/fory/CPPXlangTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,16 @@ private void runBazelCommand(String... args) throws IOException {
public void testConsistentNamed() throws java.io.IOException {
super.testConsistentNamed();
}

@Test
@Override
public void testStructWithUnionFields() throws java.io.IOException {
throw new SkipException("Union types not yet supported in C++");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add cpp tests in cpp/fory/serialization/xlang_test_main.cc?

Only added cpp tests, and make it pass, we can ensure union xlang serialization is OK

}

@Test
@Override
public void testTopLevelUnion() throws java.io.IOException {
throw new SkipException("Union types not yet supported in C++");
}
}
12 changes: 12 additions & 0 deletions java/fory-core/src/test/java/org/apache/fory/GoXlangTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -233,4 +233,16 @@ public void testTwoEnumFieldCompatible() throws java.io.IOException {
public void testEnumSchemaEvolutionCompatible() throws java.io.IOException {
super.testEnumSchemaEvolutionCompatible();
}

@Test
@Override
public void testStructWithUnionFields() throws java.io.IOException {
throw new SkipException("Union types not yet supported in Go");
}

@Test
@Override
public void testTopLevelUnion() throws java.io.IOException {
throw new SkipException("Union types not yet supported in Go");
}
}
12 changes: 12 additions & 0 deletions java/fory-core/src/test/java/org/apache/fory/RustXlangTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,16 @@ protected CommandContext buildCommandContext(String caseName, Path dataFile) {
.build();
return new CommandContext(command, env, new File("../../rust"));
}

@Test
@Override
public void testStructWithUnionFields() throws java.io.IOException {
throw new SkipException("Union types not yet supported in Rust");
}

@Test
@Override
public void testTopLevelUnion() throws java.io.IOException {
throw new SkipException("Union types not yet supported in Rust");
}
}
107 changes: 107 additions & 0 deletions java/fory-core/src/test/java/org/apache/fory/XlangTestBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@
import org.apache.fory.memory.MemoryUtils;
import org.apache.fory.serializer.Serializer;
import org.apache.fory.test.TestUtils;
import org.apache.fory.type.union.Union;
import org.apache.fory.type.union.Union2;
import org.apache.fory.type.union.Union3;
import org.apache.fory.type.union.Union4;
import org.apache.fory.type.union.Union5;
import org.apache.fory.type.union.Union6;
import org.apache.fory.util.MurmurHash3;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
Expand Down Expand Up @@ -1575,6 +1581,107 @@ public void testEnumSchemaEvolutionCompatible() throws java.io.IOException {
Assert.assertNull(result2.f2);
}

// ============================================================================
// Union type tests
// ============================================================================

/** Struct containing Union fields of different arities (Union through Union6). */
@Data
public static class StructWithUnionFields {
public Union union;
public Union2<String, Long> union2;
public Union3<Integer, String, Double> union3;
public Union4<Integer, String, Double, Boolean> union4;
public Union5<Integer, String, Double, Boolean, Long> union5;
public Union6<Integer, String, Double, Boolean, Long, Float> union6;
}

@Test
public void testStructWithUnionFields() throws java.io.IOException {
String caseName = "test_struct_with_union_fields";
Fory fory =
Fory.builder()
.withLanguage(Language.XLANG)
.withCompatibleMode(CompatibleMode.SCHEMA_CONSISTENT)
.withCodegen(false)
.build();
fory.register(StructWithUnionFields.class, 200);

StructWithUnionFields obj = new StructWithUnionFields();
obj.union = new Union(0, 42);
obj.union2 = Union2.ofT1("hello");
obj.union3 = Union3.ofT2("world");
obj.union4 = Union4.ofT3(3.14);
obj.union5 = Union5.ofT4(true);
obj.union6 = Union6.ofT5(999L);

MemoryBuffer buffer = MemoryUtils.buffer(128);
fory.serialize(buffer, obj);

ExecutionContext ctx = prepareExecution(caseName, buffer.getBytes(0, buffer.writerIndex()));
runPeer(ctx);

MemoryBuffer buffer2 = readBuffer(ctx.dataFile());
StructWithUnionFields result = (StructWithUnionFields) fory.deserialize(buffer2);

Assert.assertEquals(result.union.getIndex(), 0);
Assert.assertEquals(result.union.getValue(), 42);
Assert.assertEquals(result.union2.getIndex(), 0);
Assert.assertEquals(result.union2.getValue(), "hello");
Assert.assertTrue(result.union2.isT1());
Assert.assertEquals(result.union3.getIndex(), 1);
Assert.assertEquals(result.union3.getValue(), "world");
Assert.assertTrue(result.union3.isT2());
Assert.assertEquals(result.union4.getIndex(), 2);
Assert.assertEquals((Double) result.union4.getValue(), 3.14, 0.001);
Assert.assertTrue(result.union4.isT3());
Assert.assertEquals(result.union5.getIndex(), 3);
Assert.assertEquals(result.union5.getValue(), true);
Assert.assertTrue(result.union5.isT4());
Assert.assertEquals(result.union6.getIndex(), 4);
Assert.assertEquals(result.union6.getValue(), 999L);
Assert.assertTrue(result.union6.isT5());
}

@Test
public void testTopLevelUnion() throws java.io.IOException {
String caseName = "test_top_level_union";
Fory fory =
Fory.builder()
.withLanguage(Language.XLANG)
.withCompatibleMode(CompatibleMode.SCHEMA_CONSISTENT)
.withCodegen(false)
.build();

// Test Union with integer value
Union union1 = new Union(0, 42);
MemoryBuffer buffer = MemoryUtils.buffer(64);
fory.serialize(buffer, union1);

ExecutionContext ctx1 =
prepareExecution(caseName + "_int", buffer.getBytes(0, buffer.writerIndex()));
runPeer(ctx1);

MemoryBuffer buffer2 = readBuffer(ctx1.dataFile());
Union result1 = (Union) fory.deserialize(buffer2);
Assert.assertEquals(result1.getIndex(), 0);
Assert.assertEquals(result1.getValue(), 42);

// Test Union with string value
Union union2 = new Union(1, "hello");
buffer = MemoryUtils.buffer(64);
fory.serialize(buffer, union2);

ExecutionContext ctx2 =
prepareExecution(caseName + "_str", buffer.getBytes(0, buffer.writerIndex()));
runPeer(ctx2);

MemoryBuffer buffer3 = readBuffer(ctx2.dataFile());
Union result2 = (Union) fory.deserialize(buffer3);
Assert.assertEquals(result2.getIndex(), 1);
Assert.assertEquals(result2.getValue(), "hello");
}

@SuppressWarnings("unchecked")
private void assertStringEquals(Object actual, Object expected, boolean useToString) {
if (useToString) {
Expand Down
Loading