Skip to content

add task solution#89

Open
NataliaTopornitska wants to merge 3 commits intomate-academy:masterfrom
NataliaTopornitska:develop
Open

add task solution#89
NataliaTopornitska wants to merge 3 commits intomate-academy:masterfrom
NataliaTopornitska:develop

Conversation

@NataliaTopornitska
Copy link

No description provided.

Copy link

@mateacademy-ai-mentor mateacademy-ai-mentor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

I’m requesting changes because the current test suite has critical blockers that violate the reduce spec and the task’s checklist.

Critical issues to fix:

  • Empty array without initialValue must throw: your tests currently expect no calls or undefined. Replace with expect(() => [].reduce2(callback)).toThrow(TypeError) (see src/reduce.test.js lines ~48–53 and ~75–79).
  • Non-mutation test is ineffective: expect(array).toEqual(array) always passes. Save a copy before calling reduce: const original = array.slice(); array.reduce2(cb, init); expect(array).toEqual(original) (around lines ~24–30). This is required for immutability.
  • Missing required edge-case coverage: add tests for sparse arrays (holes skipped), arrays with undefined/null, single-element arrays (with/without initialValue), mutation during iteration (modify visited indices, add/delete unvisited indices), explicit left-to-right order assertions, and non-number accumulations (strings/objects). Also add a callback-arguments test for the no-initialValue path ensuring the first accumulator is the first defined element and the next index is used.

Minor cleanups (non-blockers): remove extra semicolons after some expect calls and optionally assert that the callback is not called for empty arrays when initialValue is provided.

You have a solid start on the basic cases; addressing the above will bring the suite in line with the ECMAScript behavior and the assignment’s checklist. Keep going—you’re close!


✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨

Important

Fix the issues, commit the changes, and then re-request my review using the Re-request review button2 in the Reviewers tab.

Tip

If you have any comments about this review, please leave a message in the Add a comment section below and mention me with the @mateacademy-ai-mentor tag3.
I will read your message during my next review of your pull request. Please do not reply directly to my comments, as that feature is not supported yet.

Caution

Do not close the pull request until the review is complete. Closing it early can lead to unexpected behavior and disrupt the review process.

Footnotes

  1. Rate AI review example

  2. Re-request AI review example

  3. Add AI review comments example

