arguments.es5.js 25 KB

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