michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: var BUGNUMBER = 384412; michael@0: var summary = 'Exercise frame handling code'; michael@0: var actual = ''; michael@0: var expect = ''; michael@0: michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: test(); michael@0: //----------------------------------------------------------------------------- michael@0: michael@0: function test() michael@0: { michael@0: enterFunc ('test'); michael@0: printBugNumber(BUGNUMBER); michael@0: printStatus (summary); michael@0: michael@0: /* michael@0: * Generators michael@0: */ michael@0: michael@0: /* Generator yields properly */ michael@0: f = (function(n) { for (var i = 0; i != n; i++) yield i }); michael@0: g = f(3); michael@0: expect(0, g.next()); michael@0: expect(1, g.next()); michael@0: expect(2, g.next()); michael@0: s = "no exception"; michael@0: try { g.next(); } catch (e) { s = e + ""; } michael@0: expect("[object StopIteration]", s); michael@0: michael@0: /* Generator yields properly in finally */ michael@0: f = (function(n) { michael@0: try { michael@0: for (var i = 0; i != n; i++) michael@0: yield i; michael@0: } finally { michael@0: yield "finally"; michael@0: } michael@0: }); michael@0: michael@0: g = f(3); michael@0: expect(0, g.next()); michael@0: expect(1, g.next()); michael@0: expect(2, g.next()); michael@0: expect("finally", g.next()); michael@0: michael@0: /* Generator throws when closed with yield in finally */ michael@0: g = f(3); michael@0: expect(0, g.next()); michael@0: s = "no exception"; michael@0: try { g.close(); } catch (e) { s = e + ""; }; michael@0: expect("TypeError: yield from closing generator " + f.toSource(), s); michael@0: michael@0: michael@0: /* michael@0: * Calls that have been replaced with js_PushFrame() &c... michael@0: */ michael@0: f = (function() { return arguments[(arguments.length - 1) / 2]; }); michael@0: expect(2, f(1, 2, 3)); michael@0: expect(2, f.call(null, 1, 2, 3)); michael@0: expect(2, f.apply(null, [1, 2, 3])); michael@0: expect("a1c", "abc".replace("b", f)); michael@0: s = "no exception"; michael@0: try { michael@0: "abc".replace("b", (function() { throw "hello" })); michael@0: } catch (e) { michael@0: s = e + ""; michael@0: } michael@0: expect("hello", s); michael@0: expect(6, [1, 2, 3].reduce(function(a, b) { return a + b; })); michael@0: s = "no exception"; michael@0: try { michael@0: [1, 2, 3].reduce(function(a, b) { if (b == 2) throw "hello"; }); michael@0: } catch (e) { michael@0: s = e + ""; michael@0: } michael@0: expect("hello", s); michael@0: michael@0: /* michael@0: * __noSuchMethod__ michael@0: */ michael@0: o = {}; michael@0: s = "no exception"; michael@0: try { michael@0: o.hello(); michael@0: } catch (e) { michael@0: s = e + ""; michael@0: } michael@0: expect("TypeError: o.hello is not a function", s); michael@0: o.__noSuchMethod__ = (function() { return "world"; }); michael@0: expect("world", o.hello()); michael@0: o.__noSuchMethod__ = 1; michael@0: s = "no exception"; michael@0: try { michael@0: o.hello(); michael@0: } catch (e) { michael@0: s = e + ""; michael@0: } michael@0: expect("TypeError: o.hello is not a function", s); michael@0: o.__noSuchMethod__ = {}; michael@0: s = "no exception"; michael@0: try { michael@0: o.hello(); michael@0: } catch (e) { michael@0: s = e + ""; michael@0: } michael@0: expect("TypeError: ({}) is not a function", s); michael@0: s = "no exception"; michael@0: try { michael@0: eval("o.hello()"); michael@0: } catch (e) { michael@0: s = e + ""; michael@0: } michael@0: expect("TypeError: ({}) is not a function", s); michael@0: s = "no exception"; michael@0: try { [2, 3, 0].sort({}); } catch (e) { s = e + ""; } michael@0: expect("TypeError: ({}) is not a function", s); michael@0: michael@0: /* michael@0: * Generator expressions. michael@0: */ michael@0: String.prototype.__iterator__ = (function () { michael@0: /* michael@0: * NOTE: michael@0: * Without the "0 + ", the loop over does not terminate because michael@0: * the iterator gets run on a string with an empty length property. michael@0: */ michael@0: for (let i = 0; i != 0 + this.length; i++) michael@0: yield this[i]; michael@0: }); michael@0: expect(["a1", "a2", "a3", "b1", "b2", "b3", "c1", "c2", "c3"] + "", michael@0: ([a + b for (a in 'abc') for (b in '123')]) + ""); michael@0: michael@0: print("End of Tests"); michael@0: michael@0: /* michael@0: * Utility functions michael@0: */ michael@0: function expect(a, b) { michael@0: print('expect: ' + a + ', actual: ' + b); michael@0: reportCompare(a, b, summary); michael@0: } michael@0: michael@0: michael@0: exitFunc ('test'); michael@0: }