array_at.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft Corporation and contributors. All rights reserved.
  3. // Copyright (c) 2021 ChakraCore Project Contributors. All rights reserved.
  4. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  5. //-------------------------------------------------------------------------------------------------------
  6. WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js");
  7. const ArrayPrototype = Array.prototype;
  8. const at = ArrayPrototype.at;
  9. const call = Function.call.bind(Function.call); // (fn: Function, thisArg: any, ...args: any[]) => any
  10. const tests = [
  11. {
  12. name: "Existence of Array.prototype.at",
  13. body: function () {
  14. assert.isTrue(typeof at === "function", "Array.prototype.at should be a function");
  15. }
  16. },
  17. {
  18. name: "Array.prototype.at's descriptor",
  19. body: function () {
  20. const desc = Object.getOwnPropertyDescriptor(ArrayPrototype, "at");
  21. assert.areEqual(desc.configurable, true, "Array.prototype.at should be configurable");
  22. assert.areEqual(desc.writable, true, "Array.prototype.at should be writable");
  23. assert.areEqual(desc.enumerable, false, "Array.prototype.at should not be enumerable");
  24. }
  25. },
  26. {
  27. name: "Properties of Array.prototype.at",
  28. body: function () {
  29. const nameDesc = Object.getOwnPropertyDescriptor(at, "name");
  30. assert.areEqual(at.name, "at", 'Array.prototype.at.name should be "at"');
  31. assert.areEqual(nameDesc.configurable, true, "Array.prototype.at.name should be configurable");
  32. assert.areEqual(nameDesc.writable, false, "Array.prototype.at.name should not be writable");
  33. assert.areEqual(nameDesc.enumerable, false, "Array.prototype.at.name should not be enumerable");
  34. const lengthDesc = Object.getOwnPropertyDescriptor(at, "length");
  35. assert.areEqual(at.length, 1, 'Array.prototype.at.length should be 1');
  36. assert.areEqual(lengthDesc.configurable, true, "Array.prototype.at.length should be configurable");
  37. assert.areEqual(lengthDesc.writable, false, "Array.prototype.at.length should not be writable");
  38. assert.areEqual(lengthDesc.enumerable, false, "Array.prototype.at.length should not be enumerable");
  39. }
  40. },
  41. {
  42. name: "Array.prototype.at called on nullish object",
  43. body: function () {
  44. assert.throws(() => { at.call(null) }, TypeError);
  45. assert.throws(() => { at.call(undefined) }, TypeError);
  46. }
  47. },
  48. {
  49. name: "Indexation of array with non-numerical argument",
  50. body: function () {
  51. const array = [0, 1];
  52. assert.areEqual(array.at(false), 0, 'array.at(false) should be 0');
  53. assert.areEqual(array.at(null), 0, 'array.at(null) should be 0');
  54. assert.areEqual(array.at(undefined), 0, 'array.at(undefined) should be 0');
  55. assert.areEqual(array.at(""), 0, 'array.at("") should be 0');
  56. assert.areEqual(array.at(function () { }), 0, 'array.at(function() {}) should be 0');
  57. assert.areEqual(array.at([]), 0, 'array.at([]) should be 0');
  58. assert.areEqual(array.at(true), 1, 'array.at(true) should be 1');
  59. assert.areEqual(array.at("1"), 1, 'array.at("1") should be 1');
  60. }
  61. },
  62. {
  63. name: "Indexation of array with negative numerical argument",
  64. body: function () {
  65. const array = [7, 1, 4, , 2, 12];
  66. assert.areEqual(array.at(0), 7, 'array.at(0) should be 7');
  67. assert.areEqual(array.at(-1), 12, 'array.at(-1) should be 12');
  68. assert.areEqual(array.at(-2), 2, 'array.at(-2) should be 2');
  69. assert.areEqual(array.at(-3), undefined, 'array.at(-3) should be undefined');
  70. assert.areEqual(array.at(-4), 4, 'array.at(-4) should be 4');
  71. }
  72. },
  73. {
  74. name: "Indexation of array with positive numerical argument",
  75. body: function () {
  76. const array = [7, 1, 4, , 2, 12];
  77. assert.areEqual(array.at(0), 7, 'array.at(0) should be 7');
  78. assert.areEqual(array.at(1), 1, 'array.at(-1) should be 1');
  79. assert.areEqual(array.at(2), 4, 'array.at(-2) should be 4');
  80. assert.areEqual(array.at(3), undefined, 'array.at(-3) should be undefined');
  81. assert.areEqual(array.at(4), 2, 'array.at(-4) should be 2');
  82. }
  83. },
  84. {
  85. name: "Out of bounds",
  86. body: function () {
  87. const array = [];
  88. assert.areEqual(array.at(0), undefined, `array.at(0) should be undefined`);
  89. assert.areEqual(array.at(-1), undefined, `array.at(-1) should be undefined`);
  90. assert.areEqual(array.at(2), undefined, `array.at(2) should be undefined`);
  91. }
  92. },
  93. {
  94. name: "Argument ToInteger()",
  95. body: function () {
  96. let count = 0;
  97. const index = {
  98. valueOf() {
  99. count++;
  100. return 1;
  101. }
  102. };
  103. const array = [0, 1, 2, 3];
  104. assert.areEqual(array.at(index), 1, 'result of array.at(index) should be 1');
  105. assert.areEqual(count, 1, 'The value of count should be 1');
  106. }
  107. },
  108. {
  109. name: "Array.prototype.at called on Array-Like object",
  110. body: function () {
  111. const arraylike = { 0: 1, 1: 2, 2: 3, length: 2 };
  112. assert.areEqual(call(at, arraylike, 0), 1, `call(at, arraylike, 0) should be 1`);
  113. assert.areEqual(call(at, arraylike, -1), 2, `call(at, arraylike, -1) should be 2`); // -1 + arraylike.length === 1
  114. assert.areEqual(call(at, arraylike, 2), undefined, `call(at, arraylike, 2) should be undefined`);
  115. }
  116. }
  117. ];
  118. testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });