Skip to content

Commit

Permalink
Merge f7b9bfe into 41bb8b9
Browse files Browse the repository at this point in the history
  • Loading branch information
mweststrate committed May 1, 2018
2 parents 41bb8b9 + f7b9bfe commit d0e1684
Show file tree
Hide file tree
Showing 6 changed files with 331 additions and 148 deletions.
27 changes: 16 additions & 11 deletions __tests__/flow/flow.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ const result = produce({x: 3}, draft => {
console.log(result.x)

const result2 = produce({x: 3}, draft => {
return {x: 4};
return {x: 4}
})

console.log(result2.x)

const f = produce((draft): ({x: number}) => { return {x: 4}; });
f({x: 3});
const f = produce((draft): {x: number} => {
return {x: 4}
})
f({x: 3})

const f2 = produce((draft): void => {})
f2({x: 3})
Expand All @@ -43,28 +45,31 @@ produce({x: 3}, [])

{
// curried & initial arg
const f = produce((state, increment: number): void => {
state.x += increment
}, { x: 3})
const f = produce(
(state, increment: number): void => {
state.x += increment
},
{x: 3}
)

// $ExpectError Too few arguments
f({x : 5})
f({x: 5})

// $ExpectError
f({x : 5}, "test")
f({x: 5}, "test")

f({x : 5}, 3)
f({x: 5}, 3)

f(undefined, 3)
}

{
// curried f & no initial arg
const f2 = produce((state: {x:number}, increment: number): void => {
const f2 = produce((state: {x: number}, increment: number): void => {
state.x += increment
})

f2({x : 5}, 3)
f2({x: 5}, 3)

// $ExpectError
f2(undefined, 3)
Expand Down
187 changes: 187 additions & 0 deletions __tests__/recursive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
"use strict"
import produce, {setUseProxies} from "../src/immer"
import {isArray, isPlainObject, isString, keys, trim} from "lodash"

const nonPlainObject = () => {}

runTests("proxy", true)
runTests("es5", false)

function runTests(name, useProxies) {
describe("recursive - " + name, () => {
setUseProxies(useProxies)

const testCases = [
{
title: "in a simple non-recursive case",
recursiveTransform: recursivelyTrimStrings,
baseState: " hello ",
desiredState: "hello"
},
{
title: "in a simple non-recursive unchanged case",
recursiveTransform: recursivelyTrimStrings,
baseState: "hello",
desiredState: "hello"
},
{
title: "if baseState is an object that does not change",
recursiveTransform: recursivelyTrimStrings,
baseState: {
a: 1,
b: "test",
c: {
a: [true, null, false, "test"],
b: 1
}
}
},
{
title: "if baseState is an array does not change",
recursiveTransform: recursivelyTrimStrings,
baseState: [true, null, false, "test"]
},
{
title: "when all leafs are changing",
recursiveTransform: recursivelyTrimStrings,
baseState: {
x: " hello ",
arr: [
"world ",
42,
" !!!",
{
x: 42,
test: "true "
}
]
},
desiredState: {
x: "hello",
arr: [
"world",
42,
"!!!",
{
x: 42,
test: "true"
}
]
}
},
{
title: "when there is an unchanged leaf array",
recursiveTransform: recursivelyTrimStrings,
baseState: {
x: " hello ",
arr: [1, 2, 3]
},
desiredState: {
x: "hello",
arr: [1, 2, 3]
}
},
{
title:
"when there is an unchanged leaf object in an unchanged array",
recursiveTransform: recursivelyTrimStrings,
baseState: {
arr: [
"!!!",
{
x: 42,
y: "test"
}
]
},
desiredState: {
arr: [
"!!!",
{
x: 42,
y: "test"
}
]
}
},
{
title:
"when there is an unchanged leaf object in a changed array",
recursiveTransform: recursivelyTrimStrings,
baseState: {
arr: [
" !!!",
{
x: 42,
y: "test"
}
]
},
desiredState: {
arr: [
"!!!",
{
x: 42,
y: "test"
}
]
}
},
{
title:
"when there is an unchanged leaf array in a changed object",
recursiveTransform: recursivelyTrimStrings,
baseState: {
test: "!!! ",
arr: [1, 2, 3]
},
desiredState: {
test: "!!!",
arr: [1, 2, 3]
}
},
{
title: "when there non-plain objects",
recursiveTransform: recursivelyTrimStrings,
baseState: {
a: [nonPlainObject, 1],
b: nonPlainObject
}
}
]

testCases
.slice(0, 9)
.forEach(({title, baseState, desiredState, recursiveTransform}) => {
it(`should not leave drafts ${title}`, () => {
const next = recursiveTransform(baseState)
if (desiredState) {
// an exception is thrown during deep comparison if any of the drafts is not finalized
expect(next).toEqual(desiredState)
} else {
expect(next).toBe(baseState)
}
})
})
})
}

function recursivelyTrimStrings(source) {
if (isString(source)) {
return trim(source)
} else if (isArray(source)) {
return produce(source, draft =>
draft.forEach((el, i) => {
const v = recursivelyTrimStrings(el)
draft[i] = v
})
)
} else if (isPlainObject(source)) {
return produce(source, draft => {
keys(draft).forEach(key => {
draft[key] = recursivelyTrimStrings(draft[key])
})
})
}
return source
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"react-native": "dist/immer.module.js",
"types": "./dist/immer.d.ts",
"scripts": {
"watch": "jest --watch",
"test": "jest",
"test:perf": "yarn-or-npm build && node --expose-gc node_modules/jest-cli/bin/jest.js --verbose --testRegex '__performance_tests__/.*?js$'",
"test:flow": "yarn-or-npm flow check",
Expand Down
Loading

0 comments on commit d0e1684

Please sign in to comment.