Commit | Line | Data |
---|---|---|
970ed795 | 1 | /****************************************************************************** |
3abe9331 | 2 | * Copyright (c) 2000-2015 Ericsson Telecom AB |
970ed795 EL |
3 | * All rights reserved. This program and the accompanying materials |
4 | * are made available under the terms of the Eclipse Public License v1.0 | |
5 | * which accompanies this distribution, and is available at | |
6 | * http://www.eclipse.org/legal/epl-v10.html | |
7 | ******************************************************************************/ | |
8 | module AttributeTestcases { | |
9 | ||
10 | import from Functions all; | |
11 | import from Types all; | |
12 | ||
13 | ||
14 | ||
15 | //tests in case of no attributes: | |
16 | //if omit fields do not appear in the encoded text | |
17 | //if all not omitted field appear in the encoded text | |
18 | //if all not omitted field value appear in the correct form | |
19 | testcase tc_NoAttributeOnUpperLevel() runs on MTC { | |
20 | var Profile0 p := { | |
21 | name := "Bob", | |
22 | phone_no := { 6, 1, 3377760 }, | |
23 | email_addr := omit, | |
24 | meetings := omit | |
25 | } | |
26 | ||
27 | var octetstring os := char2oct("{\"name\":\"Bob\",\"phone_no\":{\"CountryPrefix\":6,\"NetworkPrefix\":1,\"LocalNumber\":3377760}}"); | |
28 | f_check_encoding(encoded:= f_enc_profile0(p), expected := os); | |
29 | f_bool2verdict( match(f_dec_profile0(f_enc_profile0(p)), p) ); | |
30 | } | |
31 | ||
32 | //tests in case of selecting attributes: | |
33 | //if omit fields appear in the encoded | |
34 | //if all not omitted field value appear in the correct form | |
35 | testcase tc_name_as_omit_as_null() runs on MTC { | |
36 | var Profile p := { | |
37 | name := "Bob", | |
38 | phone_no := { 6, 1, 3377760 }, | |
39 | email_addr := omit, | |
40 | meetings := omit | |
41 | } | |
42 | ||
43 | var octetstring os := char2oct("{\"name\":\"Bob\",\"phone\":{\"CountryPrefix\":6,\"NetworkPrefix\":1,\"LocalNumber\":3377760},\"meetings\":null}"); | |
44 | f_check_encoding(encoded:= f_enc_profile(p), expected := os); | |
45 | f_bool2verdict( match(f_dec_profile(f_enc_profile(p)), p) ); | |
46 | } | |
47 | ||
48 | testcase tc_name_as() runs on MTC { | |
49 | var Profile p := { | |
50 | name := "Bob", | |
51 | phone_no := { 6, 1, 3377760 }, | |
52 | email_addr := "bob@ericsson.com", | |
53 | meetings := omit | |
54 | } | |
55 | ||
56 | var octetstring os := char2oct("{\"name\":\"Bob\",\"phone\":{\"CountryPrefix\":6,\"NetworkPrefix\":1,\"LocalNumber\":3377760},\"email\":\"bob@ericsson.com\",\"meetings\":null}"); | |
57 | f_check_encoding(encoded:= f_enc_profile(p), expected := os); | |
58 | f_bool2verdict( match(f_dec_profile(f_enc_profile(p)), p) ); | |
59 | } | |
60 | ||
feade998 | 61 | // testing attribute "name as ..." when the aliases are keywords of the JSON variant syntax |
62 | testcase tc_name_as_with_keywords() runs on MTC { | |
63 | var KeywordFields p := { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; | |
64 | var octetstring os := char2oct("{\"omit\":1,\"as\":2,\"null\":3,\"name\":4,\"value\":5,\"default\":6,\"extend\":7,\"metainfo\":8,\"for\":9,\"unbound\":10,\"JSON\":11}"); | |
65 | f_check_encoding(encoded := f_enc_kw_fld(p), expected := os); | |
66 | f_bool2verdict( match(f_dec_kw_fld(os), p) ); | |
67 | } | |
68 | ||
970ed795 EL |
69 | //tests in case of selecting attributes: |
70 | //if omit fields appear in the encoded | |
71 | //if all not omitted field value appear in the correct form | |
72 | testcase tc_attribute_compactprint1() runs on MTC { | |
73 | var Profile p := { | |
74 | name := "Bob", | |
75 | phone_no := { 6, 1, 3377760 }, | |
76 | email_addr := omit, | |
77 | meetings := omit | |
78 | } | |
79 | ||
80 | var octetstring os := char2oct("{\"name\":\"Bob\",\"phone\":{\"CountryPrefix\":6,\"NetworkPrefix\":1,\"LocalNumber\":3377760},\"meetings\":null}"); | |
81 | f_check_encoding(encoded:= f_enc_profile_compact(p), expected := os); | |
82 | f_bool2verdict( match(f_dec_profile(f_enc_profile_compact(p)), p) ); | |
83 | } | |
84 | ||
85 | testcase tc_attribute_compactprint2() runs on MTC { | |
86 | var Profile p := { | |
87 | name := "Bob", | |
88 | phone_no := { 6, 1, 3377760 }, | |
89 | email_addr := "bob@ericsson.com", | |
90 | meetings := omit | |
91 | } | |
92 | ||
93 | var octetstring os := char2oct("{\"name\":\"Bob\",\"phone\":{\"CountryPrefix\":6,\"NetworkPrefix\":1,\"LocalNumber\":3377760},\"email\":\"bob@ericsson.com\",\"meetings\":null}"); | |
94 | f_check_encoding(encoded:= f_enc_profile_compact(p), expected := os); | |
95 | f_bool2verdict( match(f_dec_profile(f_enc_profile_compact(p)), p) ); | |
96 | } | |
97 | ||
98 | testcase tc_attribute_compactprintp() runs on MTC { | |
99 | var Profile p := { | |
100 | name := "Bob", | |
101 | phone_no := { 6, 1, 3377760 }, | |
102 | email_addr := "bob@ericsson.com", | |
103 | meetings := omit | |
104 | } | |
105 | ||
106 | var octetstring os := char2oct("{\"name\":\"Bob\",\"phone\":{\"CountryPrefix\":6,\"NetworkPrefix\":1,\"LocalNumber\":3377760},\"email\":\"bob@ericsson.com\",\"meetings\":null}"); | |
107 | f_check_encoding(encoded:= f_enc_profile_compact_p(p), expected := os); | |
108 | f_bool2verdict( match(f_dec_profile(f_enc_profile_compact_p(p)), p) ); | |
109 | } | |
110 | ||
111 | ||
112 | //tests in case of selecting attributes: | |
113 | //if omit fields appear in the encoded | |
114 | //if all not omitted field value appear in the correct form | |
115 | //pretty printing | |
116 | testcase tc_attribute_prettyprint1() runs on MTC { | |
117 | var Profile p := { | |
118 | name := "Bob", | |
119 | phone_no := { 6, 1, 3377760 }, | |
120 | email_addr := omit, | |
121 | meetings := omit | |
122 | } | |
123 | ||
124 | var octetstring os := char2oct("{\n\t\"name\" : \"Bob\",\n\t\"phone\" : {\n\t\t\"CountryPrefix\" : 6,\n\t\t\"NetworkPrefix\" : 1,\n\t\t\"LocalNumber\" : 3377760\n\t},\n\t\"meetings\" : null\n}"); | |
125 | f_check_encoding(encoded:= f_enc_profile_pretty(p), expected := os); | |
126 | f_bool2verdict( match(f_dec_profile(f_enc_profile(p)), p) ); | |
127 | } | |
128 | ||
129 | //pretty printing | |
130 | testcase tc_attribute_prettyprint2() runs on MTC { | |
131 | var Profile p := { | |
132 | name := "Bob", | |
133 | phone_no := { 6, 1, 3377760 }, | |
134 | email_addr := "bob@ericsson.com", | |
135 | meetings := omit | |
136 | } | |
137 | ||
138 | var octetstring os := char2oct("{\"name\":\"Bob\",\"phone\":{\"CountryPrefix\":6,\"NetworkPrefix\":1,\"LocalNumber\":3377760},\"email\":\"bob@ericsson.com\",\"meetings\":null}"); | |
139 | f_check_encoding(encoded:= f_enc_profile(p), expected := os); | |
140 | f_bool2verdict( match(f_dec_profile(f_enc_profile(p)), p) ); | |
141 | } | |
142 | ||
143 | ||
144 | ||
145 | testcase tc_attribute_union() runs on MTC { | |
146 | var CBA c:= { | |
147 | f_val:= 1.75 | |
148 | } | |
149 | var octetstring os := char2oct("{\"float\":1.750000}"); | |
150 | f_check_encoding(encoded:= f_enc_cba(c) , expected := os); | |
151 | f_bool2verdict( match(f_dec_cba(f_enc_cba(c)), c) ); | |
152 | ||
153 | c:= { i_val := -2 } | |
154 | os := char2oct("{\"int\":-2}"); | |
155 | f_check_encoding(encoded:= f_enc_cba(c) , expected := os); | |
156 | f_bool2verdict( match(f_dec_cba(f_enc_cba(c)), c) ); | |
157 | ||
158 | c:= { cs_val := "Hello" } | |
159 | os := char2oct("{\"string\":\"Hello\"}"); | |
160 | f_check_encoding(encoded:= f_enc_cba(c) , expected := os); | |
161 | f_bool2verdict( match(f_dec_cba(f_enc_cba(c)), c) ); | |
162 | ||
163 | c:= { date_val := {"March",28,Friday} } | |
164 | os := char2oct("{\"date\":{\"month\":\"March\",\"day_idx\":28,\"day_name\":\"Friday\"}}"); | |
165 | f_check_encoding(encoded:= f_enc_cba(c) , expected := os); | |
166 | f_bool2verdict( match(f_dec_cba(f_enc_cba(c)), c) ); | |
167 | } | |
168 | ||
169 | // Encoding unions as JSON values (without the braces and the field name) | |
170 | // The decoder will attempt to decode each field and the first to successfully decode the value | |
171 | // will be the selected one (thus the order of the fields is important) | |
172 | testcase tc_attribute_as_value() runs on MTC { | |
173 | var Stuff stuff := { { ival := 18 }, { osval := '1D66FE'O }, { csval := "almafa" }, { bval := true }, { fval := 1.8e-20}, { ucsval := "almácska" }, { bsval := '1101101'B }, { prodval := { name := "Shoe", price := 79.99, code := 'A4C'H } }, { roival := { 1, 3, 3, 7 } }, { prod2val := { "Car", 14000.0, omit } }, { sizeval := Large }, { unival := { hsval := 'EE0'H } }, { unival := { rocsval := { "one", "two", "ten" } } } }; | |
174 | ||
175 | var octetstring os := unichar2oct("[18,\"1D66FE\",\"almafa\",true,1.800000e-20,\"almácska\",\"1101101\",{\"name\":\"Shoe\",\"price\":79.990000,\"code\":\"A4C\"},[1,3,3,7],{\"name\":\"Car\",\"price\":14000.000000},\"Large\",\"EE0\",[\"one\",\"two\",\"ten\"]]", "UTF-8"); | |
176 | f_check_encoding(encoded:= f_enc_stuff(stuff) , expected := os); | |
177 | f_bool2verdict( match(f_dec_stuff(f_enc_stuff(stuff)), stuff) ); | |
178 | setverdict(pass); | |
179 | } | |
180 | ||
181 | // Testing default values for record fields (decoding only) | |
182 | testcase tc_attribute_default() runs on MTC { | |
183 | var octetstring os := char2oct("{}"); | |
184 | var RecDef d := { i := -19, f := 1000000.000000, b := false, bs := '101'B, hs := 'DEAD'H, os := '1DE7'O, cs := "empty", ucs := "üres", size := Tiny, vt := fail }; | |
185 | f_bool2verdict( match(f_dec_def(os), d) ); | |
186 | ||
187 | os := char2oct("{ \"b\" : null }"); | |
188 | d.b := omit; | |
189 | f_bool2verdict( match(f_dec_def(os), d) ); | |
190 | } | |
191 | ||
3abe9331 | 192 | // Encoding a few values of ASN.1 types with the coding instruction "as value" |
193 | // Results are the same as with the TTCN-3 types | |
194 | testcase tc_attribute_as_value_asn() runs on MTC { | |
195 | var AsnStuff stuff := { { nval := NULL }, { ival := -10 }, { anyval := 'DCBA'O }, { vsval := "something" }, { pardval := { id := 0, priority := low, val := { iNTEGER := -10 } } } }; | |
196 | var octetstring os := char2oct("[null,-10,\"DCBA\",\"something\",{\"id\":0,\"priority\":\"low\",\"val\":{\"iNTEGER\":-10}}]"); | |
197 | f_check_encoding(encoded := f_enc_asn_stuff(stuff), expected := os); | |
198 | f_bool2verdict( match(f_dec_asn_stuff(f_enc_asn_stuff(stuff)), stuff) ); | |
199 | } | |
200 | ||
201 | // Encoding a record with 2 optional union fields encoded as JSON values (attribute 'as value') | |
202 | // and as the 'null' value when omitted (attribute 'omit as null'). | |
203 | // One of the unions ('uniAsn') can decode the JSON value 'null' (field 'nval'), thus omitting | |
204 | // the union and setting this field have the same encoding, and decoding 'null' always sets the | |
205 | // field instead of omitting the union. | |
206 | // The other union ('uniTtcn') cannot decode the JSON value 'null', thus decoding 'null' omits | |
207 | // the union. | |
208 | testcase tc_attribute_optional_as_value() runs on MTC { | |
209 | var OptionalUnions val1 := { dummy := "nothing", uniTtcn := omit, uniAsn := omit }; | |
210 | var OptionalUnions val2 := { dummy := "nothing", uniTtcn := omit, uniAsn := { nval := NULL } }; | |
211 | var octetstring os := char2oct("{\"dummy\":\"nothing\",\"uniTtcn\":null,\"uniAsn\":null}"); | |
212 | f_check_encoding(encoded := f_enc_opt_uni(val1), expected := os); | |
213 | f_check_encoding(encoded := f_enc_opt_uni(val2), expected := os); | |
214 | f_bool2verdict( match(f_dec_opt_uni(os), val2) ); | |
215 | } | |
216 | ||
217 | // Encoding records and sets with unbound fields with meta info (attribute 'metainfo for unbound') | |
218 | // The unbound fields will have the 'null' value and an extra (meta info) field will be inserted | |
219 | // into the JSON document (after the current field) to specify that the field is unbound. | |
220 | testcase tc_attribute_metainfo_for_unbound() runs on MTC { | |
221 | // regular encoding and decoding tests | |
222 | var MetainfoRecord r := { num := 6 }; | |
223 | var octetstring os := char2oct("{\"num\":6,\"str\":null,\"metainfo str\":\"unbound\"}"); | |
224 | f_check_encoding(encoded := f_enc_meta_rec(r), expected := os); | |
225 | f_bool2verdict( log2str(f_dec_meta_rec(os)) == log2str(r) ); | |
226 | ||
227 | var MetainfoSet s := { str := "abc" }; | |
228 | os := char2oct("{\"int\":null,\"metainfo int\":\"unbound\",\"str\":\"abc\",\"octets\":null,\"metainfo octets\":\"unbound\"}"); | |
229 | f_check_encoding(encoded := f_enc_meta_set(s), expected := os); | |
230 | f_bool2verdict( log2str(f_dec_meta_set(os)) == log2str(s) ); | |
231 | ||
232 | // positive decoding tests (these cannot be produced by the encoder, but are still accepted by the decoder) | |
233 | os := char2oct("{ \"int\" : 3, \"str\" : \"abc\", \"octets\" : \"1234\", \"metainfo int\" : \"unbound\" }"); | |
234 | var MetainfoSet res := { str := "abc", octets := '1234'O }; | |
235 | f_bool2verdict( log2str(f_dec_meta_set(os)) == log2str(res) ); | |
236 | ||
237 | os := char2oct("{ \"metainfo int\" : \"unbound\", \"int\" : null, \"str\" : \"abc\", \"octets\" : \"1234\" }"); | |
238 | f_bool2verdict( log2str(f_dec_meta_set(os)) == log2str(res) ); // same expected result | |
239 | } | |
970ed795 | 240 | |
3abe9331 | 241 | // Negative tests for decoding with the unbound meta info attribute |
242 | testcase tc_attribute_metainfo_for_unbound_negtest() runs on MTC { | |
243 | var octetstring os := char2oct("{ \"metainfo num\" : \"unbound\", \"num\" : 6, \"str\" : \"qwe\" }"); | |
244 | var MetainfoRecord dummyRec; | |
245 | @try { | |
246 | dummyRec := f_dec_meta_rec(os); | |
247 | setverdict(fail, "Expected error when decoding ", os); | |
248 | } | |
249 | @catch (msg) { | |
250 | if (not match (msg, pattern "*Meta info not applicable to field 'num'")) { | |
251 | setverdict(fail, "Unexpected error message when decoding ", os, " (msg: ", msg, ")"); | |
252 | } | |
253 | } | |
254 | ||
255 | os := char2oct("{ \"metainfo dummy\" : \"unbound\", \"num\" : 6, \"str\" : \"qwe\" }"); | |
256 | @try { | |
257 | dummyRec := f_dec_meta_rec(os); | |
258 | setverdict(fail, "Expected error when decoding ", os); | |
259 | } | |
260 | @catch (msg) { | |
261 | if (not match (msg, pattern "*Meta info provided for non-existent field 'dummy'")) { | |
262 | setverdict(fail, "Unexpected error message when decoding ", os, " (msg: ", msg, ")"); | |
263 | } | |
264 | } | |
265 | ||
266 | os := char2oct("{ \"int\" : 3, \"str\" : \"abc\", \"octets\" : \"1234\", \"metainfo int\" : \"bound\" }"); | |
267 | var MetainfoSet dummySet; | |
268 | @try { | |
269 | dummySet := f_dec_meta_set(os); | |
270 | setverdict(fail, "Expected error when decoding ", os); | |
271 | } | |
272 | @catch (msg) { | |
273 | if (not match (msg, pattern "*Invalid meta info for field 'num'")) { | |
274 | setverdict(fail, "Unexpected error message when decoding ", os, " (msg: ", msg, ")"); | |
275 | } | |
276 | } | |
277 | ||
278 | os := char2oct("{ \"int\" : 3, \"str\" : \"abc\", \"octets\" : \"1234\", \"metainfo int\" : 88 }"); | |
279 | @try { | |
280 | dummySet := f_dec_meta_set(os); | |
281 | setverdict(fail, "Expected error when decoding ", os); | |
282 | } | |
283 | @catch (msg) { | |
284 | if (not match (msg, pattern "*Invalid meta info for field 'num'")) { | |
285 | setverdict(fail, "Unexpected error message when decoding ", os, " (msg: ", msg, ")"); | |
286 | } | |
287 | } | |
288 | ||
289 | os := char2oct("{ \"int\" : null, \"str\" : \"abc\", \"octets\" : \"1234\" }"); | |
290 | @try { | |
291 | dummySet := f_dec_meta_set(os); | |
292 | setverdict(fail, "Expected error when decoding ", os); | |
293 | } | |
294 | @catch (msg) { | |
295 | if (not match (msg, pattern "*Invalid JSON token found while decoding field 'num'")) { | |
296 | setverdict(fail, "Unexpected error message when decoding ", os, " (msg: ", msg, ")"); | |
297 | } | |
298 | } | |
299 | ||
300 | os := char2oct("{ \"metainfo int\" : \"unbound\", \"int\" : [ 1, 3 ], \"str\" : \"abc\", \"octets\" : \"1234\" }"); | |
301 | @try { | |
302 | dummySet := f_dec_meta_set(os); | |
303 | setverdict(fail, "Expected error when decoding ", os); | |
304 | } | |
305 | @catch (msg) { | |
306 | if (not match (msg, pattern "*Invalid JSON token found while decoding field 'num'")) { | |
307 | setverdict(fail, "Unexpected error message when decoding ", os, " (msg: ", msg, ")"); | |
308 | } | |
309 | } | |
310 | setverdict(pass); | |
311 | } | |
970ed795 | 312 | |
feade998 | 313 | // Decoding test for the 'metainfo for unbound' attribute, where all fields of an embedded record are |
314 | // set to unbound by meta info. The decoded embedded record should be unbound. | |
315 | testcase tc_attribute_metainfo_for_unbound_empty_rec() runs on MTC { | |
316 | var charstring dec_str := "{\"mynum\":99,\"mystr\":\"aa\", \"myRec\": {\"num\":null,\"metainfo num\":\"unbound\",\"str\":null,\"metainfo str\":\"unbound\" } }"; | |
317 | var MetainfoOuterRecord dec_val := f_dec_meta_outer_rec(char2oct(dec_str)); | |
318 | if (isbound(dec_val.myRec)) { | |
319 | setverdict(fail, "Field myrec should be unbound after decoding, instead of ", dec_val.myRec); | |
320 | } | |
321 | var MetainfoOuterRecord dec_val_exp := { mynum := 99, mystr := "aa", myRec := - }; | |
322 | if (log2str(dec_val) != log2str(dec_val_exp)) { | |
323 | setverdict(fail, "Invalid value after decoding. Expected: ", dec_val_exp, ", got: ", dec_val); | |
324 | } | |
325 | setverdict(pass); | |
326 | } | |
327 | ||
328 | // Encoding array types with unbound elements with meta info (attribute 'metainfo for unbound') | |
329 | // A JSON object with one key-value pair (containing the meta info) specifies that an element is unbound. | |
330 | testcase tc_attribute_metainfo_for_unbound_arrays() runs on MTC { | |
331 | // test 1: pre-generated array type (record of integer) | |
332 | var MetainfoRecOf recof := { 1, 2, -, 4 }; | |
333 | var octetstring os := char2oct("[1,2,{\"metainfo []\":\"unbound\"},4]"); | |
334 | f_check_encoding(encoded := f_enc_meta_recof(recof), expected := os); | |
335 | f_bool2verdict( log2str(f_dec_meta_recof(os)) == log2str(recof) ); | |
336 | ||
337 | // test 2: array of a structured type (set of MetainfoRecord) | |
338 | var MetainfoSetOf setof := { { num := 3, str := "abc" }, -, { num := 6 } }; | |
339 | os := char2oct("[{\"num\":3,\"str\":\"abc\"},{\"metainfo []\":\"unbound\"},{\"num\":6,\"str\":null,\"metainfo str\":\"unbound\"}]"); | |
340 | f_check_encoding(encoded := f_enc_meta_setof(setof), expected := os); | |
341 | f_bool2verdict( log2str(f_dec_meta_setof(os)) == log2str(setof) ); | |
342 | ||
343 | // test 3: TTCN-3 array (float [3]) | |
344 | var MetainfoArray arr := { 3.0, 6.0, - }; | |
345 | os := char2oct("[3.000000,6.000000,{\"metainfo []\":\"unbound\"}]"); | |
346 | f_check_encoding(encoded := f_enc_meta_arr(arr), expected := os); | |
347 | f_bool2verdict( log2str(f_dec_meta_arr(os)) == log2str(arr) ); | |
348 | } | |
349 | ||
970ed795 EL |
350 | |
351 | control { | |
352 | execute(tc_NoAttributeOnUpperLevel()) | |
353 | execute(tc_name_as_omit_as_null()); | |
354 | execute(tc_name_as()); | |
feade998 | 355 | execute(tc_name_as_with_keywords()); |
970ed795 EL |
356 | execute(tc_attribute_compactprint1()); |
357 | execute(tc_attribute_compactprint2()); | |
358 | execute(tc_attribute_compactprintp()); | |
359 | execute(tc_attribute_prettyprint1()); | |
360 | execute(tc_attribute_prettyprint2()); | |
361 | execute(tc_attribute_union()); | |
362 | execute(tc_attribute_as_value()); | |
363 | //execute(tc_attribute_default()); | |
3abe9331 | 364 | execute(tc_attribute_as_value_asn()); |
365 | execute(tc_attribute_optional_as_value()); | |
366 | execute(tc_attribute_metainfo_for_unbound()); | |
367 | execute(tc_attribute_metainfo_for_unbound_negtest()); | |
feade998 | 368 | execute(tc_attribute_metainfo_for_unbound_empty_rec()); |
369 | execute(tc_attribute_metainfo_for_unbound_arrays()); | |
970ed795 EL |
370 | } |
371 | } |