Comment on lines +24 to +30
it('should not mutate array', () => {
const array = [1, 2, 3, 4];

array.reduce2(callback, 0);

expect(array).toEqual(array);
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "should not mutate array" test is ineffective: expect(array).toEqual(array) always passes because it compares the object to itself. To properly assert non-mutation, save a copy of the original array before calling reduce2, for example:

const original = array.slice()
array.reduce2(callback, 0)
expect(array).toEqual(original)

This change will satisfy requirement 3.4 (ensure the reduce function does not mutate the original array).

Comment on lines +48 to +54
it('should not run callback if array is empty', () => {
const array = [];

array.reduce2(callback);

expect(callback).toHaveBeenCalledTimes(0); ;
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test claims "should not run callback if array is empty" but calls array.reduce2(callback) without an initial value. Per the ECMAScript spec and the task requirements you must expect a TypeError when reducing an empty array without an initialValue. Replace this with something like:

expect(() => array.reduce2(callback)).toThrow(TypeError)

(See the task description for error-handling requirements.)

Comment on lines +75 to +79
it('should return undefined if array is empty and no initial value', () => {
const array = [];
const result = array.reduce2(callback);

expect(result).toBe(undefined); ;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test expects undefined for reducing an empty array with no initial value. That is incorrect — the implementation must throw a TypeError in this case. Update or remove this test so the suite expects the correct error behavior.

Comment on lines +32 to +45
it('should run callback array`s length times if initialValue is', () => {
const array = [1, 2, 3, 4];

array.reduce2(callback, 0);

expect(callback).toHaveBeenCalledTimes(array.length); ;
});

it('should run callback array`s length - 1 times if no initialValue', () => {
const array = [1, 2, 3, 4];

array.reduce2(callback);

expect(callback).toHaveBeenCalledTimes(array.length - 1); ;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The callback-invocation-count tests for the simple full-array cases are OK, but you still need explicit tests for these missing important scenarios:

  • Sparse arrays (holes) — ensure holes are skipped and the callback is not called for them.
  • Arrays containing undefined and null — these are real elements and must be visited.
  • Single-element arrays: without initialValue should return that element and never call the callback; with initialValue should call the callback once.
  • Mutation during iteration: modifying already visited indices should not affect past iterations; additions at unvisited indices should be visited; deletions of unvisited indices should be skipped.

Add one test per scenario to satisfy the checklist.

Comment on lines +56 to +65
it('should run callback with correct arguments', () => {
const array = [1, 2, 3, 4];

array.reduce2(callback, 0);

expect(callback).toHaveBeenNthCalledWith(1, 0, 1, 0, array);
expect(callback).toHaveBeenNthCalledWith(2, 1, 2, 1, array);
expect(callback).toHaveBeenNthCalledWith(3, 3, 3, 2, array);
expect(callback).toHaveBeenNthCalledWith(4, 6, 4, 3, array);
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test that checks callback arguments (toHaveBeenNthCalledWith) is useful, but it only exercises the case with an initialValue. Add a complementary test for when initialValue is omitted: verify that the first accumulator is strictly equal (===) to the first defined element and that the first callback currentIndex is the next defined index. Also assert that the 4th argument passed to the callback (array) is the original array reference. This addresses requirement 3.5 and 3.1.

Comment on lines +56 to +72
it('should run callback with correct arguments', () => {
const array = [1, 2, 3, 4];

array.reduce2(callback, 0);

expect(callback).toHaveBeenNthCalledWith(1, 0, 1, 0, array);
expect(callback).toHaveBeenNthCalledWith(2, 1, 2, 1, array);
expect(callback).toHaveBeenNthCalledWith(3, 3, 3, 2, array);
expect(callback).toHaveBeenNthCalledWith(4, 6, 4, 3, array);
});

it('should return initial value if array is empty', () => {
const array = [];
const initialValue = 0;
const result = array.reduce2(callback, initialValue);

expect(result).toBe(initialValue); ;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add explicit tests to verify left-to-right order and different accumulator/result types:

  • Record sequence of (index, value) pairs seen by the callback and assert the sequence is left-to-right.
  • Test accumulation of strings and objects (verify value/reference behavior and return types).

These tests will make iteration order and return-type requirements explicit.

Comment on lines +37 to +79
expect(callback).toHaveBeenCalledTimes(array.length); ;
});

it('should run callback array`s length - 1 times if no initialValue', () => {
const array = [1, 2, 3, 4];

array.reduce2(callback);

expect(callback).toHaveBeenCalledTimes(array.length - 1); ;
});

it('should not run callback if array is empty', () => {
const array = [];

array.reduce2(callback);

expect(callback).toHaveBeenCalledTimes(0); ;
});

it('should run callback with correct arguments', () => {
const array = [1, 2, 3, 4];

array.reduce2(callback, 0);

expect(callback).toHaveBeenNthCalledWith(1, 0, 1, 0, array);
expect(callback).toHaveBeenNthCalledWith(2, 1, 2, 1, array);
expect(callback).toHaveBeenNthCalledWith(3, 3, 3, 2, array);
expect(callback).toHaveBeenNthCalledWith(4, 6, 4, 3, array);
});

it('should return initial value if array is empty', () => {
const array = [];
const initialValue = 0;
const result = array.reduce2(callback, initialValue);

expect(result).toBe(initialValue); ;
});

it('should return undefined if array is empty and no initial value', () => {
const array = [];
const result = array.reduce2(callback);

expect(result).toBe(undefined); ;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: there are extra redundant semicolons after some expect calls (e.g., expect(...); ;). They are harmless but noisy — remove the duplicate ; for clarity.

Copy link

@mateacademy-ai-mentor mateacademy-ai-mentor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

I’m requesting changes because there are critical blockers preventing the task from meeting the spec and passing CI.

Critical issues to fix (blockers):

  • src/reduce.js: You must capture the array length at the start and use it for all bounds. Using arr.length dynamically allows appended elements to be visited, violating the spec (checklist 1.5/3.4). Hint: const len = arr.length; and use len in the hole-skip while loop and the main for-loop.
  • src/reduce.js: When no initialValue is provided, handle all-holes arrays correctly. After skipping holes, if startIndex >= len, throw TypeError('Reduce of empty array with no initial value') (checklist 1.2/3.5). Otherwise accumulator = arr[startIndex] may incorrectly use undefined.
  • src/reduce.js: Add an explicit guard if (this == null) throw new TypeError(...) near the top to ensure calling with this of null/undefined throws clearly (checklist 3.8).
  • src/reduce.test.js (CI blocker): Lint fails and stops the run. Address: no-extend-native on the prototype assignment (add // eslint-disable-next-line no-extend-native on that line or a file-level disable), max-len (wrap long lines), and no-sparse-arrays (use a programmatic sparse array or disable on that line). Without these, tests won’t execute.
  • src/reduce.test.js: Fix the incorrect expectation that pushed elements are visited; per spec, elements added beyond the initial length must be ignored. Update the test to expect only the original elements’ sum and/or assert the callback runs only up to the captured length.
  • src/reduce.test.js: Fix the “skip deleted unvisited indices” test to actually accumulate values; currently it returns acc and doesn’t change the result.

Minor but important additions:

  • Add tests for: non-function callback throws TypeError, callback this is undefined in strict mode, leading-holes without initialValue (including all-holes TypeError), array-like receivers and this of null/undefined throwing, and ignoring non-numeric properties.

You’ve got a solid base and good coverage; once these changes are in, you’ll align with the spec and the checklist. Keep it up!


✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨

Important

Fix the issues, commit the changes, and then re-request my review using the Re-request review button2 in the Reviewers tab.

Tip

If you have any comments about this review, please leave a message in the Add a comment section below and mention me with the @mateacademy-ai-mentor tag3.
I will read your message during my next review of your pull request. Please do not reply directly to my comments, as that feature is not supported yet.

Caution

Do not close the pull request until the review is complete. Closing it early can lead to unexpected behavior and disrupt the review process.

Footnotes

  1. Rate AI review example

  2. Re-request AI review example

  3. Add AI review comments example

Comment on lines +10 to +11
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good: the function checks the callback type and throws when it's not a function. This satisfies the checklist item that a non-function callback must cause a TypeError. The thrown message callback + ' is not a function' is acceptable, though you could prefer a message that does not coerce callback to string. Keep this check.

src/reduce.js Outdated
throw new TypeError(callback + ' is not a function');
}

const arr = this;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential runtime-safety / clarity: before using this, explicitly guard against this == null (null or undefined) and throw a TypeError. As currently written, accessing this.length will implicitly throw if this is null/undefined, but an explicit check is clearer and matches the requirement that method calls with this of null/undefined should throw. Add this near the top before const arr = this;.

src/reduce.js Outdated
Comment on lines +15 to +16
let hasInitialValue = arguments.length > 1;
let accumulator;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Critical: capture the array length at the start of the call. Right now the code uses arr.length dynamically (see the while loop and the for-loop) which allows appended elements to be visited. Per spec you must determine length once at the start, e.g. const len = arr.length;, and use len throughout. This change addresses checklist items 1.5 and 3.4.

src/reduce.js Outdated
Comment on lines +19 to +21
if (arr.length === 0 && !hasInitialValue) {
throw new TypeError('Reduce of empty array with no initial value');
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: the function currently throws only when arr.length === 0 && !hasInitialValue. That misses arrays with positive length but all holes (e.g., new Array(3) or [ , , ]) and no initialValue — those should also throw TypeError. After skipping holes, if startIndex >= len you must throw TypeError('Reduce of empty array with no initial value'). Update the logic that finds the first present element to check against the captured len and throw accordingly. This fixes checklist item 1.2 and 3.5.

src/reduce.js Outdated
Comment on lines +27 to +31
while (startIndex < arr.length && !(startIndex in arr)) {
startIndex++;
}
accumulator = arr[startIndex];
startIndex++;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When searching for the first present element (no initialValue branch), use the captured len instead of arr.length. After the while loop that skips holes, check if (startIndex >= len) and throw TypeError. Setting accumulator = arr[startIndex] without that check can cause undefined to be used incorrectly when there are only holes.

Comment on lines +49 to +56
it('should run callback with correct arguments when initialValue is provided', () => {
const array = [1, 2, 3, 4];
array.reduce2(callback, 0);
expect(callback).toHaveBeenNthCalledWith(1, 0, 1, 0, array);
expect(callback).toHaveBeenNthCalledWith(2, 1, 2, 1, array);
expect(callback).toHaveBeenNthCalledWith(3, 3, 3, 2, array);
expect(callback).toHaveBeenNthCalledWith(4, 6, 4, 3, array);
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing required test: assert callback this binding is undefined (strict mode). The file uses 'use strict' at the top, so add a test that captures this inside the callback and asserts it is undefined (checklist item 3.3). For example, use a mock implementation that records this and assert expect(recordedThis).toBeUndefined().

Comment on lines +74 to +77
it('should skip empty slots in sparse arrays', () => {
const array = [1, , 3];
const result = array.reduce2((acc, cur) => acc + cur, 0);
expect(result).toBe(4);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing required test: leading-holes with no initialValue. Add a test that verifies when an array has leading holes the first present element is used as the accumulator and the first callback invocation starts at the index of the next present element. Also add a test that an array consisting only of holes (e.g., new Array(3)) without initialValue throws a TypeError (checklist item 3.5).

Comment on lines +120 to +140
const seen = [];
array.reduce2((acc, cur, i) => {
seen.push([i, cur]);
return acc;
}, 0);
expect(seen).toEqual([[0, 1], [1, 2], [2, 3]]);
});

it('should work with string concatenation', () => {
const array = ['a', 'b', 'c'];
const result = array.reduce2((acc, cur) => acc + cur, '');
expect(result).toBe('abc');
});

it('should work with objects as accumulator', () => {
const array = ['x', 'y'];
const result = array.reduce2((acc, cur, i) => {
acc[i] = cur;
return acc;
}, {});
expect(result).toEqual({ 0: 'x', 1: 'y' });

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing required tests around this and array-like receivers: because reduce is implemented as a method, add tests that:

  • verify reduce works when called on array-like objects (e.g., reduce.call({0:1,1:2,length:2}, cb, 0)), and
  • verify calling the method with this equal to null or undefined throws TypeError (checklist item 3.8).
    Add these near the other edge-case tests toward the bottom of the file.

Comment on lines +120 to +140
const seen = [];
array.reduce2((acc, cur, i) => {
seen.push([i, cur]);
return acc;
}, 0);
expect(seen).toEqual([[0, 1], [1, 2], [2, 3]]);
});

it('should work with string concatenation', () => {
const array = ['a', 'b', 'c'];
const result = array.reduce2((acc, cur) => acc + cur, '');
expect(result).toBe('abc');
});

it('should work with objects as accumulator', () => {
const array = ['x', 'y'];
const result = array.reduce2((acc, cur, i) => {
acc[i] = cur;
return acc;
}, {});
expect(result).toEqual({ 0: 'x', 1: 'y' });

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing test: ensure non-numeric/out-of-range properties do not affect iteration. Add a test that sets array.foo = 'x' or array[100] = 'x' (out of initial length) and assert those properties are not visited during reduce (checklist item 3.7).

Comment on lines +33 to +42
it('should run callback array`s length times if initialValue is provided', () => {
const array = [1, 2, 3, 4];
array.reduce2(callback, 0);
expect(callback).toHaveBeenCalledTimes(array.length);
});

it('should run callback array`s length - 1 times if no initialValue', () => {
const array = [1, 2, 3, 4];
array.reduce2(callback);
expect(callback).toHaveBeenCalledTimes(array.length - 1);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: callback-count tests (should run callback array's length times... and ...length - 1 times if no initialValue) are correct for dense arrays, but add additional tests that assert call counts when the array is sparse (holes) to confirm holes are skipped and call counts reflect present elements only.

Copy link

@mateacademy-ai-mentor mateacademy-ai-mentor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

Decision: APPROVE

Great work on src/reduce.js: you correctly guard this == null, validate the callback, coerce and cache len (using >>> 0), skip holes via k in arr, properly handle the no-initialValue/all-holes error, and ignore elements appended during iteration—this aligns well with native reduce semantics.

Educational approval note: to help you progress while learning, I’m approving while recommending a few targeted test additions for completeness.

Critical tests to add:

  • Starting-index with no initialValue: first call should use accumulator === array[0] and currentIndex === 1 (add an explicit toHaveBeenNthCalledWith).
  • Single-element without initialValue: should return that element and not call the callback.
  • Appended elements during iteration: ensure newly pushed items are ignored and call count equals initial length.
  • Accumulator type changes mid-reduction: assert parity with native reduce.
  • Falsy values present (0, '', false, null, undefined): ensure they’re processed (not treated as holes).
  • Large array iteration: deterministic count and result.

Minor improvement: add a brief comment where you call callback(accumulator, arr[k], k, arr) noting it’s an intentional bare call so this is undefined in strict mode. Nicely done—your implementation is solid; these tests will make the suite airtight.


✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨

Footnotes

  1. Rate AI review example

Comment on lines +9 to +10
if (this == null) {
throw new TypeError('Array.prototype.reduce called on null or undefined');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good: guard for null/undefined receiver is present which ensures calling with this == null throws as required by the spec. This addresses the checklist item about throwing on null/undefined receivers.

}

const arr = Object(this);
const len = arr.length >>> 0;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good: length is captured once into len (using >>> 0) so the iteration bounds are fixed and elements appended during iteration will not be visited. This resolves the earlier issue where dynamic arr.length could cause appended items to be visited.

Comment on lines +27 to +33
while (k < len && !(k in arr)) {
k++;
}

if (k >= len) {
throw new TypeError('Reduce of empty array with no initial value');
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good: the implementation explicitly scans for the first existing element when no initialValue is provided and throws TypeError('Reduce of empty array with no initial value') if none is found. This correctly covers the all-holes case.


for (let i = startIndex; i < this.length; i++) {
prev = callback(prev, this[i], i, this);
for (; k < len; k++) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good: the main for loop uses the captured len and checks k in arr to skip holes — this matches native reduce behavior for sparse arrays and ensures correct iteration counts.

prev = callback(prev, this[i], i, this);
for (; k < len; k++) {
if (k in arr) {
accumulator = callback(accumulator, arr[k], k, arr);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor suggestion: you call the callback as a bare function (callback(accumulator, arr[k], k, arr)), which is correct and will produce this === undefined in strict-mode callbacks. Consider adding a short comment explaining that this is intentional (so future readers understand this will be undefined for strict callbacks).

expect(callback).toHaveBeenNthCalledWith(3, 3, 3, 2, array);
expect(callback).toHaveBeenNthCalledWith(4, 6, 4, 3, array);
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add an explicit test verifying starting-index behavior for the no initialValue path. The file already checks callback arguments with an initialValue, but the spec also requires verifying the other path: when no initialValue is provided the first callback invocation should have accumulator === array[0] and currentIndex === 1. Example you can add right after the initial-arguments test:

it('should start at index 1 and use array[0] as accumulator when no initialValue', () => {
  const array = [10, 20, 30];
  const cb = jest.fn((acc, cur, idx, arr) => acc + cur);
  array.reduce2(cb);
  expect(cb).toHaveBeenNthCalledWith(1, 10, 20, 1, array);
});

This ensures the starting-index behavior required by the spec is explicitly asserted.

const array = [];
expect(() => array.reduce2(callback)).toThrow(TypeError);
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a test for the single-element array without an initialValue. Per the spec, reduce should return that single element and should NOT call the callback. I don't see this specific assertion in the suite. Example to add near the empty-array/all-holes tests:

it('should return single element without calling callback when no initialValue', () => {
  const array = [42];
  const cb = jest.fn();
  const result = array.reduce2(cb);
  expect(result).toBe(42);
  expect(cb).toHaveBeenCalledTimes(0);
});

This closes the checklist item for single-element arrays.

const result = array.reduce2((acc, cur) => acc + cur, 0);
expect(result).toBe(4);
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a test covering arrays that include falsy values (0, '', false, null, undefined) to ensure they are processed when present (they should not be treated as holes). A minimal test could assert sum/concatenation/processing of those values to match native reduce. Example:

it('should process falsy values present in array', () => {
  const array = [0, '', false, null, undefined];
  const result = array.reduce2((acc, cur) => acc + String(cur) + '|', '');
  const expected = array.reduce((acc, cur) => acc + String(cur) + '|', '');
  expect(result).toBe(expected);
});

This verifies falsy but present elements are visited and passed to the callback.

const result = array.reduce2((acc, cur) => acc + cur, 0);
expect(result).toBe(6); // only 1+2+3
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add tests for: (1) verifying elements appended during iteration are ignored, and (2) a large-array deterministic test to ensure iteration completes and the callback is invoked the expected number of times.

Example for appended-element behavior:

it('should ignore elements appended after iteration begins', () => {
  const array = [1, 2, 3];
  const cb = jest.fn((acc, cur, idx, arr) => {
    if (idx === 0) arr.push(100); // appended during iteration
    return acc + cur;
  });
  const result = array.reduce2(cb, 0);
  expect(result).toBe(6); // 1+2+3, appended 100 must be ignored
  expect(cb).toHaveBeenCalledTimes(3);
});

Example for large-array test:

it('should iterate over large arrays and call callback expected number of times', () => {
  const size = 1000;
  const array = Array.from({ length: size }, (_, i) => i + 1);
  const cb = jest.fn((acc, cur) => acc + cur);
  const result = array.reduce2(cb, 0);
  expect(cb).toHaveBeenCalledTimes(size);
  expect(result).toBe(array.reduce((a, b) => a + b, 0));
});

These catch regressions where the implementation might read arr.length dynamically or otherwise visit appended items.

const result = array.reduce2((acc, cur) => acc + cur, '');
expect(result).toBe('abc');
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a test ensuring the implementation matches native reduce when the accumulator changes type during reduction. The checklist requires correct behavior when the callback returns different types and accumulator changes type. Example:

it('should handle accumulator changing type during reduction', () => {
  const array = [1, 2, 3];
  const resultCustom = array.reduce2((acc, cur, i) => {
    if (i === 1) return String(acc) + cur; // change type to string
    return acc + cur;
  }, 0);
  const resultNative = array.reduce((acc, cur, i) => {
    if (i === 1) return String(acc) + cur;
    return acc + cur;
  }, 0);
  expect(resultCustom).toBe(resultNative);
});

This ensures type transitions of the accumulator behave identically to the native implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants