ES6Class_BaseClassConstruction.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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. // ES6 super chain tests
  6. WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js");
  7. var tests = [
  8. {
  9. name: "Simple base class object construction",
  10. body: function () {
  11. class Simple {
  12. bar() {
  13. return 'bar';
  14. }
  15. constructor(val) {
  16. this.val = val;
  17. this.foo = "Simple";
  18. }
  19. };
  20. let result = new Simple('val');
  21. assert.areEqual("Simple", result.foo, "'this' is valid to use in Simple.constructor");
  22. assert.areEqual("val", result.val, "Arguments passed to Simple.constructor pass through correctly");
  23. assert.areEqual("bar", result.bar(), "Result object can call class members");
  24. assert.isTrue(result instanceof Simple, "new Simple(); uses new.target as 'Simple' itself which creates instanceof Simple class");
  25. }
  26. },
  27. {
  28. name: "Simple base class object construction which uses a lambda to access this",
  29. body: function () {
  30. class Simple {
  31. constructor(val) {
  32. let arrow = () => {
  33. this.val = val;
  34. this.foo = "Simple";
  35. };
  36. arrow();
  37. }
  38. };
  39. let result = new Simple('val');
  40. assert.areEqual("Simple", result.foo, "'this' is valid to use in Simple.constructor");
  41. assert.areEqual("val", result.val, "Arguments passed to Simple.constructor pass through correctly");
  42. assert.isTrue(result instanceof Simple, "new Simple(); uses new.target as 'Simple' itself which creates instanceof Simple class");
  43. }
  44. },
  45. {
  46. name: "Base class constructors return 'this' if they explicitly return a non-object",
  47. body: function () {
  48. class ReturnArgumentBaseClass {
  49. constructor(val) {
  50. this.foo = 'ReturnArgumentBaseClass';
  51. return val;
  52. }
  53. };
  54. let result = new ReturnArgumentBaseClass(null);
  55. assert.areEqual("ReturnArgumentBaseClass", result.foo, "new ReturnArgumentBaseClass(null); returns 'this'");
  56. assert.isTrue(result instanceof ReturnArgumentBaseClass, "new ReturnArgumentBaseClass(null); returns an instance of ReturnArgumentBaseClass");
  57. result = new ReturnArgumentBaseClass(undefined);
  58. assert.areEqual("ReturnArgumentBaseClass", result.foo, "new ReturnArgumentBaseClass(undefined); returns 'this'");
  59. assert.isTrue(result instanceof ReturnArgumentBaseClass, "new ReturnArgumentBaseClass(undefined); returns an instance of ReturnArgumentBaseClass");
  60. result = new ReturnArgumentBaseClass();
  61. assert.areEqual("ReturnArgumentBaseClass", result.foo, "new ReturnArgumentBaseClass(); returns 'this'");
  62. assert.isTrue(result instanceof ReturnArgumentBaseClass, "new ReturnArgumentBaseClass(); returns an instance of ReturnArgumentBaseClass");
  63. result = new ReturnArgumentBaseClass('string');
  64. assert.areEqual("ReturnArgumentBaseClass", result.foo, "new ReturnArgumentBaseClass('string'); returns 'this'");
  65. assert.isTrue(result instanceof ReturnArgumentBaseClass, "new ReturnArgumentBaseClass('string'); returns an instance of ReturnArgumentBaseClass");
  66. result = new ReturnArgumentBaseClass(5);
  67. assert.areEqual("ReturnArgumentBaseClass", result.foo, "new ReturnArgumentBaseClass(5); returns 'this'");
  68. assert.isTrue(result instanceof ReturnArgumentBaseClass, "new ReturnArgumentBaseClass(5); returns an instance of ReturnArgumentBaseClass");
  69. }
  70. },
  71. {
  72. name: "Base class constructors which return an object override return of 'this'",
  73. body: function () {
  74. class ReturnArgumentBaseClass {
  75. constructor(val) {
  76. this.foo = 'ReturnArgumentBaseClass';
  77. return val;
  78. }
  79. };
  80. let result = new ReturnArgumentBaseClass({foo:'test'});
  81. assert.areEqual("test", result.foo, "new ReturnArgumentBaseClass({foo:'test'}); returns {foo:'test'}");
  82. assert.isFalse(result instanceof ReturnArgumentBaseClass, "new ReturnArgumentBaseClass({foo:'test'}); doesn't return an instance of ReturnArgumentBaseClass");
  83. result = new ReturnArgumentBaseClass(new Boolean(false));
  84. assert.areEqual(new Boolean(false), result, "new ReturnArgumentBaseClass(new Boolean(false)); returns new Boolean(false)");
  85. assert.isTrue(result instanceof Boolean, "new ReturnArgumentBaseClass(new Boolean(false)); returns an instance of Boolean");
  86. }
  87. },
  88. {
  89. name: "Class that extends null has right prototypes",
  90. body: function () {
  91. class A extends null {}
  92. assert.areEqual(Function.prototype, Object.getPrototypeOf(A));
  93. assert.areEqual(null, Object.getPrototypeOf(A.prototype));
  94. }
  95. },
  96. {
  97. name: "Class that extends null binds this in constructor",
  98. body: function () {
  99. var thisVal;
  100. class B extends null {
  101. constructor() { thisVal = this; }
  102. }
  103. var b = new B();
  104. assert.areEqual(true, b instanceof B);
  105. assert.areEqual(thisVal, b);
  106. }
  107. },
  108. {
  109. name: "Class that extends null throws TypeError upon super call in constructor",
  110. body: function () {
  111. var beforeSuper = 0;
  112. var afterSuper = 0;
  113. class C extends null {
  114. constructor() {
  115. beforeSuper++;
  116. super();
  117. afterSuper++;
  118. }
  119. }
  120. assert.throws(function(){new C();}, TypeError, "super", "Function is not a constructor");
  121. assert.areEqual(1, beforeSuper);
  122. assert.areEqual(0, afterSuper);
  123. }
  124. },
  125. {
  126. name: "Class that extends null with implicit return in constructor",
  127. body: function () {
  128. class A extends null {
  129. constructor() {}
  130. }
  131. var a;
  132. assert.doesNotThrow(()=>{a = new A()});
  133. assert.areEqual(A.prototype, Object.getPrototypeOf(a));
  134. }
  135. },
  136. {
  137. name: "Class that extends null with explicit return in constructor",
  138. body: function () {
  139. class A extends null {
  140. constructor() { return {}; }
  141. }
  142. var a;
  143. assert.doesNotThrow(()=>{a = new A()});
  144. assert.areEqual(Object.prototype, Object.getPrototypeOf(a));
  145. }
  146. },
  147. ];
  148. testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });