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_while()
24{
25    var i, c;
26    i = 0;
27    c = 0;
28    while (i < 3) {
29        c++;
30        i++;
31    }
32    assert(c === 3);
33}
34
35function test_while_break()
36{
37    var i, c;
38    i = 0;
39    c = 0;
40    while (i < 3) {
41        c++;
42        if (i == 1)
43            break;
44        i++;
45    }
46    assert(c === 2 && i === 1);
47}
48
49function test_do_while()
50{
51    var i, c;
52    i = 0;
53    c = 0;
54    do {
55        c++;
56        i++;
57    } while (i < 3);
58    assert(c === 3 && i === 3);
59}
60
61function test_for()
62{
63    var i, c;
64    c = 0;
65    for(i = 0; i < 3; i++) {
66        c++;
67    }
68    assert(c === 3 && i === 3);
69
70    c = 0;
71    for(var j = 0; j < 3; j++) {
72        c++;
73    }
74    assert(c === 3 && j === 3);
75}
76
77function test_for_in()
78{
79    var i, tab, a, b;
80
81    tab = [];
82    for(i in {x:1, y: 2}) {
83        tab.push(i);
84    }
85    assert(tab.toString(), "x,y", "for_in");
86
87    /* prototype chain test */
88    a = {x:2, y: 2, "1": 3};
89    b = {"4" : 3 };
90    Object.setPrototypeOf(a, b);
91    tab = [];
92    for(i in a) {
93        tab.push(i);
94    }
95    assert(tab.toString(), "1,x,y,4", "for_in");
96
97    /* non enumerable properties hide enumerables ones in the
98       prototype chain */
99    a = {y: 2, "1": 3};
100    Object.defineProperty(a, "x", { value: 1 });
101    b = {"x" : 3 };
102    Object.setPrototypeOf(a, b);
103    tab = [];
104    for(i in a) {
105        tab.push(i);
106    }
107    assert(tab.toString(), "1,y", "for_in");
108
109    /* array optimization */
110    a = [];
111    for(i = 0; i < 10; i++)
112        a.push(i);
113    tab = [];
114    for(i in a) {
115        tab.push(i);
116    }
117    assert(tab.toString(), "0,1,2,3,4,5,6,7,8,9", "for_in");
118
119    /* iterate with a field */
120    a={x:0};
121    tab = [];
122    for(a.x in {x:1, y: 2}) {
123        tab.push(a.x);
124    }
125    assert(tab.toString(), "x,y", "for_in");
126
127    /* iterate with a variable field */
128    a=[0];
129    tab = [];
130    for(a[0] in {x:1, y: 2}) {
131        tab.push(a[0]);
132    }
133    assert(tab.toString(), "x,y", "for_in");
134
135    /* variable definition in the for in */
136    tab = [];
137    for(var j in {x:1, y: 2}) {
138        tab.push(j);
139    }
140    assert(tab.toString(), "x,y", "for_in");
141
142    /* variable assigment in the for in */
143    tab = [];
144    for(var k = 2 in {x:1, y: 2}) {
145        tab.push(k);
146    }
147    assert(tab.toString(), "x,y", "for_in");
148}
149
150function test_for_in2()
151{
152    var i;
153    tab = [];
154    for(i in {x:1, y: 2, z:3}) {
155        if (i === "y")
156            continue;
157        tab.push(i);
158    }
159    assert(tab.toString() == "x,z");
160
161    tab = [];
162    for(i in {x:1, y: 2, z:3}) {
163        if (i === "z")
164            break;
165        tab.push(i);
166    }
167    assert(tab.toString() == "x,y");
168}
169
170function test_for_break()
171{
172    var i, c;
173    c = 0;
174    L1: for(i = 0; i < 3; i++) {
175        c++;
176        if (i == 0)
177            continue;
178        while (1) {
179            break L1;
180        }
181    }
182    assert(c === 2 && i === 1);
183}
184
185function test_switch1()
186{
187    var i, a, s;
188    s = "";
189    for(i = 0; i < 3; i++) {
190        a = "?";
191        switch(i) {
192        case 0:
193            a = "a";
194            break;
195        case 1:
196            a = "b";
197            break;
198        default:
199            a = "c";
200            break;
201        }
202        s += a;
203    }
204    assert(s === "abc" && i === 3);
205}
206
207function test_switch2()
208{
209    var i, a, s;
210    s = "";
211    for(i = 0; i < 4; i++) {
212        a = "?";
213        switch(i) {
214        case 0:
215            a = "a";
216            break;
217        case 1:
218            a = "b";
219            break;
220        case 2:
221            continue;
222        default:
223            a = "" + i;
224            break;
225        }
226        s += a;
227    }
228    assert(s === "ab3" && i === 4);
229}
230
231function test_try_catch1()
232{
233    try {
234        throw "hello";
235    } catch (e) {
236        assert(e, "hello", "catch");
237        return;
238    }
239    assert(false, "catch");
240}
241
242function test_try_catch2()
243{
244    var a;
245    try {
246        a = 1;
247    } catch (e) {
248        a = 2;
249    }
250    assert(a, 1, "catch");
251}
252
253function test_try_catch3()
254{
255    var s;
256    s = "";
257    try {
258        s += "t";
259    } catch (e) {
260        s += "c";
261    } finally {
262        s += "f";
263    }
264    assert(s, "tf", "catch");
265}
266
267function test_try_catch4()
268{
269    var s;
270    s = "";
271    try {
272        s += "t";
273        throw "c";
274    } catch (e) {
275        s += e;
276    } finally {
277        s += "f";
278    }
279    assert(s, "tcf", "catch");
280}
281
282function test_try_catch5()
283{
284    var s;
285    s = "";
286    for(;;) {
287        try {
288            s += "t";
289            break;
290            s += "b";
291        } finally {
292            s += "f";
293        }
294    }
295    assert(s, "tf", "catch");
296}
297
298function test_try_catch6()
299{
300    function f() {
301        try {
302            s += 't';
303            return 1;
304        } finally {
305            s += "f";
306        }
307    }
308    var s = "";
309    assert(f() === 1);
310    assert(s, "tf", "catch6");
311}
312
313function test_try_catch7()
314{
315    var s;
316    s = "";
317
318    try {
319        try {
320            s += "t";
321            throw "a";
322        } finally {
323            s += "f";
324        }
325    } catch(e) {
326        s += e;
327    } finally {
328        s += "g";
329    }
330    assert(s, "tfag", "catch");
331}
332
333function test_try_catch8()
334{
335    var i, s;
336
337    s = "";
338    for(var i in {x:1, y:2}) {
339        try {
340            s += i;
341            throw "a";
342        } catch (e) {
343            s += e;
344        } finally {
345            s += "f";
346        }
347    }
348    assert(s === "xafyaf");
349}
350
351test_while();
352test_while_break();
353test_do_while();
354test_for();
355test_for_break();
356test_switch1();
357test_switch2();
358test_for_in();
359test_for_in2();
360
361test_try_catch1();
362test_try_catch2();
363test_try_catch3();
364test_try_catch4();
365test_try_catch5();
366test_try_catch6();
367test_try_catch7();
368test_try_catch8();
369