2017-12-16 21:13:52 +08:00
|
|
|
'use strict'
|
|
|
|
|
2017-09-22 18:24:13 +08:00
|
|
|
import { readFileSync } from 'fs'
|
2017-09-30 03:52:17 +08:00
|
|
|
import test from 'ava'
|
2017-12-13 18:47:12 +08:00
|
|
|
import { setIn, getIn, deleteIn } from '../src/utils/immutabilityHelpers'
|
2016-09-09 17:01:06 +08:00
|
|
|
import {
|
2017-12-15 21:02:42 +08:00
|
|
|
META,
|
2017-12-16 03:34:07 +08:00
|
|
|
esonToJson, pathExists, transform,
|
2017-12-15 19:59:45 +08:00
|
|
|
parseJSONPointer, compileJSONPointer,
|
2017-12-13 18:47:12 +08:00
|
|
|
jsonToEson,
|
2017-12-15 19:59:45 +08:00
|
|
|
expand, expandOne, expandPath, applyErrors, search, nextSearchResult,
|
|
|
|
previousSearchResult,
|
|
|
|
applySelection, pathsFromSelection,
|
2017-12-15 21:02:42 +08:00
|
|
|
SELECTED, SELECTED_END
|
2017-09-08 19:36:15 +08:00
|
|
|
} from '../src/eson'
|
2017-12-15 21:02:42 +08:00
|
|
|
import 'console.table'
|
|
|
|
import repeat from 'lodash/repeat'
|
2017-12-16 02:57:21 +08:00
|
|
|
import { assertDeepEqualEson } from './utils/assertDeepEqualEson'
|
2016-08-21 18:45:25 +08:00
|
|
|
|
2017-12-13 18:47:12 +08:00
|
|
|
test('jsonToEson', t => {
|
2017-12-15 21:02:42 +08:00
|
|
|
assertDeepEqualEson(t, jsonToEson(1), {[META]: {id: '[ID]', path: [], type: 'value', value: 1}})
|
|
|
|
assertDeepEqualEson(t, jsonToEson("foo"), {[META]: {id: '[ID]', path: [], type: 'value', value: "foo"}})
|
|
|
|
assertDeepEqualEson(t, jsonToEson(null), {[META]: {id: '[ID]', path: [], type: 'value', value: null}})
|
|
|
|
assertDeepEqualEson(t, jsonToEson(false), {[META]: {id: '[ID]', path: [], type: 'value', value: false}})
|
|
|
|
assertDeepEqualEson(t, jsonToEson({a:1, b: 2}), {
|
2017-12-16 04:02:17 +08:00
|
|
|
[META]: {id: '[ID]', path: [], type: 'Object', props: ['a', 'b']},
|
2017-12-15 21:02:42 +08:00
|
|
|
a: {[META]: {id: '[ID]', path: ['a'], type: 'value', value: 1}},
|
|
|
|
b: {[META]: {id: '[ID]', path: ['b'], type: 'value', value: 2}}
|
2017-11-30 04:52:18 +08:00
|
|
|
})
|
|
|
|
|
2017-12-15 21:02:42 +08:00
|
|
|
const actual = jsonToEson([1,2])
|
|
|
|
const expected = [
|
2017-12-16 02:57:21 +08:00
|
|
|
{[META]: {id: '[ID]', path: ['0'], type: 'value', value: 1}},
|
|
|
|
{[META]: {id: '[ID]', path: ['1'], type: 'value', value: 2}}
|
2017-12-15 21:02:42 +08:00
|
|
|
]
|
|
|
|
expected[META] = {id: '[ID]', path: [], type: 'Array'}
|
|
|
|
assertDeepEqualEson(t, actual, expected)
|
2017-11-30 04:52:18 +08:00
|
|
|
})
|
|
|
|
|
2017-09-08 19:36:15 +08:00
|
|
|
test('esonToJson', t => {
|
2017-12-16 02:57:21 +08:00
|
|
|
const json = {
|
|
|
|
"obj": {
|
|
|
|
"arr": [1,2, {"first":3,"last":4}]
|
|
|
|
},
|
|
|
|
"str": "hello world",
|
|
|
|
"nill": null,
|
|
|
|
"bool": false
|
|
|
|
}
|
|
|
|
const eson = jsonToEson(json)
|
|
|
|
t.deepEqual(esonToJson(eson), json)
|
2016-08-21 18:45:25 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
test('expand a single path', t => {
|
2017-12-13 18:47:12 +08:00
|
|
|
const eson = jsonToEson({
|
|
|
|
"obj": {
|
|
|
|
"arr": [1,2, {"first":3,"last":4}]
|
|
|
|
},
|
|
|
|
"str": "hello world",
|
|
|
|
"nill": null,
|
|
|
|
"bool": false
|
|
|
|
})
|
|
|
|
|
2017-09-22 18:24:13 +08:00
|
|
|
const path = ['obj', 'arr', 2]
|
2017-12-13 18:47:12 +08:00
|
|
|
const collapsed = expandOne(eson, path, false)
|
2017-12-15 21:02:42 +08:00
|
|
|
t.is(collapsed.obj.arr[2][META].expanded, false)
|
|
|
|
assertDeepEqualEson(t, deleteIn(collapsed, path.concat([META, 'expanded'])), eson)
|
2017-12-13 18:47:12 +08:00
|
|
|
|
|
|
|
const expanded = expandOne(eson, path, true)
|
2017-12-15 21:02:42 +08:00
|
|
|
t.is(expanded.obj.arr[2][META].expanded, true)
|
|
|
|
assertDeepEqualEson(t, deleteIn(expanded, path.concat([META, 'expanded'])), eson)
|
2017-12-13 18:47:12 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
test('expand all objects/arrays on a path', t => {
|
|
|
|
const eson = jsonToEson({
|
|
|
|
"obj": {
|
|
|
|
"arr": [1,2, {"first":3,"last":4}]
|
|
|
|
},
|
|
|
|
"str": "hello world",
|
|
|
|
"nill": null,
|
|
|
|
"bool": false
|
|
|
|
})
|
2016-08-21 18:45:25 +08:00
|
|
|
|
2017-12-13 18:47:12 +08:00
|
|
|
const path = ['obj', 'arr', 2]
|
2017-09-22 18:24:13 +08:00
|
|
|
|
2017-12-13 18:47:12 +08:00
|
|
|
const collapsed = expandPath(eson, path, false)
|
2017-12-15 21:02:42 +08:00
|
|
|
t.is(collapsed[META].expanded, false)
|
|
|
|
t.is(collapsed.obj[META].expanded, false)
|
|
|
|
t.is(collapsed.obj.arr[META].expanded, false)
|
|
|
|
t.is(collapsed.obj.arr[2][META].expanded, false)
|
2017-12-13 18:47:12 +08:00
|
|
|
|
|
|
|
const expanded = expandPath(eson, path, true)
|
2017-12-15 21:02:42 +08:00
|
|
|
t.is(expanded[META].expanded, true)
|
|
|
|
t.is(expanded.obj[META].expanded, true)
|
|
|
|
t.is(expanded.obj.arr[META].expanded, true)
|
|
|
|
t.is(expanded.obj.arr[2][META].expanded, true)
|
2017-12-13 18:47:12 +08:00
|
|
|
|
|
|
|
let orig = expanded
|
2017-12-15 21:02:42 +08:00
|
|
|
orig = deleteIn(orig, [].concat([META, 'expanded']))
|
|
|
|
orig = deleteIn(orig, ['obj'].concat([META, 'expanded']))
|
|
|
|
orig = deleteIn(orig, ['obj', 'arr'].concat([META, 'expanded']))
|
|
|
|
orig = deleteIn(orig, ['obj', 'arr', 2].concat([META, 'expanded']))
|
2017-12-13 18:47:12 +08:00
|
|
|
|
2017-12-15 21:02:42 +08:00
|
|
|
assertDeepEqualEson(t, orig, eson)
|
2016-08-21 18:45:25 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
test('expand a callback', t => {
|
2017-12-13 18:47:12 +08:00
|
|
|
const eson = jsonToEson({
|
|
|
|
"obj": {
|
|
|
|
"arr": [1,2, {"first":3,"last":4}]
|
|
|
|
},
|
|
|
|
"str": "hello world",
|
|
|
|
"nill": null,
|
|
|
|
"bool": false
|
|
|
|
})
|
|
|
|
|
|
|
|
function filterCallback (path) {
|
2016-08-21 18:45:25 +08:00
|
|
|
return path.length >= 1
|
|
|
|
}
|
2017-12-13 18:47:12 +08:00
|
|
|
const expandedValue = false
|
|
|
|
const collapsed = expand(eson, filterCallback, expandedValue)
|
2017-12-15 21:02:42 +08:00
|
|
|
t.is(collapsed[META].expanded, undefined)
|
|
|
|
t.is(collapsed.obj[META].expanded, expandedValue)
|
|
|
|
t.is(collapsed.obj.arr[META].expanded, expandedValue)
|
|
|
|
t.is(collapsed.obj.arr[2][META].expanded, expandedValue)
|
2017-12-13 18:47:12 +08:00
|
|
|
|
|
|
|
let orig = collapsed
|
2017-12-15 21:02:42 +08:00
|
|
|
orig = deleteIn(orig, ['obj'].concat([META, 'expanded']))
|
|
|
|
orig = deleteIn(orig, ['obj', 'arr'].concat([META, 'expanded']))
|
|
|
|
orig = deleteIn(orig, ['obj', 'arr', 2].concat([META, 'expanded']))
|
|
|
|
assertDeepEqualEson(t, orig, eson)
|
2016-08-21 18:45:25 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
test('expand a callback should not change the object when nothing happens', t => {
|
2017-12-13 18:47:12 +08:00
|
|
|
const eson = jsonToEson({a: [1,2,3], b: {c: 4}})
|
2016-08-21 18:45:25 +08:00
|
|
|
function callback (path) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
const expanded = false
|
2017-12-13 18:47:12 +08:00
|
|
|
const collapsed = expand(eson, callback, expanded)
|
|
|
|
|
|
|
|
t.is(collapsed, eson)
|
|
|
|
})
|
|
|
|
|
|
|
|
test('transform (no change)', t => {
|
|
|
|
const eson = jsonToEson({a: [1,2,3], b: {c: 4}})
|
|
|
|
const updated = transform(eson, (value, path) => value)
|
2017-12-15 21:02:42 +08:00
|
|
|
assertDeepEqualEson(t, updated, eson)
|
2017-12-13 18:47:12 +08:00
|
|
|
t.is(updated, eson)
|
|
|
|
})
|
|
|
|
|
|
|
|
test('transform (change based on value)', t => {
|
|
|
|
const eson = jsonToEson({a: [1,2,3], b: {c: 4}})
|
|
|
|
|
|
|
|
const updated = transform(eson,
|
2017-12-15 21:02:42 +08:00
|
|
|
(value, path) => value[META].value === 2 ? jsonToEson(20, path) : value)
|
2017-12-13 18:47:12 +08:00
|
|
|
const expected = jsonToEson({a: [1,20,3], b: {c: 4}})
|
|
|
|
|
2017-12-15 21:02:42 +08:00
|
|
|
assertDeepEqualEson(t, updated, expected)
|
2017-12-13 18:47:12 +08:00
|
|
|
t.is(updated.b, eson.b) // should not have replaced b
|
|
|
|
})
|
|
|
|
|
|
|
|
test('transform (change based on path)', t => {
|
|
|
|
const eson = jsonToEson({a: [1,2,3], b: {c: 4}})
|
2016-08-21 18:45:25 +08:00
|
|
|
|
2017-12-13 18:47:12 +08:00
|
|
|
const updated = transform(eson,
|
|
|
|
(value, path) => path.join('.') === 'a.1' ? jsonToEson(20, path) : value)
|
|
|
|
const expected = jsonToEson({a: [1,20,3], b: {c: 4}})
|
|
|
|
|
2017-12-15 21:02:42 +08:00
|
|
|
assertDeepEqualEson(t, updated, expected)
|
2017-12-13 18:47:12 +08:00
|
|
|
t.is(updated.b, eson.b) // should not have replaced b
|
2016-08-21 18:45:25 +08:00
|
|
|
})
|
|
|
|
|
2016-09-09 17:01:06 +08:00
|
|
|
test('pathExists', t => {
|
2017-12-16 02:57:21 +08:00
|
|
|
const eson = jsonToEson({
|
|
|
|
"obj": {
|
|
|
|
"arr": [1,2, {"first":3,"last":4}]
|
|
|
|
},
|
|
|
|
"str": "hello world",
|
|
|
|
"nill": null,
|
|
|
|
"bool": false
|
|
|
|
})
|
|
|
|
|
|
|
|
t.is(pathExists(eson, ['obj', 'arr', 2, 'first']), true)
|
|
|
|
t.is(pathExists(eson, ['obj', 'foo']), false)
|
|
|
|
t.is(pathExists(eson, ['obj', 'foo', 'bar']), false)
|
|
|
|
t.is(pathExists(eson, []), true)
|
2016-09-09 17:01:06 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
test('parseJSONPointer', t => {
|
|
|
|
t.deepEqual(parseJSONPointer('/obj/a'), ['obj', 'a'])
|
|
|
|
t.deepEqual(parseJSONPointer('/arr/-'), ['arr', '-'])
|
|
|
|
t.deepEqual(parseJSONPointer('/foo/~1~0 ~0~1'), ['foo', '/~ ~/'])
|
2016-10-18 02:38:35 +08:00
|
|
|
t.deepEqual(parseJSONPointer('/obj'), ['obj'])
|
2016-10-28 17:04:06 +08:00
|
|
|
t.deepEqual(parseJSONPointer('/'), [''])
|
|
|
|
t.deepEqual(parseJSONPointer(''), [])
|
2016-09-09 17:01:06 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
test('compileJSONPointer', t => {
|
|
|
|
t.deepEqual(compileJSONPointer(['foo', 'bar']), '/foo/bar')
|
|
|
|
t.deepEqual(compileJSONPointer(['foo', '/~ ~/']), '/foo/~1~0 ~0~1')
|
2016-10-28 17:04:06 +08:00
|
|
|
t.deepEqual(compileJSONPointer(['']), '/')
|
|
|
|
t.deepEqual(compileJSONPointer([]), '')
|
2016-09-09 17:01:06 +08:00
|
|
|
})
|
|
|
|
|
2016-11-12 21:10:10 +08:00
|
|
|
test('add and remove errors', t => {
|
2017-12-14 21:30:02 +08:00
|
|
|
const eson = jsonToEson({
|
|
|
|
"obj": {
|
|
|
|
"arr": [1,2, {"first":3,"last":4}]
|
|
|
|
},
|
|
|
|
"str": "hello world",
|
|
|
|
"nill": null,
|
|
|
|
"bool": false
|
|
|
|
})
|
|
|
|
|
2017-09-22 18:24:13 +08:00
|
|
|
const jsonSchemaErrors = [
|
|
|
|
{dataPath: '/obj/arr/2/last', message: 'String expected'},
|
|
|
|
{dataPath: '/nill', message: 'Null expected'}
|
|
|
|
]
|
|
|
|
|
2017-12-14 23:40:55 +08:00
|
|
|
const actual1 = applyErrors(eson, jsonSchemaErrors)
|
2017-12-14 21:30:02 +08:00
|
|
|
|
|
|
|
let expected = eson
|
2017-12-15 21:02:42 +08:00
|
|
|
expected = setIn(expected, ['obj', 'arr', '2', 'last', META, 'error'], jsonSchemaErrors[0])
|
|
|
|
expected = setIn(expected, ['nill', META, 'error'], jsonSchemaErrors[1])
|
|
|
|
assertDeepEqualEson(t, actual1, expected)
|
2017-09-22 18:24:13 +08:00
|
|
|
|
2017-12-14 21:30:02 +08:00
|
|
|
// re-applying the same errors should not change eson
|
2017-12-14 23:40:55 +08:00
|
|
|
const actual2 = applyErrors(actual1, jsonSchemaErrors)
|
2017-12-14 21:30:02 +08:00
|
|
|
t.is(actual2, actual1)
|
2017-09-22 18:24:13 +08:00
|
|
|
|
2017-12-14 21:30:02 +08:00
|
|
|
// clear errors
|
2017-12-14 23:40:55 +08:00
|
|
|
const actual3 = applyErrors(actual2, [])
|
2017-12-15 21:02:42 +08:00
|
|
|
assertDeepEqualEson(t, actual3, eson)
|
2017-12-14 21:30:02 +08:00
|
|
|
t.is(actual3.str, eson.str) // shouldn't have touched values not affected by the errors
|
2016-11-20 03:44:58 +08:00
|
|
|
})
|
|
|
|
|
2016-11-20 04:21:09 +08:00
|
|
|
test('search', t => {
|
2017-12-13 23:48:22 +08:00
|
|
|
const eson = jsonToEson({
|
|
|
|
"obj": {
|
|
|
|
"arr": [1,2, {"first":3,"last":4}]
|
|
|
|
},
|
|
|
|
"str": "hello world",
|
|
|
|
"nill": null,
|
|
|
|
"bool": false
|
|
|
|
})
|
2017-12-16 21:13:52 +08:00
|
|
|
const result = search(eson, 'L')
|
|
|
|
const esonWithSearch = result.eson
|
|
|
|
const matches = result.searchResult.matches
|
|
|
|
const active = result.searchResult.active
|
2016-11-28 04:16:17 +08:00
|
|
|
|
2017-12-13 23:48:22 +08:00
|
|
|
t.deepEqual(matches, [
|
2017-12-16 02:57:21 +08:00
|
|
|
{path: ['obj', 'arr', '2', 'last'], area: 'property'},
|
2017-11-03 21:23:04 +08:00
|
|
|
{path: ['str'], area: 'value'},
|
|
|
|
{path: ['nill'], area: 'property'},
|
|
|
|
{path: ['nill'], area: 'value'},
|
|
|
|
{path: ['bool'], area: 'property'},
|
|
|
|
{path: ['bool'], area: 'value'}
|
2016-11-28 04:16:17 +08:00
|
|
|
])
|
2017-12-16 02:57:21 +08:00
|
|
|
t.deepEqual(active, {path: ['obj', 'arr', '2', 'last'], area: 'property'})
|
2016-11-28 04:16:17 +08:00
|
|
|
|
2017-12-13 23:48:22 +08:00
|
|
|
let expected = esonWithSearch
|
2017-12-15 21:02:42 +08:00
|
|
|
expected = setIn(expected, ['obj', 'arr', '2', 'last', META, 'searchProperty'], 'active')
|
|
|
|
expected = setIn(expected, ['str', META, 'searchValue'], 'normal')
|
|
|
|
expected = setIn(expected, ['nill', META, 'searchProperty'], 'normal')
|
|
|
|
expected = setIn(expected, ['nill', META, 'searchValue'], 'normal')
|
|
|
|
expected = setIn(expected, ['bool', META, 'searchProperty'], 'normal')
|
|
|
|
expected = setIn(expected, ['bool', META, 'searchValue'], 'normal')
|
|
|
|
|
|
|
|
assertDeepEqualEson(t, esonWithSearch, expected)
|
2016-11-12 21:10:10 +08:00
|
|
|
})
|
2016-12-30 21:05:11 +08:00
|
|
|
|
|
|
|
test('nextSearchResult', t => {
|
2017-12-13 23:48:22 +08:00
|
|
|
const eson = jsonToEson({
|
|
|
|
"obj": {
|
|
|
|
"arr": [1,2, {"first":3,"last":4}]
|
|
|
|
},
|
|
|
|
"str": "hello world",
|
|
|
|
"nill": null,
|
|
|
|
"bool": false
|
|
|
|
})
|
2017-12-16 21:13:52 +08:00
|
|
|
const first = search(eson, 'A')
|
2016-12-30 21:05:11 +08:00
|
|
|
|
2017-12-16 21:13:52 +08:00
|
|
|
t.deepEqual(first.searchResult.matches, [
|
2017-12-13 23:48:22 +08:00
|
|
|
{path: ['obj', 'arr'], area: 'property'},
|
2017-12-16 02:57:21 +08:00
|
|
|
{path: ['obj', 'arr', '2', 'last'], area: 'property'},
|
2017-12-13 23:48:22 +08:00
|
|
|
{path: ['bool'], area: 'value'}
|
|
|
|
])
|
2016-12-30 21:05:11 +08:00
|
|
|
|
2017-12-16 21:13:52 +08:00
|
|
|
t.deepEqual(first.searchResult.active, {path: ['obj', 'arr'], area: 'property'})
|
|
|
|
t.is(getIn(first.eson, ['obj', 'arr', META, 'searchProperty']), 'active')
|
|
|
|
t.is(getIn(first.eson, ['obj', 'arr', '2', 'last', META, 'searchProperty']), 'normal')
|
|
|
|
t.is(getIn(first.eson, ['bool', META, 'searchValue']), 'normal')
|
2017-12-13 23:48:22 +08:00
|
|
|
|
2017-12-16 21:13:52 +08:00
|
|
|
const second = nextSearchResult(first.eson, first.searchResult)
|
|
|
|
t.deepEqual(second.searchResult.active, {path: ['obj', 'arr', '2', 'last'], area: 'property'})
|
2017-12-15 21:02:42 +08:00
|
|
|
t.is(getIn(second.eson, ['obj', 'arr', META, 'searchProperty']), 'normal')
|
2017-12-16 02:57:21 +08:00
|
|
|
t.is(getIn(second.eson, ['obj', 'arr', '2', 'last', META, 'searchProperty']), 'active')
|
2017-12-15 21:02:42 +08:00
|
|
|
t.is(getIn(second.eson, ['bool', META, 'searchValue']), 'normal')
|
2017-12-13 23:48:22 +08:00
|
|
|
|
2017-12-16 21:13:52 +08:00
|
|
|
const third = nextSearchResult(second.eson, second.searchResult)
|
|
|
|
t.deepEqual(third.searchResult.active, {path: ['bool'], area: 'value'})
|
2017-12-15 21:02:42 +08:00
|
|
|
t.is(getIn(third.eson, ['obj', 'arr', META, 'searchProperty']), 'normal')
|
2017-12-16 02:57:21 +08:00
|
|
|
t.is(getIn(third.eson, ['obj', 'arr', '2', 'last', META, 'searchProperty']), 'normal')
|
2017-12-15 21:02:42 +08:00
|
|
|
t.is(getIn(third.eson, ['bool', META, 'searchValue']), 'active')
|
2017-12-13 23:48:22 +08:00
|
|
|
|
2017-12-16 21:13:52 +08:00
|
|
|
const wrappedAround = nextSearchResult(third.eson, third.searchResult)
|
|
|
|
t.deepEqual(wrappedAround.searchResult.active, {path: ['obj', 'arr'], area: 'property'})
|
2017-12-15 21:02:42 +08:00
|
|
|
t.is(getIn(wrappedAround.eson, ['obj', 'arr', META, 'searchProperty']), 'active')
|
2017-12-16 02:57:21 +08:00
|
|
|
t.is(getIn(wrappedAround.eson, ['obj', 'arr', '2', 'last', META, 'searchProperty']), 'normal')
|
2017-12-15 21:02:42 +08:00
|
|
|
t.is(getIn(wrappedAround.eson, ['bool', META, 'searchValue']), 'normal')
|
2016-12-30 21:05:11 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
test('previousSearchResult', t => {
|
2017-12-13 23:48:22 +08:00
|
|
|
const eson = jsonToEson({
|
|
|
|
"obj": {
|
|
|
|
"arr": [1,2, {"first":3,"last":4}]
|
|
|
|
},
|
|
|
|
"str": "hello world",
|
|
|
|
"nill": null,
|
|
|
|
"bool": false
|
|
|
|
})
|
2017-12-16 21:13:52 +08:00
|
|
|
const init = search(eson, 'A')
|
2016-12-30 21:05:11 +08:00
|
|
|
|
2017-12-16 21:13:52 +08:00
|
|
|
t.deepEqual(init.searchResult.matches, [
|
2017-12-13 23:48:22 +08:00
|
|
|
{path: ['obj', 'arr'], area: 'property'},
|
2017-12-16 02:57:21 +08:00
|
|
|
{path: ['obj', 'arr', '2', 'last'], area: 'property'},
|
2017-12-13 23:48:22 +08:00
|
|
|
{path: ['bool'], area: 'value'}
|
|
|
|
])
|
2016-12-30 21:05:11 +08:00
|
|
|
|
2017-12-16 21:13:52 +08:00
|
|
|
t.deepEqual(init.searchResult.active, {path: ['obj', 'arr'], area: 'property'})
|
|
|
|
t.is(getIn(init.eson, ['obj', 'arr', META, 'searchProperty']), 'active')
|
|
|
|
t.is(getIn(init.eson, ['obj', 'arr', '2', 'last', META, 'searchProperty']), 'normal')
|
|
|
|
t.is(getIn(init.eson, ['bool', META, 'searchValue']), 'normal')
|
2017-12-13 23:48:22 +08:00
|
|
|
|
2017-12-16 21:13:52 +08:00
|
|
|
const third = previousSearchResult(init.eson, init.searchResult)
|
|
|
|
t.deepEqual(third.searchResult.active, {path: ['bool'], area: 'value'})
|
2017-12-15 21:02:42 +08:00
|
|
|
t.is(getIn(third.eson, ['obj', 'arr', META, 'searchProperty']), 'normal')
|
2017-12-16 02:57:21 +08:00
|
|
|
t.is(getIn(third.eson, ['obj', 'arr', '2', 'last', META, 'searchProperty']), 'normal')
|
2017-12-15 21:02:42 +08:00
|
|
|
t.is(getIn(third.eson, ['bool', META, 'searchValue']), 'active')
|
2017-12-13 23:48:22 +08:00
|
|
|
|
2017-12-16 21:13:52 +08:00
|
|
|
const second = previousSearchResult(third.eson, third.searchResult)
|
|
|
|
t.deepEqual(second.searchResult.active, {path: ['obj', 'arr', '2', 'last'], area: 'property'})
|
2017-12-15 21:02:42 +08:00
|
|
|
t.is(getIn(second.eson, ['obj', 'arr', META, 'searchProperty']), 'normal')
|
2017-12-16 02:57:21 +08:00
|
|
|
t.is(getIn(second.eson, ['obj', 'arr', '2', 'last', META, 'searchProperty']), 'active')
|
2017-12-15 21:02:42 +08:00
|
|
|
t.is(getIn(second.eson, ['bool', META, 'searchValue']), 'normal')
|
2017-12-13 23:48:22 +08:00
|
|
|
|
2017-12-16 21:13:52 +08:00
|
|
|
const first = previousSearchResult(second.eson, second.searchResult)
|
|
|
|
t.deepEqual(first.searchResult.active, {path: ['obj', 'arr'], area: 'property'})
|
2017-12-15 21:02:42 +08:00
|
|
|
t.is(getIn(first.eson, ['obj', 'arr', META, 'searchProperty']), 'active')
|
2017-12-16 02:57:21 +08:00
|
|
|
t.is(getIn(first.eson, ['obj', 'arr', '2', 'last', META, 'searchProperty']), 'normal')
|
2017-12-15 21:02:42 +08:00
|
|
|
t.is(getIn(first.eson, ['bool', META, 'searchValue']), 'normal')
|
2016-12-30 21:05:11 +08:00
|
|
|
})
|
2017-01-06 20:57:16 +08:00
|
|
|
|
2017-09-22 17:38:23 +08:00
|
|
|
test('selection (object)', t => {
|
2017-12-14 23:40:55 +08:00
|
|
|
const eson = jsonToEson({
|
|
|
|
"obj": {
|
|
|
|
"arr": [1,2, {"first":3,"last":4}]
|
|
|
|
},
|
|
|
|
"str": "hello world",
|
|
|
|
"nill": null,
|
|
|
|
"bool": false
|
|
|
|
})
|
2017-09-22 17:38:23 +08:00
|
|
|
const selection = {
|
2017-11-22 17:12:59 +08:00
|
|
|
start: ['obj', 'arr', '2', 'last'],
|
|
|
|
end: ['nill']
|
2017-09-22 17:38:23 +08:00
|
|
|
}
|
|
|
|
|
2017-12-14 23:40:55 +08:00
|
|
|
const actual = applySelection(eson, selection)
|
2017-09-22 18:24:13 +08:00
|
|
|
|
2017-12-14 23:40:55 +08:00
|
|
|
let expected = eson
|
2017-12-15 21:02:42 +08:00
|
|
|
expected = setIn(expected, ['obj', META, 'selected'], SELECTED)
|
|
|
|
expected = setIn(expected, ['str', META, 'selected'], SELECTED)
|
|
|
|
expected = setIn(expected, ['nill', META, 'selected'], SELECTED_END)
|
|
|
|
assertDeepEqualEson(t, actual, expected)
|
2017-12-14 23:40:55 +08:00
|
|
|
|
|
|
|
// test whether old selection results are cleaned up
|
|
|
|
const selection2 = {
|
|
|
|
start: ['nill'],
|
|
|
|
end: ['bool']
|
|
|
|
}
|
|
|
|
const actual2 = applySelection(actual, selection2)
|
|
|
|
let expected2 = eson
|
2017-12-15 21:02:42 +08:00
|
|
|
expected2 = setIn(expected2, ['nill', META, 'selected'], SELECTED)
|
|
|
|
expected2 = setIn(expected2, ['bool', META, 'selected'], SELECTED_END)
|
|
|
|
assertDeepEqualEson(t, actual2, expected2)
|
2017-09-22 17:38:23 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
test('selection (array)', t => {
|
2017-12-14 23:40:55 +08:00
|
|
|
const eson = jsonToEson({
|
|
|
|
"obj": {
|
|
|
|
"arr": [1,2, {"first":3,"last":4}]
|
|
|
|
},
|
|
|
|
"str": "hello world",
|
|
|
|
"nill": null,
|
|
|
|
"bool": false
|
|
|
|
})
|
2017-09-22 17:38:23 +08:00
|
|
|
const selection = {
|
2017-11-22 17:12:59 +08:00
|
|
|
start: ['obj', 'arr', '1'],
|
|
|
|
end: ['obj', 'arr', '0'] // note the "wrong" order of start and end
|
2017-09-22 17:38:23 +08:00
|
|
|
}
|
|
|
|
|
2017-12-14 23:40:55 +08:00
|
|
|
const actual = applySelection(eson, selection)
|
2017-09-22 17:38:23 +08:00
|
|
|
|
2017-12-14 23:40:55 +08:00
|
|
|
let expected = eson
|
2017-12-15 21:02:42 +08:00
|
|
|
expected = setIn(expected, ['obj', 'arr', '0', META, 'selected'], SELECTED_END)
|
|
|
|
expected = setIn(expected, ['obj', 'arr', '1', META, 'selected'], SELECTED)
|
2017-09-22 18:24:13 +08:00
|
|
|
|
2017-12-15 21:02:42 +08:00
|
|
|
assertDeepEqualEson(t, actual, expected)
|
2017-09-22 17:38:23 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
test('selection (value)', t => {
|
2017-12-14 23:40:55 +08:00
|
|
|
const eson = jsonToEson({
|
|
|
|
"obj": {
|
|
|
|
"arr": [1,2, {"first":3,"last":4}]
|
|
|
|
},
|
|
|
|
"str": "hello world",
|
|
|
|
"nill": null,
|
|
|
|
"bool": false
|
|
|
|
})
|
2017-09-22 17:38:23 +08:00
|
|
|
const selection = {
|
2017-11-22 17:12:59 +08:00
|
|
|
start: ['obj', 'arr', '2', 'first'],
|
|
|
|
end: ['obj', 'arr', '2', 'first']
|
2017-09-22 17:38:23 +08:00
|
|
|
}
|
|
|
|
|
2017-12-14 23:40:55 +08:00
|
|
|
const actual = applySelection(eson, selection)
|
2017-12-15 21:02:42 +08:00
|
|
|
const expected = setIn(eson, ['obj', 'arr', '2', 'first', META, 'selected'], SELECTED_END)
|
|
|
|
assertDeepEqualEson(t, actual, expected)
|
2017-09-22 17:38:23 +08:00
|
|
|
})
|
|
|
|
|
2017-09-29 17:08:44 +08:00
|
|
|
test('selection (node)', t => {
|
2017-12-14 23:40:55 +08:00
|
|
|
const eson = jsonToEson({
|
|
|
|
"obj": {
|
|
|
|
"arr": [1,2, {"first":3,"last":4}]
|
|
|
|
},
|
|
|
|
"str": "hello world",
|
|
|
|
"nill": null,
|
|
|
|
"bool": false
|
|
|
|
})
|
2017-09-22 17:38:23 +08:00
|
|
|
const selection = {
|
2017-11-22 17:12:59 +08:00
|
|
|
start: ['obj', 'arr'],
|
|
|
|
end: ['obj', 'arr']
|
2017-09-22 17:38:23 +08:00
|
|
|
}
|
|
|
|
|
2017-12-14 23:40:55 +08:00
|
|
|
const actual = applySelection(eson, selection)
|
2017-12-15 21:02:42 +08:00
|
|
|
const expected = setIn(eson, ['obj', 'arr', META, 'selected'], SELECTED_END)
|
|
|
|
assertDeepEqualEson(t, actual, expected)
|
2017-09-22 17:38:23 +08:00
|
|
|
})
|
|
|
|
|
2017-09-30 03:52:17 +08:00
|
|
|
test('pathsFromSelection (object)', t => {
|
2017-12-16 03:34:07 +08:00
|
|
|
const eson = jsonToEson({
|
|
|
|
"obj": {
|
|
|
|
"arr": [1,2, {"first":3,"last":4}]
|
|
|
|
},
|
|
|
|
"str": "hello world",
|
|
|
|
"nill": null,
|
|
|
|
"bool": false
|
|
|
|
})
|
2017-09-30 03:52:17 +08:00
|
|
|
const selection = {
|
2017-11-22 17:12:59 +08:00
|
|
|
start: ['obj', 'arr', '2', 'last'],
|
|
|
|
end: ['nill']
|
2017-09-30 03:52:17 +08:00
|
|
|
}
|
|
|
|
|
2017-12-16 03:34:07 +08:00
|
|
|
t.deepEqual(pathsFromSelection(eson, selection), [
|
2017-09-30 03:52:17 +08:00
|
|
|
['obj'],
|
|
|
|
['str'],
|
|
|
|
['nill']
|
|
|
|
])
|
|
|
|
})
|
|
|
|
|
|
|
|
test('pathsFromSelection (array)', t => {
|
2017-12-16 03:34:07 +08:00
|
|
|
const eson = jsonToEson({
|
|
|
|
"obj": {
|
|
|
|
"arr": [1,2, {"first":3,"last":4}]
|
|
|
|
},
|
|
|
|
"str": "hello world",
|
|
|
|
"nill": null,
|
|
|
|
"bool": false
|
|
|
|
})
|
2017-09-30 03:52:17 +08:00
|
|
|
const selection = {
|
2017-11-22 17:12:59 +08:00
|
|
|
start: ['obj', 'arr', '1'],
|
|
|
|
end: ['obj', 'arr', '0'] // note the "wrong" order of start and end
|
2017-09-30 03:52:17 +08:00
|
|
|
}
|
|
|
|
|
2017-12-16 03:34:07 +08:00
|
|
|
t.deepEqual(pathsFromSelection(eson, selection), [
|
2017-09-30 03:52:17 +08:00
|
|
|
['obj', 'arr', '0'],
|
|
|
|
['obj', 'arr', '1']
|
|
|
|
])
|
|
|
|
})
|
|
|
|
|
|
|
|
test('pathsFromSelection (value)', t => {
|
2017-12-16 03:34:07 +08:00
|
|
|
const eson = jsonToEson({
|
|
|
|
"obj": {
|
|
|
|
"arr": [1,2, {"first":3,"last":4}]
|
|
|
|
},
|
|
|
|
"str": "hello world",
|
|
|
|
"nill": null,
|
|
|
|
"bool": false
|
|
|
|
})
|
2017-09-30 03:52:17 +08:00
|
|
|
const selection = {
|
2017-11-22 17:12:59 +08:00
|
|
|
start: ['obj', 'arr', '2', 'first'],
|
|
|
|
end: ['obj', 'arr', '2', 'first']
|
2017-09-30 03:52:17 +08:00
|
|
|
}
|
|
|
|
|
2017-12-16 03:34:07 +08:00
|
|
|
t.deepEqual(pathsFromSelection(eson, selection), [
|
2017-09-30 03:52:17 +08:00
|
|
|
['obj', 'arr', '2', 'first'],
|
|
|
|
])
|
|
|
|
})
|
|
|
|
|
2017-11-22 17:12:59 +08:00
|
|
|
test('pathsFromSelection (before)', t => {
|
2017-12-16 03:34:07 +08:00
|
|
|
const eson = jsonToEson({
|
|
|
|
"obj": {
|
|
|
|
"arr": [1,2, {"first":3,"last":4}]
|
|
|
|
},
|
|
|
|
"str": "hello world",
|
|
|
|
"nill": null,
|
|
|
|
"bool": false
|
|
|
|
})
|
2017-11-22 17:12:59 +08:00
|
|
|
const selection = {
|
|
|
|
before: ['obj', 'arr', '2', 'first']
|
|
|
|
}
|
|
|
|
|
2017-12-16 03:34:07 +08:00
|
|
|
t.deepEqual(pathsFromSelection(eson, selection), [])
|
2017-11-22 17:12:59 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
test('pathsFromSelection (after)', t => {
|
2017-12-16 03:34:07 +08:00
|
|
|
const eson = jsonToEson({
|
|
|
|
"obj": {
|
|
|
|
"arr": [1,2, {"first":3,"last":4}]
|
|
|
|
},
|
|
|
|
"str": "hello world",
|
|
|
|
"nill": null,
|
|
|
|
"bool": false
|
|
|
|
})
|
2017-11-22 17:12:59 +08:00
|
|
|
const selection = {
|
|
|
|
after: ['obj', 'arr', '2', 'first']
|
|
|
|
}
|
|
|
|
|
2017-12-16 03:34:07 +08:00
|
|
|
t.deepEqual(pathsFromSelection(eson, selection), [])
|
2017-11-22 17:12:59 +08:00
|
|
|
})
|
|
|
|
|
2017-01-06 20:57:16 +08:00
|
|
|
// helper function to print JSON in the console
|
|
|
|
function printJSON (json, message = null) {
|
|
|
|
if (message) {
|
|
|
|
console.log(message)
|
|
|
|
}
|
|
|
|
console.log(JSON.stringify(json, null, 2))
|
2017-09-08 17:14:41 +08:00
|
|
|
}
|
2017-09-22 18:24:13 +08:00
|
|
|
|
2017-12-15 21:02:42 +08:00
|
|
|
function printESON (eson, message = null) {
|
|
|
|
if (message) {
|
|
|
|
console.log(message)
|
|
|
|
}
|
|
|
|
|
|
|
|
let data = []
|
|
|
|
|
|
|
|
transform(eson, function (value, path) {
|
|
|
|
// const strPath = padEnd(, 20)
|
|
|
|
// console.log(`${strPath} ${'value' in value[META] ? value[META].value : ''} ${JSON.stringify(value[META])}`)
|
|
|
|
|
|
|
|
data.push({
|
|
|
|
path: '[' + path.join(', ') + ']',
|
|
|
|
value: repeat(' ', path.length) + (value[META].type === 'Object'
|
|
|
|
? '{...}'
|
|
|
|
: value[META].type === 'Array'
|
|
|
|
? '[...]'
|
|
|
|
: JSON.stringify(value[META].value)),
|
|
|
|
meta: JSON.stringify(value[META])
|
|
|
|
})
|
|
|
|
|
|
|
|
return value
|
|
|
|
})
|
|
|
|
|
|
|
|
console.table(data)
|
|
|
|
}
|
|
|
|
|
2017-09-30 03:52:17 +08:00
|
|
|
// helper function to load a JSON file
|
2017-09-22 18:24:13 +08:00
|
|
|
function loadJSON (filename) {
|
|
|
|
return JSON.parse(readFileSync(__dirname + '/' + filename, 'utf-8'))
|
|
|
|
}
|