Iterator.from.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. describe("errors", () => {
  2. test("called with non-Object", () => {
  3. expect(() => {
  4. Iterator.from(Symbol.hasInstance);
  5. }).toThrowWithMessage(TypeError, "Symbol(Symbol.hasInstance) is not a string");
  6. });
  7. test("@@iterator is not callable", () => {
  8. const iterable = {};
  9. iterable[Symbol.iterator] = 12389;
  10. expect(() => {
  11. Iterator.from(iterable);
  12. }).toThrowWithMessage(TypeError, "12389 is not a function");
  13. });
  14. test("@@iterator throws an exception", () => {
  15. function TestError() {}
  16. const iterable = {};
  17. iterable[Symbol.iterator] = () => {
  18. throw new TestError();
  19. };
  20. expect(() => {
  21. Iterator.from(iterable);
  22. }).toThrow(TestError);
  23. });
  24. test("@@iterator return a non-Object", () => {
  25. const iterable = {};
  26. iterable[Symbol.iterator] = () => {
  27. return Symbol.hasInstance;
  28. };
  29. expect(() => {
  30. Iterator.from(iterable);
  31. }).toThrowWithMessage(TypeError, "Symbol(Symbol.hasInstance) is not an object");
  32. });
  33. });
  34. describe("normal behavior", () => {
  35. test("length is 1", () => {
  36. expect(Iterator.from).toHaveLength(1);
  37. });
  38. test("create Iterator from a string", () => {
  39. const iterator = Iterator.from("ab");
  40. let result = iterator.next();
  41. expect(result.value).toBe("a");
  42. expect(result.done).toBeFalse();
  43. result = iterator.next();
  44. expect(result.value).toBe("b");
  45. expect(result.done).toBeFalse();
  46. result = iterator.next();
  47. expect(result.value).toBeUndefined();
  48. expect(result.done).toBeTrue();
  49. });
  50. test("does not coerce strings to objects", () => {
  51. const stringIterator = String.prototype[Symbol.iterator];
  52. let observedType = null;
  53. Object.defineProperty(String.prototype, Symbol.iterator, {
  54. get() {
  55. "use strict";
  56. observedType = typeof this;
  57. return stringIterator;
  58. },
  59. });
  60. Iterator.from("ab");
  61. expect(observedType).toBe("string");
  62. });
  63. test("create Iterator from generator", () => {
  64. function* generator() {
  65. yield 1;
  66. yield 2;
  67. }
  68. const iterator = Iterator.from(generator());
  69. let result = iterator.next();
  70. expect(result.value).toBe(1);
  71. expect(result.done).toBeFalse();
  72. result = iterator.next();
  73. expect(result.value).toBe(2);
  74. expect(result.done).toBeFalse();
  75. result = iterator.next();
  76. expect(result.value).toBeUndefined();
  77. expect(result.done).toBeTrue();
  78. });
  79. test("create Iterator from iterator-like object", () => {
  80. class TestIterator {
  81. next() {
  82. if (this.#first) {
  83. this.#first = false;
  84. return { value: 1, done: false };
  85. }
  86. return { value: undefined, done: true };
  87. }
  88. #first = true;
  89. }
  90. const testIterator = new TestIterator();
  91. const iterator = Iterator.from(testIterator);
  92. let result = iterator.next();
  93. expect(result.value).toBe(1);
  94. expect(result.done).toBeFalse();
  95. result = iterator.next();
  96. expect(result.value).toBeUndefined();
  97. expect(result.done).toBeTrue();
  98. });
  99. });