1# encoding: utf-8
2#
3# Copyright (c) ZeroC, Inc. All rights reserved.
4#
5
6def twoways(helper, communicator, p)
7
8    literals = p.opStringLiterals();
9
10    test(Test::S0 == "\\" &&
11         Test::S0 == Test::Sw0 &&
12         Test::S0 == literals[0] &&
13         Test::S0 == literals[11]);
14
15    test(Test::S1 == "A" &&
16         Test::S1 == Test::Sw1 &&
17         Test::S1 == literals[1] &&
18         Test::S1 == literals[12]);
19
20    test(Test::S2 == "Ice" &&
21         Test::S2 == Test::Sw2 &&
22         Test::S2 == literals[2] &&
23         Test::S2 == literals[13]);
24
25    test(Test::S3 == "A21" &&
26         Test::S3 == Test::Sw3 &&
27         Test::S3 == literals[3] &&
28         Test::S3 == literals[14]);
29
30    test(Test::S4 == "\\u0041 \\U00000041" &&
31         Test::S4 == Test::Sw4 &&
32         Test::S4 == literals[4] &&
33         Test::S4 == literals[15]);
34
35    test(Test::S5 == "\u00FF" &&
36         Test::S5 == Test::Sw5 &&
37         Test::S5 == literals[5] &&
38         Test::S5 == literals[16]);
39
40    test(Test::S6 == "\u03FF" &&
41         Test::S6 == Test::Sw6 &&
42         Test::S6 == literals[6] &&
43         Test::S6 == literals[17]);
44
45    test(Test::S7 == "\u05F0" &&
46         Test::S7 == Test::Sw7 &&
47         Test::S7 == literals[7] &&
48         Test::S7 == literals[18]);
49
50    test(Test::S8 == "\u{10000}" &&
51         Test::S8 == Test::Sw8 &&
52         Test::S8 == literals[8] &&
53         Test::S8 == literals[19]);
54
55    test(Test::S9 == "\u{01F34C}" &&
56         Test::S9 == Test::Sw9 &&
57         Test::S9 == literals[9] &&
58         Test::S9 == literals[20]);
59
60    test(Test::S10 == "\u0DA7" &&
61         Test::S10 == Test::Sw10 &&
62         Test::S10 == literals[10] &&
63         Test::S10 == literals[21]);
64
65    test(Test::Ss0 == "\'\"\x3f\\\a\b\f\n\r\t\v\6" &&
66         Test::Ss0 == Test::Ss1 &&
67         Test::Ss0 == Test::Ss2 &&
68         Test::Ss0 == literals[22] &&
69         Test::Ss0 == literals[23] &&
70         Test::Ss0 == literals[24]);
71
72    test(Test::Ss3 == "\\\\U\\u\\" &&
73         Test::Ss3 == literals[25]);
74
75    test(Test::Ss4 == "\\A\\" &&
76         Test::Ss4 == literals[26]);
77
78    test(Test::Ss5 == "\\u0041\\" &&
79         Test::Ss5 == literals[27]);
80
81    test(Test::Su0 == Test::Su1 &&
82         Test::Su0 == Test::Su2 &&
83         Test::Su0 == literals[28] &&
84         Test::Su0 == literals[29] &&
85         Test::Su0 == literals[30]);
86
87    #
88    # ice_ping
89    #
90    p.ice_ping
91
92    #
93    # ice_isA
94    #
95    test(p.ice_isA("::Test::MyClass"))
96
97    #
98    # ice_ids
99    #
100    ids = p.ice_ids
101    test(ids.length == 3)
102    test(ids[0] == "::Ice::Object")
103    test(ids[1] == "::Test::MyClass")
104    test(ids[2] == "::Test::MyDerivedClass")
105
106    #
107    # ice_id
108    #
109    test(p.ice_id == "::Test::MyDerivedClass")
110
111    #
112    # Proxy ice_staticId
113    #
114    test(Test::MyClassPrx::ice_staticId() == "::Test::MyClass")
115    test(Test::MyDerivedClassPrx::ice_staticId() == "::Test::MyDerivedClass")
116    test(Ice::ObjectPrx::ice_staticId() == Ice::Value::ice_staticId())
117
118    #
119    # opVoid
120    #
121    p.opVoid()
122
123    #
124    # opByte
125    #
126    r, b = p.opByte(0xff, 0x0f)
127    test(b == 0xf0)
128    test(r == 0xff)
129
130    #
131    # opBool
132    #
133    r, b = p.opBool(true, false)
134    test(b)
135    test(!r)
136
137    #
138    # opShortIntLong
139    #
140    r, s, i, l = p.opShortIntLong(10, 11, 12)
141    test(s == 10)
142    test(i == 11)
143    test(l == 12)
144    test(r == 12)
145
146    r, s, i, l = p.opShortIntLong(-32768, -2147483648, -9223372036854775808)
147    test(s == -32768)
148    test(i == -2147483648)
149    test(l == -9223372036854775808)
150    test(r == -9223372036854775808)
151
152    r, s, i, l = p.opShortIntLong(32767, 2147483647, 9223372036854775807)
153    test(s == 32767)
154    test(i == 2147483647)
155    test(l == 9223372036854775807)
156    test(r == 9223372036854775807)
157
158    #
159    # opFloatDouble
160    #
161    r, f, d = p.opFloatDouble(3.14, 1.1E10)
162    test(f - 3.14 < 0.001)
163    test(d == 1.1E10)
164    test(r == 1.1E10)
165
166    #
167    # Test invalid ranges for numbers
168    #
169    begin
170        r, b = p.opByte(0x01ff, 0x01ff)
171        test(false)
172    rescue TypeError
173    end
174
175    begin
176        r, s, i, l = p.opShortIntLong(32767 + 1, 0, 0)
177        test(false)
178    rescue TypeError
179    end
180
181    begin
182        r, s, i, l = p.opShortIntLong(-32768 - 1, 0, 0)
183        test(false)
184    rescue TypeError
185    end
186
187    begin
188        r, s, i, l = p.opShortIntLong(0, 2147483647 + 1, 0)
189        test(false)
190    rescue TypeError
191    end
192
193    begin
194        r, s, i, l = p.opShortIntLong(0, -2147483648 - 1, 0)
195        test(false)
196    rescue TypeError
197    end
198
199    begin
200        r, s, i, l = p.opShortIntLong(0, 0, 9223372036854775807 + 1)
201        test(false)
202    rescue TypeError
203    end
204
205    begin
206        r, s, i, l = p.opShortIntLong(0, 0, -9223372036854775808 - 1)
207        test(false)
208    rescue TypeError
209    end
210
211    r, f, d = p.opFloatDouble(3.402823466E38, 0.0)
212    r, f, d = p.opFloatDouble(-3.402823466E38, 0.0)
213
214    #
215    # For portability, don't use Float::NAN here.
216    #
217    nan = 0.0 / 0.0
218    for val in [nan, -nan]
219        r, f, d = p.opFloatDouble(val, val)
220        test(r.nan? && f.nan? && d.nan?)
221    end
222    #
223    # For portability, don't use Float::INFINITY here.
224    #
225    inf = 1.0 / 0.0
226    for val in [inf, -inf]
227        r, f, d = p.opFloatDouble(val, val)
228        test(r.infinite? != 0 && f.infinite? != 0 && d.infinite? != 0)
229    end
230
231    begin
232        r, f, d = p.opFloatDouble(3.402823466E38*2, 0.0)
233        test(false)
234    rescue TypeError
235    end
236
237    begin
238        r, f, d = p.opFloatDouble(-3.402823466E38*2, 0.0)
239        test(false)
240    rescue TypeError
241    end
242
243    #
244    # opString
245    #
246    r, s = p.opString("hello", "world")
247    test(s == "world hello")
248    test(r == "hello world")
249
250    #
251    # opMyEnum
252    #
253    r, e = p.opMyEnum(Test::MyEnum::Enum2)
254    test(e == Test::MyEnum::Enum2)
255    test(r == Test::MyEnum::Enum3)
256
257    #
258    # opMyClass
259    #
260    r, c1, c2 = p.opMyClass(p)
261    test(Ice::proxyIdentityAndFacetEqual(c1, p))
262    test(!Ice::proxyIdentityAndFacetEqual(c2, p))
263    test(Ice::proxyIdentityAndFacetEqual(r, p))
264    test(c1.ice_getIdentity() == Ice::stringToIdentity("test"))
265    test(c2.ice_getIdentity() == Ice::stringToIdentity("noSuchIdentity"))
266    test(r.ice_getIdentity() == Ice::stringToIdentity("test"))
267    r.opVoid()
268    c1.opVoid()
269    begin
270        c2.opVoid()
271        test(false)
272    rescue Ice::ObjectNotExistException
273    end
274
275    r, c1, c2 = p.opMyClass(nil)
276    test(!c1)
277    test(c2)
278    test(Ice::proxyIdentityAndFacetEqual(r, p))
279    r.opVoid()
280
281    #
282    # opStruct
283    #
284    si1 = Test::Structure.new
285    si1.p = p
286    si1.e = Test::MyEnum::Enum3
287    si1.s = Test::AnotherStruct.new
288    si1.s.s = "abc"
289    si2 = Test::Structure.new
290    si2.p = nil
291    si2.e = Test::MyEnum::Enum2
292    si2.s = Test::AnotherStruct.new
293    si2.s.s = "def"
294
295    rso, so = p.opStruct(si1, si2)
296    test(!rso.p)
297    test(rso.e == Test::MyEnum::Enum2)
298    test(rso.s.s == "def")
299    test(so.p == p)
300    test(so.e == Test::MyEnum::Enum3)
301    test(so.s.s == "a new string")
302    so.p.opVoid()
303
304    # Test marshalling of null structs and structs with null members.
305    si1 = Test::Structure.new
306    si2 = nil
307
308    rso, so = p.opStruct(si1, si2)
309    test(!rso.p)
310    test(rso.e == Test::MyEnum::Enum1)
311    test(rso.s.s == "")
312    test(!so.p)
313    test(so.e == Test::MyEnum::Enum1)
314    test(so.s.s == "a new string")
315
316    #
317    # opByteS
318    #
319    bsi1 = [0x01, 0x11, 0x12, 0x22]
320    bsi2 = [0xf1, 0xf2, 0xf3, 0xf4]
321
322    rso, bso = p.opByteS(bsi1, bsi2)
323    test(bso.length == 4)
324    test(bso.unpack("C*").reverse() == bsi1)
325    arr = bsi1.dup().concat(bsi2)
326    test(rso.length == 8)
327    test(rso.unpack("C*") == arr)
328
329    #
330    # opBoolS
331    #
332    bsi1 = [true, true, false]
333    bsi2 = [false]
334
335    rso, bso = p.opBoolS(bsi1, bsi2)
336    test(bso.length == 4)
337    test(bso[0])
338    test(bso[1])
339    test(!bso[2])
340    test(!bso[3])
341    test(rso.length == 3)
342    test(!rso[0])
343    test(rso[1])
344    test(rso[2])
345
346    #
347    # opShortIntLongS
348    #
349    ssi = [1, 2, 3]
350    isi = [5, 6, 7, 8]
351    lsi = [10, 30, 20]
352
353    rso, sso, iso, lso = p.opShortIntLongS(ssi, isi, lsi)
354    test(sso.length == 3)
355    test(sso[0] == 1)
356    test(sso[1] == 2)
357    test(sso[2] == 3)
358    test(iso.length == 4)
359    test(iso[0] == 8)
360    test(iso[1] == 7)
361    test(iso[2] == 6)
362    test(iso[3] == 5)
363    test(lso.length == 6)
364    test(lso[0] == 10)
365    test(lso[1] == 30)
366    test(lso[2] == 20)
367    test(lso[3] == 10)
368    test(lso[4] == 30)
369    test(lso[5] == 20)
370    test(rso.length == 3)
371    test(rso[0] == 10)
372    test(rso[1] == 30)
373    test(rso[2] == 20)
374
375    #
376    # opFloatDoubleS
377    #
378    fsi = [3.14, 1.11]
379    dsi = [1.1E10, 1.2E10, 1.3E10]
380
381    rso, fso, dso = p.opFloatDoubleS(fsi, dsi)
382    test(fso.length == 2)
383    test(fso[0] - 3.14 < 0.001)
384    test(fso[1] - 1.11 < 0.001)
385    test(dso.length == 3)
386    test(dso[0] == 1.3E10)
387    test(dso[1] == 1.2E10)
388    test(dso[2] == 1.1E10)
389    test(rso.length == 5)
390    test(rso[0] == 1.1E10)
391    test(rso[1] == 1.2E10)
392    test(rso[2] == 1.3E10)
393    test(rso[3] - 3.14 < 0.001)
394    test(rso[4] - 1.11 < 0.001)
395
396    #
397    # opStringS
398    #
399    ssi1 = ['abc', 'de', 'fghi']
400    ssi2 = ['xyz']
401
402    rso, sso = p.opStringS(ssi1, ssi2)
403    test(sso.length == 4)
404    test(sso[0] == "abc")
405    test(sso[1] == "de")
406    test(sso[2] == "fghi")
407    test(sso[3] == "xyz")
408    test(rso.length == 3)
409    test(rso[0] == "fghi")
410    test(rso[1] == "de")
411    test(rso[2] == "abc")
412
413    #
414    # opByteSS
415    #
416    bsi1 = [[0x01, 0x11, 0x12], [0xff]]
417    bsi2 = [[0x0e], [0xf2, 0xf1]]
418
419    rso, bso = p.opByteSS(bsi1, bsi2)
420    test(bso.length == 2)
421    test(bso[0].length == 1)
422    test(bso[0].unpack("C*") == [0xff])
423    test(bso[1].length == 3)
424    test(bso[1].unpack("C*") == [0x01, 0x11, 0x12])
425    test(rso.length == 4)
426    test(rso[0].length == 3)
427    test(rso[0].unpack("C*") == [0x01, 0x11, 0x12])
428    test(rso[1].length == 1)
429    test(rso[1].unpack("C*") == [0xff])
430    test(rso[2].length == 1)
431    test(rso[2].unpack("C*") == [0x0e])
432    test(rso[3].length == 2)
433    test(rso[3].unpack("C*") == [0xf2, 0xf1])
434
435    #
436    # opBoolSS
437    #
438    bsi1 = [[true], [false], [true, true]];
439    bsi2 = [[false, false, true]];
440
441    rso, bso = p.opBoolSS(bsi1, bsi2);
442    test(bso.length == 4);
443    test(bso[0].length == 1);
444    test(bso[0][0]);
445    test(bso[1].length == 1);
446    test(!bso[1][0]);
447    test(bso[2].length == 2);
448    test(bso[2][0]);
449    test(bso[2][1]);
450    test(bso[3].length == 3);
451    test(!bso[3][0]);
452    test(!bso[3][1]);
453    test(bso[3][2]);
454    test(rso.length == 3);
455    test(rso[0].length == 2);
456    test(rso[0][0]);
457    test(rso[0][1]);
458    test(rso[1].length == 1);
459    test(!rso[1][0]);
460    test(rso[2].length == 1);
461    test(rso[2][0]);
462
463    #
464    # opShortIntLongSS
465    #
466    ssi = [[1, 2, 5], [13], []];
467    isi = [[24, 98], [42]];
468    lsi = [[496, 1729]];
469
470    rso, sso, iso, lso = p.opShortIntLongSS(ssi, isi, lsi);
471    test(rso.length == 1);
472    test(rso[0].length == 2);
473    test(rso[0][0] == 496);
474    test(rso[0][1] == 1729);
475    test(sso.length == 3);
476    test(sso[0].length == 3);
477    test(sso[0][0] == 1);
478    test(sso[0][1] == 2);
479    test(sso[0][2] == 5);
480    test(sso[1].length == 1);
481    test(sso[1][0] == 13);
482    test(sso[2].length == 0);
483    test(iso.length == 2);
484    test(iso[0].length == 1);
485    test(iso[0][0] == 42);
486    test(iso[1].length == 2);
487    test(iso[1][0] == 24);
488    test(iso[1][1] == 98);
489    test(lso.length == 2);
490    test(lso[0].length == 2);
491    test(lso[0][0] == 496);
492    test(lso[0][1] == 1729);
493    test(lso[1].length == 2);
494    test(lso[1][0] == 496);
495    test(lso[1][1] == 1729);
496
497    #
498    # opFloatDoubleSS
499    #
500    fsi = [[3.14], [1.11], []]
501    dsi = [[1.1E10, 1.2E10, 1.3E10]]
502
503    rso, fso, dso = p.opFloatDoubleSS(fsi, dsi)
504    test(fso.length == 3)
505    test(fso[0].length == 1)
506    test(fso[0][0] - 3.14 < 0.001)
507    test(fso[1].length == 1)
508    test(fso[1][0] - 1.11 < 0.001)
509    test(fso[2].length == 0)
510    test(dso.length == 1)
511    test(dso[0].length == 3)
512    test(dso[0][0] == 1.1E10)
513    test(dso[0][1] == 1.2E10)
514    test(dso[0][2] == 1.3E10)
515    test(rso.length == 2)
516    test(rso[0].length == 3)
517    test(rso[0][0] == 1.1E10)
518    test(rso[0][1] == 1.2E10)
519    test(rso[0][2] == 1.3E10)
520    test(rso[1].length == 3)
521    test(rso[1][0] == 1.1E10)
522    test(rso[1][1] == 1.2E10)
523    test(rso[1][2] == 1.3E10)
524
525    #
526    # opStringSS
527    #
528    ssi1 = [['abc'], ['de', 'fghi']]
529    ssi2 = [[], [], ['xyz']]
530
531    rso, sso = p.opStringSS(ssi1, ssi2)
532    test(sso.length == 5)
533    test(sso[0].length == 1)
534    test(sso[0][0] == "abc")
535    test(sso[1].length == 2)
536    test(sso[1][0] == "de")
537    test(sso[1][1] == "fghi")
538    test(sso[2].length == 0)
539    test(sso[3].length == 0)
540    test(sso[4].length == 1)
541    test(sso[4][0] == "xyz")
542    test(rso.length == 3)
543    test(rso[0].length == 1)
544    test(rso[0][0] == "xyz")
545    test(rso[1].length == 0)
546    test(rso[2].length == 0)
547
548    #
549    # opStringSSS
550    #
551    sssi1 = [[['abc', 'de'], ['xyz']], [['hello']]]
552    sssi2 = [[['', ''], ['abcd']], [['']], []]
553
554    rsso, ssso = p.opStringSSS(sssi1, sssi2)
555    test(ssso.length == 5)
556    test(ssso[0].length == 2)
557    test(ssso[0][0].length == 2)
558    test(ssso[0][1].length == 1)
559    test(ssso[1].length == 1)
560    test(ssso[1][0].length == 1)
561    test(ssso[2].length == 2)
562    test(ssso[2][0].length == 2)
563    test(ssso[2][1].length == 1)
564    test(ssso[3].length == 1)
565    test(ssso[3][0].length == 1)
566    test(ssso[4].length == 0)
567    test(ssso[0][0][0] == "abc")
568    test(ssso[0][0][1] == "de")
569    test(ssso[0][1][0] == "xyz")
570    test(ssso[1][0][0] == "hello")
571    test(ssso[2][0][0] == "")
572    test(ssso[2][0][1] == "")
573    test(ssso[2][1][0] == "abcd")
574    test(ssso[3][0][0] == "")
575
576    test(rsso.length == 3)
577    test(rsso[0].length == 0)
578    test(rsso[1].length == 1)
579    test(rsso[1][0].length == 1)
580    test(rsso[2].length == 2)
581    test(rsso[2][0].length == 2)
582    test(rsso[2][1].length == 1)
583    test(rsso[1][0][0] == "")
584    test(rsso[2][0][0] == "")
585    test(rsso[2][0][1] == "")
586    test(rsso[2][1][0] == "abcd")
587
588    #
589    # opByteBoolD
590    #
591    di1 = {10=>true, 100=>false}
592    di2 = {10=>true, 11=>false, 101=>true}
593
594    ro, d = p.opByteBoolD(di1, di2)
595
596    test(d == di1)
597    test(ro.length == 4)
598    test(ro[10])
599    test(!ro[11])
600    test(!ro[100])
601    test(ro[101])
602
603    #
604    # opShortIntD
605    #
606    di1 = {110=>-1, 1100=>123123}
607    di2 = {110=>-1, 111=>-100, 1101=>0}
608
609    ro, d = p.opShortIntD(di1, di2)
610
611    test(d == di1)
612    test(ro.length == 4)
613    test(ro[110] == -1)
614    test(ro[111] == -100)
615    test(ro[1100] == 123123)
616    test(ro[1101] == 0)
617
618    #
619    # opLongFloatD
620    #
621    di1 = {999999110=>-1.1, 999999111=>123123.2}
622    di2 = {999999110=>-1.1, 999999120=>-100.4, 999999130=>0.5}
623
624    ro, d = p.opLongFloatD(di1, di2)
625
626    for k in d.keys
627        test((d[k] - di1[k]).abs < 0.01)
628    end
629    test(ro.length == 4)
630    test(ro[999999110] - -1.1 < 0.01)
631    test(ro[999999120] - -100.4 < 0.01)
632    test(ro[999999111] - 123123.2 < 0.01)
633    test(ro[999999130] - 0.5 < 0.01)
634
635    #
636    # opStringStringD
637    #
638    di1 = {'foo'=>'abc -1.1', 'bar'=>'abc 123123.2'}
639    di2 = {'foo'=>'abc -1.1', 'FOO'=>'abc -100.4', 'BAR'=>'abc 0.5'}
640
641    ro, d = p.opStringStringD(di1, di2)
642
643    test(d == di1)
644    test(ro.length == 4)
645    test(ro["foo"] == "abc -1.1")
646    test(ro["FOO"] == "abc -100.4")
647    test(ro["bar"] == "abc 123123.2")
648    test(ro["BAR"] == "abc 0.5")
649
650    #
651    # opStringMyEnumD
652    #
653    di1 = {'abc'=>Test::MyEnum::Enum1, ''=>Test::MyEnum::Enum2}
654    di2 = {'abc'=>Test::MyEnum::Enum1, 'qwerty'=>Test::MyEnum::Enum3, 'Hello!!'=>Test::MyEnum::Enum2}
655
656    ro, d = p.opStringMyEnumD(di1, di2)
657
658    test(d == di1)
659    test(ro.length == 4)
660    test(ro["abc"] == Test::MyEnum::Enum1)
661    test(ro["qwerty"] == Test::MyEnum::Enum3)
662    test(ro[""] == Test::MyEnum::Enum2)
663    test(ro["Hello!!"] == Test::MyEnum::Enum2)
664
665    #
666    # opMyEnumStringD
667    #
668    di1 = {Test::MyEnum::Enum1=>'abc'}
669    di2 = {Test::MyEnum::Enum2=>'Hello!!', Test::MyEnum::Enum3=>'qwerty'}
670
671    ro, d = p.opMyEnumStringD(di1, di2)
672
673    test(d == di1)
674    test(ro.length == 3)
675    test(ro[Test::MyEnum::Enum1] == "abc")
676    test(ro[Test::MyEnum::Enum2] == "Hello!!")
677    test(ro[Test::MyEnum::Enum3] == "qwerty")
678
679    #
680    # opMyStructMyEnumD
681    #
682    s11 = Test::MyStruct.new
683    s11.i = 1
684    s11.j = 1
685    s12 = Test::MyStruct.new
686    s12.i = 1
687    s12.j = 2
688    s22 = Test::MyStruct.new
689    s22.i = 2
690    s22.j = 2
691    s23 = Test::MyStruct.new
692    s23.i = 2
693    s23.j = 3
694    di1 = {s11=>Test::MyEnum::Enum1, s12=>Test::MyEnum::Enum2}
695    di2 = {s11=>Test::MyEnum::Enum1, s22=>Test::MyEnum::Enum3, s23=>Test::MyEnum::Enum2}
696
697    ro, d = p.opMyStructMyEnumD(di1, di2)
698
699    test(d == di1)
700    test(ro.length == 4)
701    test(ro[s11] == Test::MyEnum::Enum1)
702    test(ro[s12] == Test::MyEnum::Enum2)
703    test(ro[s22] == Test::MyEnum::Enum3)
704    test(ro[s23] == Test::MyEnum::Enum2)
705
706    #
707    # opByteBoolDS
708    #
709    # di1 = {10=>true, 100=>false}
710    # di2 = {10=>true, 11=>false, 101=>true}
711
712    dsi1 = [{ 10=>true, 100=>false }, { 10=>true, 11=>false, 101=>true }]
713    dsi2 = [{ 100=>false, 101=>false }]
714
715    ro, d = p.opByteBoolDS(dsi1, dsi2)
716
717    test(ro.length == 2)
718    test(ro[0].length == 3)
719    test(ro[0][10])
720    test(!ro[0][11])
721    test(ro[0][101])
722    test(ro[1].length == 2)
723    test(ro[1][10])
724    test(!ro[1][100])
725    test(d.length == 3)
726    test(d[0].length == 2)
727    test(!d[0][100])
728    test(!d[0][101])
729    test(d[1].length == 2)
730    test(d[1][10])
731    test(!d[1][100])
732    test(d[2].length == 3)
733    test(d[2][10])
734    test(!d[2][11])
735    test(d[2][101])
736
737    #
738    # opShortIntDS
739    #
740    dsi1 = [{ 110=>-1, 1100=>123123 }, { 110=>-1, 111=>-100, 1101=>0 }]
741    dsi2 = [{ 100=>-1001 }]
742
743    ro, d = p.opShortIntDS(dsi1, dsi2)
744
745    test(ro.length == 2)
746    test(ro[0].length == 3)
747    test(ro[0][110] == -1)
748    test(ro[0][111] == -100)
749    test(ro[0][1101] == 0)
750    test(ro[1].length == 2)
751    test(ro[1][110] == -1)
752    test(ro[1][1100] == 123123)
753
754    test(d.length == 3)
755    test(d[0].length == 1)
756    test(d[0][100] == -1001)
757    test(d[1].length == 2)
758    test(d[1][110] == -1)
759    test(d[1][1100] == 123123)
760    test(d[2].length == 3)
761    test(d[2][110] == -1)
762    test(d[2][111] == -100)
763    test(d[2][1101] == 0)
764
765    #
766    # opLongFloatDS
767    #
768    dsi1 = [{ 999999110=>-1.1, 999999111=>123123.2 }, { 999999110=>-1.1, 999999120=>-100.4, 999999130=>0.5 }]
769    dsi2 = [{ 999999140=>3.14 }]
770
771    ro, d = p.opLongFloatDS(dsi1, dsi2)
772
773    test(ro.length == 2)
774    test(ro[0].length == 3)
775    test(ro[0][999999110] - -1.1 < 0.01)
776    test(ro[0][999999120] - -100.4 < 0.01)
777    test(ro[0][999999130] - 0.5 < 0.01)
778    test(ro[1].length == 2)
779    test(ro[1][999999110] - -1.1 < 0.01)
780    test(ro[1][999999111] - 123123.2 < 0.01)
781    test(d.length == 3)
782    test(d[0].length == 1)
783    test(d[0][999999140] - 3.14 < 0.01)
784    test(d[1].length == 2)
785    test(d[1][999999110] - -1.1 < 0.01)
786    test(d[1][999999111] - 123123.2 < 0.01)
787    test(d[2].length == 3)
788    test(d[2][999999110] - -1.1 < 0.01)
789    test(d[2][999999120] - -100.4 < 0.01)
790    test(d[2][999999130] - 0.5 < 0.01)
791
792    #
793    # opStringStringDS
794    #
795
796    dsi1 = [{ "foo"=>"abc -1.1", "bar"=>"abc 123123.2" }, { "foo"=>"abc -1.1", "FOO"=>"abc -100.4", "BAR"=>"abc 0.5" }]
797    dsi2 = [{ "f00"=>"ABC -3.14" }]
798
799    ro, d = p.opStringStringDS(dsi1, dsi2)
800
801    test(ro.length == 2)
802    test(ro[0].length == 3)
803    test(ro[0]["foo"] == "abc -1.1")
804    test(ro[0]["FOO"] == "abc -100.4")
805    test(ro[0]["BAR"] == "abc 0.5")
806    test(ro[1].length == 2)
807    test(ro[1]["foo"] == "abc -1.1")
808    test(ro[1]["bar"] == "abc 123123.2")
809
810    test(d.length == 3)
811    test(d[0].length == 1)
812    test(d[0]["f00"] == "ABC -3.14")
813    test(d[1].length == 2)
814    test(d[1]["foo"] == "abc -1.1")
815    test(d[1]["bar"] == "abc 123123.2")
816    test(d[2].length == 3)
817    test(d[2]["foo"] == "abc -1.1")
818    test(d[2]["FOO"] == "abc -100.4")
819    test(d[2]["BAR"] == "abc 0.5")
820
821    #
822    # opStringMyEnumDS
823    #
824    dsi1 = [
825            { "abc"=>Test::MyEnum::Enum1, ""=>Test::MyEnum::Enum2 },
826            { "abc"=>Test::MyEnum::Enum1, "qwerty"=>Test::MyEnum::Enum3, "Hello!!"=>Test::MyEnum::Enum2 }
827           ]
828
829    dsi2 = [{ "Goodbye"=>Test::MyEnum::Enum1 }]
830
831    ro, d = p.opStringMyEnumDS(dsi1, dsi2)
832
833    test(ro.length == 2)
834    test(ro[0].length == 3)
835    test(ro[0]["abc"] == Test::MyEnum::Enum1)
836    test(ro[0]["qwerty"] == Test::MyEnum::Enum3)
837    test(ro[0]["Hello!!"] == Test::MyEnum::Enum2)
838    test(ro[1].length == 2)
839    test(ro[1]["abc"] == Test::MyEnum::Enum1)
840    test(ro[1][""] == Test::MyEnum::Enum2)
841
842    test(d.length == 3)
843    test(d[0].length == 1)
844    test(d[0]["Goodbye"] == Test::MyEnum::Enum1)
845    test(d[1].length == 2)
846    test(d[1]["abc"] == Test::MyEnum::Enum1)
847    test(d[1][""] == Test::MyEnum::Enum2)
848    test(d[2].length == 3)
849    test(d[2]["abc"] == Test::MyEnum::Enum1)
850    test(d[2]["qwerty"] == Test::MyEnum::Enum3)
851    test(d[2]["Hello!!"] == Test::MyEnum::Enum2)
852
853    #
854    # opMyEnumStringDS
855    #
856    dsi1 = [{ Test::MyEnum::Enum1=>'abc' }, { Test::MyEnum::Enum2=>'Hello!!', Test::MyEnum::Enum3=>'qwerty'}]
857    dsi2 = [{ Test::MyEnum::Enum1=>'Goodbye' }]
858
859    ro, d = p.opMyEnumStringDS(dsi1, dsi2)
860
861    test(ro.length == 2)
862    test(ro[0].length == 2)
863    test(ro[0][Test::MyEnum::Enum2] == "Hello!!")
864    test(ro[0][Test::MyEnum::Enum3] == "qwerty")
865    test(ro[1].length == 1)
866    test(ro[1][Test::MyEnum::Enum1] == "abc")
867
868    test(d.length == 3)
869    test(d[0].length == 1)
870    test(d[0][Test::MyEnum::Enum1] == "Goodbye")
871    test(d[1].length == 1)
872    test(d[1][Test::MyEnum::Enum1] == "abc")
873    test(d[2].length == 2)
874    test(d[2][Test::MyEnum::Enum2] == "Hello!!")
875    test(d[2][Test::MyEnum::Enum3] == "qwerty")
876
877    #
878    # opMyStructMyEnumDS
879    #
880    s11 = Test::MyStruct.new
881    s11.i = 1
882    s11.j = 1
883    s12 = Test::MyStruct.new
884    s12.i = 1
885    s12.j = 2
886    s22 = Test::MyStruct.new
887    s22.i = 2
888    s22.j = 2
889    s23 = Test::MyStruct.new
890    s23.i = 2
891    s23.j = 3
892
893    dsi1 = [
894            { s11=>Test::MyEnum::Enum1, s12=>Test::MyEnum::Enum2 },
895            { s11=>Test::MyEnum::Enum1, s22=>Test::MyEnum::Enum3, s23=>Test::MyEnum::Enum2 }
896           ]
897    dsi2 = [{ s23=>Test::MyEnum::Enum3 }]
898
899    ro, d = p.opMyStructMyEnumDS(dsi1, dsi2)
900
901    test(ro.length == 2)
902    test(ro[0].length == 3)
903    test(ro[0][s11] == Test::MyEnum::Enum1)
904    test(ro[0][s22] == Test::MyEnum::Enum3)
905    test(ro[0][s23] == Test::MyEnum::Enum2)
906    test(ro[1].length == 2)
907    test(ro[1][s11] == Test::MyEnum::Enum1)
908    test(ro[1][s12] == Test::MyEnum::Enum2)
909
910    test(d.length == 3)
911    test(d[0].length == 1)
912    test(d[0][s23] == Test::MyEnum::Enum3)
913    test(d[1].length == 2)
914    test(d[1][s11] == Test::MyEnum::Enum1)
915    test(d[1][s12] == Test::MyEnum::Enum2)
916    test(d[2].length == 3)
917    test(d[2][s11] == Test::MyEnum::Enum1)
918    test(d[2][s22] == Test::MyEnum::Enum3)
919    test(d[2][s23] == Test::MyEnum::Enum2)
920
921    #
922    # opByteByteSD
923    #
924    sdi1 = { 0x01=>[0x01, 0x11], 0x22=>[0x12] }
925    sdi2 = { 0xf1=>[0xf2, 0xf3] }
926
927    ro, d = p.opByteByteSD(sdi1, sdi2)
928
929    test(d.length == 1)
930    test(d[0xf1].length == 2)
931    test(d[0xf1].unpack("C*") == [0xf2, 0xf3])
932    test(ro.length == 3)
933    test(ro[0x01].length == 2)
934    test(ro[0x01].unpack("C*") == [0x01, 0x11])
935    test(ro[0x22].length == 1)
936    test(ro[0x22].unpack("C*") == [0x12])
937    test(ro[0xf1].length == 2)
938    test(ro[0xf1].unpack("C*") == [0xf2, 0xf3])
939
940    #
941    # opBoolBoolSD
942    #
943    sdi1 = { false=>[true, false], true=>[false, true, true] }
944    sdi2 = { false=>[true, false] }
945
946    ro, d = p.opBoolBoolSD(sdi1, sdi2)
947
948    test(d.length == 1)
949    test(d[false].length == 2)
950    test(d[false][0])
951    test(!d[false][1])
952    test(ro.length == 2)
953    test(ro[false].length == 2)
954    test(ro[false][0])
955    test(!ro[false][1])
956    test(ro[true].length == 3)
957    test(!ro[true][0])
958    test(ro[true][1])
959    test(ro[true][2])
960
961    #
962    # opShortShortSD
963    #
964    sdi1 = { 1=>[1, 2, 3], 2=>[4, 5] }
965    sdi2 = { 4=>[6, 7] }
966
967    ro, d = p.opShortShortSD(sdi1, sdi2)
968
969    test(d.length == 1)
970    test(d[4].length == 2)
971    test(d[4][0] == 6)
972    test(d[4][1] == 7)
973    test(ro.length == 3)
974    test(ro[1].length == 3)
975    test(ro[1][0] == 1)
976    test(ro[1][1] == 2)
977    test(ro[1][2] == 3)
978    test(ro[2].length == 2)
979    test(ro[2][0] == 4)
980    test(ro[2][1] == 5)
981    test(ro[4].length == 2)
982    test(ro[4][0] == 6)
983    test(ro[4][1] == 7)
984
985    #
986    # opIntIntSD
987    #
988    sdi1 = { 100=>[100, 200, 300], 200=>[400, 500] }
989    sdi2 = { 400=>[600, 700] }
990
991    ro, d = p.opIntIntSD(sdi1, sdi2)
992
993    test(d.length == 1)
994    test(d[400].length == 2)
995    test(d[400][0] == 600)
996    test(d[400][1] == 700)
997    test(ro.length == 3)
998    test(ro[100].length == 3)
999    test(ro[100][0] == 100)
1000    test(ro[100][1] == 200)
1001    test(ro[100][2] == 300)
1002    test(ro[200].length == 2)
1003    test(ro[200][0] == 400)
1004    test(ro[200][1] == 500)
1005    test(ro[400].length == 2)
1006    test(ro[400][0] == 600)
1007    test(ro[400][1] == 700)
1008
1009    #
1010    # opLongLongSD
1011    #
1012    sdi1 = { 999999990=>[999999110, 999999111, 999999110], 999999991=>[999999120, 999999130] }
1013    sdi2 = { 999999992=>[999999110, 999999120] }
1014
1015    ro, d = p.opLongLongSD(sdi1, sdi2)
1016
1017    test(d.length == 1)
1018    test(d[999999992].length == 2)
1019    test(d[999999992][0] == 999999110)
1020    test(d[999999992][1] == 999999120)
1021    test(ro.length == 3)
1022    test(ro[999999990].length == 3)
1023    test(ro[999999990][0] == 999999110)
1024    test(ro[999999990][1] == 999999111)
1025    test(ro[999999990][2] == 999999110)
1026    test(ro[999999991].length == 2)
1027    test(ro[999999991][0] == 999999120)
1028    test(ro[999999991][1] == 999999130)
1029    test(ro[999999992].length == 2)
1030    test(ro[999999992][0] == 999999110)
1031    test(ro[999999992][1] == 999999120)
1032
1033    #
1034    # opStringFloatSD
1035    #
1036    sdi1 = { "abc"=>[-1.1, 123123.2, 100.0], "ABC"=>[42.24, -1.61] }
1037    sdi2 = { "aBc"=>[-3.14, 3.14] }
1038
1039    ro, d = p.opStringFloatSD(sdi1, sdi2)
1040
1041    test(d.length == 1)
1042    test(d["aBc"].length == 2)
1043    test(d["aBc"][0] - -3.14 < 0.01)
1044    test(d["aBc"][1] - 3.14 < 0.01)
1045
1046    test(ro.length == 3)
1047    test(ro["abc"].length == 3)
1048    test(ro["abc"][0] - -1.1 < 0.01)
1049    test(ro["abc"][1] - 123123.2 < 0.01)
1050    test(ro["abc"][2] - 100.0 < 0.01)
1051    test(ro["ABC"].length == 2)
1052    test(ro["ABC"][0] - 42.24 < 0.01)
1053    test(ro["ABC"][1] - -1.61 < 0.01)
1054    test(ro["aBc"].length == 2)
1055    test(ro["aBc"][0] - -3.14 < 0.01)
1056    test(ro["aBc"][1] - 3.14 < 0.01)
1057
1058    #
1059    # opStringDoubleSD
1060    #
1061    sdi1 = { "Hello!!"=>[1.1E10, 1.2E10, 1.3E10], "Goodbye"=>[1.4E10, 1.5E10] }
1062    sdi2 = { ""=>[1.6E10, 1.7E10] }
1063
1064    ro, d = p.opStringDoubleSD(sdi1, sdi2);
1065
1066    test(d.length == 1)
1067    test(d[""].length == 2)
1068    test(d[""][0] == 1.6E10)
1069    test(d[""][1] == 1.7E10)
1070    test(ro.length == 3)
1071    test(ro["Hello!!"].length == 3)
1072    test(ro["Hello!!"][0] == 1.1E10)
1073    test(ro["Hello!!"][1] == 1.2E10)
1074    test(ro["Hello!!"][2] == 1.3E10)
1075    test(ro["Goodbye"].length == 2)
1076    test(ro["Goodbye"][0] == 1.4E10)
1077    test(ro["Goodbye"][1] == 1.5E10)
1078    test(ro[""].length == 2)
1079    test(ro[""][0] == 1.6E10)
1080    test(ro[""][1] == 1.7E10)
1081
1082    #
1083    # opStringStringSD
1084    #
1085    sdi1 = { "abc"=>["abc", "de", "fghi"] , "def"=>["xyz", "or"] }
1086    sdi2 = { "ghi"=>["and", "xor"] }
1087
1088    ro, d = p.opStringStringSD(sdi1, sdi2)
1089
1090    test(d.length == 1)
1091    test(d["ghi"].length == 2)
1092    test(d["ghi"][0] == "and")
1093    test(d["ghi"][1] == "xor")
1094    test(ro.length == 3)
1095    test(ro["abc"].length == 3)
1096    test(ro["abc"][0] == "abc")
1097    test(ro["abc"][1] == "de")
1098    test(ro["abc"][2] == "fghi")
1099    test(ro["def"].length == 2)
1100    test(ro["def"][0] == "xyz")
1101    test(ro["def"][1] == "or")
1102    test(ro["ghi"].length == 2)
1103    test(ro["ghi"][0] == "and")
1104    test(ro["ghi"][1] == "xor")
1105
1106    #
1107    # opMyEnumMyEnumSD
1108    #
1109    sdi1 = {
1110            Test::MyEnum::Enum3=>[Test::MyEnum::Enum1, Test::MyEnum::Enum1, Test::MyEnum::Enum2],
1111            Test::MyEnum::Enum2=>[Test::MyEnum::Enum1, Test::MyEnum::Enum2]
1112           }
1113    sdi2 = { Test::MyEnum::Enum1=>[Test::MyEnum::Enum3, Test::MyEnum::Enum3] }
1114
1115    ro, d = p.opMyEnumMyEnumSD(sdi1, sdi2)
1116
1117    test(d.length == 1)
1118    test(d[Test::MyEnum::Enum1].length == 2)
1119    test(d[Test::MyEnum::Enum1][0] == Test::MyEnum::Enum3)
1120    test(d[Test::MyEnum::Enum1][1] == Test::MyEnum::Enum3)
1121    test(ro.length == 3)
1122    test(ro[Test::MyEnum::Enum3].length == 3)
1123    test(ro[Test::MyEnum::Enum3][0] == Test::MyEnum::Enum1)
1124    test(ro[Test::MyEnum::Enum3][1] == Test::MyEnum::Enum1)
1125    test(ro[Test::MyEnum::Enum3][2] == Test::MyEnum::Enum2)
1126    test(ro[Test::MyEnum::Enum2].length == 2)
1127    test(ro[Test::MyEnum::Enum2][0] == Test::MyEnum::Enum1)
1128    test(ro[Test::MyEnum::Enum2][1] == Test::MyEnum::Enum2)
1129    test(ro[Test::MyEnum::Enum1].length == 2)
1130    test(ro[Test::MyEnum::Enum1][0] == Test::MyEnum::Enum3)
1131    test(ro[Test::MyEnum::Enum1][1] == Test::MyEnum::Enum3)
1132
1133    #
1134    # opIntS
1135    #
1136    lengths = [ 0, 1, 2, 126, 127, 128, 129, 253, 254, 255, 256, 257, 1000 ]
1137    for l in lengths
1138        s = []
1139        for i in (0...l)
1140            s.push(i)
1141        end
1142        r = p.opIntS(s)
1143        test(r.length == l)
1144        for j in (0...r.length)
1145            test(r[j] == -j)
1146        end
1147    end
1148
1149    #
1150    # opContext
1151    #
1152    ctx = {'one'=>'ONE', 'two'=>'TWO', 'three'=>'THREE'}
1153
1154    r = p.opContext()
1155    test(p.ice_getContext().length == 0)
1156    test(r != ctx)
1157
1158    r = p.opContext(ctx)
1159    test(p.ice_getContext().length == 0)
1160    test(r == ctx)
1161
1162    p2 = Test::MyClassPrx::checkedCast(p.ice_context(ctx))
1163    test(p2.ice_getContext() == ctx)
1164    r = p2.opContext()
1165    test(r == ctx)
1166    r = p2.opContext(ctx)
1167    test(r == ctx)
1168
1169    #
1170    # opIdempotent
1171    #
1172    p.opIdempotent
1173
1174    #
1175    # opNonmutating
1176    #
1177    p.opNonmutating
1178
1179    test(p.opByte1(0xFF) == 0xFF)
1180    test(p.opShort1(0x7FFF) == 0x7FFF)
1181    test(p.opInt1(0x7FFFFFFF) == 0x7FFFFFFF)
1182    test(p.opLong1(0x7FFFFFFFFFFFFFFF) == 0x7FFFFFFFFFFFFFFF)
1183    test(p.opFloat1(1.0) == 1.0)
1184    test(p.opDouble1(1.0) == 1.0)
1185    test(p.opString1("opString1") == "opString1")
1186    test(p.opStringS1(nil).length == 0)
1187    test(p.opByteBoolD1(nil).length == 0)
1188    test(p.opStringS2(nil).length == 0)
1189    test(p.opByteBoolD2(nil).length == 0)
1190
1191    d = Test::MyDerivedClassPrx::uncheckedCast(p)
1192    s = Test::MyStruct1.new
1193    s.tesT = "Test.MyStruct1.s"
1194    s.myClass = nil
1195    s.myStruct1 = "Test.MyStruct1.myStruct1"
1196    s = d.opMyStruct1(s)
1197    test(s.tesT == "Test.MyStruct1.s")
1198    test(s.myClass == nil)
1199    test(s.myStruct1 == "Test.MyStruct1.myStruct1")
1200    c = Test::MyClass1.new
1201    c.tesT = "Test.MyClass1.testT"
1202    c.myClass = nil
1203    c.myClass1 = "Test.MyClass1.myClass1"
1204    c = d.opMyClass1(c)
1205    test(c.tesT == "Test.MyClass1.testT")
1206    test(c.myClass == nil)
1207    test(c.myClass1 == "Test.MyClass1.myClass1")
1208
1209    p1 = p.opMStruct1()
1210    p1.e = Test::MyEnum::Enum3
1211    (p3, p2) = p.opMStruct2(p1)
1212    test(p2 == p1 && p3 == p1)
1213
1214    p.opMSeq1();
1215    p1 = ["test"]
1216    (p3, p2) = p.opMSeq2(p1)
1217    test(p2[0] == "test" && p3[0] == "test");
1218
1219    p.opMDict1();
1220
1221    p1 = { "test" => "test" }
1222    (p3, p2) = p.opMDict2(p1)
1223    test(p3["test"] == "test" && p2["test"] == "test")
1224
1225    #
1226    # Test implicit context propagation
1227    #
1228    impls = [ 'Shared', 'PerThread' ]
1229    for i in impls
1230        initData = Ice::InitializationData.new
1231        initData.properties = communicator.getProperties().clone()
1232        initData.properties.setProperty('Ice.ImplicitContext', i)
1233        ic = Ice::initialize(initData)
1234
1235        ctx = {'one'=>'ONE', 'two'=>'TWO', 'three'=>'THREE'}
1236
1237        p = Test::MyClassPrx::uncheckedCast(ic.stringToProxy("test:#{helper.getTestEndpoint()}"))
1238
1239        ic.getImplicitContext().setContext(ctx)
1240        test(ic.getImplicitContext().getContext() == ctx)
1241        test(p.opContext() == ctx)
1242
1243        test(ic.getImplicitContext().containsKey('zero') == false);
1244        r = ic.getImplicitContext().put('zero', 'ZERO');
1245        test(r == '');
1246        test(ic.getImplicitContext().containsKey('zero') == true);
1247        test(ic.getImplicitContext().get('zero') == 'ZERO');
1248
1249        ctx = ic.getImplicitContext().getContext()
1250        test(p.opContext() == ctx)
1251
1252        prxContext = {'one'=>'UN', 'four'=>'QUATRE'}
1253
1254        combined = ctx.clone()
1255        combined.update(prxContext)
1256        test(combined['one'] == 'UN')
1257
1258        p = Test::MyClassPrx::uncheckedCast(p.ice_context(prxContext))
1259        ic.getImplicitContext().setContext({})
1260        test(p.opContext() == prxContext)
1261
1262        ic.getImplicitContext().setContext(ctx)
1263        test(p.opContext() == combined)
1264
1265        test(ic.getImplicitContext().remove('one') == 'ONE');
1266
1267        ic.destroy()
1268    end
1269end
1270