Extended immutableJSONPatch with options fromJSON, toJSON, clone
This commit is contained in:
parent
dc814a3aa5
commit
410353c86f
|
@ -159,7 +159,7 @@ class App extends Component {
|
|||
|
||||
handlePatch = (patch, revert) => {
|
||||
this.log('onPatch patch=', patch, ', revert=', revert)
|
||||
window.immutableJsonPatch = patch
|
||||
window.immutableJSONPatch = patch
|
||||
window.revert = revert
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
name: 'myObject',
|
||||
onPatch: function (patch, revert) {
|
||||
log('onPatch patch=', patch, ', revert=', revert)
|
||||
window.immutableJsonPatch = patch
|
||||
window.immutableJSONPatch = patch
|
||||
window.revert = revert
|
||||
},
|
||||
onPatchText: function (patch, revert) {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import { sort } from './actions'
|
||||
import { createAssertEqualEson } from './utils/assertEqualEson'
|
||||
import { ID, syncEson } from './eson'
|
||||
import { immutableJsonPatch } from './immutableJsonPatch'
|
||||
import { immutableJSONPatch } from './immutableJSONPatch'
|
||||
|
||||
const assertEqualEson = createAssertEqualEson(expect)
|
||||
|
||||
|
@ -20,14 +20,14 @@ const assertEqualEson = createAssertEqualEson(expect)
|
|||
it('sort root Array', () => {
|
||||
const eson = syncEson([1,3,2])
|
||||
|
||||
assertEqualEson(immutableJsonPatch(eson, sort(eson, [])).json, syncEson([1,2,3]))
|
||||
assertEqualEson(immutableJsonPatch(eson, sort(eson, [], 'asc')).json, syncEson([1,2,3]))
|
||||
assertEqualEson(immutableJsonPatch(eson, sort(eson, [], 'desc')).json, syncEson([3,2,1]))
|
||||
assertEqualEson(immutableJSONPatch(eson, sort(eson, [])).json, syncEson([1,2,3]))
|
||||
assertEqualEson(immutableJSONPatch(eson, sort(eson, [], 'asc')).json, syncEson([1,2,3]))
|
||||
assertEqualEson(immutableJSONPatch(eson, sort(eson, [], 'desc')).json, syncEson([3,2,1]))
|
||||
})
|
||||
|
||||
it('sort nested Array', () => {
|
||||
const eson = syncEson({arr: [4,1,8,5,3,9,2,7,6]})
|
||||
const actual = immutableJsonPatch(eson, sort(eson, ['arr'])).json
|
||||
const actual = immutableJSONPatch(eson, sort(eson, ['arr'])).json
|
||||
const expected = syncEson({arr: [1,2,3,4,5,6,7,8,9]})
|
||||
assertEqualEson(actual, expected)
|
||||
})
|
||||
|
@ -35,7 +35,7 @@ it('sort nested Array', () => {
|
|||
it('sort nested Array reverse order', () => {
|
||||
// no order provided -> order ascending, but if nothing changes, order descending
|
||||
const eson = syncEson({arr: [1,2,3,4,5,6,7,8,9]})
|
||||
const actual = immutableJsonPatch(eson, sort(eson, ['arr'])).json
|
||||
const actual = immutableJSONPatch(eson, sort(eson, ['arr'])).json
|
||||
const expected = syncEson({arr: [9,8,7,6,5,4,3,2,1]})
|
||||
assertEqualEson(actual, expected)
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import { createFindKeyBinding } from '../utils/keyBindings'
|
|||
import { KEY_BINDINGS } from '../constants'
|
||||
|
||||
import ModeButton from './menu/ModeButton'
|
||||
import { immutableJsonPatch } from '../immutableJsonPatch'
|
||||
import { immutableJSONPatch } from '../immutableJSONPatch'
|
||||
|
||||
const AJV_OPTIONS = {
|
||||
allErrors: true,
|
||||
|
@ -330,7 +330,7 @@ export default class TextMode extends Component {
|
|||
patch (operations) {
|
||||
const json = this.get()
|
||||
|
||||
const result = immutableJsonPatch(json, operations)
|
||||
const result = immutableJSONPatch(json, operations)
|
||||
|
||||
this.set(result.data)
|
||||
|
||||
|
|
|
@ -48,16 +48,15 @@ import {
|
|||
} from './utils/domSelector'
|
||||
import { createFindKeyBinding } from '../utils/keyBindings'
|
||||
import { KEY_BINDINGS } from '../constants'
|
||||
import { immutableJsonPatch } from '../immutableJsonPatch'
|
||||
import { immutableJSONPatch } from '../immutableJSONPatch'
|
||||
import {
|
||||
applyErrors, applySelection, contentsFromPaths,
|
||||
expand,
|
||||
EXPANDED,
|
||||
expandPath,
|
||||
expandPath, immutableESONPatch,
|
||||
nextSearchResult, pathsFromSelection, previousSearchResult,
|
||||
search,
|
||||
syncEson,
|
||||
toEsonPatchOperation
|
||||
syncEson
|
||||
} from '../eson'
|
||||
|
||||
const AJV_OPTIONS = {
|
||||
|
@ -904,8 +903,8 @@ export default class TreeMode extends PureComponent {
|
|||
const historyIndex = this.state.historyIndex
|
||||
const historyItem = history[historyIndex]
|
||||
|
||||
const jsonResult = immutableJsonPatch(this.state.json, historyItem.undo)
|
||||
const esonResult = immutableJsonPatch(this.state.eson, historyItem.undo.map(toEsonPatchOperation))
|
||||
const jsonResult = immutableJSONPatch(this.state.json, historyItem.undo)
|
||||
const esonResult = immutableESONPatch(this.state.eson, historyItem.undo)
|
||||
|
||||
// FIXME: apply search
|
||||
this.setState({
|
||||
|
@ -925,8 +924,8 @@ export default class TreeMode extends PureComponent {
|
|||
const historyIndex = this.state.historyIndex - 1
|
||||
const historyItem = history[historyIndex]
|
||||
|
||||
const jsonResult = immutableJsonPatch(this.state.json, historyItem.redo)
|
||||
const esonResult = immutableJsonPatch(this.state.eson, historyItem.undo.map(toEsonPatchOperation))
|
||||
const jsonResult = immutableJSONPatch(this.state.json, historyItem.redo)
|
||||
const esonResult = immutableESONPatch(this.state.eson, historyItem.redo)
|
||||
|
||||
// FIXME: apply search
|
||||
this.setState({
|
||||
|
@ -954,8 +953,8 @@ export default class TreeMode extends PureComponent {
|
|||
|
||||
console.log('patch', operations) // TODO: cleanup
|
||||
|
||||
const jsonResult = immutableJsonPatch(this.state.json, operations)
|
||||
const esonResult = immutableJsonPatch(this.state.eson, operations.map(toEsonPatchOperation))
|
||||
const jsonResult = immutableJSONPatch(this.state.json, operations)
|
||||
const esonResult = immutableESONPatch(this.state.eson, operations)
|
||||
|
||||
if (this.props.history !== false) {
|
||||
// update data and store history
|
||||
|
|
|
@ -7,6 +7,7 @@ import isEmpty from 'lodash/isEmpty'
|
|||
import isEqual from 'lodash/isEqual'
|
||||
import naturalSort from 'javascript-natural-sort'
|
||||
import times from 'lodash/times'
|
||||
import { immutableJSONPatch } from './immutableJSONPatch'
|
||||
|
||||
export const ID = typeof Symbol === 'function' ? Symbol('id') : '@jsoneditor-id'
|
||||
export const TYPE = typeof Symbol === 'function' ? Symbol('type') : '@jsoneditor-type' // 'object', 'array', 'value', or 'undefined'
|
||||
|
@ -529,14 +530,19 @@ export function pathsFromSelection (eson, selection) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Convert the value of a JSON Patch action into a ESON object
|
||||
* @param {JSONPatchOperation} operation
|
||||
* @returns {ESONPatchOperation}
|
||||
* Apply a JSON patch document to an ESON object.
|
||||
* - Applies meta information to added values
|
||||
* - Reckons with creating unique id's when duplicating data
|
||||
* @param eson
|
||||
* @param operations
|
||||
* @returns {{json: JSON, revert: JSONPatchDocument, error: (Error|null)}}
|
||||
*/
|
||||
export function toEsonPatchOperation (operation) {
|
||||
return ('value' in operation)
|
||||
? setIn(operation, ['value'], syncEson(operation.value))
|
||||
: operation
|
||||
export function immutableESONPatch (eson, operations) {
|
||||
return immutableJSONPatch(eson, operations, {
|
||||
fromJSON: (value, previousEson) => syncEson(value, previousEson),
|
||||
toJSON: (eson) => eson[VALUE],
|
||||
clone: (value) => setIn(value, [ID], createId())
|
||||
})
|
||||
}
|
||||
|
||||
// TODO: comment
|
||||
|
|
|
@ -4,15 +4,22 @@ import initial from 'lodash/initial'
|
|||
import { setIn, getIn, deleteIn, insertAt, existsIn } from './utils/immutabilityHelpers'
|
||||
import { parseJSONPointer, compileJSONPointer } from './jsonPointer'
|
||||
|
||||
const DEFAULT_OPTIONS = {
|
||||
fromJSON: (json, previousObject) => json,
|
||||
toJSON: (object) => object,
|
||||
clone: (object) => object
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a patch to a JSON object
|
||||
* The original JSON object will not be changed,
|
||||
* instead, the patch is applied in an immutable way
|
||||
* @param {JSON} json
|
||||
* @param {JSONPatchDocument} operations Array with JSON patch actions
|
||||
* @param {JSONPatchOptions} [options]
|
||||
* @return {{json: JSON, revert: JSONPatchDocument, error: Error | null}}
|
||||
*/
|
||||
export function immutableJsonPatch (json, operations) {
|
||||
export function immutableJSONPatch (json, operations, options = DEFAULT_OPTIONS) {
|
||||
let updatedJson = json
|
||||
let revert = []
|
||||
|
||||
|
@ -23,14 +30,14 @@ export function immutableJsonPatch (json, operations) {
|
|||
|
||||
switch (operation.op) {
|
||||
case 'add': {
|
||||
const result = add(updatedJson, path, operation.value)
|
||||
const result = add(updatedJson, path, operation.value, options)
|
||||
updatedJson = result.json
|
||||
revert = result.revert.concat(revert)
|
||||
break
|
||||
}
|
||||
|
||||
case 'remove': {
|
||||
const result = remove(updatedJson, path)
|
||||
const result = remove(updatedJson, path, options)
|
||||
updatedJson = result.json
|
||||
revert = result.revert.concat(revert)
|
||||
|
||||
|
@ -38,7 +45,7 @@ export function immutableJsonPatch (json, operations) {
|
|||
}
|
||||
|
||||
case 'replace': {
|
||||
const result = replace(updatedJson, path, operation.value)
|
||||
const result = replace(updatedJson, path, operation.value, options)
|
||||
updatedJson = result.json
|
||||
revert = result.revert.concat(revert)
|
||||
|
||||
|
@ -54,7 +61,7 @@ export function immutableJsonPatch (json, operations) {
|
|||
}
|
||||
}
|
||||
|
||||
const result = copy(updatedJson, path, from)
|
||||
const result = copy(updatedJson, path, from, options)
|
||||
updatedJson = result.json
|
||||
revert = result.revert.concat(revert)
|
||||
|
||||
|
@ -70,7 +77,7 @@ export function immutableJsonPatch (json, operations) {
|
|||
}
|
||||
}
|
||||
|
||||
const result = move(updatedJson, path, from)
|
||||
const result = move(updatedJson, path, from, options)
|
||||
updatedJson = result.json
|
||||
revert = result.revert.concat(revert)
|
||||
|
||||
|
@ -79,7 +86,7 @@ export function immutableJsonPatch (json, operations) {
|
|||
|
||||
case 'test': {
|
||||
// when a test fails, cancel the whole patch and return the error
|
||||
const error = test(updatedJson, path, operation.value)
|
||||
const error = test(updatedJson, path, operation.value, options)
|
||||
if (error) {
|
||||
return { json, revert: [], error}
|
||||
}
|
||||
|
@ -110,13 +117,15 @@ export function immutableJsonPatch (json, operations) {
|
|||
* @param {JSON} json
|
||||
* @param {Path} path
|
||||
* @param {JSON} value
|
||||
* @param {JSONPatchOptions} [options]
|
||||
* @return {{json: JSON, revert: JSONPatchDocument}}
|
||||
*/
|
||||
export function replace (json, path, value) {
|
||||
export function replace (json, path, value, options) {
|
||||
const oldValue = getIn(json, path)
|
||||
const newValue = options.fromJSON(value, oldValue)
|
||||
|
||||
return {
|
||||
json: setIn(json, path, value),
|
||||
json: setIn(json, path, newValue),
|
||||
revert: [{
|
||||
op: 'replace',
|
||||
path: compileJSONPointer(path),
|
||||
|
@ -129,9 +138,10 @@ export function replace (json, path, value) {
|
|||
* Remove an item or property
|
||||
* @param {JSON} json
|
||||
* @param {Path} path
|
||||
* @param {JSONPatchOptions} [options]
|
||||
* @return {{json: JSON, revert: JSONPatchDocument}}
|
||||
*/
|
||||
export function remove (json, path) {
|
||||
export function remove (json, path, options) {
|
||||
const oldValue = getIn(json, path)
|
||||
|
||||
return {
|
||||
|
@ -139,7 +149,7 @@ export function remove (json, path) {
|
|||
revert: [{
|
||||
op: 'add',
|
||||
path: compileJSONPointer(path),
|
||||
value: oldValue
|
||||
value: options.toJSON(oldValue)
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
@ -148,27 +158,28 @@ export function remove (json, path) {
|
|||
* @param {JSON} json
|
||||
* @param {Path} path
|
||||
* @param {JSON} value
|
||||
* @param {JSONPatchOptions} [options]
|
||||
* @return {{json: JSON, revert: JSONPatchDocument}}
|
||||
* @private
|
||||
*/
|
||||
export function add (json, path, value) {
|
||||
export function add (json, path, value, options) {
|
||||
const resolvedPath = resolvePathIndex(json, path)
|
||||
const parent = getIn(json, initial(path))
|
||||
const parentIsArray = Array.isArray(parent)
|
||||
const oldValue = getIn(json, resolvedPath)
|
||||
const newValue = options.fromJSON(value, oldValue)
|
||||
|
||||
const updatedJson = parentIsArray
|
||||
? insertAt(json, resolvedPath, value)
|
||||
: setIn(json, resolvedPath, value)
|
||||
? insertAt(json, resolvedPath, newValue)
|
||||
: setIn(json, resolvedPath, newValue)
|
||||
|
||||
if (!parentIsArray && existsIn(json, resolvedPath)) {
|
||||
const oldValue = getIn(json, resolvedPath)
|
||||
|
||||
return {
|
||||
json: updatedJson,
|
||||
revert: [{
|
||||
op: 'replace',
|
||||
path: compileJSONPointer(resolvedPath),
|
||||
value: oldValue
|
||||
value: options.toJSON(oldValue)
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
@ -188,13 +199,20 @@ export function add (json, path, value) {
|
|||
* @param {JSON} json
|
||||
* @param {Path} path
|
||||
* @param {Path} from
|
||||
* @param {JSONPatchOptions} [options]
|
||||
* @return {{json: JSON, revert: ESONPatchDocument}}
|
||||
* @private
|
||||
*/
|
||||
export function copy (json, path, from) {
|
||||
const value = getIn(json, from)
|
||||
export function copy (json, path, from, options) {
|
||||
const value = options.clone
|
||||
? options.clone(getIn(json, from))
|
||||
: options.fromJSON(options.toJSON(getIn(json, from)), undefined)
|
||||
|
||||
return add(json, path, value)
|
||||
return add(json, path, value, {
|
||||
fromJSON: DEFAULT_OPTIONS.fromJSON,
|
||||
toJSON: options.toJSON,
|
||||
clone: options.clone
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -202,17 +220,18 @@ export function copy (json, path, from) {
|
|||
* @param {JSON} json
|
||||
* @param {Path} path
|
||||
* @param {Path} from
|
||||
* @param {JSONPatchOptions} [options]
|
||||
* @return {{json: JSON, revert: ESONPatchDocument}}
|
||||
* @private
|
||||
*/
|
||||
export function move (json, path, from) {
|
||||
export function move (json, path, from, options) {
|
||||
const resolvedPath = resolvePathIndex(json, path)
|
||||
const parent = getIn(json, initial(path))
|
||||
const parentIsArray = Array.isArray(parent)
|
||||
const oldValue = getIn(json, path)
|
||||
const value = getIn(json, from)
|
||||
|
||||
const removedJson = remove(json, from).json
|
||||
const removedJson = remove(json, from, options).json
|
||||
const updatedJson = parentIsArray
|
||||
? insertAt(removedJson, resolvedPath, value)
|
||||
: setIn(removedJson, resolvedPath, value)
|
||||
|
@ -230,7 +249,7 @@ export function move (json, path, from) {
|
|||
{
|
||||
op: 'add',
|
||||
path: compileJSONPointer(resolvedPath),
|
||||
value: oldValue
|
||||
value: options.toJSON(oldValue)
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -254,10 +273,11 @@ export function move (json, path, from) {
|
|||
* Throws an error when the test fails.
|
||||
* @param {JSON} json
|
||||
* @param {Path} path
|
||||
* @param {*} value
|
||||
* @param {JSON} value
|
||||
* @param {JSONPatchOptions} [options]
|
||||
* @return {null | Error} Returns an error when the tests, returns null otherwise
|
||||
*/
|
||||
export function test (json, path, value) {
|
||||
export function test (json, path, value, options) {
|
||||
if (value === undefined) {
|
||||
return new Error('Test failed, no value provided')
|
||||
}
|
||||
|
@ -266,7 +286,7 @@ export function test (json, path, value) {
|
|||
return new Error('Test failed, path not found')
|
||||
}
|
||||
|
||||
const actualValue = getIn(json, path)
|
||||
const actualValue = options.toJSON(getIn(json, path))
|
||||
if (!isEqual(actualValue, value)) {
|
||||
return new Error('Test failed, value differs')
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
'use strict'
|
||||
|
||||
import { immutableJsonPatch } from './immutableJsonPatch'
|
||||
import { immutableJSONPatch } from './immutableJSONPatch'
|
||||
|
||||
test('test toBe', () => {
|
||||
const a = { x: 2 }
|
||||
|
@ -22,7 +22,7 @@ test('jsonpatch add', () => {
|
|||
{op: 'add', path: '/obj/b', value: {foo: 'bar'}}
|
||||
]
|
||||
|
||||
const result = immutableJsonPatch(json, patch)
|
||||
const result = immutableJSONPatch(json, patch)
|
||||
|
||||
expect(result.json).toEqual({
|
||||
arr: [1,2,3],
|
||||
|
@ -44,7 +44,7 @@ test('jsonpatch add: insert in matrix', () => {
|
|||
{op: 'add', path: '/arr/1', value: 4}
|
||||
]
|
||||
|
||||
const result = immutableJsonPatch(json, patch)
|
||||
const result = immutableJSONPatch(json, patch)
|
||||
|
||||
expect(result.json).toEqual({
|
||||
arr: [1,4,2,3],
|
||||
|
@ -66,7 +66,7 @@ test('jsonpatch add: append to matrix', () => {
|
|||
{op: 'add', path: '/arr/-', value: 4}
|
||||
]
|
||||
|
||||
const result = immutableJsonPatch(json, patch)
|
||||
const result = immutableJSONPatch(json, patch)
|
||||
|
||||
expect(result.json).toEqual({
|
||||
arr: [1,2,3,4],
|
||||
|
@ -90,7 +90,7 @@ test('jsonpatch remove', () => {
|
|||
{op: 'remove', path: '/arr/1'},
|
||||
]
|
||||
|
||||
const result = immutableJsonPatch(json, patch)
|
||||
const result = immutableJSONPatch(json, patch)
|
||||
|
||||
expect(result.json).toEqual({
|
||||
arr: [1,3],
|
||||
|
@ -103,7 +103,7 @@ test('jsonpatch remove', () => {
|
|||
])
|
||||
|
||||
// test revert
|
||||
const result2 = immutableJsonPatch(result.json, result.revert)
|
||||
const result2 = immutableJSONPatch(result.json, result.revert)
|
||||
|
||||
expect(result2.json).toEqual(json)
|
||||
expect(result2.revert).toEqual(patch)
|
||||
|
@ -122,7 +122,7 @@ test('jsonpatch replace', () => {
|
|||
{op: 'replace', path: '/arr/1', value: 200},
|
||||
]
|
||||
|
||||
const result = immutableJsonPatch(json, patch)
|
||||
const result = immutableJSONPatch(json, patch)
|
||||
|
||||
expect(result.json).toEqual({
|
||||
arr: [1,200,3],
|
||||
|
@ -135,7 +135,7 @@ test('jsonpatch replace', () => {
|
|||
])
|
||||
|
||||
// test revert
|
||||
const result2 = immutableJsonPatch(result.json, result.revert)
|
||||
const result2 = immutableJSONPatch(result.json, result.revert)
|
||||
|
||||
expect(result2.json).toEqual(json)
|
||||
expect(result2.revert).toEqual([
|
||||
|
@ -155,7 +155,7 @@ test('jsonpatch copy', () => {
|
|||
{op: 'copy', from: '/obj', path: '/arr/2'},
|
||||
]
|
||||
|
||||
const result = immutableJsonPatch(json, patch)
|
||||
const result = immutableJSONPatch(json, patch)
|
||||
|
||||
expect(result.json).toEqual({
|
||||
arr: [1, 2, {a:4}, 3],
|
||||
|
@ -166,7 +166,7 @@ test('jsonpatch copy', () => {
|
|||
])
|
||||
|
||||
// test revert
|
||||
const result2 = immutableJsonPatch(result.json, result.revert)
|
||||
const result2 = immutableJSONPatch(result.json, result.revert)
|
||||
|
||||
expect(result2.json).toEqual(json)
|
||||
expect(result2.revert).toEqual([
|
||||
|
@ -187,7 +187,7 @@ test('jsonpatch move', () => {
|
|||
{op: 'move', from: '/obj', path: '/arr/2'},
|
||||
]
|
||||
|
||||
const result = immutableJsonPatch(json, patch)
|
||||
const result = immutableJSONPatch(json, patch)
|
||||
|
||||
expect(result.error).toEqual(null)
|
||||
expect(result.json).toEqual({
|
||||
|
@ -199,7 +199,7 @@ test('jsonpatch move', () => {
|
|||
])
|
||||
|
||||
// test revert
|
||||
const result2 = immutableJsonPatch(result.json, result.revert)
|
||||
const result2 = immutableJSONPatch(result.json, result.revert)
|
||||
|
||||
expect(result2.json).toEqual(json)
|
||||
expect(result2.revert).toEqual(patch)
|
||||
|
@ -214,7 +214,7 @@ test('jsonpatch move and replace', () => {
|
|||
{op: 'move', from: '/a', path: '/b'},
|
||||
]
|
||||
|
||||
const result = immutableJsonPatch(json, patch)
|
||||
const result = immutableJSONPatch(json, patch)
|
||||
|
||||
expect(result.json).toEqual({ b : 2 })
|
||||
expect(result.revert).toEqual([
|
||||
|
@ -223,7 +223,7 @@ test('jsonpatch move and replace', () => {
|
|||
])
|
||||
|
||||
// test revert
|
||||
const result2 = immutableJsonPatch(result.json, result.revert)
|
||||
const result2 = immutableJSONPatch(result.json, result.revert)
|
||||
|
||||
expect(result2.json).toEqual(json)
|
||||
expect(result2.revert).toEqual([
|
||||
|
@ -243,7 +243,7 @@ test('jsonpatch move and replace (nested)', () => {
|
|||
{op: 'move', from: '/obj', path: '/arr'},
|
||||
]
|
||||
|
||||
const result = immutableJsonPatch(json, patch)
|
||||
const result = immutableJSONPatch(json, patch)
|
||||
|
||||
expect(result.json).toEqual({
|
||||
arr: {a:4},
|
||||
|
@ -255,7 +255,7 @@ test('jsonpatch move and replace (nested)', () => {
|
|||
])
|
||||
|
||||
// test revert
|
||||
const result2 = immutableJsonPatch(result.json, result.revert)
|
||||
const result2 = immutableJSONPatch(result.json, result.revert)
|
||||
|
||||
expect(result2.json).toEqual(json)
|
||||
expect(result2.revert).toEqual([
|
||||
|
@ -277,7 +277,7 @@ test('jsonpatch test (ok)', () => {
|
|||
{op: 'add', path: '/added', value: 'ok'}
|
||||
]
|
||||
|
||||
const result = immutableJsonPatch(json, patch)
|
||||
const result = immutableJSONPatch(json, patch)
|
||||
|
||||
expect(result.json).toEqual({
|
||||
arr: [1,2,3],
|
||||
|
@ -300,7 +300,7 @@ test('jsonpatch test (fail: path not found)', () => {
|
|||
{op: 'add', path: '/added', value: 'ok'}
|
||||
]
|
||||
|
||||
const result = immutableJsonPatch(json, patch)
|
||||
const result = immutableJSONPatch(json, patch)
|
||||
|
||||
// patch shouldn't be applied
|
||||
expect(result.json).toEqual({
|
||||
|
@ -322,7 +322,7 @@ test('jsonpatch test (fail: value not equal)', () => {
|
|||
{op: 'add', path: '/added', value: 'ok'}
|
||||
]
|
||||
|
||||
const result = immutableJsonPatch(json, patch)
|
||||
const result = immutableJSONPatch(json, patch)
|
||||
|
||||
// patch shouldn't be applied
|
||||
expect(result.json).toEqual({
|
||||
|
@ -332,3 +332,41 @@ test('jsonpatch test (fail: value not equal)', () => {
|
|||
expect(result.revert).toEqual([])
|
||||
expect(result.error.toString()).toEqual('Error: Test failed, value differs')
|
||||
})
|
||||
|
||||
test('jsonpatch options', () => {
|
||||
const json = {
|
||||
arr: [1,2,3],
|
||||
obj: {a : 2}
|
||||
}
|
||||
|
||||
const patch = [
|
||||
{op: 'add', path: '/obj/a', value: 4 }
|
||||
]
|
||||
const result = immutableJSONPatch(json, patch, {
|
||||
fromJSON: function (value, previousObject) {
|
||||
return { value, previousObject }
|
||||
},
|
||||
toJSON: value => value
|
||||
})
|
||||
expect(result.json).toEqual({
|
||||
arr: [1,2,3],
|
||||
obj: {a : { value: 4, previousObject: 2 }}
|
||||
})
|
||||
|
||||
|
||||
const patch2 = [
|
||||
{op: 'add', path: '/obj/b', value: 4 }
|
||||
]
|
||||
const result2 = immutableJSONPatch(json, patch2, {
|
||||
fromJSON: function (value, previousObject) {
|
||||
return { value, previousObject }
|
||||
},
|
||||
toJSON: value => value
|
||||
})
|
||||
expect(result2.json).toEqual({
|
||||
arr: [1,2,3],
|
||||
obj: {a : 2, b: { value: 4, previousObject: undefined }}
|
||||
})
|
||||
})
|
||||
|
||||
// TODO: test all operations with JSONPatchOptions (not just add)
|
|
@ -73,6 +73,14 @@
|
|||
* @typedef {JSONPatchOperation[]} JSONPatchDocument
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* fromJSON: function(json: JSON, previousObject: * | undefined),
|
||||
* toJSON: function(object: *),
|
||||
* clone: function(object: *)
|
||||
* }} JSONPatchOptions
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* op: 'add' | 'remove' | 'replace' | 'copy' | 'move' | 'test',
|
||||
|
|
Loading…
Reference in New Issue