|
|
@@ -0,0 +1,171 @@
|
|
|
+//-------------------------------------------------------------------------------------------------------
|
|
|
+// Copyright (C) Microsoft. All rights reserved.
|
|
|
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
|
|
|
+//-------------------------------------------------------------------------------------------------------
|
|
|
+
|
|
|
+WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js");
|
|
|
+
|
|
|
+var tests = [
|
|
|
+ {
|
|
|
+ name: "The execution of the get or set attribute on an object should be \
|
|
|
+performed with the same context from which they were called from.",
|
|
|
+ body: function () {
|
|
|
+ var a = {};
|
|
|
+ var f = 'f';
|
|
|
+ class C {
|
|
|
+ // get and set should execute in the context of their caller, in
|
|
|
+ // this example that would be "a"
|
|
|
+ set f(x) { assert.isTrue(a === this); }
|
|
|
+ get f() {
|
|
|
+ assert.isTrue(a === this);
|
|
|
+
|
|
|
+ // Necessary as get must be called as a function and should
|
|
|
+ // not throw an error
|
|
|
+ return function () { }
|
|
|
+ }
|
|
|
+ foo() { assert.isTrue(a === this) }
|
|
|
+ }
|
|
|
+ class D extends C {
|
|
|
+ // The current context is "a" and not D since apply() and call()
|
|
|
+ // overrided D.
|
|
|
+ g() { super.f(); }
|
|
|
+ h() { super.f = 5; }
|
|
|
+ i() { super.f; }
|
|
|
+ j() { super['f'] }
|
|
|
+ k() { super['f']() }
|
|
|
+ l() { super['f'] = 5 }
|
|
|
+ m() { super[f] }
|
|
|
+ n() { super[f]() }
|
|
|
+ o() { super[f] = 5 }
|
|
|
+ p() { super.foo() }
|
|
|
+ }
|
|
|
+ new D().g.apply(a);
|
|
|
+ new D().g.call(a);
|
|
|
+ new D().h.apply(a);
|
|
|
+ new D().h.call(a);
|
|
|
+ new D().i.apply(a);
|
|
|
+ new D().i.call(a);
|
|
|
+ new D().j.apply(a);
|
|
|
+ new D().j.call(a);
|
|
|
+ new D().k.apply(a);
|
|
|
+ new D().k.call(a);
|
|
|
+ new D().l.apply(a);
|
|
|
+ new D().l.call(a);
|
|
|
+
|
|
|
+ // These tests are not run as they are not currently fixed. Tests using a property
|
|
|
+ // accessor with bracket notation (ex: super[prop]) will result in a LdElemI_A
|
|
|
+ // opcode which cannot take another property to be used as the context during the
|
|
|
+ // execution of the property access - this limitation may require the addition of
|
|
|
+ // another opcode (possibly adding the opcode LdSuperElemI_A).
|
|
|
+
|
|
|
+ // new D().m.apply(a);
|
|
|
+ // new D().m.call(a);
|
|
|
+ // new D().n.apply(a);
|
|
|
+ // new D().n.call(a);
|
|
|
+ // new D().o.apply(a);
|
|
|
+ // new D().o.call(a);
|
|
|
+
|
|
|
+ new D().p.apply(a);
|
|
|
+ new D().p.call(a);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "The execution of the get or set attribute on an object should be \
|
|
|
+performed with the same context from which they were called from. This test uses \
|
|
|
+lambda functions as an alternative way of obtaining the class' context.",
|
|
|
+ body: function () {
|
|
|
+ var a = {};
|
|
|
+ class C {
|
|
|
+ set f(x) { assert.isTrue(a === (() => this)()); }
|
|
|
+ get f() {
|
|
|
+ assert.isTrue(a === (() => this)());
|
|
|
+ return function () { }
|
|
|
+ }
|
|
|
+ foo() { assert.isTrue(a === this) }
|
|
|
+ }
|
|
|
+ class D extends C {
|
|
|
+ g() { super.f(); }
|
|
|
+ h() { super.f = 5; }
|
|
|
+ i() { super.f; }
|
|
|
+ j() { super['f'] }
|
|
|
+ k() { super['f']() }
|
|
|
+ l() { super['f'] = 5 }
|
|
|
+ m() { super[f] }
|
|
|
+ n() { super[f]() }
|
|
|
+ o() { super[f] = 5 }
|
|
|
+ p() { super.foo() }
|
|
|
+ }
|
|
|
+ new D().g.apply(a);
|
|
|
+ new D().g.call(a);
|
|
|
+ new D().h.apply(a);
|
|
|
+ new D().h.call(a);
|
|
|
+ new D().i.apply(a);
|
|
|
+ new D().i.call(a);
|
|
|
+ new D().j.apply(a);
|
|
|
+ new D().j.call(a);
|
|
|
+ new D().k.apply(a);
|
|
|
+ new D().k.call(a);
|
|
|
+ new D().l.apply(a);
|
|
|
+ new D().l.call(a);
|
|
|
+ // new D().m.apply(a);
|
|
|
+ // new D().m.call(a);
|
|
|
+ // new D().n.apply(a);
|
|
|
+ // new D().n.call(a);
|
|
|
+ // new D().o.apply(a);
|
|
|
+ // new D().o.call(a);
|
|
|
+ new D().p.apply(a);
|
|
|
+ new D().p.call(a);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "The execution of the get or set attribute on an object should be \
|
|
|
+performed with the same context from which they were called from. This test uses \
|
|
|
+lambda functions as an alternative way of obtaining the class' context. This text \
|
|
|
+also uses eval statements.",
|
|
|
+ body: function () {
|
|
|
+ var a = {};
|
|
|
+ class C {
|
|
|
+ set f(x) { eval("assert.isTrue(a === (() => this)())"); }
|
|
|
+ get f() {
|
|
|
+ eval("assert.isTrue(a === (() => this)())");
|
|
|
+ return function () { }
|
|
|
+ }
|
|
|
+ foo() { assert.isTrue(a === this) }
|
|
|
+ }
|
|
|
+ class D extends C {
|
|
|
+ g() { eval("super.f();") }
|
|
|
+ h() { eval("super.f = 5;") }
|
|
|
+ i() { eval("super.f;") }
|
|
|
+ j() { eval("super['f']") }
|
|
|
+ k() { eval("super['f']()") }
|
|
|
+ l() { eval("super['f'] = 5") }
|
|
|
+ m() { eval("super[f]") }
|
|
|
+ n() { eval("super[f]()") }
|
|
|
+ o() { eval("super[f] = 5") }
|
|
|
+ p() { eval("super.foo()") }
|
|
|
+ }
|
|
|
+ eval("new D().g.apply(a);");
|
|
|
+ eval("new D().g.call(a);");
|
|
|
+ eval("new D().h.apply(a);");
|
|
|
+ eval("new D().h.call(a);");
|
|
|
+ eval("new D().i.apply(a);");
|
|
|
+ eval("new D().i.call(a);");
|
|
|
+ eval("new D().j.apply(a);");
|
|
|
+ eval("new D().j.call(a);");
|
|
|
+ eval("new D().k.apply(a);");
|
|
|
+ eval("new D().k.call(a);");
|
|
|
+ eval("new D().l.apply(a);");
|
|
|
+ eval("new D().l.call(a);");
|
|
|
+ // eval("new D().m.apply(a);");
|
|
|
+ // eval("new D().m.call(a);");
|
|
|
+ // eval("new D().n.apply(a);");
|
|
|
+ // eval("new D().n.call(a);");
|
|
|
+ // eval("new D().o.apply(a);");
|
|
|
+ // eval("new D().o.call(a);");
|
|
|
+ eval("new D().p.apply(a);");
|
|
|
+ eval("new D().p.call(a);");
|
|
|
+ }
|
|
|
+ },
|
|
|
+]
|
|
|
+
|
|
|
+testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });
|