blob: dc195ae017d647566a3a77799d0ad66e2257e235 [file] [log] [blame]
Matthias Andreas Benkarddf853ef2023-12-10 20:29:35 +01001package eu.mulk.jgvariant.core;
2
3import java.text.ParseException;
Matthias Andreas Benkarde1c093e2024-03-03 09:01:19 +01004import java.util.*;
5import java.util.function.Supplier;
Matthias Andreas Benkarddf853ef2023-12-10 20:29:35 +01006import net.jqwik.api.*;
7
8@SuppressWarnings("java:S2187")
9class DecoderPropertyTest {
10
11 @Group
12 class VariantRoundtripLaw implements RoundtripLaw<Variant> {
13
14 @Override
15 public Decoder<Variant> decoder() {
16 return Decoder.ofVariant();
17 }
18
19 @Override
20 public Arbitrary<Variant> anyT() {
21 return anyVariant();
22 }
23 }
24
25 interface RoundtripLaw<T> {
26
27 @Property
28 default boolean roundtripsWell(@ForAll(value = "anyT") T entityLeft) {
29 var decoder = decoder();
30 var bytes = decoder.encode(entityLeft);
31 var entityRight = decoder.decode(bytes);
Matthias Andreas Benkarde1c093e2024-03-03 09:01:19 +010032 return Objects.equals(entityLeft, entityRight);
Matthias Andreas Benkarddf853ef2023-12-10 20:29:35 +010033 }
34
35 Decoder<T> decoder();
36
37 @Provide
38 Arbitrary<T> anyT();
39 }
40
41 @Provide
42 Arbitrary<Variant> anyVariant() {
Matthias Andreas Benkarde1c093e2024-03-03 09:01:19 +010043 // Base cases
Matthias Andreas Benkarddf853ef2023-12-10 20:29:35 +010044 var anyString = Arbitraries.strings().map(s -> new Variant(parseSignature("s"), s));
45 var anyInt = Arbitraries.integers().map(i -> new Variant(parseSignature("i"), i));
46 var anyLong = Arbitraries.longs().map(l -> new Variant(parseSignature("x"), l));
47 var anyDouble = Arbitraries.doubles().map(d -> new Variant(parseSignature("d"), d));
48 var anyBoolean =
49 Arbitraries.of(Boolean.TRUE, Boolean.FALSE).map(b -> new Variant(parseSignature("b"), b));
50 var anyByte = Arbitraries.bytes().map(b -> new Variant(parseSignature("y"), b));
51 var anyShort = Arbitraries.shorts().map(s -> new Variant(parseSignature("n"), s));
52 var anyByteArray = Arbitraries.bytes().list().map(b -> new Variant(parseSignature("ay"), b));
Matthias Andreas Benkarde1c093e2024-03-03 09:01:19 +010053
54 // Singly recursive cases
55 Supplier<Arbitrary<Variant>> anySome =
56 () ->
57 anyVariant()
58 .map(
59 x ->
60 new Variant(
61 parseSignature("m" + x.signature().toString()),
62 Optional.of(x.value())));
63 Supplier<Arbitrary<Variant>> anyNone =
64 () ->
65 anyVariant()
66 .map(
67 x ->
68 new Variant(
69 parseSignature("m" + x.signature().toString()), Optional.empty()));
70 Supplier<Arbitrary<Variant>> anyNestedVariant =
71 () -> anyVariant().map(v -> new Variant(parseSignature("v"), v));
72
73 // Fixed-multiplicity recursive cases
74 /* fixme: Object[] does not work for comparison by Object#equals() */
75 Supplier<Arbitrary<Variant>> anyPair =
76 () ->
77 Combinators.combine(anyVariant(), anyVariant())
78 .as(
79 (v1, v2) ->
80 new Variant(
81 parseSignature("(%s%s)".formatted(v1.signature(), v2.signature())),
82 new Object[] {v1.value(), v2.value()}));
83 Supplier<Arbitrary<Variant>> anyTriple =
84 () ->
85 Combinators.combine(anyVariant(), anyVariant(), anyVariant())
86 .as(
87 (v1, v2, v3) ->
88 new Variant(
89 parseSignature(
90 "(%s%s%s)"
91 .formatted(v1.signature(), v2.signature(), v3.signature())),
92 new Object[] {v1.value(), v2.value(), v3.value()}));
93
94 // Indefinite-multiplicity recursive cases
95 Supplier<Arbitrary<Variant>> anyVariantList =
96 () ->
97 anyVariant().list().map(ArrayList::new).map(l -> new Variant(parseSignature("av"), l));
98 Supplier<Arbitrary<Variant>> anyStringVariantMap =
99 () ->
100 Arbitraries.maps(Arbitraries.strings(), anyVariant())
101 .map(LinkedHashMap::new)
102 .map(m -> new Variant(parseSignature("a{sv}"), m));
103
104 // fixme: anyPair, anyTriple (see above)
105 return Arbitraries.frequencyOf(
106 Tuple.of(10, anyString),
107 Tuple.of(10, anyInt),
108 Tuple.of(10, anyLong),
109 Tuple.of(10, anyDouble),
110 Tuple.of(10, anyBoolean),
111 Tuple.of(10, anyByte),
112 Tuple.of(10, anyShort),
113 Tuple.of(10, anyByteArray),
114 Tuple.of(10, Arbitraries.lazy(anySome)),
115 Tuple.of(10, Arbitraries.lazy(anyNone)),
116 Tuple.of(10, Arbitraries.lazy(anyNestedVariant)),
117 Tuple.of(1, Arbitraries.lazy(anyStringVariantMap)),
118 Tuple.of(1, Arbitraries.lazy(anyVariantList))
119 /*,
120 anyPair,
121 anyTriple
122 */ );
Matthias Andreas Benkarddf853ef2023-12-10 20:29:35 +0100123 }
124
125 private Signature parseSignature(String s) {
126 try {
127 return Signature.parse(s);
128 } catch (ParseException e) {
129 throw new AssertionError(e);
130 }
131 }
132}