arguments.es5.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  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. // Note: each test has name (string) and body (function) properties.
  8. // Success is when the body does not throw, failure -- when it throws.
  9. test01: {
  10. name: "formal arg: simple: verify connection: named vs indexed arg",
  11. body: function () {
  12. var passedValue = 1;
  13. function f(a) {
  14. var val1 = 2;
  15. a = val1;
  16. assert.areEqual(val1, a, "wrong value of named parameter (val1)");
  17. assert.areEqual(val1, arguments[0], "wrong value of indexed parameter (val1)");
  18. var val2 = 3;
  19. arguments[0] = val2;
  20. assert.areEqual(val2, arguments[0], "wrong value of indexed parameter (val2)");
  21. assert.areEqual(val2, a, "wrong value of named parameter (val2)");
  22. }
  23. f(passedValue);
  24. }
  25. },
  26. test02: {
  27. name: "formal arg: defineProperty, check property descriptor",
  28. body: function () {
  29. var passedValue = 1;
  30. function f(a) {
  31. var val = 2;
  32. Object.defineProperty(arguments, 0, { configurable: false, enumerable: false, value: val });
  33. // Note that we expect writable: true because this was omitted in defineProperty above
  34. // which is actually re-define property with all attributes == true.
  35. var expected = { configurable: false, enumerable: false, writable: true, value: val };
  36. assert.areEqual(expected, Object.getOwnPropertyDescriptor(arguments, 0), "wrong value of getOwnPropertyDescriptor");
  37. assert.areEqual(val, a, "wrong value of named parameter");
  38. }
  39. f(passedValue);
  40. }
  41. },
  42. test03: {
  43. name: "formal arg: defineProperty, set writable to false, verify writability and lost connection. WOOB 1128023",
  44. body: function () {
  45. var passedValue = 1;
  46. function f(a) {
  47. Object.defineProperty(arguments, 0, { writable: false });
  48. var expected = { configurable: true, enumerable: true, writable: false, value: passedValue };
  49. assert.areEqual(expected, Object.getOwnPropertyDescriptor(arguments, 0), "wrong value of getOwnPropertyDescriptor");
  50. // Attempt to change arguments[0] which is not writable now.
  51. var val1 = 2;
  52. arguments[0] = val1;
  53. assert.areEqual(passedValue, arguments[0], "non-writable changed");
  54. assert.areEqual(passedValue, a, "non-writable changed: named arg also changed");
  55. // Change named arg value, verify we are in connection named vs indexed arg.
  56. var val2 = 3;
  57. a = val2;
  58. assert.areEqual(val2, a, "Attemp to change named arg: didn't work");
  59. assert.areEqual(passedValue, arguments[0], "At this time we should not be connected, but we are");
  60. }
  61. f(passedValue);
  62. }
  63. },
  64. test04: {
  65. name: "formal arg: defineProperty, set writable to false AND set value, verify that value changed in both named and indexed arg and that the item was disconnected",
  66. body: function () {
  67. var passedValue = 1;
  68. function f(a) {
  69. var val1 = 2;
  70. var val2 = 3;
  71. Object.defineProperty(arguments, 0, { writable: false, value: val1 });
  72. var expected = { configurable: true, enumerable: true, writable: false, value: val1 };
  73. assert.areEqual(expected, Object.getOwnPropertyDescriptor(arguments, 0), "wrong value of getOwnPropertyDescriptor");
  74. assert.areEqual(val1, arguments[0], "value: arguments[0]");
  75. assert.areEqual(val1, a, "value: a");
  76. // Verify we are disconnected now.
  77. a = val2;
  78. assert.areEqual(val2, a, "new value: a");
  79. assert.areEqual(val1, arguments[0], "value: arguments[0] -- did not get disconnected!");
  80. }
  81. f(passedValue);
  82. }
  83. },
  84. test05: {
  85. name: "formal arg: defineProperty w/o cause of disconnect, verify still connected to named arg",
  86. body: function () {
  87. var passedValue = 1;
  88. var val1 = 2;
  89. var val2 = 3;
  90. function f(a) {
  91. Object.defineProperty(arguments, 0, { value: val1 });
  92. a = val1;
  93. assert.areEqual(val1, arguments[0], "arguments[0] got disconnected");
  94. arguments[0] = val2;
  95. assert.areEqual(val2, a, "a got disconnected");
  96. }
  97. f(passedValue);
  98. }
  99. },
  100. test06: {
  101. name: "formal arg: defineProperty, disconnect arg[0], verify that arg[1] is still connected",
  102. body: function () {
  103. function f(a, b) {
  104. Object.defineProperty(arguments, 0, { writable: false });
  105. var val1 = 3;
  106. var val2 = 4;
  107. arguments[1] = val1;
  108. assert.areEqual(val1, b, "arg[1] got disconnected");
  109. b = val2;
  110. assert.areEqual(val2, arguments[1], "arg[1] got disconnected");
  111. }
  112. f(1, 2);
  113. }
  114. },
  115. test07: {
  116. name: "formal arg: defineProperty: convert to accessor property",
  117. body: function () {
  118. function f(a) {
  119. var isGetterFired = false;
  120. var isSetterFired = false;
  121. Object.defineProperty(arguments, 0, {
  122. get: function() { isGetterFired = true; return this.value; },
  123. set: function(arg) { isSetterFired = true; this.value = arg; }
  124. });
  125. assert.areEqual(undefined, arguments[0], "unexpected arg[0] value right after conversion to accessor property");
  126. assert.areEqual(true, isGetterFired, "isGetterFired (1)");
  127. isGetterFired = false;
  128. var val1 = 2;
  129. arguments[0] = val1;
  130. assert.areEqual(true, isSetterFired, "isSetterFired");
  131. assert.areEqual(val1, arguments[0], "get value after set");
  132. assert.areEqual(true, isGetterFired, "isGetterFired (2)");
  133. }
  134. f(1);
  135. }
  136. },
  137. test08: {
  138. name: "formal arg: defineProperty: convert to accessor, then to data property, verify value and that connection is lost",
  139. body: function () {
  140. var passedValue = 1;
  141. var val1 = 2;
  142. var val2 = 3;
  143. function f(a) {
  144. Object.defineProperty(arguments, 0, {
  145. get: function() { return this.value; },
  146. set: function(arg) { this.value = arg; }
  147. });
  148. Object.defineProperty(arguments, 0, { value: val1 });
  149. a = val2;
  150. assert.areEqual(arguments[0], val1, "arguments[0]");
  151. assert.areNotEqual(arguments[0], a, "arguments[0] != a");
  152. }
  153. f(passedValue);
  154. }
  155. },
  156. test09: {
  157. name: "formal arg: defineProperty: force convert to ES5 version but keep connected, check enumeration",
  158. body: function () {
  159. var passedValue = 1;
  160. function f(a) {
  161. Object.defineProperty(arguments, 0, { enumerable: true });
  162. var accumulator = "";
  163. for (var i in arguments) {
  164. accumulator += i.toString() + ": " + arguments[i] + ";";
  165. }
  166. assert.areEqual("0: " + passedValue + ";" , accumulator, "accumulator");
  167. }
  168. f(passedValue);
  169. }
  170. },
  171. test10: {
  172. name: "formal arg: defineProperty: set non-enumerable/non-writable/delete, check enumeration",
  173. body: function () {
  174. var passedValue1 = 2;
  175. var passedValue2 = 4;
  176. function f(a, b, c, d) {
  177. Object.defineProperty(arguments, 0, { enumerable: false }); // arguments[0].enumerable = false.
  178. Object.defineProperty(arguments, 1, { writable: false }); // arguments[1].writable = false -> disconnected.
  179. delete arguments[2]; // arguments[2] is deleted.
  180. var i, accumulator = "";
  181. for (i in arguments) {
  182. accumulator += i.toString() + ": " + arguments[i] + ";";
  183. }
  184. // Note that we expect [1].enumerable = true because this was omitted in defineProperty above
  185. // which is actually re-define property that previously already had enumerable = true.
  186. assert.areEqual("1: " + passedValue1 + ";" + "3: " + passedValue2 + ";", accumulator, "accumulator");
  187. }
  188. f(1, passedValue1, 3, passedValue2);
  189. }
  190. },
  191. test11: {
  192. name: "passed/undeclared arg: verify there is no correlation with Object.prototype indexed data properties. WOOB 1143896",
  193. body: function () {
  194. var passedValue = "passed";
  195. Object.defineProperty(Object.prototype, 0, { value: "from proto", configurable: true, writable: false });
  196. try {
  197. function f() { return arguments; }
  198. var argObj = f(passedValue);
  199. assert.areEqual(passedValue, argObj[0]);
  200. } finally {
  201. delete Object.prototype[0];
  202. }
  203. }
  204. },
  205. test12: {
  206. name: "formal arg: verify there is no correlation with Object.prototype indexed properties",
  207. body: function () {
  208. var passedValue = "passed";
  209. Object.defineProperty(Object.prototype, 0, { value: "from proto", configurable: true, writable: false });
  210. try {
  211. function f(a) { return arguments }
  212. var argObj = f(passedValue);
  213. assert.areEqual(passedValue, argObj[0]);
  214. } finally {
  215. delete Object.prototype[0];
  216. }
  217. }
  218. },
  219. test13: {
  220. name: "passed/undeclared arg: verify there is no correlation with Object.prototype indexed accessor properties. WOOB 1144602",
  221. body: function () {
  222. var initial = "initial";
  223. var passedValue = "passed";
  224. var data = initial;
  225. Object.defineProperty(Object.prototype, 0, {
  226. configurable: true,
  227. get: function() { return data; },
  228. set: function(arg) { data = arg; }
  229. });
  230. try {
  231. function f() { return arguments; }
  232. var argObj = f(passedValue);
  233. assert.areEqual(initial, data, "data: should not be changed as setter on prototype should not be fired");
  234. assert.areEqual(passedValue, argObj[0], "argObj[0]");
  235. } finally {
  236. delete Object.prototype[0];
  237. }
  238. }
  239. },
  240. test14: {
  241. name: "formal arg: verify there is no correlation with Object.prototype indexed accessor properties",
  242. body: function () {
  243. var initial = "initial";
  244. var passedValue = "passed";
  245. var data = initial;
  246. Object.defineProperty(Object.prototype, 0, {
  247. configurable: true,
  248. get: function() { return data; },
  249. set: function(arg) { data = arg; }
  250. });
  251. try {
  252. function f(a) { return arguments; }
  253. var argObj = f(passedValue);
  254. assert.areEqual(initial, data, "data: should not be changed as setter on prototype should not be fired");
  255. assert.areEqual(passedValue, argObj[0], "argObj[0]");
  256. } finally {
  257. delete Object.prototype[0];
  258. }
  259. }
  260. },
  261. test15: {
  262. name: "formal arg: delete, make sure it's deleted",
  263. body: function () {
  264. var passedValue = 1;
  265. function f(a) {
  266. Object.defineProperty(arguments, 0, { enumerable: false }); // Force convert to ES5 version.
  267. delete arguments[0];
  268. assert.areEqual(undefined, arguments[0], "was not deleted.");
  269. assert.areEqual(passedValue, a, "a is changed.");
  270. }
  271. f(passedValue);
  272. }
  273. },
  274. test16: {
  275. name: "formal arg: delete, add, check named arg is not changed",
  276. body: function () {
  277. var passedValue = 1;
  278. function f(a, b) {
  279. Object.defineProperty(arguments, 0, { enumerable: false }); // Force convert to ES5 version.
  280. delete arguments[0];
  281. arguments[0] = passedValue + 1;
  282. assert.areEqual(passedValue, a, "a is changed.");
  283. }
  284. f(passedValue, 2);
  285. }
  286. },
  287. test17: {
  288. name: "formal arg: delete, then defineProperty with attributes for data property, check the value",
  289. body: function () {
  290. var passedValue = 1;
  291. function f(a) {
  292. delete arguments[0];
  293. var val = 2;
  294. Object.defineProperty(arguments, 0, { enumerable: true, configurable: true, writable: true, value: val });
  295. assert.areEqual(val, arguments[0], "wrong value");
  296. }
  297. f(passedValue);
  298. }
  299. },
  300. test18: {
  301. name: "formal arg: delete, then defineProperty with attributes for accessor property, check the enumeration",
  302. body: function () {
  303. var passedValue = 1;
  304. var getter = function() {return this.value; };
  305. var setter = function(arg) { this.value = arg; };
  306. function f(a) {
  307. delete arguments[0];
  308. Object.defineProperty(arguments, 0, { enumerable: true, configurable: true, get: getter, set: setter });
  309. var expected = { configurable: true, enumerable: true, get: getter, set: setter };
  310. assert.areEqual(expected, Object.getOwnPropertyDescriptor(arguments, 0), "wrong descriptor");
  311. var accumulator = "";
  312. for (var i in arguments) {
  313. accumulator += i.toString() + ": " + arguments[i] + ";";
  314. }
  315. assert.areEqual("0: " + undefined + ";", accumulator, "accumulator 2");
  316. }
  317. f(passedValue);
  318. }
  319. },
  320. test19: {
  321. name: "formal arg, es5 heap arguments: delete, add, check enumerable/order",
  322. body: function () {
  323. var passedValue1 = 1;
  324. var passedValue2 = 2;
  325. var newValue1 = 100;
  326. var newValue2 = 200;
  327. var i, accumulator;
  328. function f(a, b) {
  329. // Scenario 1: delete prior to converting to ES5 version.
  330. delete arguments[0]; // Delete [0] prior to conversion to ES5.
  331. Object.defineProperty(arguments, 0, { configurable: true, enumerable: true, value: newValue1 }); // Bring back [0] by defineProperty. Now args is ES5.
  332. accumulator = "";
  333. for (i in arguments) {
  334. accumulator += i.toString() + ": " + arguments[i] + ";";
  335. }
  336. assert.areEqual("0: " + newValue1 + ";" + "1: " + passedValue2 + ";", accumulator, "accumulator 1");
  337. // Scenario 2: delete after converting to ES5 version.
  338. Object.defineProperty(arguments, 0, { configurable: true, enumerable: true, writable: true, value: newValue1 }); // Bring back [0] by defineProperty. Now args is ES5.
  339. delete arguments[0]; // Delete [0] prior after conversion to ES5.
  340. arguments[0] = newValue2; // Bring back [0] by setting value.
  341. accumulator = "";
  342. for (i in arguments) {
  343. accumulator += i.toString() + ": " + arguments[i] + ";";
  344. }
  345. assert.areEqual("0: " + newValue2 + ";" + "1: " + passedValue2 + ";", accumulator, "accumulator 2");
  346. }
  347. f(passedValue1, passedValue2);
  348. }
  349. },
  350. test20: {
  351. name: "formal arg, es5 heap arguments: delete, add, keep another arg in objectArray and use one non-formal, check enumerable/order",
  352. body: function () {
  353. var passedValue1 = 1;
  354. var passedValue2 = 2;
  355. var passedValue3 = 3;
  356. var passedValue4 = 4;
  357. var newValue = 100;
  358. function f(a, b, c) {
  359. Object.defineProperty(arguments, 0, { enumerable: true }); // Add objectArray item
  360. Object.defineProperty(arguments, 2, { enumerable: true }); // Add objectArray item
  361. var accumulator = "";
  362. delete arguments[0];
  363. arguments[0] = newValue;
  364. for (var i in arguments) {
  365. accumulator += i.toString() + ": " + arguments[i] + ";";
  366. }
  367. assert.areEqual(
  368. "0: " + newValue + ";" + "1: " + passedValue2 + ";" + "2: " + passedValue3 + ";" + "3: " + passedValue4 + ";",
  369. accumulator,
  370. "accumulator");
  371. }
  372. f(passedValue1, passedValue2, passedValue3, passedValue4);
  373. }
  374. },
  375. test21: {
  376. name: "formal arg: defineProperty, set enumerable to false, check getOwnPropertyNames",
  377. body: function (a, b) {
  378. function f(a) {
  379. Object.defineProperty(arguments, 0, { enumerable: false });
  380. // Note: Object.getOwnPropertyNames returns all properties, even non-enumerable.
  381. var actual = Object.getOwnPropertyNames(arguments);
  382. var expected = { 0: "0", 1: "1", 2: "length", 3: "callee" };
  383. assert.areEqual(expected, actual, "wrong property names");
  384. }
  385. f(101, 102);
  386. }
  387. },
  388. test22Helper: function test22Helper(isConvertNeeded, messagePrefix) {
  389. function mkerr(message) {
  390. return messagePrefix + ": " + message;
  391. }
  392. var passedValue = 1;
  393. var newPropertyName = "x";
  394. function f(a, b) {
  395. if (isConvertNeeded) {
  396. Object.defineProperty(arguments, 1, { enumerable: true }); // Force convert to ES5 version.
  397. }
  398. Object.preventExtensions(arguments); // No new properties can be added.
  399. assert.areEqual(false, Object.isExtensible(arguments), mkerr("isExtensible"));
  400. try {
  401. Object.defineProperty(arguments, newPropertyName, { enumerable: true, value: 100 }); // add new property
  402. assert.fail(mkerr("did not throw exception"));
  403. } catch (ex) {
  404. }
  405. arguments[newPropertyName] = 100;
  406. assert.areEqual(undefined, arguments[newPropertyName], mkerr("New property was added after preventExtensions was called"));
  407. }
  408. f(passedValue, passedValue + 1);
  409. },
  410. test22_1: {
  411. name: "arguments (non-ES5 version): call Object.preventExtensions, try add new property by defineProperty and direct set",
  412. body: function () {
  413. tests.test22Helper(false, "non-ES5 version");
  414. }
  415. },
  416. test22_2: {
  417. name: "arguments (ES5 version): call Object.preventExtensions, try add new property by defineProperty and direct set",
  418. body: function () {
  419. tests.test22Helper(true, "ES5 version");
  420. }
  421. },
  422. test23Helper: function test23Helper(isConvertNeeded, messagePrefix) {
  423. function mkerr(message) {
  424. return messagePrefix + ": " + message;
  425. }
  426. var passedValue = 1;
  427. function f(a, b) {
  428. if (isConvertNeeded) {
  429. Object.defineProperty(arguments, 1, { enumerable: true }); // Force convert to ES5 version.
  430. }
  431. Object.preventExtensions(arguments); // This causes configurable, writable = false for all properties + Object.preventExtensions.
  432. // Note: formals existed prior to calling Object.preventExtensions, thus they are still modifiable.
  433. assert.areEqual(false, Object.isExtensible(arguments), "isExtensible");
  434. var actual = Object.getOwnPropertyDescriptor(arguments, 0);
  435. var expected = { configurable: true, enumerable: true, writable: true, value: passedValue };
  436. assert.areEqual(expected, actual, mkerr("wrong descriptor - initial"));
  437. // Try to modify/re-configure
  438. // Note: do not change value here as it causes different code path than exercised by identified issue.
  439. Object.defineProperty(arguments, 0, { enumerable: false });
  440. Object.defineProperty(arguments, 0, { writable: false });
  441. Object.defineProperty(arguments, 0, { configurable: false });
  442. var expected = { configurable: false, enumerable: false, writable: false, value: passedValue };
  443. assert.areEqual(expected, Object.getOwnPropertyDescriptor(arguments, 0), mkerr("wrong descriptor - after redefine"));
  444. }
  445. f(passedValue, passedValue + 1);
  446. },
  447. // After Object.preventExtensions(arguments) we can't modify the attributes on formals.
  448. test23_1: {
  449. name: "arguments (non-ES5 version): call Object.preventExtensions, make sure we can still modify atttibutes on formals without changing the value",
  450. body: function () {
  451. tests.test23Helper(false, "non-ES5 version");
  452. }
  453. },
  454. // After Object.preventExtensions(arguments) we can't modify the attributes on formals.
  455. test23_2: {
  456. name: "arguments (ES5 version): call Object.preventExtensions, make sure we can still modify atttibutes on formals without changing the value",
  457. body: function () {
  458. tests.test23Helper(true, "ES5 version");
  459. }
  460. },
  461. test24Helper: function test24Helper(isConvertNeeded, messagePrefix) {
  462. function mkerr(message) {
  463. return messagePrefix + ": " + message;
  464. }
  465. var passedValue = 1;
  466. function f(a, b) {
  467. if (isConvertNeeded) {
  468. Object.defineProperty(arguments, 1, { enumerable: true }); // Force convert to ES5 version.
  469. }
  470. Object.seal(arguments); // This causes configurable = false for all properties + Object.preventExtensions.
  471. assert.areEqual(true, Object.isSealed(arguments), mkerr("isSealed"));
  472. assert.areEqual(false, Object.isExtensible(arguments), mkerr("isExtensible"));
  473. var actual = Object.getOwnPropertyDescriptor(arguments, 0);
  474. var expected = { configurable: false, enumerable: true, writable: true, value: passedValue };
  475. assert.areEqual(expected, actual, mkerr("wrong descriptor"));
  476. }
  477. f(passedValue, passedValue + 1);
  478. },
  479. // Object.freeze(arguments -- not ES5 version) does not set configurable to false on formals.
  480. test24_1: {
  481. name: "arguments (non-ES5 version): call Object.seal, verify descriptor on formal",
  482. body: function () {
  483. tests.test24Helper(false, "non-ES5 version");
  484. }
  485. },
  486. test24_2: {
  487. name: "arguments (ES5 version): call Object.seal, verify descriptor on formal",
  488. body: function () {
  489. tests.test24Helper(true, "ES5 version");
  490. }
  491. },
  492. test25Helper: function test25Helper(isConvertNeeded, messagePrefix) {
  493. function mkerr(message) {
  494. return messagePrefix + ": " + message;
  495. }
  496. var passedValue = 1;
  497. function f(a, b) {
  498. if (isConvertNeeded) {
  499. Object.defineProperty(arguments, 1, { enumerable: true }); // Force convert to ES5 version.
  500. }
  501. Object.freeze(arguments); // This causes configurable AND writable = false for all properties + Object.preventExtensions.
  502. assert.areEqual(true, Object.isFrozen(arguments), mkerr("isFrozen"));
  503. assert.areEqual(true, Object.isSealed(arguments), mkerr("isSealed"));
  504. assert.areEqual(false, Object.isExtensible(arguments), mkerr("isExtensible"));
  505. var actual = Object.getOwnPropertyDescriptor(arguments, 0);
  506. var expected = { configurable: false, enumerable: true, writable: false, value: passedValue };
  507. assert.areEqual(expected, actual, mkerr("wrong descriptor"));
  508. }
  509. f(passedValue, passedValue + 1);
  510. },
  511. // Object.freeze(arguments -- not ES5 version) does not set configurable and writable to false on formals.
  512. test25_1: {
  513. name: "arguments (non-ES5 version): call Object.freeze, verify descriptor on formal",
  514. body: function () {
  515. tests.test25Helper(false, "non-ES5 version");
  516. }
  517. },
  518. test25_2: {
  519. name: "arguments (ES5 version): call Object.freeze, verify descriptor on formal",
  520. body: function () {
  521. tests.test25Helper(true, "ES5 version");
  522. }
  523. },
  524. test26: {
  525. name: "formal arg: delete, preventExtensions, enumerate, make sure the item is deleted",
  526. body: function () {
  527. var passedValue1 = 1;
  528. var passedValue2 = 2;
  529. function f(a, b) {
  530. delete arguments[1];
  531. Object.preventExtensions(arguments);
  532. var accumulator = "";
  533. for (var i in arguments) {
  534. accumulator += i.toString() + ": " + arguments[i] + ";";
  535. }
  536. assert.areEqual("0: " + passedValue1 + ";", accumulator, "accumulator");
  537. assert.areEqual(undefined, arguments[1], "arguments[1]");
  538. }
  539. f(passedValue1, passedValue2);
  540. }
  541. },
  542. test27: {
  543. name: "formal arg: convert to ES5 version, change value and set writable to false",
  544. body: function () {
  545. var passedValue1 = 1;
  546. var val = 2;
  547. function f(a) {
  548. Object.defineProperty(arguments, 0, { enumerable: true });
  549. a = val;
  550. Object.defineProperty(arguments, 0, { writable: false });
  551. var expected = { configurable: true, enumerable: true, writable: false, value: val };
  552. assert.areEqual(expected, Object.getOwnPropertyDescriptor(arguments, 0));
  553. }
  554. f(passedValue1);
  555. }
  556. },
  557. test28: {
  558. name: "formal arg: convert to ES5 version, enumerate when number of actual params is less than number of formals",
  559. body: function () {
  560. var accumulator = "";
  561. function f(a, b) {
  562. Object.preventExtensions(arguments);
  563. for (var i in arguments) {
  564. if (accumulator.length != 0) accumulator += ",";
  565. accumulator += arguments[i];
  566. }
  567. }
  568. var value = 5;
  569. f(value);
  570. var expected = helpers.isVersion10OrLater ?
  571. value.toString() :
  572. value.toString() + ",undefined"; // IE9 compat mode -- Win8 558490.
  573. assert.areEqual(expected, accumulator, "Wrong accumulated value");
  574. }
  575. }
  576. }
  577. testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });