Implemented function search
This commit is contained in:
parent
96186b836a
commit
e5e61b71e3
|
@ -461,7 +461,7 @@ export function expand (data, callback, expanded) {
|
||||||
// console.log('expand', callback, expand)
|
// console.log('expand', callback, expand)
|
||||||
|
|
||||||
if (typeof callback === 'function') {
|
if (typeof callback === 'function') {
|
||||||
return transform (data, function (value, path, root) {
|
return transform (data, function (value, path) {
|
||||||
if (value.type === 'Array' || value.type === 'Object') {
|
if (value.type === 'Array' || value.type === 'Object') {
|
||||||
if (callback(path)) {
|
if (callback(path)) {
|
||||||
return setIn(value, ['expanded'], expanded)
|
return setIn(value, ['expanded'], expanded)
|
||||||
|
@ -503,18 +503,51 @@ export function addErrors (data, errors) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merge one or multiple errors (for example JSON schema errors)
|
* Search some text in all properties and values
|
||||||
* into the data
|
|
||||||
*
|
*
|
||||||
* @param {JSONData} data
|
* @param {JSONData} data
|
||||||
* @param {string} search
|
* @param {string} text
|
||||||
|
* @return {JSONData} Returns an updated `data` object containing the search results
|
||||||
*/
|
*/
|
||||||
export function setSearch (data, search) {
|
export function search (data, text) {
|
||||||
let updatedData = data
|
return transform(data, function (value) {
|
||||||
|
// search in values
|
||||||
|
if (value.type === 'value') {
|
||||||
|
if (containsCaseInsensitive(value.value, text)) {
|
||||||
|
return setIn(value, ['search'], true)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return deleteIn(value, ['search'])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: traverse over the data, add a field search: 'field'|'value' to all matching fields/values
|
// search object property names
|
||||||
|
if (value.type === 'Object') {
|
||||||
|
let updatedProps = value.props
|
||||||
|
updatedProps.forEach((prop, index) => {
|
||||||
|
if (containsCaseInsensitive(prop.name, text)) {
|
||||||
|
updatedProps = setIn(updatedProps, [index, 'search'], true)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
updatedProps = deleteIn(updatedProps, [index, 'search'])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
return updatedData
|
return setIn(value, ['props'], updatedProps)
|
||||||
|
}
|
||||||
|
|
||||||
|
return value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do a case insensitive search for a search text in a text
|
||||||
|
* @param {String} text
|
||||||
|
* @param {String} search
|
||||||
|
* @return {boolean} Returns true if `search` is found in `text`
|
||||||
|
*/
|
||||||
|
export function containsCaseInsensitive (text, search) {
|
||||||
|
return String(text).toLowerCase().indexOf(search.toLowerCase()) !== -1
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -543,8 +576,8 @@ function recurseTransform (value, path, root, callback) {
|
||||||
let updatedItems = updatedValue.items
|
let updatedItems = updatedValue.items
|
||||||
|
|
||||||
updatedValue.items.forEach((item, index) => {
|
updatedValue.items.forEach((item, index) => {
|
||||||
updatedItems = setIn(updatedItems, [index],
|
const updatedItem = recurseTransform(item, path.concat(String(index)), root, callback)
|
||||||
recurseTransform(item, path.concat(String(index)), root, callback))
|
updatedItems = setIn(updatedItems, [index], updatedItem)
|
||||||
})
|
})
|
||||||
|
|
||||||
updatedValue = setIn(updatedValue, ['items'], updatedItems)
|
updatedValue = setIn(updatedValue, ['items'], updatedItems)
|
||||||
|
@ -556,8 +589,8 @@ function recurseTransform (value, path, root, callback) {
|
||||||
let updatedProps = updatedValue.props
|
let updatedProps = updatedValue.props
|
||||||
|
|
||||||
updatedValue.props.forEach((prop, index) => {
|
updatedValue.props.forEach((prop, index) => {
|
||||||
updatedProps = setIn(updatedProps, [index, 'value'],
|
const updatedItem = recurseTransform(prop.value, path.concat(prop.name), root, callback)
|
||||||
recurseTransform(prop.value, path.concat(prop.name), root, callback))
|
updatedProps = setIn(updatedProps, [index, 'value'], updatedItem)
|
||||||
})
|
})
|
||||||
|
|
||||||
updatedValue = setIn(updatedValue, ['props'], updatedProps)
|
updatedValue = setIn(updatedValue, ['props'], updatedProps)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import test from 'ava';
|
import test from 'ava';
|
||||||
import {
|
import {
|
||||||
jsonToData, dataToJson, patchData, pathExists, transform,
|
jsonToData, dataToJson, patchData, pathExists, transform, search,
|
||||||
parseJSONPointer, compileJSONPointer,
|
parseJSONPointer, compileJSONPointer,
|
||||||
expand, addErrors
|
expand, addErrors
|
||||||
} from '../src/jsonData'
|
} from '../src/jsonData'
|
||||||
|
@ -237,6 +237,194 @@ const JSON_DATA_EXAMPLE_COLLAPSED_2 = {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// after search for 'O' (case insensitive)
|
||||||
|
const JSON_DATA_EXAMPLE_SEARCH_1 = {
|
||||||
|
type: 'Object',
|
||||||
|
expanded: true,
|
||||||
|
props: [
|
||||||
|
{
|
||||||
|
name: 'obj',
|
||||||
|
search: true,
|
||||||
|
value: {
|
||||||
|
type: 'Object',
|
||||||
|
expanded: true,
|
||||||
|
props: [
|
||||||
|
{
|
||||||
|
name: 'arr',
|
||||||
|
value: {
|
||||||
|
type: 'Array',
|
||||||
|
expanded: true,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
type: 'value',
|
||||||
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'value',
|
||||||
|
value: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'Object',
|
||||||
|
expanded: true,
|
||||||
|
props: [
|
||||||
|
{
|
||||||
|
name: 'a',
|
||||||
|
value: {
|
||||||
|
type: 'value',
|
||||||
|
value: 3
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'b',
|
||||||
|
value: {
|
||||||
|
type: 'value',
|
||||||
|
value: 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'str',
|
||||||
|
value: {
|
||||||
|
type: 'value',
|
||||||
|
value: 'hello world',
|
||||||
|
search: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'nill',
|
||||||
|
value: {
|
||||||
|
type: 'value',
|
||||||
|
value: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'bool',
|
||||||
|
search: true,
|
||||||
|
value: {
|
||||||
|
type: 'value',
|
||||||
|
value: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// after search for '2'
|
||||||
|
const JSON_DATA_EXAMPLE_SEARCH_2 = {
|
||||||
|
type: 'Object',
|
||||||
|
expanded: true,
|
||||||
|
props: [
|
||||||
|
{
|
||||||
|
name: 'obj',
|
||||||
|
value: {
|
||||||
|
type: 'Object',
|
||||||
|
expanded: true,
|
||||||
|
props: [
|
||||||
|
{
|
||||||
|
name: 'arr',
|
||||||
|
value: {
|
||||||
|
type: 'Array',
|
||||||
|
expanded: true,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
type: 'value',
|
||||||
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'value',
|
||||||
|
value: 2,
|
||||||
|
search: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'Object',
|
||||||
|
expanded: true,
|
||||||
|
props: [
|
||||||
|
{
|
||||||
|
name: 'a',
|
||||||
|
value: {
|
||||||
|
type: 'value',
|
||||||
|
value: 3
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'b',
|
||||||
|
value: {
|
||||||
|
type: 'value',
|
||||||
|
value: 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'str',
|
||||||
|
value: {
|
||||||
|
type: 'value',
|
||||||
|
value: 'hello world'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'nill',
|
||||||
|
value: {
|
||||||
|
type: 'value',
|
||||||
|
value: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'bool',
|
||||||
|
value: {
|
||||||
|
type: 'value',
|
||||||
|
value: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
const JSON_DATA_SMALL = {
|
||||||
|
type: 'Object',
|
||||||
|
props: [
|
||||||
|
{
|
||||||
|
name: 'obj',
|
||||||
|
value: {
|
||||||
|
type: 'Object',
|
||||||
|
props: [
|
||||||
|
{
|
||||||
|
name: 'a',
|
||||||
|
value: {
|
||||||
|
type: 'value',
|
||||||
|
value: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'arr',
|
||||||
|
value: {
|
||||||
|
type: 'Array',
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
type: 'value',
|
||||||
|
value: 3
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const JSON_SCHEMA_ERRORS = [
|
const JSON_SCHEMA_ERRORS = [
|
||||||
{dataPath: '/obj/arr/2/b', message: 'String expected'},
|
{dataPath: '/obj/arr/2/b', message: 'String expected'},
|
||||||
{dataPath: '/nill', message: 'Null expected'}
|
{dataPath: '/nill', message: 'Null expected'}
|
||||||
|
@ -740,43 +928,10 @@ test('add and remove errors', t => {
|
||||||
|
|
||||||
test('transform', t => {
|
test('transform', t => {
|
||||||
// {obj: {a: 2}, arr: [3]}
|
// {obj: {a: 2}, arr: [3]}
|
||||||
const data = {
|
|
||||||
type: 'Object',
|
|
||||||
props: [
|
|
||||||
{
|
|
||||||
name: 'obj',
|
|
||||||
value: {
|
|
||||||
type: 'Object',
|
|
||||||
props: [
|
|
||||||
{
|
|
||||||
name: 'a',
|
|
||||||
value: {
|
|
||||||
type: 'value',
|
|
||||||
value: 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'arr',
|
|
||||||
value: {
|
|
||||||
type: 'Array',
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
type: 'value',
|
|
||||||
value: 3
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
let log = []
|
let log = []
|
||||||
const transformed = transform(data, function (value, path, root) {
|
const transformed = transform(JSON_DATA_SMALL, function (value, path, root) {
|
||||||
t.truthy(root === data)
|
t.truthy(root === JSON_DATA_SMALL)
|
||||||
|
|
||||||
log.push([value, path, root])
|
log.push([value, path, root])
|
||||||
|
|
||||||
|
@ -792,21 +947,31 @@ test('transform', t => {
|
||||||
// console.log('transformed', JSON.stringify(transformed, null, 2))
|
// console.log('transformed', JSON.stringify(transformed, null, 2))
|
||||||
|
|
||||||
const EXPECTED_LOG = [
|
const EXPECTED_LOG = [
|
||||||
[data, [], data],
|
[JSON_DATA_SMALL, [], JSON_DATA_SMALL],
|
||||||
[data.props[0].value, ['obj'], data],
|
[JSON_DATA_SMALL.props[0].value, ['obj'], JSON_DATA_SMALL],
|
||||||
[data.props[0].value.props[0].value, ['obj', 'a'], data],
|
[JSON_DATA_SMALL.props[0].value.props[0].value, ['obj', 'a'], JSON_DATA_SMALL],
|
||||||
[data.props[1].value, ['arr'], data],
|
[JSON_DATA_SMALL.props[1].value, ['arr'], JSON_DATA_SMALL],
|
||||||
[data.props[1].value.items[0], ['arr', '0'], data],
|
[JSON_DATA_SMALL.props[1].value.items[0], ['arr', '0'], JSON_DATA_SMALL],
|
||||||
]
|
]
|
||||||
|
|
||||||
// log.forEach((row, index) => {
|
// log.forEach((row, index) => {
|
||||||
// t.deepEqual(log[index], EXPECTED_LOG[index], 'should have equal log at index ' + index )
|
// t.deepEqual(log[index], EXPECTED_LOG[index], 'should have equal log at index ' + index )
|
||||||
// })
|
// })
|
||||||
t.deepEqual(log, EXPECTED_LOG)
|
t.deepEqual(log, EXPECTED_LOG)
|
||||||
t.truthy(transformed !== data)
|
t.truthy(transformed !== JSON_DATA_SMALL)
|
||||||
t.truthy(transformed.props[0].value !== data.props[0].value)
|
t.truthy(transformed.props[0].value !== JSON_DATA_SMALL.props[0].value)
|
||||||
t.truthy(transformed.props[0].value.props[0].value !== data.props[0].value.props[0].value)
|
t.truthy(transformed.props[0].value.props[0].value !== JSON_DATA_SMALL.props[0].value.props[0].value)
|
||||||
t.truthy(data.props[1].value === data.props[1].value)
|
t.truthy(JSON_DATA_SMALL.props[1].value === JSON_DATA_SMALL.props[1].value)
|
||||||
t.truthy(data.props[1].value.items[0] === data.props[1].value.items[0])
|
t.truthy(JSON_DATA_SMALL.props[1].value.items[0] === JSON_DATA_SMALL.props[1].value.items[0])
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
test('search', t => {
|
||||||
|
const result1 = search(JSON_DATA_EXAMPLE, 'O')
|
||||||
|
t.deepEqual(result1, JSON_DATA_EXAMPLE_SEARCH_1)
|
||||||
|
|
||||||
|
// search for something else. Should clean up earlier search results
|
||||||
|
const result2 = search(result1, '2')
|
||||||
|
t.deepEqual(result2, JSON_DATA_EXAMPLE_SEARCH_2)
|
||||||
|
})
|
||||||
|
|
Loading…
Reference in New Issue