test: virual attribute parsing on records Co-authored-by-AI: IBM Bob (1.126.0+bob2.1.0)
diff --git a/src/test/java/org/eclipse/yasson/records/RecordTest.java b/src/test/java/org/eclipse/yasson/records/RecordTest.java index 3c1b72a..250a001 100644 --- a/src/test/java/org/eclipse/yasson/records/RecordTest.java +++ b/src/test/java/org/eclipse/yasson/records/RecordTest.java
@@ -1,5 +1,6 @@ /* * Copyright (c) 2021, 2025 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2026 Contributors to the Eclipse Foundation * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -21,7 +22,9 @@ import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -119,4 +122,72 @@ .fromJson(expected, new TestTypeToken<CarWithGenerics<Color>>() {}.getType()); assertThat(deserialized, is(car)); } + // ----------------------------------------------------------------- + // isVirtualAccessorMethod — virtual (computed) record attributes + // ----------------------------------------------------------------- + + /** + * A record's zero-parameter, non-void method whose name does not match any + * component must be serialized as a JSON property (virtual attribute). + */ + @Test + public void testRecordVirtualAttributeIsIncludedInJson() { + RecordWithVirtualAttributes record = new RecordWithVirtualAttributes("skoda", "green"); + String json = Jsonbs.defaultJsonb.toJson(record); + + assertThat(json, containsString("\"displayName\":\"skoda (green)\"")); + assertThat(json, containsString("\"componentCount\":2")); + } + + /** + * The standard record components must still appear alongside the virtual attributes. + */ + @Test + public void testRecordVirtualAttributeDoesNotSuppressComponents() { + RecordWithVirtualAttributes record = new RecordWithVirtualAttributes("skoda", "green"); + String json = Jsonbs.defaultJsonb.toJson(record); + + assertThat(json, containsString("\"type\":\"skoda\"")); + assertThat(json, containsString("\"color\":\"green\"")); + } + + /** + * {@code hashCode()} is explicitly excluded by {@code isVirtualAccessorMethod} + * and must not appear in the serialized JSON. + */ + @Test + public void testRecordHashCodeMethodIsNotIncludedInJson() { + RecordWithVirtualAttributes record = new RecordWithVirtualAttributes("skoda", "green"); + String json = Jsonbs.defaultJsonb.toJson(record); + + assertThat(json, not(containsString("\"hashCode\""))); + } + + /** + * {@code toString()} is explicitly excluded by {@code isVirtualAccessorMethod} + * and must not appear in the serialized JSON. + */ + @Test + public void testRecordToStringMethodIsNotIncludedInJson() { + RecordWithVirtualAttributes record = new RecordWithVirtualAttributes("skoda", "green"); + String json = Jsonbs.defaultJsonb.toJson(record); + + assertThat(json, not(containsString("\"toString\""))); + } + + /** + * Virtual attributes are read-only; deserialization of the underlying components + * must still work correctly even when virtual attribute keys are present in the JSON. + * Unknown virtual attribute keys are simply ignored on the way in. + */ + @Test + public void testRecordVirtualAttributeIsIgnoredDuringDeserialization() { + String json = "{\"type\":\"skoda\",\"color\":\"green\"," + + "\"displayName\":\"skoda (green)\",\"componentCount\":2}"; + RecordWithVirtualAttributes deserialized = + Jsonbs.defaultJsonb.fromJson(json, RecordWithVirtualAttributes.class); + + assertThat(deserialized.type(), is("skoda")); + assertThat(deserialized.color(), is("green")); + } }
diff --git a/src/test/java/org/eclipse/yasson/records/RecordWithVirtualAttributes.java b/src/test/java/org/eclipse/yasson/records/RecordWithVirtualAttributes.java new file mode 100644 index 0000000..dfd65f5 --- /dev/null +++ b/src/test/java/org/eclipse/yasson/records/RecordWithVirtualAttributes.java
@@ -0,0 +1,37 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, + * or the Eclipse Distribution License v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ + +package org.eclipse.yasson.records; + +/** + * A record that exposes virtual (computed) attributes alongside its regular components. + * <p> + * <ul> + * <li>{@code type} and {@code color} are standard record components.</li> + * <li>{@code displayName()} is a virtual attribute: a zero-parameter, non-void method + * whose name does not match any component — it should appear in the serialized JSON.</li> + * <li>{@code hashCode()} and {@code toString()} are explicitly excluded by + * {@code isVirtualAccessorMethod} and must NOT appear in the JSON.</li> + * </ul> + */ +public record RecordWithVirtualAttributes(String type, String color) { + + /** Virtual (computed) attribute — should be included in JSON output. */ + public String displayName() { + return type + " (" + color + ")"; + } + + /** Returns a numeric virtual attribute — should be included in JSON output. */ + public int componentCount() { + return 2; + } +}