File: TfunctionSubref.ttcn

package info (click to toggle)
eclipse-titan 8.2.0-1
  • links: PTS
  • area: main
  • in suites: bookworm, sid
  • size: 103,544 kB
  • sloc: cpp: 271,008; ansic: 33,683; yacc: 23,419; makefile: 15,483; lex: 9,204; java: 4,848; perl: 4,555; sh: 2,242; xml: 1,378; javascript: 85; awk: 48; php: 32; python: 13
file content (591 lines) | stat: -rw-r--r-- 26,946 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
/******************************************************************************
 * Copyright (c) 2000-2021 Ericsson Telecom AB
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
 *
 * Contributors:
 *   Balasko, Jeno
 *   Baranyi, Botond
 *
 ******************************************************************************/

// This module contains tests for using subreferences (field names and array indexes) on the
// return values of function calls.
module TfunctionSubref {

/* * * * Types * * * */
type record Rec {
  integer num,
  charstring str
}

type record of integer RoI;

type union Uni {
  integer i,
  float f,
  boolean b,
  bitstring bs,
  hexstring hs,
  octetstring os,
  charstring cs,
  universal charstring ucs,
  verdicttype vt,
  enumerated { Small, Medium, Large } size
}

type octetstring Arr[4];

type record of Uni RoUni;

type set Complex {
  Rec rec,
  RoI roi,
  RoUni unis
}

type port PT message {
  inout integer, octetstring
}
with { extension "internal" };

type component CT {
  timer t;
  port PT pt;
}

/* * * * Tested functions * * * */
function f_rec(in Rec x) return Rec { return x; }

function f_roi(in RoI x) return RoI { return x; }

function f_uni(in Uni x) return Uni { return x; }

function f_arr(in Arr x) return Arr { return x; }

function f_complex(in Complex x) return Complex { return x; }

function f_rec_temp(in template Rec x) return template Rec { return x; }

function f_roi_temp(in template RoI x) return template RoI { return x; }

function f_uni_temp(in template Uni x) return template Uni { return x; }

function f_arr_temp(in template Arr x) return template Arr { return x; }

function f_complex_temp(in template Complex x) return template Complex { return x; }

/* * * * Helper functions for certain test cases * * * */
function f_test(in charstring p1, in integer p2, in boolean p3, in octetstring p4)
{
  if (p1 == c_rec.str) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", c_rec.str, ", got: ", p1); }
  if (p2 == c_roi[0]) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", c_roi[0], ", got: ", p2); }
  if (p3 == c_unis[2].b) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", c_unis[2].b, ", got: ", p3); }
  if (p4 == c_arr[1]) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", c_arr[1], ", got: ", p4); }
}

function f_test_temp(in template charstring p1, in template integer p2,
  in template boolean p3, in template octetstring p4)
{
  if (log2str(p1) == log2str(t_rec.str)) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", t_rec.str, ", got: ", p1); }
  if (log2str(p2) == log2str(t_roi[0])) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", t_roi[0], ", got: ", p2); }
  if (log2str(p3) == log2str(t_unis[2].b)) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", t_unis[2].b, ", got: ", p3); }
  if (log2str(p4) == log2str(t_arr[1])) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", t_arr[1], ", got: ", p4); }
}

external function ef_enc_int(in integer x) return octetstring
  with { extension "prototype(convert) encode(JSON)" };

external function ef_enc_oct(in octetstring x) return octetstring
  with { extension "prototype(convert) encode(JSON)" };

altstep as_ct() runs on CT
{
  var integer bad_int;
  var octetstring bad_os;
  [] pt.receive(integer:?) -> value bad_int {
    setverdict(fail, "Expected octetstring value instead of ", bad_int);
  }
  [] pt.receive(octetstring:?) -> value bad_os {
    setverdict(fail, "Expected integer value instead of ", bad_os);
  }
  [] t.timeout {
    setverdict(inconc, "Receive timed out");
  }
}

/* * * * Constants and templates * * * */
const Rec c_rec := { num := 3, str := "a0" };
const RoI c_roi := { 1, 2, 4, 8, 16 };
const RoUni c_unis := { { i := -6 }, { f := 0.5 }, { b := true }, { bs := '1101'B }, { hs := '3D7'H },
  { os := '44A1'O }, { cs := "abc" }, { ucs := "víz" }, { vt := error }, { size := Small } };
const Arr c_arr := { '01'O, 'DE'O, 'ABBA'O, '1234EEFF'O };

template Rec t_rec := { num := (0..100), str := pattern "a*b" };
template RoI t_roi := { ?, 0, ((-10..-1), (1..10)) };
template RoUni t_unis := { { i := (0..infinity) }, { f := (-1.0..1.0) }, { b := ? }, { bs := ? length (1..4) },
  { hs := '12345FF'H }, { os := ('0000'O, 'FFFF'O) }, { cs := ("a".."z") length (5) }, { ucs := "víz" },
  { vt := ? }, { size := (Small, Large) } };
template Arr t_arr := { ? length (2), ?, 'FEFEFE'O, 'DEADBEEF'O };

/* * * * Test cases * * * */
testcase tc_func_subref_var_assign() runs on CT
{
  var integer x1 := f_rec(c_rec).num;
  var integer x2 := f_roi(c_roi)[4];
  var integer x3 := f_uni(c_unis[0]).i;
  var charstring str1 := f_rec(c_rec).str;
  var charstring str2 := f_uni(c_unis[6]).cs;
  var octetstring os := f_arr(c_arr)[1];
  if (x1 == c_rec.num) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", c_rec.num, ", got: ", x1); }
  if (x2 == c_roi[4]) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", c_roi[4], ", got: ", x2); }
  if (x3 == c_unis[0].i) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", c_unis[0].i, ", got: ", x3); }
  if (str1 == c_rec.str) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", c_rec.str, ", got: ", str1); }
  if (str2 == c_unis[6].cs) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", c_unis[6].cs, ", got: ", str2); }
  if (os == c_arr[1]) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", c_roi[1], ", got: ", os); }
}

testcase tc_func_subref_equality() runs on CT
{
  if (f_rec(c_rec).str == c_rec.str) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", c_rec.str, ", got: ", f_rec(c_rec).str); }
  if (f_roi(c_roi)[2] == c_roi[2]) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", c_roi[2], ", got: ", f_roi(c_roi)[2]); }
  if (f_uni(c_unis[3]).bs == c_unis[3].bs) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", c_unis[3].bs, ", got: ", f_uni(c_unis[3]).bs); }
  if (f_arr(c_arr)[3] == c_arr[3]) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", c_arr[3], ", got: ", f_arr(c_arr)[3]); }
  if (f_rec(c_rec).num != 100) { setverdict(pass); }
  else { setverdict(fail, "Expected anything other than 100"); }
  if (f_roi(c_roi)[1] != 16) { setverdict(pass); }
  else { setverdict(fail, "Expected anything other than 16"); }
  if (f_uni(c_unis[8]).vt != pass) { setverdict(pass); }
  else { setverdict(fail, "Expected anything other than pass"); }
  if (f_arr(c_arr)[0] != 'DE'O) { setverdict(pass); }
  else { setverdict(fail, "Expected anything other than 'DE'O"); }
}

testcase tc_func_subref_bound_and_present() runs on CT
{
  if (isbound(f_rec(c_rec).str)) { setverdict(pass); }
  else { setverdict(fail, "Expected bound record field"); }
  if (isbound(f_roi(c_roi)[2])) { setverdict(pass); }
  else { setverdict(fail, "Expected bound record of element"); }
  if (isbound(f_uni(c_unis[2]).b)) { setverdict(pass); }
  else { setverdict(fail, "Expected bound union alternative"); }
  if (isbound(f_arr(c_arr)[2])) { setverdict(pass); }
  else { setverdict(fail, "Expected bound array element"); }
  if (ispresent(f_uni(c_unis[9]).size)) { setverdict(pass); }
  else { setverdict(fail, "Expected present union alternative"); }
}

testcase tc_func_subref_math_expr() runs on CT
{
  var integer int_expr := -f_rec(c_rec).num + f_roi(c_roi)[3] * f_uni(c_unis[0]).i;
  var integer int_expr_e := -c_rec.num + c_roi[3] * c_unis[0].i;
  var float float_expr := 4.0 / f_uni(c_unis[1]).f;
  var float float_expr_e := 4.0 / c_unis[1].f;
  if (int_expr == int_expr_e) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", int_expr_e, ", got: ", int_expr); }
  if (float_expr == float_expr_e) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", float_expr_e, ", got: ", float_expr); }
}

testcase tc_func_subref_bool_expr() runs on CT
{
  var boolean bool_expr := (not f_uni(c_unis[2]).b) or (f_rec(c_rec).num > 0 and
    f_roi(c_roi)[2] < 10 xor f_uni(c_unis[9]).size >= Medium);
  var boolean bool_expr_e := (not c_unis[2].b) or (c_rec.num > 0 and
    c_roi[2] < 10 xor c_unis[9].size >= Medium);
  if (bool_expr == bool_expr_e) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", bool_expr_e, ", got: ", bool_expr); }
}

testcase tc_func_subref_binary_expr() runs on CT
{
  var bitstring bs_expr := f_uni(c_unis[3]).bs >> f_roi(c_roi)[1];
  var bitstring bs_expr_e := c_unis[3].bs >> c_roi[1];
  var hexstring hs_expr := f_uni(c_unis[4]).hs <@ f_rec(c_rec).num;
  var hexstring hs_expr_e := c_unis[4].hs <@ c_rec.num;
  var octetstring os_expr := f_uni(c_unis[5]).os and4b (not4b f_arr(c_arr)[2]);
  var octetstring os_expr_e := c_unis[5].os and4b (not4b c_arr[2]);
  if (bs_expr == bs_expr_e) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", bs_expr_e, ", got: ", bs_expr); }
  if (hs_expr == hs_expr_e) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", hs_expr_e, ", got: ", hs_expr); }
  if (os_expr == os_expr_e) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", os_expr_e, ", got: ", os_expr); }
}

testcase tc_func_subref_str_concat() runs on CT
{
  var bitstring bs_expr := f_uni(c_unis[3]).bs & f_uni(c_unis[3]).bs;
  var bitstring bs_expr_e := c_unis[3].bs & c_unis[3].bs;
  var hexstring hs_expr := 'FF'H & f_uni(c_unis[4]).hs & 'FF'H;
  var hexstring hs_expr_e := 'FF'H & c_unis[4].hs & 'FF'H;
  var octetstring os_expr := f_uni(c_unis[5]).os & f_arr(c_arr)[3];
  var octetstring os_expr_e := c_unis[5].os & c_arr[3];
  var charstring cs_expr := f_uni(c_unis[6]).cs & " " & f_rec(c_rec).str;
  var charstring cs_expr_e := c_unis[6].cs & " " & c_rec.str;
  var universal charstring ucs_expr := "x" & f_uni(c_unis[7]).ucs & "x";
  var universal charstring ucs_expr_e := "x" & c_unis[7].ucs & "x";
  if (bs_expr == bs_expr_e) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", bs_expr_e, ", got: ", bs_expr); }
  if (hs_expr == hs_expr_e) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", hs_expr_e, ", got: ", hs_expr); }
  if (os_expr == os_expr_e) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", os_expr_e, ", got: ", os_expr); }
  if (cs_expr == cs_expr_e) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", cs_expr_e, ", got: ", cs_expr); }
  if (ucs_expr == ucs_expr_e) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", ucs_expr_e, ", got: ", ucs_expr); }
}

testcase tc_func_subref_str_length() runs on CT
{
  if (lengthof(f_uni(c_unis[3]).bs) == lengthof(c_unis[3].bs)) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", lengthof(c_unis[3].bs), ", got: ", lengthof(f_uni(c_unis[3]).bs)); }
  if (lengthof(f_uni(c_unis[4]).hs) == lengthof(c_unis[4].hs)) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", lengthof(c_unis[4].hs), ", got: ", lengthof(f_uni(c_unis[4]).hs)); }
  if (lengthof(f_uni(c_unis[5]).os) == lengthof(c_unis[5].os)) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", lengthof(c_unis[5].os), ", got: ", lengthof(f_uni(c_unis[5]).os)); }
  if (lengthof(f_arr(c_arr)[1]) == lengthof(c_arr[1])) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", lengthof(c_arr[1]), ", got: ", lengthof(f_arr(c_arr)[1])); }
  if (lengthof(f_uni(c_unis[6]).cs) == lengthof(c_unis[6].cs)) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", lengthof(c_unis[6].cs), ", got: ", lengthof(f_uni(c_unis[6]).cs)); }
  if (lengthof(f_rec(c_rec).str) == lengthof(c_rec.str)) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", lengthof(c_rec.str), ", got: ", lengthof(f_rec(c_rec).str)); }
  if (lengthof(f_uni(c_unis[7]).ucs) == lengthof(c_unis[7].ucs)) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", lengthof(c_unis[7].ucs), ", got: ", lengthof(f_uni(c_unis[7]).ucs)); }
}

testcase tc_func_subref_str_index() runs on CT
{
  if (f_uni(c_unis[3]).bs[2] == c_unis[3].bs[2]) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", c_unis[3].bs[2], ", got: ", f_uni(c_unis[3]).bs[2]); }
  if (f_uni(c_unis[4]).hs[2] == c_unis[4].hs[2]) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", c_unis[4].hs[2], ", got: ", f_uni(c_unis[4]).hs[2]); }
  if (f_uni(c_unis[5]).os[1] == c_unis[5].os[1]) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", c_unis[5].os[1], ", got: ", f_uni(c_unis[5]).os[1]); }
  if (f_arr(c_arr)[2][1] == c_arr[2][1]) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", c_arr[2][1], ", got: ", f_arr(c_arr)[2][1]); }
  if (f_uni(c_unis[6]).cs[2] == c_unis[6].cs[2]) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", c_unis[6].cs[2], ", got: ", f_uni(c_unis[6]).cs[2]); }
  if (f_rec(c_rec).str[0] == c_rec.str[0]) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", c_rec.str[0], ", got: ", f_rec(c_rec).str[0]); }
  if (f_uni(c_unis[7]).ucs[2] == c_unis[7].ucs[2]) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", c_unis[7].ucs[2], ", got: ", f_uni(c_unis[7]).ucs[2]); }
}

testcase tc_func_subref_log() runs on CT
{
  var charstring sep := " | ";
  var charstring log_str := log2str(f_rec(c_rec).str, sep, f_roi(c_roi)[3], sep, f_uni(c_unis[9]).size,
    sep, f_arr(c_arr)[0]);
  var charstring log_str_e := log2str(c_rec.str, sep, c_roi[3], sep, c_unis[9].size, sep, c_arr[0]);
  if (log_str == log_str_e) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", log_str_e, ", got: ", log_str); }
  log(f_rec(c_rec).str,f_roi(c_roi)[3], f_uni(c_unis[9]).size, f_arr(c_arr)[0]);
}

testcase tc_func_subref_structure() runs on CT
{
  var Rec rec1 := { num := f_rec(c_rec).num, str := f_rec(c_rec).str }; // == c_rec
  var Rec rec2 := { f_roi(c_roi)[1], f_uni(c_unis[6]).cs };
  var Rec rec2_e := { c_roi[1], c_unis[6].cs };
  var RoI roi := { f_uni(c_unis[0]).i, 91, f_roi(c_roi)[3], 0 };
  var RoI roi_e := { c_unis[0].i, 91, c_roi[3], 0 };
  var Uni uni := { vt := f_uni(c_unis[8]).vt }; // == c_unis[8]
  var Arr arr := { [0] := f_arr(c_arr)[0], [1] := f_arr(c_arr)[1],
    [2] := f_arr(c_arr)[2], [3] := f_arr(c_arr)[3] }; // == c_arr
  if (rec1 == c_rec) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", c_rec, ", got: ", rec1); }
  if (rec2 == rec2_e) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", rec2_e, ", got: ", rec2); }
  if (roi == roi_e) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", roi_e, ", got: ", roi); }
  if (uni == c_unis[8]) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", c_unis[8], ", got: ", uni); }
  if (arr == c_arr) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", c_arr, ", got: ", arr); }
}

testcase tc_func_subref_convert() runs on CT
{
  var integer int_res := hex2int(f_uni(c_unis[4]).hs) + oct2int(f_arr(c_arr)[3]);
  var integer int_res_e := hex2int(c_unis[4].hs) + oct2int(c_arr[3]);
  var Arr arr_res := { int2oct(f_roi(c_roi)[3], 2), str2oct(f_rec(c_rec).str),
    char2oct(f_uni(c_unis[6]).cs), unichar2oct(f_uni(c_unis[7]).ucs, "UTF-8") };
  var Arr arr_res_e := { int2oct(c_roi[3], 2), str2oct(c_rec.str),
    char2oct(c_unis[6].cs), unichar2oct(c_unis[7].ucs, "UTF-8") };
  if (int_res == int_res_e) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", int_res_e, ", got: ", int_res); }
  if (arr_res == arr_res_e) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", arr_res_e, ", got: ", arr_res); }
}

testcase tc_func_subref_parameter() runs on CT
{
  f_test(f_rec(c_rec).str, f_roi(c_roi)[0], f_uni(c_unis[2]).b, f_arr(c_arr)[1]);
  var Arr enc_arr := { ef_enc_int(f_rec(c_rec).num), ef_enc_int(f_roi(c_roi)[2]),
    ef_enc_oct(f_uni(c_unis[5]).os), ef_enc_oct(f_arr(c_arr)[3]) };
  var Arr enc_arr_e := { ef_enc_int(c_rec.num), ef_enc_int(c_roi[2]),
    ef_enc_oct(c_unis[5].os), ef_enc_oct(c_arr[3]) };
  if (enc_arr == enc_arr_e) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", enc_arr_e, ", got: ", enc_arr); }
}

testcase tc_func_subref_send() runs on CT
{
  connect(mtc:pt, mtc:pt);
  pt.send(f_rec(c_rec).num);
  pt.send(f_roi(c_roi)[1]);
  pt.send(f_uni(c_unis[0]).i);
  pt.send(f_arr(c_arr)[2]);
  var default def := activate(as_ct());
  var integer bad_int;
  var octetstring bad_os;
  t.start(1.0);
  alt {
    [] pt.receive(c_rec.num) { setverdict(pass); }
    [] pt.receive(integer:?) -> value bad_int 
      { setverdict(fail, "Expected: ", c_rec.num, ", got: ", bad_int); }
  }
  alt {
    [] pt.receive(c_roi[1]) { setverdict(pass); }
    [] pt.receive(integer:?) -> value bad_int 
      { setverdict(fail, "Expected: ", c_roi[1], ", got: ", bad_int); }
  }
  alt {
    [] pt.receive(c_unis[0].i) { setverdict(pass); }
    [] pt.receive(integer:?) -> value bad_int 
      { setverdict(fail, "Expected: ", c_unis[0].i, ", got: ", bad_int); }
  }
  alt {
    [] pt.receive(c_arr[2]) { setverdict(pass); }
    [] pt.receive(octetstring:?) -> value bad_os 
      { setverdict(fail, "Expected: ", c_arr[2], ", got: ", bad_os); }
  }
  deactivate(def);
}

testcase tc_func_subref_complex() runs on CT
{
  var Complex x := { rec := c_rec, roi := c_roi, unis := c_unis };
  var RoI roi_res := { f_complex(x).rec.num, 3 * f_complex(x).roi[2],
    float2int(f_complex(x).unis[1].f) - lengthof(f_complex(x).roi) };
  var RoI roi_res_e := { x.rec.num, 3 * x.roi[2], 
    float2int(x.unis[1].f) - lengthof(x.roi) };
  if (roi_res == roi_res_e) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", roi_res_e, ", got: ", roi_res); }
  if (f_complex(x).unis[9].size == x.unis[9].size) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", x.unis[9].size, ", got: ", f_complex(x).unis[9].size); }
  if (isbound(f_complex(x).rec)) { setverdict(pass); }
  else { setverdict(fail, "Expected bound record field"); }
}

testcase tc_func_subref_ttcn2string() runs on CT
{
  var charstring str1 := ttcn2string(f_rec(c_rec).str);
  var charstring str1_e := ttcn2string(c_rec.str);
  var charstring str2 := ttcn2string(f_roi(c_roi)[1]);
  var charstring str2_e := ttcn2string(c_roi[1]);
  var charstring str3 := ttcn2string(f_uni(c_unis[7]).ucs);
  var charstring str3_e := ttcn2string(c_unis[7].ucs);
  var charstring str4 := ttcn2string(f_arr(c_arr)[2]);
  var charstring str4_e := ttcn2string(c_arr[2]);
  if (str1 == str1_e) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", str1_e, ", got: ", str1); }
  if (str2 == str2_e) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", str2_e, ", got: ", str2); }
  if (str3 == str3_e) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", str3_e, ", got: ", str3); }
  if (str4 == str4_e) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", str4_e, ", got: ", str4); }
}

testcase tc_func_subref_temp_var_assign() runs on CT
{
  var template charstring vt1 := f_rec_temp(t_rec).str;
  var template integer vt2 := f_roi_temp(t_roi)[0];
  var template verdicttype vt3 := f_uni_temp(t_unis[8]).vt;
  var template octetstring vt4 := f_arr_temp(t_arr)[3];
  if (log2str(vt1) == log2str(t_rec.str)) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", t_rec.str, ", got: ", vt1); }
  if (log2str(vt2) == log2str(t_roi[0])) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", t_roi[0], ", got: ", vt2); }
  if (log2str(vt3) == log2str(t_unis[8].vt)) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", t_unis[8].vt, ", got: ", vt3); }
  if (log2str(vt4) == log2str(t_arr[3])) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", t_arr[3], ", got: ", vt4); }
}

testcase tc_func_subref_temp_match() runs on CT
{
  var charstring v_good1 := "affx_Y1b";
  var integer v_good2 := -19;
  var float v_good3 := 0.6;
  var octetstring v_good4 := '12EF'O;
  var integer v_bad1 := 331;
  var integer v_bad2 := -20;
  var bitstring v_bad3 := '110111'B;
  var octetstring v_bad4 := 'ABCDEF'O;
  if (match(v_good1, f_rec_temp(t_rec).str)) { setverdict(pass); }
  else { setverdict(fail, "Expected ", v_good1, " to match ", f_rec_temp(t_rec).str); }
  if (match(v_good2, f_roi_temp(t_roi)[0])) { setverdict(pass); }
  else { setverdict(fail, "Expected ", v_good2, " to match ", f_roi_temp(t_roi)[0]); }
  if (match(v_good3, f_uni_temp(t_unis[1]).f)) { setverdict(pass); }
  else { setverdict(fail, "Expected ", v_good3, " to match ", f_uni_temp(t_unis[1]).f); }
  if (match(v_good4, f_arr_temp(t_arr)[0])) { setverdict(pass); }
  else { setverdict(fail, "Expected ", v_good4, " to match ", f_arr_temp(t_arr)[0]); }
  if (not match(v_bad1, f_rec_temp(t_rec).num)) { setverdict(pass); }
  else { setverdict(fail, "Expected ", v_bad1, " not to match ", f_rec_temp(t_rec).num); }
  if (not match(v_bad2, f_roi_temp(t_roi)[2])) { setverdict(pass); }
  else { setverdict(fail, "Expected ", v_bad2, " not to match ", f_roi_temp(t_roi)[2]); }
  if (not match(v_bad3, f_uni_temp(t_unis[3]).bs)) { setverdict(pass); }
  else { setverdict(fail, "Expected ", v_bad3, " not to match ", f_uni_temp(t_unis[3]).bs); }
  if (not match(v_bad4, f_arr_temp(t_arr)[3])) { setverdict(pass); }
  else { setverdict(fail, "Expected ", v_bad4, " not to match ", f_arr_temp(t_arr)[3]); }
}

testcase tc_func_subref_temp_value() runs on CT
{
  if (not isvalue(f_rec_temp(t_rec).num)) { setverdict(pass); }
  else { setverdict(fail, "Expected ", f_rec_temp(t_rec).num, " to not be a value."); }
  if (isvalue(f_roi_temp(t_roi)[1])) { setverdict(pass); }
  else { setverdict(fail, "Expected ", f_roi_temp(t_roi)[1], " to be a value."); }
  if (isvalue(f_uni_temp(t_unis[4]).hs)) { setverdict(pass); }
  else { setverdict(fail, "Expected ", f_uni_temp(t_unis[4]).hs, " to be a value."); }
  if (isvalue(f_arr_temp(t_arr)[2])) { setverdict(pass); }
  else { setverdict(fail, "Expected ", f_arr_temp(t_arr)[2], " to be a value."); }
  if (valueof(f_roi_temp(t_roi)[1]) == valueof(t_roi[1])) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", t_roi[1], ", got: ", f_roi_temp(t_roi)[1]); }
  if (valueof(f_uni_temp(t_unis[7]).ucs) == valueof(t_unis[7].ucs)) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", t_unis[7].ucs, ", got: ", f_uni_temp(t_unis[7]).ucs); }
  if (valueof(f_arr_temp(t_arr)[3]) == valueof(t_arr[3])) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", t_arr[3], ", got: ", f_arr_temp(t_arr)[3]); }
}

testcase tc_func_subref_temp_structure() runs on CT
{
  var template Rec rec1 := { num := f_rec_temp(t_rec).num, str := f_rec_temp(t_rec).str }; // == t_rec
  var template Rec rec2 := { f_roi_temp(t_roi)[1], f_uni_temp(t_unis[6]).cs };
  var template Rec rec2_e := { t_roi[1], t_unis[6].cs };
  var template RoI roi := { f_uni_temp(t_unis[0]).i, 91, f_roi_temp(t_roi)[2], (0..infinity) };
  var template RoI roi_e := { t_unis[0].i, 91, t_roi[2], (0..infinity) };
  var template Uni uni := { vt := f_uni_temp(t_unis[8]).vt }; // == t_unis[8]
  var template Arr arr := { [3] := f_arr_temp(t_arr)[3], [2] := f_arr_temp(t_arr)[2],
    [1] := f_arr_temp(t_arr)[1], [0] := f_arr_temp(t_arr)[0] }; // == t_arr
  if (log2str(rec1) == log2str(t_rec)) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", t_rec, ", got: ", rec1); }
  if (log2str(rec2) == log2str(rec2_e)) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", rec2_e, ", got: ", rec2); }
  if (log2str(roi) == log2str(roi_e)) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", roi_e, ", got: ", roi); }
  if (log2str(uni) == log2str(t_unis[8])) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", t_unis[8], ", got: ", uni); }
  if (log2str(arr) == log2str(t_arr)) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", t_arr, ", got: ", arr); }
}

testcase tc_func_subref_temp_parameter() runs on CT
{
  f_test_temp(f_rec_temp(t_rec).str, f_roi_temp(t_roi)[0],
    f_uni_temp(t_unis[2]).b, f_arr_temp(t_arr)[1]);
}

testcase tc_func_subref_temp_send_receive() runs on CT
{
  connect(mtc:pt, mtc:pt);
  pt.send(17);
  pt.send(f_roi_temp(t_roi)[1]);
  pt.send(123456789101112);
  pt.send(f_arr_temp(t_arr)[2]);
  var default def := activate(as_ct());
  var integer bad_int;
  var octetstring bad_os;
  t.start(1.0);
  alt {
    [] pt.receive(f_rec_temp(t_rec).num) { setverdict(pass); }
    [] pt.receive(integer:?) -> value bad_int 
      { setverdict(fail, "Expected: ", f_rec_temp(t_rec).num, ", got: ", bad_int); }
  }
  alt {
    [] pt.receive(f_roi_temp(t_roi)[1]) { setverdict(pass); }
    [] pt.receive(integer:?) -> value bad_int 
      { setverdict(fail, "Expected: ", f_roi_temp(t_roi)[1], ", got: ", bad_int); }
  }
  alt {
    [] pt.receive(f_uni_temp(t_unis[0]).i) { setverdict(pass); }
    [] pt.receive(integer:?) -> value bad_int 
      { setverdict(fail, "Expected: ", f_uni_temp(t_unis[0]).i, ", got: ", bad_int); }
  }
  alt {
    [] pt.receive(f_arr_temp(t_arr)[2]) { setverdict(pass); }
    [] pt.receive(octetstring:?) -> value bad_os 
      { setverdict(fail, "Expected: ", f_arr_temp(t_arr)[2], ", got: ", bad_os); }
  }
  deactivate(def);
}

testcase tc_func_subref_temp_complex() runs on CT
{
  var template Complex x := { rec := t_rec, roi := t_roi, unis := t_unis };
  var template RoI roi_res := { f_complex_temp(x).rec.num, f_complex_temp(x).roi[2],
    f_complex_temp(x).unis[0].i };
  var template RoI roi_res_e := { x.rec.num, x.roi[2], x.unis[0].i };
  if (log2str(roi_res) == log2str(roi_res_e)) { setverdict(pass); }
  else { setverdict(fail, "Expected: ", roi_res_e, ", got: ", roi_res); }
  if (match(valueof(x.unis[7].ucs), f_complex_temp(x).unis[7].ucs)) { setverdict(pass); }
  else { setverdict(fail, "Expected ", x.unis[7].ucs, " to match ", f_complex_temp(x).unis[7].ucs); }
  if (not isvalue(f_complex_temp(x).rec)) { setverdict(pass); }
  else { setverdict(fail, "Expected ", f_complex_temp(x).rec, " not to be a value"); }
}

/* * * * Control part * * * */
control {
  // test cases for functions returning values
  execute(tc_func_subref_var_assign());
  execute(tc_func_subref_equality());
  execute(tc_func_subref_bound_and_present());
  execute(tc_func_subref_math_expr());
  execute(tc_func_subref_bool_expr());
  execute(tc_func_subref_binary_expr());
  execute(tc_func_subref_str_concat());
  execute(tc_func_subref_str_length());
  execute(tc_func_subref_str_index());
  execute(tc_func_subref_log());
  execute(tc_func_subref_structure());
  execute(tc_func_subref_convert());
  execute(tc_func_subref_parameter());
  execute(tc_func_subref_send());
  execute(tc_func_subref_complex());
  execute(tc_func_subref_ttcn2string());

  // test cases for functions returning templates
  execute(tc_func_subref_temp_var_assign());
  execute(tc_func_subref_temp_match());
  execute(tc_func_subref_temp_value());
  execute(tc_func_subref_temp_structure());
  execute(tc_func_subref_temp_parameter());
  execute(tc_func_subref_temp_send_receive());
  execute(tc_func_subref_temp_complex());
}

}