Refactor sorting to return a JSONPatchDocument
This commit is contained in:
parent
a28335fe57
commit
a24045cb42
|
@ -1351,11 +1351,6 @@
|
||||||
"iterate-iterator": "^1.0.1"
|
"iterate-iterator": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"javascript-natural-sort": {
|
|
||||||
"version": "0.7.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz",
|
|
||||||
"integrity": "sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k="
|
|
||||||
},
|
|
||||||
"jest-worker": {
|
"jest-worker": {
|
||||||
"version": "26.0.0",
|
"version": "26.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.0.0.tgz",
|
||||||
|
@ -1635,6 +1630,11 @@
|
||||||
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
|
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"natural-compare-lite": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
|
||||||
|
"integrity": "sha1-F7CVgZiJef3a/gIB6TG6kzyWy7Q="
|
||||||
|
},
|
||||||
"normalize-package-data": {
|
"normalize-package-data": {
|
||||||
"version": "2.5.0",
|
"version": "2.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
|
||||||
|
|
|
@ -21,8 +21,8 @@
|
||||||
"ace-builds": "1.4.12",
|
"ace-builds": "1.4.12",
|
||||||
"ajv": "6.12.3",
|
"ajv": "6.12.3",
|
||||||
"classnames": "2.2.6",
|
"classnames": "2.2.6",
|
||||||
"javascript-natural-sort": "0.7.1",
|
|
||||||
"lodash-es": "4.17.15",
|
"lodash-es": "4.17.15",
|
||||||
|
"natural-compare-lite": "1.4.0",
|
||||||
"svelte-awesome": "2.3.0",
|
"svelte-awesome": "2.3.0",
|
||||||
"svelte-select": "3.11.1",
|
"svelte-select": "3.11.1",
|
||||||
"svelte-simple-modal": "0.6.0"
|
"svelte-simple-modal": "0.6.0"
|
||||||
|
|
|
@ -120,12 +120,14 @@
|
||||||
console.time('create large json')
|
console.time('create large json')
|
||||||
const largeJson = {}
|
const largeJson = {}
|
||||||
largeJson.numbers = []
|
largeJson.numbers = []
|
||||||
|
largeJson.randomNumbers = []
|
||||||
largeJson.array = []
|
largeJson.array = []
|
||||||
for (let i = 0; i < count; i++) {
|
for (let i = 0; i < count; i++) {
|
||||||
const longitude = 4 + i / count
|
const longitude = 4 + i / count
|
||||||
const latitude = 51 + i / count
|
const latitude = 51 + i / count
|
||||||
|
|
||||||
largeJson.numbers.push(i)
|
largeJson.numbers.push(i)
|
||||||
|
largeJson.randomNumbers.push(Math.round(Math.random() * 1000))
|
||||||
largeJson.array.push({
|
largeJson.array.push({
|
||||||
name: 'Item ' + i,
|
name: 'Item ' + i,
|
||||||
id: String(i),
|
id: String(i),
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
import { sortArray, sortObjectKeys } from '../../logic/sort.js'
|
import { sortArray, sortObjectKeys } from '../../logic/sort.js'
|
||||||
|
|
||||||
export let json
|
export let json
|
||||||
export let path
|
export let rootPath
|
||||||
export let onSort
|
export let onSort
|
||||||
|
|
||||||
const {close} = getContext('simple-modal')
|
const {close} = getContext('simple-modal')
|
||||||
|
@ -57,17 +57,14 @@
|
||||||
|
|
||||||
const property = selectedProperty.value
|
const property = selectedProperty.value
|
||||||
const direction = selectedDirection.value
|
const direction = selectedDirection.value
|
||||||
const sortedJson = sortArray(json, property, direction)
|
const operations = sortArray(json, rootPath, property, direction)
|
||||||
|
|
||||||
onSort(sortedJson)
|
onSort(operations)
|
||||||
} else if (isObject(json)) {
|
} else if (isObject(json)) {
|
||||||
const direction = selectedDirection.value
|
const direction = selectedDirection.value
|
||||||
const sortedJson = sortObjectKeys(json, direction)
|
const operations = sortObjectKeys(json, rootPath, direction)
|
||||||
|
|
||||||
// FIXME: the keys are now sorted, but the JSONEditor refuses to reorder when already rendered -> need to do a JSONPatch
|
onSort(operations)
|
||||||
console.log('sorted object keys:', Object.keys(sortedJson))
|
|
||||||
|
|
||||||
onSort(sortedJson)
|
|
||||||
} else {
|
} else {
|
||||||
console.error('Cannot sort: no array or object')
|
console.error('Cannot sort: no array or object')
|
||||||
}
|
}
|
||||||
|
@ -86,7 +83,7 @@
|
||||||
<col width="75%">
|
<col width="75%">
|
||||||
</colgroup>
|
</colgroup>
|
||||||
<tbody>
|
<tbody>
|
||||||
{#if path.length > 0}
|
{#if rootPath.length > 0}
|
||||||
<tr>
|
<tr>
|
||||||
<th>Path</th>
|
<th>Path</th>
|
||||||
<td>
|
<td>
|
||||||
|
@ -94,7 +91,7 @@
|
||||||
class="path"
|
class="path"
|
||||||
type="text"
|
type="text"
|
||||||
readonly
|
readonly
|
||||||
value={stringifyPath(path)}
|
value={stringifyPath(rootPath)}
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -263,29 +263,23 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSort () {
|
function handleSort () {
|
||||||
const path = selection && selection.paths
|
const rootPath = selection && selection.paths
|
||||||
? selection.paths.length > 1
|
? selection.paths.length > 1
|
||||||
? initial(first(selection.paths)) // the parent path of the paths
|
? initial(first(selection.paths)) // the parent path of the paths
|
||||||
: first(selection.paths) // the first and only path
|
: first(selection.paths) // the first and only path
|
||||||
: []
|
: []
|
||||||
|
|
||||||
open(SortModal, {
|
open(SortModal, {
|
||||||
json: getIn(doc, path),
|
json: getIn(doc, rootPath),
|
||||||
path,
|
rootPath,
|
||||||
onSort: async sortedJson => {
|
onSort: async (operations) => {
|
||||||
console.log('onSort', path, sortedJson)
|
console.log('onSort', rootPath, operations)
|
||||||
|
|
||||||
// TODO: replace this with move events instead of a big replace (currently we lose state)
|
|
||||||
const operations = [{
|
|
||||||
op: 'replace',
|
|
||||||
path: compileJSONPointer(path),
|
|
||||||
value: sortedJson
|
|
||||||
}]
|
|
||||||
patch(operations, selection)
|
patch(operations, selection)
|
||||||
|
|
||||||
await tick()
|
await tick()
|
||||||
|
|
||||||
handleExpand(path, true, false)
|
handleExpand(rootPath, true, false)
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
...SIMPLE_MODAL_OPTIONS,
|
...SIMPLE_MODAL_OPTIONS,
|
||||||
|
|
|
@ -1,17 +1,80 @@
|
||||||
|
import naturalCompare from 'natural-compare-lite'
|
||||||
import { getIn } from '../utils/immutabilityHelpers.js'
|
import { getIn } from '../utils/immutabilityHelpers.js'
|
||||||
import naturalSort from 'javascript-natural-sort'
|
import { compileJSONPointer } from '../utils/jsonPointer.js'
|
||||||
|
|
||||||
|
function caseInsensitiveNaturalCompare (a, b) {
|
||||||
|
const aLower = typeof a === 'string' ? a.toLowerCase() : a
|
||||||
|
const bLower = typeof b === 'string' ? b.toLowerCase() : b
|
||||||
|
|
||||||
|
return naturalCompare(aLower, bLower)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort the keys of an object
|
||||||
|
* @param {Object} object The object to be sorted
|
||||||
|
* @param {Path} [rootPath=[]] Relative path when the array was located
|
||||||
|
* @param {1 | -1} [direction=1] Pass 1 to sort ascending, -1 to sort descending
|
||||||
|
* @return {JSONPatchDocument} Returns a JSONPatch document with move operation
|
||||||
|
* to get the array sorted.
|
||||||
|
*/
|
||||||
|
export function sortObjectKeys (object, rootPath = [], direction = 1) {
|
||||||
|
const keys = Object.keys(object)
|
||||||
|
const sortedKeys = keys.slice()
|
||||||
|
|
||||||
|
sortedKeys.sort((keyA, keyB) => {
|
||||||
|
return direction * caseInsensitiveNaturalCompare(keyA, keyB)
|
||||||
|
})
|
||||||
|
|
||||||
|
// const sortedObject = {}
|
||||||
|
// keys.forEach(key => {
|
||||||
|
// sortedObject[key] = object[key]
|
||||||
|
// })
|
||||||
|
|
||||||
|
// TODO: only move the properties that are needed to move
|
||||||
|
const operations = []
|
||||||
|
for (let i = 0; i < sortedKeys.length; i++) {
|
||||||
|
const key = sortedKeys[i]
|
||||||
|
const path = compileJSONPointer(rootPath.concat(key))
|
||||||
|
operations.push({
|
||||||
|
op: 'move',
|
||||||
|
from: path,
|
||||||
|
path
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return operations
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort the items of an array
|
* Sort the items of an array
|
||||||
* @param {Array} array The array to be sorted
|
* @param {Array} array The array to be sorted
|
||||||
* @param {Path} [path=[]] Nested path to the property on which to sort the contents
|
* @param {Path} [rootPath=[]] Relative path when the array was located
|
||||||
* @param {1 | -1} [direction=1] Pass 1 to sort ascending, -1 to sort descending
|
* @param {Path} [propertyPath=[]] Nested path to the property on which to sort the contents
|
||||||
* @return {Array} Returns a sorted shallow copy of the array
|
* @param {1 | -1} [direction=1] Pass 1 to sort ascending, -1 to sort descending
|
||||||
|
* @return {JSONPatchDocument} Returns a JSONPatch document with move operation
|
||||||
|
* to get the array sorted.
|
||||||
*/
|
*/
|
||||||
export function sortArray (array, path = [], direction = 1) {
|
export function sortArray (array, rootPath = [], propertyPath = [], direction = 1) {
|
||||||
function comparator (a, b) {
|
const comparator = createObjectComparator(propertyPath, direction)
|
||||||
const valueA = getIn(a, path)
|
|
||||||
const valueB = getIn(b, path)
|
return getSortingMoves(array, comparator).map(({ fromIndex, toIndex }) => {
|
||||||
|
return {
|
||||||
|
op: 'move',
|
||||||
|
from: compileJSONPointer(rootPath.concat(fromIndex)),
|
||||||
|
path: compileJSONPointer(rootPath.concat(toIndex))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a comparator function to compare nested properties in an array
|
||||||
|
* @param {Path} propertyPath
|
||||||
|
* @param {1 | -1} direction
|
||||||
|
*/
|
||||||
|
function createObjectComparator (propertyPath, direction) {
|
||||||
|
return function comparator (a, b) {
|
||||||
|
const valueA = getIn(a, propertyPath)
|
||||||
|
const valueB = getIn(b, propertyPath)
|
||||||
|
|
||||||
if (valueA === undefined) {
|
if (valueA === undefined) {
|
||||||
return direction
|
return direction
|
||||||
|
@ -22,54 +85,31 @@ export function sortArray (array, path = [], direction = 1) {
|
||||||
|
|
||||||
if (typeof valueA !== 'string' && typeof valueB !== 'string') {
|
if (typeof valueA !== 'string' && typeof valueB !== 'string') {
|
||||||
// both values are a number, boolean, or null -> use simple, fast sorting
|
// both values are a number, boolean, or null -> use simple, fast sorting
|
||||||
return valueA > valueB
|
return valueA > valueB
|
||||||
? direction
|
? direction
|
||||||
: valueA < valueB
|
: valueA < valueB
|
||||||
? -direction
|
? -direction
|
||||||
: 0
|
: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
return direction * naturalSort(valueA, valueB)
|
return direction * caseInsensitiveNaturalCompare(valueA, valueB)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: use lodash orderBy, split comparator and direction?
|
|
||||||
const sortedArray = array.slice()
|
|
||||||
sortedArray.sort(comparator)
|
|
||||||
|
|
||||||
return sortedArray
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sort the keys of an object
|
|
||||||
* @param {Object} object The object to be sorted
|
|
||||||
* @param {1 | -1} [direction=1] Pass 1 to sort ascending, -1 to sort descending
|
|
||||||
* @return {Object} Returns a sorted shallow copy of the object
|
|
||||||
*/
|
|
||||||
export function sortObjectKeys (object, direction = 1) {
|
|
||||||
const keys = Object.keys(object)
|
|
||||||
keys.sort((keyA, keyB) => {
|
|
||||||
return direction * naturalSort(keyA, keyB)
|
|
||||||
})
|
|
||||||
|
|
||||||
const sortedObject = {}
|
|
||||||
keys.forEach(key => sortedObject[key] = object[key])
|
|
||||||
|
|
||||||
return sortedObject
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an array containing all move operations
|
* Create an array containing all move operations
|
||||||
* needed to sort the array contents.
|
* needed to sort the array contents.
|
||||||
* @param {Array} array
|
* @param {Array} array
|
||||||
* @param {function (a, b) => number} comparator
|
* @param {function (a, b) => number} comparator
|
||||||
* @param {Array.<{fromIndex: number, toIndex: number}>}
|
* @param {Array.<{fromIndex: number, toIndex: number}>}
|
||||||
*/
|
*/
|
||||||
export function sortMoveOperations (array, comparator) {
|
export function getSortingMoves (array, comparator) {
|
||||||
const operations = []
|
const operations = []
|
||||||
const sorted = []
|
const sorted = []
|
||||||
|
|
||||||
|
// TODO: rewrite the function to pass a callback instead of returning an array?
|
||||||
for (let i = 0; i < array.length; i++) {
|
for (let i = 0; i < array.length; i++) {
|
||||||
// TODO: implement a faster way to sort (binary tree sort?)
|
// TODO: implement a faster way to sort. Something with longest increasing subsequence?
|
||||||
// TODO: can we simplify the following code?
|
// TODO: can we simplify the following code?
|
||||||
const item = array[i]
|
const item = array[i]
|
||||||
if (i > 0 && comparator(sorted[i - 1], item) > 0) {
|
if (i > 0 && comparator(sorted[i - 1], item) > 0) {
|
||||||
|
@ -83,7 +123,7 @@ export function sortMoveOperations (array, comparator) {
|
||||||
toIndex: j
|
toIndex: j
|
||||||
})
|
})
|
||||||
|
|
||||||
sorted.splice(j, 0, [item])
|
sorted.splice(j, 0, item)
|
||||||
} else {
|
} else {
|
||||||
sorted.push(item)
|
sorted.push(item)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,61 +1,131 @@
|
||||||
import assert from 'assert'
|
import assert from 'assert'
|
||||||
import { sortArray, sortObjectKeys, sortMoveOperations } from './sort.js'
|
import { sortArray, sortObjectKeys, getSortingMoves } from './sort.js'
|
||||||
|
|
||||||
describe.only('sort', () => {
|
describe('sort', () => {
|
||||||
|
|
||||||
it('should sort array', () => {
|
|
||||||
assert.deepStrictEqual(sortArray([ 2, 3, 1 ]), [1, 2, 3])
|
|
||||||
assert.deepStrictEqual(sortArray([ 2, 3, 1 ], undefined, -1), [3, 2, 1])
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should sort array using natural sort', () => {
|
|
||||||
assert.deepStrictEqual(sortArray([ '10', '2', '1' ]), ['1', '2', '10'])
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should sort array by nested properties', () => {
|
|
||||||
const a = {data: { value: 1 }}
|
|
||||||
const b = {data: { value: 2 }}
|
|
||||||
const c = {data: { value: 3 }}
|
|
||||||
|
|
||||||
assert.deepStrictEqual(sortArray([ b, c, a ], ['data', 'value']), [a, b, c])
|
|
||||||
assert.deepStrictEqual(sortArray([ b, a, c ], ['data', 'value']), [a, b, c])
|
|
||||||
assert.deepStrictEqual(sortArray([ b, a, c ], ['data', 'value'], 1), [a, b, c])
|
|
||||||
assert.deepStrictEqual(sortArray([ b, a, c ], ['data', 'value'], -1), [c, b, a])
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should sort object keys', () => {
|
it('should sort object keys', () => {
|
||||||
const object = { b: 1, c: 1, a: 1 }
|
const object = { b: 1, c: 1, a: 1 }
|
||||||
|
|
||||||
assert.deepStrictEqual(Object.keys(sortObjectKeys(object)), ['a', 'b', 'c'])
|
assert.deepStrictEqual(sortObjectKeys(object), [
|
||||||
assert.deepStrictEqual(Object.keys(sortObjectKeys(object, 1)), ['a', 'b', 'c'])
|
{ op: 'move', from: '/a', path: '/a' },
|
||||||
assert.deepStrictEqual(Object.keys(sortObjectKeys(object, -1)), ['c', 'b', 'a'])
|
{ op: 'move', from: '/b', path: '/b' },
|
||||||
|
{ op: 'move', from: '/c', path: '/c' }
|
||||||
|
])
|
||||||
|
|
||||||
|
assert.deepStrictEqual(sortObjectKeys(object, undefined, 1), [
|
||||||
|
{ op: 'move', from: '/a', path: '/a' },
|
||||||
|
{ op: 'move', from: '/b', path: '/b' },
|
||||||
|
{ op: 'move', from: '/c', path: '/c' }
|
||||||
|
])
|
||||||
|
|
||||||
|
assert.deepStrictEqual(sortObjectKeys(object, undefined, -1), [
|
||||||
|
{ op: 'move', from: '/c', path: '/c' },
|
||||||
|
{ op: 'move', from: '/b', path: '/b' },
|
||||||
|
{ op: 'move', from: '/a', path: '/a' }
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should sort object keys using a rootPath', () => {
|
||||||
|
const object = { b: 1, c: 1, a: 1 }
|
||||||
|
|
||||||
|
assert.deepStrictEqual(sortObjectKeys(object, ['root', 'path']), [
|
||||||
|
{ op: 'move', from: '/root/path/a', path: '/root/path/a' },
|
||||||
|
{ op: 'move', from: '/root/path/b', path: '/root/path/b' },
|
||||||
|
{ op: 'move', from: '/root/path/c', path: '/root/path/c' }
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should sort object keys case insensitive', () => {
|
||||||
|
const object = { B: 1, a: 1 }
|
||||||
|
|
||||||
|
assert.deepStrictEqual(sortObjectKeys(object), [
|
||||||
|
{ op: 'move', from: '/a', path: '/a' },
|
||||||
|
{ op: 'move', from: '/B', path: '/B' }
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should sort array', () => {
|
||||||
|
assert.deepStrictEqual(sortArray([2, 3, 1]), [
|
||||||
|
{ op: 'move', from: '/2', path: '/0' }
|
||||||
|
])
|
||||||
|
assert.deepStrictEqual(sortArray([2, 3, 1], undefined, undefined, -1), [
|
||||||
|
{ op: 'move', from: '/1', path: '/0' }
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should sort array using natural sort', () => {
|
||||||
|
assert.deepStrictEqual(sortArray(['10', '2', '1']), [
|
||||||
|
{ op: 'move', from: '/1', path: '/0' },
|
||||||
|
{ op: 'move', from: '/2', path: '/0' }
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should sort array case insensitive', () => {
|
||||||
|
assert.deepStrictEqual(sortArray(['B', 'a']), [
|
||||||
|
{ op: 'move', from: '/1', path: '/0' }
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should sort array using a rootPath', () => {
|
||||||
|
assert.deepStrictEqual(sortArray([2, 3, 1], ['root', 'path']), [
|
||||||
|
{ op: 'move', from: '/root/path/2', path: '/root/path/0' }
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should sort array by nested properties and custom direction', () => {
|
||||||
|
const a = { data: { value: 1 } }
|
||||||
|
const b = { data: { value: 2 } }
|
||||||
|
const c = { data: { value: 3 } }
|
||||||
|
|
||||||
|
assert.deepStrictEqual(sortArray([b, a, c], undefined, ['data', 'value']), [
|
||||||
|
{ op: 'move', from: '/1', path: '/0' }
|
||||||
|
])
|
||||||
|
assert.deepStrictEqual(sortArray([b, a, c], undefined, ['data', 'value'], 1), [
|
||||||
|
{ op: 'move', from: '/1', path: '/0' }
|
||||||
|
])
|
||||||
|
assert.deepStrictEqual(sortArray([b, a, c], undefined, ['data', 'value'], -1), [
|
||||||
|
{ op: 'move', from: '/2', path: '/0' }
|
||||||
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should give the move operations needed to sort given array', () => {
|
it('should give the move operations needed to sort given array', () => {
|
||||||
const comparator = (a, b) => a - b
|
const comparator = (a, b) => a - b
|
||||||
|
|
||||||
assert.deepStrictEqual(sortMoveOperations([ 1, 2, 3 ], comparator), [])
|
assert.deepStrictEqual(getSortingMoves([1, 2, 3], comparator), [])
|
||||||
|
|
||||||
assert.deepStrictEqual(sortMoveOperations([ 2, 3, 1 ], comparator), [
|
assert.deepStrictEqual(getSortingMoves([2, 3, 1], comparator), [
|
||||||
{ fromIndex: 2, toIndex: 0 }
|
{ fromIndex: 2, toIndex: 0 }
|
||||||
])
|
])
|
||||||
|
|
||||||
assert.deepStrictEqual(sortMoveOperations([ 2, 1, 3 ], comparator), [
|
assert.deepStrictEqual(getSortingMoves([2, 1, 3], comparator), [
|
||||||
{ fromIndex: 1, toIndex: 0 }
|
{ fromIndex: 1, toIndex: 0 }
|
||||||
])
|
])
|
||||||
|
|
||||||
assert.deepStrictEqual(sortMoveOperations([ 1, 3, 2 ], comparator), [
|
assert.deepStrictEqual(getSortingMoves([1, 3, 2], comparator), [
|
||||||
{ fromIndex: 2, toIndex: 1 }
|
{ fromIndex: 2, toIndex: 1 }
|
||||||
])
|
])
|
||||||
|
|
||||||
assert.deepStrictEqual(sortMoveOperations([ 3, 2, 1 ], comparator), [
|
assert.deepStrictEqual(getSortingMoves([3, 2, 1], comparator), [
|
||||||
{ fromIndex: 1, toIndex: 0 },
|
{ fromIndex: 1, toIndex: 0 },
|
||||||
{ fromIndex: 2, toIndex: 0 }
|
{ fromIndex: 2, toIndex: 0 }
|
||||||
])
|
])
|
||||||
|
|
||||||
assert.deepStrictEqual(sortMoveOperations([ 3, 1, 2 ], comparator), [
|
assert.deepStrictEqual(getSortingMoves([3, 1, 2], comparator), [
|
||||||
{ fromIndex: 1, toIndex: 0 },
|
{ fromIndex: 1, toIndex: 0 },
|
||||||
{ fromIndex: 2, toIndex: 1 }
|
{ fromIndex: 2, toIndex: 1 }
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should give the move operations needed to sort given array containing objects', () => {
|
||||||
|
const comparator = (a, b) => a.id - b.id
|
||||||
|
|
||||||
|
const actual = getSortingMoves([{ id: 4 }, { id: 3 }, { id: 1 }, { id: 2 }], comparator)
|
||||||
|
|
||||||
|
const expected = [
|
||||||
|
{ fromIndex: 1, toIndex: 0 },
|
||||||
|
{ fromIndex: 2, toIndex: 0 },
|
||||||
|
{ fromIndex: 3, toIndex: 1 }
|
||||||
|
]
|
||||||
|
|
||||||
|
assert.deepStrictEqual(actual, expected)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue