1 module tests.cases;
2 import tests.data;
3 import mir.ser.text;
4 import mir.ion.stream;
5 import mir.ion.conv;
6 
7 struct IonTestCase {
8     string name;
9     IonTestData data;
10     bool expectedFail;
11     IonDataType wantedData;
12 }
13 
14 @IonTestCase("Known-good Ion data", IonTestData.good, false, IonDataType.all)
15 @IonTestCase("Known-good Ion typecodes", IonTestData.goodTypecodes, false, IonDataType.all)
16 @IonTestCase("Known-good Ion timestamps", IonTestData.goodTimestamp, false, IonDataType.all)
17 @IonTestCase("Known-bad Ion data", IonTestData.bad, true, IonDataType.all)
18 @IonTestCase("Known-bad Ion typecodes", IonTestData.badTypecodes, true, IonDataType.all)
19 @IonTestCase("Known-bad Ion timestamps", IonTestData.badTimestamp, true, IonDataType.all)
20 void testBasicData(Test test) {
21     if (test.type == IonDataType.binary) {
22         auto v = test.data.ion2text;
23     } else {
24         const(char)[] text = cast(const(char)[])test.data;
25         auto v = text.text2ion.ion2text;
26     }
27 }
28 
29 @IonTestCase("Binary round-trip testing", IonTestData.roundtrip, false, IonDataType.binary)
30 void testBinaryRoundTrip(Test test) {
31     const(char)[] text = test.data.ion2text;
32     const(char)[] roundtrip = text.text2ion.ion2text;
33     assert(text == roundtrip, "\nexcpected: " ~ text ~ "\n      got: " ~ roundtrip ~ "\n");
34 }
35 
36 @IonTestCase("Text round-trip testing", IonTestData.roundtrip, false, IonDataType.text)
37 void testTextRoundTrip(Test test) {
38     const(char)[] text = cast(const(char)[])test.data;
39     auto input = text.text2ion.IonValueStream;
40     if (test.verbose) {
41         debug import std.stdio;
42         debug writefln("ser: %s", input.serializeText);
43     }
44     auto roundTrip = input.serializeText.text2ion.IonValueStream;
45     if (test.verbose) {
46         if (input.serializeText != roundTrip.serializeText) {
47             debug import std.stdio;
48             debug writefln("input: %s", text);
49             debug writefln("stage 1: %s", input.serializeText);
50             debug writefln("stage 2: %s", roundTrip.serializeText);
51 
52             debug writefln("== DUMPING ION VALUE STREAM ==");
53             foreach(symbolTable, ionValue; input) {
54                 debug writefln("%s", ionValue);
55             }
56             debug writefln("== DUMPING RT VALUE STREAM ==");
57             foreach(symbolTable, ionValue; roundTrip) {
58                 debug writefln("%s", ionValue);
59             }
60         }
61     }
62     assert(input.serializeText == roundTrip.serializeText);
63 }
64 
65 @IonTestCase("Equivalence testing", IonTestData.equivs, false, IonDataType.all)
66 void testEquivs(Test test) {
67     import mir.ion.type_code;
68     import mir.ion.value;
69     IonValueStream input;
70     if (test.type == IonDataType.binary) {
71         input = test.data.ion2text.text2ion.IonValueStream;
72     } else {
73         const(char)[] text = cast(const(char)[])test.data;
74         input = text.text2ion.IonValueStream;
75     }
76 
77     foreach(const(char[])[] symbolTable, IonDescribedValue ionValue; input) {
78         if (ionValue.descriptor.type == IonTypeCode.sexp) {
79             IonSexp sexp = ionValue.get!(IonSexp);
80             IonDescribedValue first;
81             int i = 0;
82             foreach(scope IonDescribedValue value; sexp) {
83                 if (i++ == 0) {
84                     first = value;
85                 }
86                 else {
87                     assert(first == value);
88                 }
89             }
90         }
91         else if (ionValue.descriptor.type == IonTypeCode.struct_) {
92             // TODO: fill these in when the text reader doesn't throw when trying to read
93         }
94         else if (ionValue.descriptor.type == IonTypeCode.list) {
95             IonList list = ionValue.get!(IonList);
96             IonDescribedValue first;
97             int i = 0;
98             foreach(scope IonDescribedValue value; list) {
99                 if (i++ == 0) {
100                     first = value;
101                 } else {
102                     assert(value == first);
103                 }
104             }
105         }
106     }
107 }
108 
109 @IonTestCase("Non-equivalence testing", IonTestData.nonequivs, false, IonDataType.all)
110 void testNonEquivs(Test test) {
111     import mir.ion.type_code;
112     import mir.ion.value;
113     IonValueStream input;
114     if (test.type == IonDataType.binary) {
115         input = test.data.ion2text.text2ion.IonValueStream;
116     } else {
117         const(char)[] text = cast(const(char)[])test.data;
118         input = text.text2ion.IonValueStream;
119     }
120 
121     foreach(const(char[])[] symbolTable, IonDescribedValue ionValue; input) {
122         if (ionValue.descriptor.type == IonTypeCode.sexp) {
123             IonSexp sexp = ionValue.get!(IonSexp);
124             IonDescribedValue first;
125             int i = 0;
126             foreach(scope IonDescribedValue value; sexp) {
127                 if (i++ == 0) {
128                     first = value;
129                 }
130                 else {
131                     assert(value != first);
132                 }
133             }
134         }
135         else if (ionValue.descriptor.type == IonTypeCode.struct_) {
136             // TODO: fill these in when the text reader doesn't throw when trying to read
137         }
138         else if (ionValue.descriptor.type == IonTypeCode.list) {
139             IonList list = ionValue.get!(IonList);
140             IonDescribedValue first;
141             int i = 0;
142             foreach(scope IonDescribedValue value; list) {
143                 if (i++ == 0) {
144                     first = value;
145                 } else {
146                     assert(value != first, );
147                 }
148             }
149         }
150     }
151 }