1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5define([
6    "gin/test/expect",
7    "mojo/public/js/bindings/codec",
8    "mojo/public/interfaces/bindings/tests/rect.mojom",
9    "mojo/public/interfaces/bindings/tests/sample_service.mojom",
10    "mojo/public/interfaces/bindings/tests/test_structs.mojom",
11  ], function(expect, codec, rect, sample, structs) {
12  testBar();
13  testFoo();
14  testNamedRegion();
15  testTypes();
16  testAlign();
17  testUtf8();
18  this.result = "PASS";
19
20  function testBar() {
21    var bar = new sample.Bar();
22    bar.alpha = 1;
23    bar.beta = 2;
24    bar.gamma = 3;
25    bar.type = 0x08070605;
26    bar.extraProperty = "banana";
27
28    var messageName = 42;
29    var payloadSize = sample.Bar.encodedSize;
30
31    var builder = new codec.MessageBuilder(messageName, payloadSize);
32    builder.encodeStruct(sample.Bar, bar);
33
34    var message = builder.finish();
35
36    var expectedMemory = new Uint8Array([
37      16, 0, 0, 0,
38       2, 0, 0, 0,
39      42, 0, 0, 0,
40       0, 0, 0, 0,
41
42      16, 0, 0, 0,
43       4, 0, 0, 0,
44
45       1, 2, 3, 0,
46       5, 6, 7, 8,
47    ]);
48
49    var actualMemory = new Uint8Array(message.buffer.arrayBuffer);
50    expect(actualMemory).toEqual(expectedMemory);
51
52    var reader = new codec.MessageReader(message);
53
54    expect(reader.payloadSize).toBe(payloadSize);
55    expect(reader.messageName).toBe(messageName);
56
57    var bar2 = reader.decodeStruct(sample.Bar);
58
59    expect(bar2.alpha).toBe(bar.alpha);
60    expect(bar2.beta).toBe(bar.beta);
61    expect(bar2.gamma).toBe(bar.gamma);
62    expect("extraProperty" in bar2).toBeFalsy();
63  }
64
65  function testFoo() {
66    var foo = new sample.Foo();
67    foo.x = 0x212B4D5;
68    foo.y = 0x16E93;
69    foo.a = 1;
70    foo.b = 0;
71    foo.c = 3; // This will get truncated to one bit.
72    foo.bar = new sample.Bar();
73    foo.bar.alpha = 91;
74    foo.bar.beta = 82;
75    foo.bar.gamma = 73;
76    foo.data = [
77      4, 5, 6, 7, 8,
78    ];
79    foo.extra_bars = [
80      new sample.Bar(), new sample.Bar(), new sample.Bar(),
81    ];
82    for (var i = 0; i < foo.extra_bars.length; ++i) {
83      foo.extra_bars[i].alpha = 1 * i;
84      foo.extra_bars[i].beta = 2 * i;
85      foo.extra_bars[i].gamma = 3 * i;
86    }
87    foo.name = "I am a banana";
88    // This is supposed to be a handle, but we fake it with an integer.
89    foo.source = 23423782;
90    foo.array_of_array_of_bools = [
91      [true], [false, true]
92    ];
93    foo.array_of_bools = [
94      true, false, true, false, true, false, true, true
95    ];
96
97
98    var messageName = 31;
99    var payloadSize = 304;
100
101    var builder = new codec.MessageBuilder(messageName, payloadSize);
102    builder.encodeStruct(sample.Foo, foo);
103
104    var message = builder.finish();
105
106    var expectedMemory = new Uint8Array([
107      /*  0: */   16,    0,    0,    0,    2,    0,    0,    0,
108      /*  8: */   31,    0,    0,    0,    0,    0,    0,    0,
109      /* 16: */   96,    0,    0,    0,   15,    0,    0,    0,
110      /* 24: */ 0xD5, 0xB4, 0x12, 0x02, 0x93, 0x6E, 0x01,    0,
111      /* 32: */    5,    0,    0,    0,    0,    0,    0,    0,
112      /* 40: */   72,    0,    0,    0,    0,    0,    0,    0,
113    ]);
114    // TODO(abarth): Test more of the message's raw memory.
115    var actualMemory = new Uint8Array(message.buffer.arrayBuffer,
116                                      0, expectedMemory.length);
117    expect(actualMemory).toEqual(expectedMemory);
118
119    var expectedHandles = [
120      23423782,
121    ];
122
123    expect(message.handles).toEqual(expectedHandles);
124
125    var reader = new codec.MessageReader(message);
126
127    expect(reader.payloadSize).toBe(payloadSize);
128    expect(reader.messageName).toBe(messageName);
129
130    var foo2 = reader.decodeStruct(sample.Foo);
131
132    expect(foo2.x).toBe(foo.x);
133    expect(foo2.y).toBe(foo.y);
134
135    expect(foo2.a).toBe(foo.a & 1 ? true : false);
136    expect(foo2.b).toBe(foo.b & 1 ? true : false);
137    expect(foo2.c).toBe(foo.c & 1 ? true : false);
138
139    expect(foo2.bar).toEqual(foo.bar);
140    expect(foo2.data).toEqual(foo.data);
141
142    expect(foo2.extra_bars).toEqual(foo.extra_bars);
143    expect(foo2.name).toBe(foo.name);
144    expect(foo2.source).toEqual(foo.source);
145
146    expect(foo2.array_of_bools).toEqual(foo.array_of_bools);
147  }
148
149  function createRect(x, y, width, height) {
150    var r = new rect.Rect();
151    r.x = x;
152    r.y = y;
153    r.width = width;
154    r.height = height;
155    return r;
156  }
157
158  // Verify that the references to the imported Rect type in test_structs.mojom
159  // are generated correctly.
160  function testNamedRegion() {
161    var r = new structs.NamedRegion();
162    r.name = "rectangle";
163    r.rects = new Array(createRect(1, 2, 3, 4), createRect(10, 20, 30, 40));
164
165    var builder = new codec.MessageBuilder(1, structs.NamedRegion.encodedSize);
166    builder.encodeStruct(structs.NamedRegion, r);
167    var reader = new codec.MessageReader(builder.finish());
168    var result = reader.decodeStruct(structs.NamedRegion);
169
170    expect(result.name).toEqual("rectangle");
171    expect(result.rects[0]).toEqual(createRect(1, 2, 3, 4));
172    expect(result.rects[1]).toEqual(createRect(10, 20, 30, 40));
173  }
174
175  function testTypes() {
176    function encodeDecode(cls, input, expectedResult, encodedSize) {
177      var messageName = 42;
178      var payloadSize = encodedSize || cls.encodedSize;
179
180      var builder = new codec.MessageBuilder(messageName, payloadSize);
181      builder.encodeStruct(cls, input)
182      var message = builder.finish();
183
184      var reader = new codec.MessageReader(message);
185      expect(reader.payloadSize).toBe(payloadSize);
186      expect(reader.messageName).toBe(messageName);
187      var result = reader.decodeStruct(cls);
188      expect(result).toEqual(expectedResult);
189    }
190    encodeDecode(codec.String, "banana", "banana", 24);
191    encodeDecode(codec.NullableString, null, null, 8);
192    encodeDecode(codec.Int8, -1, -1);
193    encodeDecode(codec.Int8, 0xff, -1);
194    encodeDecode(codec.Int16, -1, -1);
195    encodeDecode(codec.Int16, 0xff, 0xff);
196    encodeDecode(codec.Int16, 0xffff, -1);
197    encodeDecode(codec.Int32, -1, -1);
198    encodeDecode(codec.Int32, 0xffff, 0xffff);
199    encodeDecode(codec.Int32, 0xffffffff, -1);
200    encodeDecode(codec.Float, 1.0, 1.0);
201    encodeDecode(codec.Double, 1.0, 1.0);
202  }
203
204  function testAlign() {
205    var aligned = [
206      0, // 0
207      8, // 1
208      8, // 2
209      8, // 3
210      8, // 4
211      8, // 5
212      8, // 6
213      8, // 7
214      8, // 8
215      16, // 9
216      16, // 10
217      16, // 11
218      16, // 12
219      16, // 13
220      16, // 14
221      16, // 15
222      16, // 16
223      24, // 17
224      24, // 18
225      24, // 19
226      24, // 20
227    ];
228    for (var i = 0; i < aligned.length; ++i)
229      expect(codec.align(i)).toBe(aligned[i]);
230  }
231
232  function testUtf8() {
233    var str = "B\u03ba\u1f79";  // some UCS-2 codepoints
234    var messageName = 42;
235    var payloadSize = 24;
236
237    var builder = new codec.MessageBuilder(messageName, payloadSize);
238    var encoder = builder.createEncoder(8);
239    encoder.encodeStringPointer(str);
240    var message = builder.finish();
241    var expectedMemory = new Uint8Array([
242      /*  0: */   16,    0,    0,    0,    2,    0,    0,    0,
243      /*  8: */   42,    0,    0,    0,    0,    0,    0,    0,
244      /* 16: */    8,    0,    0,    0,    0,    0,    0,    0,
245      /* 24: */   14,    0,    0,    0,    6,    0,    0,    0,
246      /* 32: */ 0x42, 0xCE, 0xBA, 0xE1, 0xBD, 0xB9,    0,    0,
247    ]);
248    var actualMemory = new Uint8Array(message.buffer.arrayBuffer);
249    expect(actualMemory.length).toEqual(expectedMemory.length);
250    expect(actualMemory).toEqual(expectedMemory);
251
252    var reader = new codec.MessageReader(message);
253    expect(reader.payloadSize).toBe(payloadSize);
254    expect(reader.messageName).toBe(messageName);
255    var str2 = reader.decoder.decodeStringPointer();
256    expect(str2).toEqual(str);
257  }
258});
259