| var testCase = function (actual, expected, message) { |
| if (actual !== expected) { |
| throw message + ". Expected '" + expected + "', but was '" + actual + "'"; |
| } |
| }; |
| |
| var testValue = 'test-value'; |
| |
| var A = class A { |
| constructor() { |
| this.idValue = testValue; |
| } |
| }; |
| |
| var B = class B extends A { |
| constructor (inArrowFuction, inConstructor, setProtoToNull) { |
| var arrow = () => () => () => { |
| if (inArrowFuction) { |
| super(); |
| testCase(this.idValue, testValue, "Error: super() should create this and put value into idValue property"); |
| } |
| }; |
| |
| if (inArrowFuction) |
| arrow()()(); |
| |
| if (inConstructor) |
| super(); |
| |
| testCase(this.idValue, testValue, "Error: arrow function should return this to constructor"); |
| } |
| }; |
| |
| for (var i=0; i < 1000; i++) { |
| new B(true, false); |
| new B(false, true); |
| } |
| |
| var testException = function (index) { |
| var exception; |
| try { |
| new B(false, false); |
| } catch (e) { |
| exception = e; |
| if (!(e instanceof ReferenceError)) |
| throw "Exception thrown was not a correct error. Expected ReferenceError but was " + e.name; |
| } |
| |
| if (!exception) |
| throw "Exception not thrown for an unitialized this at iteration #" + index; |
| } |
| |
| for (var i = 0; i < 1000; i++) { |
| testException(i, ReferenceError); |
| } |
| |
| var C = class C extends A { |
| constructor () { |
| var arrow = () => { |
| let __proto__ = 'some-text'; |
| var arr = () => { |
| testCase(typeof __proto__, 'string', "Erorr: __proto__ variable has wrong type"); |
| super(); |
| testCase(this.idValue, testValue, "Error: super() should create this and put value into idValue property"); |
| }; |
| arr(); |
| }; |
| |
| arrow(); |
| |
| testCase(this.idValue, testValue, "Error: arrow function should return this to constructor"); |
| } |
| }; |
| |
| for (var i = 0; i < 1000; i++) { |
| new C(); |
| } |
| |
| class D extends A { |
| constructor(doReplaceProto) { |
| var arrow = () => super(); |
| if (doReplaceProto) |
| D.__proto__ = function () {}; |
| arrow(); |
| } |
| } |
| |
| testCase((new D(false)).idValue, testValue, "Error: arrow function bound wrong super"); |
| testCase(typeof (new D(true)).idValue, "undefined" , "Error: arrow function bound wrong super"); |
| |
| class E extends A { |
| constructor(doReplaceProto) { |
| var arrow = () => { |
| if (doReplaceProto) |
| E.__proto__ = function () {}; |
| super(); |
| }; |
| |
| arrow(); |
| } |
| } |
| |
| testCase((new E(false)).idValue, testValue, "Error: arrow function bound wrong super #1"); |
| testCase(typeof (new E(true)).idValue, "undefined" , "Error: arrow function bound wrong super #1"); |
| |
| |
| class F extends A { |
| constructor(doReplaceProto) { |
| var arrow = () => { |
| F.__proto__ = null; |
| super(); |
| }; |
| |
| arrow(); |
| } |
| } |
| |
| var testTypeErrorException = function (index) { |
| var exception; |
| try { |
| new F(); |
| } catch (e) { |
| exception = e; |
| if (!(e instanceof TypeError)) |
| throw "Exception thrown was not a correct error. Expected TypeError but was " + e.name; |
| } |
| |
| if (!exception) |
| throw "Exception not thrown for an unitialized this at iteration #" + index; |
| } |
| |
| for (var i = 0; i < 1000; i++) { |
| testTypeErrorException(i); |
| } |
| |
| var errorStack; |
| |
| var ParentClass = class ParentClass { |
| constructor() { |
| try { |
| this.idValue = testValue; |
| throw new Error('Error'); |
| } catch (e) { |
| errorStack = e.stack; |
| } |
| } |
| }; |
| |
| var ChildClass = class ChildClass extends ParentClass { |
| constructor () { |
| var arrowInChildConstructor = () => { |
| var nestedArrow = () => { |
| super(); |
| } |
| |
| nestedArrow(); |
| }; |
| |
| arrowInChildConstructor(); |
| } |
| }; |
| |
| for (var i = 0; i < 1000; i++) { |
| errorStack = ''; |
| let c = new ChildClass(); |
| |
| let parentClassIndexOf = errorStack.indexOf('ParentClass'); |
| let nestedArrowIndexOf = errorStack.indexOf('nestedArrow'); |
| let arrowInChildConstructorIndexOf = errorStack.indexOf('arrowInChildConstructor'); |
| let childClassIndexOf = errorStack.indexOf('ChildClass'); |
| |
| testCase(parentClassIndexOf > -1 && errorStack.indexOf('ParentClass', parentClassIndexOf + 1) === -1, true, "Error: stack of error should contain ParentClass text"); |
| testCase(nestedArrowIndexOf > -1 && errorStack.indexOf('nestedArrow', nestedArrowIndexOf + 1) === -1, true, "Error: stack of error should contain nestedArrow text"); |
| testCase(arrowInChildConstructorIndexOf > -1 && errorStack.indexOf('arrowInChildConstructor', arrowInChildConstructorIndexOf + 1) === -1, true, "Error: stack of error should contain arrowInChildConstructor text"); |
| testCase(childClassIndexOf > -1 && errorStack.indexOf('ChildClass', childClassIndexOf + 1) === -1, true, "Error: stack of error should contains ChildClass text"); |
| } |