fix encoding and rb tree tests
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import { test } from '../node_modules/cutest/cutest.js'
|
||||
import { test } from '../node_modules/cutest/cutest.mjs'
|
||||
import '../node_modules/chance/chance.js'
|
||||
import Y from '../src/y.js'
|
||||
import BinaryEncoder from '../src/Binary/Encoder.js'
|
||||
import BinaryDecoder from '../src/Binary/Decoder.js'
|
||||
import { generateUserID } from '../src/Util/generateUserID.js'
|
||||
import Chance from 'chance'
|
||||
|
||||
function testEncoding (t, write, read, val) {
|
||||
let encoder = new BinaryEncoder()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import Y from '../src/y.js'
|
||||
import RedBlackTree from '../src/Util/Tree.js'
|
||||
import ID from '../src/Util/ID.js'
|
||||
import Chance from 'chance'
|
||||
import { test, proxyConsole } from 'cutest'
|
||||
|
||||
@@ -53,23 +54,16 @@ function checkRootNodeIsBlack (t, tree) {
|
||||
}
|
||||
|
||||
test('RedBlack Tree', async function redBlackTree (t) {
|
||||
let memory = new Y.memory(null, { // eslint-disable-line
|
||||
name: 'Memory',
|
||||
gcTimeout: -1
|
||||
})
|
||||
let tree = memory.os
|
||||
memory.requestTransaction(function () {
|
||||
tree.put({id: [8433]})
|
||||
tree.put({id: [12844]})
|
||||
tree.put({id: [1795]})
|
||||
tree.put({id: [30302]})
|
||||
tree.put({id: [64287]})
|
||||
tree.delete([8433])
|
||||
tree.put({id: [28996]})
|
||||
tree.delete([64287])
|
||||
tree.put({id: [22721]})
|
||||
})
|
||||
await memory.whenTransactionsFinished()
|
||||
let tree = new RedBlackTree()
|
||||
tree.put({id: new ID(8433, 0)})
|
||||
tree.put({id: new ID(12844, 0)})
|
||||
tree.put({id: new ID(1795, 0)})
|
||||
tree.put({id: new ID(30302, 0)})
|
||||
tree.put({id: new ID(64287)})
|
||||
tree.delete(new ID(8433, 0))
|
||||
tree.put({id: new ID(28996)})
|
||||
tree.delete(new ID(64287))
|
||||
tree.put({id: new ID(22721)})
|
||||
checkRootNodeIsBlack(t, tree)
|
||||
checkBlackHeightOfSubTreesAreEqual(t, tree)
|
||||
checkRedNodesDoNotHaveBlackChildren(t, tree)
|
||||
@@ -77,141 +71,122 @@ test('RedBlack Tree', async function redBlackTree (t) {
|
||||
|
||||
test(`random tests (${numberOfRBTreeTests})`, async function random (t) {
|
||||
let chance = new Chance(t.getSeed() * 1000000000)
|
||||
let memory = new Y.memory(null, { // eslint-disable-line
|
||||
name: 'Memory',
|
||||
gcTimeout: -1
|
||||
})
|
||||
let tree = memory.os
|
||||
let tree = new RedBlackTree()
|
||||
let elements = []
|
||||
memory.requestTransaction(function () {
|
||||
for (var i = 0; i < numberOfRBTreeTests; i++) {
|
||||
if (chance.bool({likelihood: 80})) {
|
||||
// 80% chance to insert an element
|
||||
let obj = [chance.integer({min: 0, max: numberOfRBTreeTests})]
|
||||
let nodeExists = tree.find(obj)
|
||||
if (!nodeExists) {
|
||||
if (elements.some(e => e[0] === obj[0])) {
|
||||
t.assert(false, 'tree and elements contain different results')
|
||||
}
|
||||
elements.push(obj)
|
||||
tree.put({id: obj})
|
||||
for (var i = 0; i < numberOfRBTreeTests; i++) {
|
||||
if (chance.bool({likelihood: 80})) {
|
||||
// 80% chance to insert an element
|
||||
let obj = new ID(chance.integer({min: 0, max: numberOfRBTreeTests}), chance.integer({min: 0, max: 1}))
|
||||
let nodeExists = tree.find(obj)
|
||||
if (nodeExists === null) {
|
||||
if (elements.some(e => e.equals(obj))) {
|
||||
t.assert(false, 'tree and elements contain different results')
|
||||
}
|
||||
} else if (elements.length > 0) {
|
||||
// ~20% chance to delete an element
|
||||
var elem = chance.pickone(elements)
|
||||
elements = elements.filter(function (e) {
|
||||
return !Y.utils.compareIds(e, elem)
|
||||
})
|
||||
tree.delete(elem)
|
||||
elements.push(obj)
|
||||
tree.put({id: obj})
|
||||
}
|
||||
} else if (elements.length > 0) {
|
||||
// ~20% chance to delete an element
|
||||
var elem = chance.pickone(elements)
|
||||
elements = elements.filter(function (e) {
|
||||
return !e.equals(elem)
|
||||
})
|
||||
tree.delete(elem)
|
||||
}
|
||||
})
|
||||
await memory.whenTransactionsFinished()
|
||||
}
|
||||
checkRootNodeIsBlack(t, tree)
|
||||
checkBlackHeightOfSubTreesAreEqual(t, tree)
|
||||
checkRedNodesDoNotHaveBlackChildren(t, tree)
|
||||
memory.requestTransaction(function () {
|
||||
let allNodesExist = true
|
||||
for (let id of elements) {
|
||||
let node = tree.find(id)
|
||||
if (!Y.utils.compareIds(node.id, id)) {
|
||||
allNodesExist = false
|
||||
}
|
||||
// TEST if all nodes exist
|
||||
let allNodesExist = true
|
||||
for (let id of elements) {
|
||||
let node = tree.find(id)
|
||||
if (!node.id.equals(id)) {
|
||||
allNodesExist = false
|
||||
}
|
||||
t.assert(allNodesExist, 'All inserted nodes exist')
|
||||
})
|
||||
memory.requestTransaction(function () {
|
||||
let findAllNodesWithLowerBoundSerach = true
|
||||
for (let id of elements) {
|
||||
let node = tree.findWithLowerBound(id)
|
||||
if (!Y.utils.compareIds(node.id, id)) {
|
||||
findAllNodesWithLowerBoundSerach = false
|
||||
}
|
||||
}
|
||||
t.assert(allNodesExist, 'All inserted nodes exist')
|
||||
// TEST lower bound search
|
||||
let findAllNodesWithLowerBoundSerach = true
|
||||
for (let id of elements) {
|
||||
let node = tree.findWithLowerBound(id)
|
||||
if (!node.id.equals(id)) {
|
||||
findAllNodesWithLowerBoundSerach = false
|
||||
}
|
||||
t.assert(
|
||||
findAllNodesWithLowerBoundSerach,
|
||||
'Find every object with lower bound search'
|
||||
)
|
||||
})
|
||||
|
||||
memory.requestTransaction(function () {
|
||||
let lowerBound = chance.pickone(elements)
|
||||
let expectedResults = elements.filter((e, pos) =>
|
||||
(Y.utils.smaller(lowerBound, e) || Y.utils.compareIds(e, lowerBound)) &&
|
||||
elements.indexOf(e) === pos
|
||||
).length
|
||||
let actualResults = 0
|
||||
tree.iterate(this, lowerBound, null, function (val) {
|
||||
if (val == null) {
|
||||
t.assert(false, 'val is undefined!')
|
||||
}
|
||||
actualResults++
|
||||
})
|
||||
t.assert(
|
||||
expectedResults === actualResults,
|
||||
'Iterating over a tree with lower bound yields the right amount of results'
|
||||
)
|
||||
})
|
||||
|
||||
memory.requestTransaction(function () {
|
||||
let expectedResults = elements.filter((e, pos) =>
|
||||
elements.indexOf(e) === pos
|
||||
).length
|
||||
let actualResults = 0
|
||||
tree.iterate(this, null, null, function (val) {
|
||||
if (val == null) {
|
||||
t.assert(false, 'val is undefined!')
|
||||
}
|
||||
actualResults++
|
||||
})
|
||||
t.assert(
|
||||
expectedResults === actualResults,
|
||||
'iterating over a tree without bounds yields the right amount of results'
|
||||
)
|
||||
})
|
||||
|
||||
memory.requestTransaction(function () {
|
||||
let upperBound = chance.pickone(elements)
|
||||
let expectedResults = elements.filter((e, pos) =>
|
||||
(Y.utils.smaller(e, upperBound) || Y.utils.compareIds(e, upperBound)) &&
|
||||
elements.indexOf(e) === pos
|
||||
).length
|
||||
let actualResults = 0
|
||||
tree.iterate(this, null, upperBound, function (val) {
|
||||
if (val == null) {
|
||||
t.assert(false, 'val is undefined!')
|
||||
}
|
||||
actualResults++
|
||||
})
|
||||
t.assert(
|
||||
expectedResults === actualResults,
|
||||
'iterating over a tree with upper bound yields the right amount of results'
|
||||
)
|
||||
})
|
||||
|
||||
memory.requestTransaction(function () {
|
||||
let upperBound = chance.pickone(elements)
|
||||
let lowerBound = chance.pickone(elements)
|
||||
if (Y.utils.smaller(upperBound, lowerBound)) {
|
||||
[lowerBound, upperBound] = [upperBound, lowerBound]
|
||||
}
|
||||
t.assert(
|
||||
findAllNodesWithLowerBoundSerach,
|
||||
'Find every object with lower bound search'
|
||||
)
|
||||
// TEST iteration (with lower bound search)
|
||||
let lowerBound = chance.pickone(elements)
|
||||
let expectedResults = elements.filter((e, pos) =>
|
||||
(lowerBound.lessThan(e) || e.equals(lowerBound)) &&
|
||||
elements.indexOf(e) === pos
|
||||
).length
|
||||
let actualResults = 0
|
||||
tree.iterate(lowerBound, null, function (val) {
|
||||
if (val == null) {
|
||||
t.assert(false, 'val is undefined!')
|
||||
}
|
||||
let expectedResults = elements.filter((e, pos) =>
|
||||
(Y.utils.smaller(lowerBound, e) || Y.utils.compareIds(e, lowerBound)) &&
|
||||
(Y.utils.smaller(e, upperBound) || Y.utils.compareIds(e, upperBound)) &&
|
||||
elements.indexOf(e) === pos
|
||||
).length
|
||||
let actualResults = 0
|
||||
tree.iterate(this, lowerBound, upperBound, function (val) {
|
||||
if (val == null) {
|
||||
t.assert(false, 'val is undefined!')
|
||||
}
|
||||
actualResults++
|
||||
})
|
||||
t.assert(
|
||||
expectedResults === actualResults,
|
||||
'iterating over a tree with upper bound yields the right amount of results'
|
||||
)
|
||||
actualResults++
|
||||
})
|
||||
t.assert(
|
||||
expectedResults === actualResults,
|
||||
'Iterating over a tree with lower bound yields the right amount of results'
|
||||
)
|
||||
|
||||
await memory.whenTransactionsFinished()
|
||||
expectedResults = elements.filter((e, pos) =>
|
||||
elements.indexOf(e) === pos
|
||||
).length
|
||||
actualResults = 0
|
||||
tree.iterate(null, null, function (val) {
|
||||
if (val == null) {
|
||||
t.assert(false, 'val is undefined!')
|
||||
}
|
||||
actualResults++
|
||||
})
|
||||
t.assert(
|
||||
expectedResults === actualResults,
|
||||
'iterating over a tree without bounds yields the right amount of results'
|
||||
)
|
||||
|
||||
let upperBound = chance.pickone(elements)
|
||||
expectedResults = elements.filter((e, pos) =>
|
||||
(e.lessThan(upperBound) || e.equals(upperBound)) &&
|
||||
elements.indexOf(e) === pos
|
||||
).length
|
||||
actualResults = 0
|
||||
tree.iterate(null, upperBound, function (val) {
|
||||
if (val == null) {
|
||||
t.assert(false, 'val is undefined!')
|
||||
}
|
||||
actualResults++
|
||||
})
|
||||
t.assert(
|
||||
expectedResults === actualResults,
|
||||
'iterating over a tree with upper bound yields the right amount of results'
|
||||
)
|
||||
|
||||
upperBound = chance.pickone(elements)
|
||||
lowerBound = chance.pickone(elements)
|
||||
if (upperBound.lessThan(lowerBound)) {
|
||||
[lowerBound, upperBound] = [upperBound, lowerBound]
|
||||
}
|
||||
expectedResults = elements.filter((e, pos) =>
|
||||
(lowerBound.lessThan(e) || e.equals(lowerBound)) &&
|
||||
(e.lessThan(upperBound) || e.equals(upperBound)) &&
|
||||
elements.indexOf(e) === pos
|
||||
).length
|
||||
actualResults = 0
|
||||
tree.iterate(lowerBound, upperBound, function (val) {
|
||||
if (val == null) {
|
||||
t.assert(false, 'val is undefined!')
|
||||
}
|
||||
actualResults++
|
||||
})
|
||||
t.assert(
|
||||
expectedResults === actualResults,
|
||||
'iterating over a tree with upper bound yields the right amount of results'
|
||||
)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user