KeepContextInSuper.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js");
  6. var tests = [
  7. {
  8. name: "The execution of the get or set attribute on an object should be \
  9. performed with the same context from which they were called from.",
  10. body: function () {
  11. var a = {};
  12. var f = 'f';
  13. class C {
  14. // get and set should execute in the context of their caller, in
  15. // this example that would be "a"
  16. set f(x) { assert.isTrue(a === this); }
  17. get f() {
  18. assert.isTrue(a === this);
  19. // Necessary as get must be called as a function and should
  20. // not throw an error
  21. return function () { }
  22. }
  23. foo() { assert.isTrue(a === this) }
  24. }
  25. class D extends C {
  26. // The current context is "a" and not D since apply() and call()
  27. // overrided D.
  28. g() { super.f(); }
  29. h() { super.f = 5; }
  30. i() { super.f; }
  31. j() { super['f'] }
  32. k() { super['f']() }
  33. l() { super['f'] = 5 }
  34. m() { super[f] }
  35. n() { super[f]() }
  36. o() { super[f] = 5 }
  37. p() { super.foo() }
  38. }
  39. new D().g.apply(a);
  40. new D().g.call(a);
  41. new D().h.apply(a);
  42. new D().h.call(a);
  43. new D().i.apply(a);
  44. new D().i.call(a);
  45. new D().j.apply(a);
  46. new D().j.call(a);
  47. new D().k.apply(a);
  48. new D().k.call(a);
  49. new D().l.apply(a);
  50. new D().l.call(a);
  51. // These tests are not run as they are not currently fixed. Tests using a property
  52. // accessor with bracket notation (ex: super[prop]) will result in a LdElemI_A
  53. // opcode which cannot take another property to be used as the context during the
  54. // execution of the property access - this limitation may require the addition of
  55. // another opcode (possibly adding the opcode LdSuperElemI_A).
  56. // new D().m.apply(a);
  57. // new D().m.call(a);
  58. // new D().n.apply(a);
  59. // new D().n.call(a);
  60. // new D().o.apply(a);
  61. // new D().o.call(a);
  62. new D().p.apply(a);
  63. new D().p.call(a);
  64. }
  65. },
  66. {
  67. name: "The execution of the get or set attribute on an object should be \
  68. performed with the same context from which they were called from. This test uses \
  69. lambda functions as an alternative way of obtaining the class' context.",
  70. body: function () {
  71. var a = {};
  72. class C {
  73. set f(x) { assert.isTrue(a === (() => this)()); }
  74. get f() {
  75. assert.isTrue(a === (() => this)());
  76. return function () { }
  77. }
  78. foo() { assert.isTrue(a === this) }
  79. }
  80. class D extends C {
  81. g() { super.f(); }
  82. h() { super.f = 5; }
  83. i() { super.f; }
  84. j() { super['f'] }
  85. k() { super['f']() }
  86. l() { super['f'] = 5 }
  87. m() { super[f] }
  88. n() { super[f]() }
  89. o() { super[f] = 5 }
  90. p() { super.foo() }
  91. }
  92. new D().g.apply(a);
  93. new D().g.call(a);
  94. new D().h.apply(a);
  95. new D().h.call(a);
  96. new D().i.apply(a);
  97. new D().i.call(a);
  98. new D().j.apply(a);
  99. new D().j.call(a);
  100. new D().k.apply(a);
  101. new D().k.call(a);
  102. new D().l.apply(a);
  103. new D().l.call(a);
  104. // new D().m.apply(a);
  105. // new D().m.call(a);
  106. // new D().n.apply(a);
  107. // new D().n.call(a);
  108. // new D().o.apply(a);
  109. // new D().o.call(a);
  110. new D().p.apply(a);
  111. new D().p.call(a);
  112. }
  113. },
  114. {
  115. name: "The execution of the get or set attribute on an object should be \
  116. performed with the same context from which they were called from. This test uses \
  117. lambda functions as an alternative way of obtaining the class' context. This text \
  118. also uses eval statements.",
  119. body: function () {
  120. var a = {};
  121. class C {
  122. set f(x) { eval("assert.isTrue(a === (() => this)())"); }
  123. get f() {
  124. eval("assert.isTrue(a === (() => this)())");
  125. return function () { }
  126. }
  127. foo() { assert.isTrue(a === this) }
  128. }
  129. class D extends C {
  130. g() { eval("super.f();") }
  131. h() { eval("super.f = 5;") }
  132. i() { eval("super.f;") }
  133. j() { eval("super['f']") }
  134. k() { eval("super['f']()") }
  135. l() { eval("super['f'] = 5") }
  136. m() { eval("super[f]") }
  137. n() { eval("super[f]()") }
  138. o() { eval("super[f] = 5") }
  139. p() { eval("super.foo()") }
  140. }
  141. eval("new D().g.apply(a);");
  142. eval("new D().g.call(a);");
  143. eval("new D().h.apply(a);");
  144. eval("new D().h.call(a);");
  145. eval("new D().i.apply(a);");
  146. eval("new D().i.call(a);");
  147. eval("new D().j.apply(a);");
  148. eval("new D().j.call(a);");
  149. eval("new D().k.apply(a);");
  150. eval("new D().k.call(a);");
  151. eval("new D().l.apply(a);");
  152. eval("new D().l.call(a);");
  153. // eval("new D().m.apply(a);");
  154. // eval("new D().m.call(a);");
  155. // eval("new D().n.apply(a);");
  156. // eval("new D().n.call(a);");
  157. // eval("new D().o.apply(a);");
  158. // eval("new D().o.call(a);");
  159. eval("new D().p.apply(a);");
  160. eval("new D().p.call(a);");
  161. }
  162. },
  163. ]
  164. testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });