protolib.js 3.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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. /// <reference path="../UnitTestFramework/UnitTestFramework.js" />
  6. if (this.WScript && this.WScript.LoadScriptFile) {
  7. WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js");
  8. }
  9. function make_engine(/*default=samethread*/thread) {
  10. return WScript.LoadScriptFile("protolib.js", thread || "samethread");
  11. }
  12. // Run a function expression in this engine
  13. function run(f) {
  14. return eval("(" + f + ")()");
  15. }
  16. // Save __proto__ descriptor at startup
  17. var __saved__proto__desc = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__");
  18. // assert __proto__ throws "this" not object. "method" default to Object.prototype.__proto__
  19. assert.throws__proto__ThisNotObject = function (f, method) {
  20. assert.throws(f, TypeError, undefined, (method || "Object.prototype.__proto__") + ": 'this' is not an Object");
  21. };
  22. // assert __proto__ throws arg not object. "method" default to Object.setPrototypeOf
  23. assert.throws__proto__ArgNotObject = function (f, method) {
  24. assert.throws(f, TypeError, undefined, (method || "Object.setPrototypeOf") + ": argument is not an Object");
  25. };
  26. // assert __proto__ throws arg not object or null. "method" default to Object.prototype.__proto__
  27. assert.throws__proto__ArgNotObjectOrNull = function (f, method) {
  28. assert.throws(f, TypeError, undefined, (method || "Object.prototype.__proto__") + ": argument is not an Object and is not null");
  29. };
  30. // assert __proto__ throws cyclic error
  31. assert.throws__proto__Cyclic = function (f, method) {
  32. assert.throws(f, TypeError, undefined, "Cyclic __proto__ value");
  33. };
  34. function disable__proto__() {
  35. delete Object.prototype.__proto__;
  36. }
  37. function verify__proto__enabled() {
  38. assert.isTrue(Object.prototype.hasOwnProperty("__proto__"), "__proto__ enabled, Object.prototype must have own property __proto__");
  39. var desc = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__");
  40. assert.isTrue(__saved__proto__desc.get === desc.get, "must have original getter");
  41. assert.isTrue(__saved__proto__desc.set === desc.set, "must have original setter");
  42. // Ignore enumerable/configurable. They can be changed and __proto__ still takes effect.
  43. var p = { a: 0 };
  44. var o = { b: 1 };
  45. assert.isTrue(o.__proto__ === Object.getPrototypeOf(o));
  46. assert.areEqual(Object.prototype, o.__proto__, "__proto__ enabled, __proto__ value should be [[prototype]]");
  47. o.__proto__ = p;
  48. assert.isTrue(o.__proto__ === Object.getPrototypeOf(o));
  49. assert.areEqual(p, o.__proto__, "__proto__ enabled, [[prototype]] should be changed");
  50. Object.setPrototypeOf(o, Object.prototype);
  51. assert.isTrue(o.__proto__ === Object.getPrototypeOf(o));
  52. assert.areEqual(Object.prototype, o.__proto__);
  53. }
  54. function verify__proto__disabled(label) {
  55. var p = { a: 0 };
  56. var o = { b: 1 };
  57. assert.areEqual(Object.prototype, Object.getPrototypeOf(o));
  58. o.__proto__ = p;
  59. assert.areEqual(Object.prototype, Object.getPrototypeOf(o), "__proto__ disabled, [[prototype]] should not be changed " + (label || ""));
  60. Object.setPrototypeOf(o, p); // always works
  61. assert.areEqual(p, Object.getPrototypeOf(o));
  62. }
  63. // verify (in a new engine) if an expression disables __proto__.
  64. function verify_disable(expr, keepEnabled) {
  65. make_engine().__verify_disable(expr, keepEnabled);
  66. }
  67. var KEEP_ENABLED = {};
  68. function __verify_disable(expr, keepEnabled) {
  69. verify__proto__enabled();
  70. helpers.writeln(expr);
  71. eval(expr);
  72. if (keepEnabled) {
  73. verify__proto__enabled();
  74. } else {
  75. verify__proto__disabled();
  76. }
  77. }