Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 53 additions & 5 deletions __tests__/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function runBaseTest(
useListener,
useArrayMethods = false
) {
const listener = useListener ? function() {} : undefined
const listener = useListener ? function () {} : undefined

const {produce, produceWithPatches} = createPatchedImmer({
autoFreeze,
Expand All @@ -73,7 +73,7 @@ function runBaseTest(
const immer = new Immer(options)

const {produce} = immer
immer.produce = function(...args) {
immer.produce = function (...args) {
return typeof args[1] === "function" && args.length < 3
? produce(...args, listener)
: produce(...args)
Expand Down Expand Up @@ -1910,6 +1910,54 @@ function runBaseTest(
})
})

describe("array search iteration bounds", () => {
test("find ignores matches appended by the predicate", () => {
const base = [1, 2]
const result = produce(base, draft => {
draft.push(3)
const found = draft.find(value => {
if (value === 1) draft.push(4)
return value === 4
})
expect(found).toBeUndefined()
})
expect(result).toEqual([1, 2, 3, 4])
expect(base).toEqual([1, 2])
})

test.each(["find", "findLast"])(
"%s visits its original range after the predicate shrinks the array",
method => {
const base = [1, 2]
const visited = []
const result = produce(base, draft => {
draft.push(3)
const found = draft[method]((value, index) => {
visited.push([value, index])
draft.length = 1
return false
})
expect(found).toBeUndefined()
})
expect(visited).toEqual(
method === "find"
? [
[1, 0],
[undefined, 1],
[undefined, 2]
]
: [
[3, 2],
[undefined, 1],
[1, 0]
]
)
expect(result).toEqual([1])
expect(base).toEqual([1, 2])
}
)
})

describe("comparison: filter vs concat behavior", () => {
test("filter returns drafts that can affect original", () => {
const base = {
Expand Down Expand Up @@ -3415,13 +3463,13 @@ function runBaseTest(

it("'this' should not be bound anymore - 1", () => {
const base = {x: 3}
const next1 = produce(base, function() {
const next1 = produce(base, function () {
expect(this).toBe(undefined)
})
})

it("'this' should not be bound anymore - 2", () => {
const incrementor = produce(function() {
const incrementor = produce(function () {
expect(this).toBe(undefined)
})
incrementor()
Expand All @@ -3430,7 +3478,7 @@ function runBaseTest(
it("should be possible to use dynamic bound this", () => {
const world = {
counter: {count: 1},
inc: produce(function(draft) {
inc: produce(function (draft) {
expect(this).toBe(world)
draft.counter.count = this.counter.count + 1
})
Expand Down
5 changes: 3 additions & 2 deletions src/plugins/arrayMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -464,11 +464,12 @@ export function enableArrayMethods() {
if (FIND_METHODS.has(method)) {
const predicate = args[0]
const thisArg = args[1]
const length = source.length
const isForward = method === "find"
const step = isForward ? 1 : -1
const start = isForward ? 0 : source.length - 1
const start = isForward ? 0 : length - 1

for (let i = start; i >= 0 && i < source.length; i += step) {
for (let i = start; i >= 0 && i < length; i += step) {
if (predicate.call(thisArg, source[i], i, source)) {
return state.draft_[i]
}
Expand Down