1function assert(actual, expected, message) {
2    if (arguments.length == 1)
3        expected = true;
4
5    if (actual === expected)
6        return;
7
8    if (actual !== null && expected !== null
9    &&  typeof actual == 'object' && typeof expected == 'object'
10    &&  actual.toString() === expected.toString())
11        return;
12
13    throw Error("assertion failed: got |" + actual + "|" +
14                ", expected |" + expected + "|" +
15                (message ? " (" + message + ")" : ""));
16}
17
18// load more elaborate version of assert if available
19try { __loadScript("test_assert.js"); } catch(e) {}
20
21/*----------------*/
22
23function test_op1()
24{
25    var r, a;
26    r = 1 + 2;
27    assert(r, 3, "1 + 2 === 3");
28
29    r = 1 - 2;
30    assert(r, -1, "1 - 2 === -1");
31
32    r = -1;
33    assert(r, -1, "-1 === -1");
34
35    r = +2;
36    assert(r, 2, "+2 === 2");
37
38    r = 2 * 3;
39    assert(r, 6, "2 * 3 === 6");
40
41    r = 4 / 2;
42    assert(r, 2, "4 / 2 === 2");
43
44    r = 4 % 3;
45    assert(r, 1, "4 % 3 === 3");
46
47    r = 4 << 2;
48    assert(r, 16, "4 << 2 === 16");
49
50    r = 1 << 0;
51    assert(r, 1, "1 << 0 === 1");
52
53    r = 1 << 31;
54    assert(r, -2147483648, "1 << 31 === -2147483648");
55
56    r = 1 << 32;
57    assert(r, 1, "1 << 32 === 1");
58
59    r = (1 << 31) < 0;
60    assert(r, true, "(1 << 31) < 0 === true");
61
62    r = -4 >> 1;
63    assert(r, -2, "-4 >> 1 === -2");
64
65    r = -4 >>> 1;
66    assert(r, 0x7ffffffe, "-4 >>> 1 === 0x7ffffffe");
67
68    r = 1 & 1;
69    assert(r, 1, "1 & 1 === 1");
70
71    r = 0 | 1;
72    assert(r, 1, "0 | 1 === 1");
73
74    r = 1 ^ 1;
75    assert(r, 0, "1 ^ 1 === 0");
76
77    r = ~1;
78    assert(r, -2, "~1 === -2");
79
80    r = !1;
81    assert(r, false, "!1 === false");
82
83    assert((1 < 2), true, "(1 < 2) === true");
84
85    assert((2 > 1), true, "(2 > 1) === true");
86
87    assert(('b' > 'a'), true, "('b' > 'a') === true");
88
89    assert(2 ** 8, 256, "2 ** 8 === 256");
90}
91
92function test_cvt()
93{
94    assert((NaN | 0) === 0);
95    assert((Infinity | 0) === 0);
96    assert(((-Infinity) | 0) === 0);
97    assert(("12345" | 0) === 12345);
98    assert(("0x12345" | 0) === 0x12345);
99    assert(((4294967296 * 3 - 4) | 0) === -4);
100
101    assert(("12345" >>> 0) === 12345);
102    assert(("0x12345" >>> 0) === 0x12345);
103    assert((NaN >>> 0) === 0);
104    assert((Infinity >>> 0) === 0);
105    assert(((-Infinity) >>> 0) === 0);
106    assert(((4294967296 * 3 - 4) >>> 0) === (4294967296 - 4));
107}
108
109function test_eq()
110{
111    assert(null == undefined);
112    assert(undefined == null);
113    assert(true == 1);
114    assert(0 == false);
115    assert("" == 0);
116    assert("123" == 123);
117    assert("122" != 123);
118    assert((new Number(1)) == 1);
119    assert(2 == (new Number(2)));
120    assert((new String("abc")) == "abc");
121    assert({} != "abc");
122}
123
124function test_inc_dec()
125{
126    var a, r;
127
128    a = 1;
129    r = a++;
130    assert(r === 1 && a === 2, true, "++");
131
132    a = 1;
133    r = ++a;
134    assert(r === 2 && a === 2, true, "++");
135
136    a = 1;
137    r = a--;
138    assert(r === 1 && a === 0, true, "--");
139
140    a = 1;
141    r = --a;
142    assert(r === 0 && a === 0, true, "--");
143
144    a = {x:true};
145    a.x++;
146    assert(a.x, 2, "++");
147
148    a = {x:true};
149    a.x--;
150    assert(a.x, 0, "--");
151
152    a = [true];
153    a[0]++;
154    assert(a[0], 2, "++");
155
156    a = {x:true};
157    r = a.x++;
158    assert(r === 1 && a.x === 2, true, "++");
159
160    a = {x:true};
161    r = a.x--;
162    assert(r === 1 && a.x === 0, true, "--");
163
164    a = [true];
165    r = a[0]++;
166    assert(r === 1 && a[0] === 2, true, "++");
167
168    a = [true];
169    r = a[0]--;
170    assert(r === 1 && a[0] === 0, true, "--");
171}
172
173function F(x)
174{
175    this.x = x;
176}
177
178function test_op2()
179{
180    var a, b;
181    a = new Object;
182    a.x = 1;
183    assert(a.x, 1, "new");
184    b = new F(2);
185    assert(b.x, 2, "new");
186
187    a = {x : 2};
188    assert(("x" in a), true, "in");
189    assert(("y" in a), false, "in");
190
191    a = {};
192    assert((a instanceof Object), true, "instanceof");
193    assert((a instanceof String), false, "instanceof");
194
195    assert((typeof 1), "number", "typeof");
196    assert((typeof Object), "function", "typeof");
197    assert((typeof null), "object", "typeof");
198    assert((typeof unknown_var), "undefined", "typeof");
199
200    a = {x: 1, if: 2, async: 3};
201    assert(a.if === 2);
202    assert(a.async === 3);
203}
204
205function test_delete()
206{
207    var a, err;
208
209    a = {x: 1, y: 1};
210    assert((delete a.x), true, "delete");
211    assert(("x" in a), false, "delete");
212
213    /* the following are not tested by test262 */
214    assert(delete "abc"[100], true);
215
216    err = false;
217    try {
218        delete null.a;
219    } catch(e) {
220        err = (e instanceof TypeError);
221    }
222    assert(err, true, "delete");
223
224    err = false;
225    try {
226        a = { f() { delete super.a; } };
227        a.f();
228    } catch(e) {
229        err = (e instanceof ReferenceError);
230    }
231    assert(err, true, "delete");
232}
233
234function test_prototype()
235{
236    function f() { }
237    assert(f.prototype.constructor, f, "prototype");
238}
239
240function test_arguments()
241{
242    function f2() {
243        assert(arguments.length, 2, "arguments");
244        assert(arguments[0], 1, "arguments");
245        assert(arguments[1], 3, "arguments");
246    }
247    f2(1, 3);
248}
249
250function test_class()
251{
252    var o;
253    class C {
254        constructor() {
255            this.x = 10;
256        }
257        f() {
258            return 1;
259        }
260        static F() {
261            return -1;
262        }
263        get y() {
264            return 12;
265        }
266    };
267    class D extends C {
268        constructor() {
269            super();
270            this.z = 20;
271        }
272        g() {
273            return 2;
274        }
275        static G() {
276            return -2;
277        }
278        h() {
279            return super.f();
280        }
281        static H() {
282            return super["F"]();
283        }
284    }
285
286    assert(C.F() === -1);
287    assert(Object.getOwnPropertyDescriptor(C.prototype, "y").get.name === "get y");
288
289    o = new C();
290    assert(o.f() === 1);
291    assert(o.x === 10);
292
293    assert(D.F() === -1);
294    assert(D.G() === -2);
295    assert(D.H() === -1);
296
297    o = new D();
298    assert(o.f() === 1);
299    assert(o.g() === 2);
300    assert(o.x === 10);
301    assert(o.z === 20);
302    assert(o.h() === 1);
303
304    /* test class name scope */
305    var E1 = class E { static F() { return E; } };
306    assert(E1 === E1.F());
307};
308
309function test_template()
310{
311    var a, b;
312    b = 123;
313    a = `abc${b}d`;
314    assert(a, "abc123d");
315
316    a = String.raw `abc${b}d`;
317    assert(a, "abc123d");
318
319    a = "aaa";
320    b = "bbb";
321    assert(`aaa${a, b}ccc`, "aaabbbccc");
322}
323
324function test_template_skip()
325{
326    var a = "Bar";
327    var { b = `${a + `a${a}` }baz` } = {};
328    assert(b, "BaraBarbaz");
329}
330
331function test_object_literal()
332{
333    var x = 0, get = 1, set = 2; async = 3;
334    a = { get: 2, set: 3, async: 4 };
335    assert(JSON.stringify(a), '{"get":2,"set":3,"async":4}');
336
337    a = { x, get, set, async };
338    assert(JSON.stringify(a), '{"x":0,"get":1,"set":2,"async":3}');
339}
340
341function test_regexp_skip()
342{
343    var a, b;
344    [a, b = /abc\(/] = [1];
345    assert(a === 1);
346
347    [a, b =/abc\(/] = [2];
348    assert(a === 2);
349}
350
351function test_labels()
352{
353    do x: { break x; } while(0);
354    if (1)
355        x: { break x; }
356    else
357        x: { break x; }
358    with ({}) x: { break x; };
359    while (0) x: { break x; };
360}
361
362test_op1();
363test_cvt();
364test_eq();
365test_inc_dec();
366test_op2();
367test_delete();
368test_prototype();
369test_arguments();
370test_class();
371test_template();
372test_template_skip();
373test_object_literal();
374test_regexp_skip();
375test_labels();
376