wallet-core/node_modules/concordance/lib/symbolProperties.js
2017-08-14 05:02:09 +02:00

107 lines
2.7 KiB
JavaScript

'use strict'
const constants = require('./constants')
const recursorUtils = require('./recursorUtils')
const DEEP_EQUAL = constants.DEEP_EQUAL
const SHALLOW_EQUAL = constants.SHALLOW_EQUAL
const UNEQUAL = constants.UNEQUAL
class Comparable {
constructor (properties) {
this.properties = properties
this.ordered = properties.slice()
}
createRecursor () {
const length = this.ordered.length
let index = 0
return () => {
if (index === length) return null
return this.ordered[index++]
}
}
compare (expected) {
if (this.properties.length !== expected.properties.length) return UNEQUAL
// Compare property keys, reordering the expected properties in the process
// so values can be compared if all keys are equal.
const ordered = []
const processed = new Set()
for (const property of this.properties) {
let extraneous = true
for (const other of expected.properties) {
if (processed.has(other.key)) continue
if (property.key.compare(other.key) === DEEP_EQUAL) {
extraneous = false
processed.add(other.key)
ordered.push(other)
break
}
}
if (extraneous) return UNEQUAL
}
expected.ordered = ordered
return SHALLOW_EQUAL
}
prepareDiff (expected) {
// Reorder the expected properties before recursion starts.
const missingProperties = []
const ordered = []
const processed = new Set()
for (const other of expected.properties) {
let missing = true
for (const property of this.properties) {
if (processed.has(property.key)) continue
if (property.key.compare(other.key) === DEEP_EQUAL) {
missing = false
processed.add(property.key)
ordered.push(other)
break
}
}
if (missing) {
missingProperties.push(other)
}
}
expected.ordered = ordered.concat(missingProperties)
return {mustRecurse: true}
}
}
Object.defineProperty(Comparable.prototype, 'isSymbolPropertiesComparable', { value: true })
exports.Comparable = Comparable
class Collector {
constructor (firstProperty, recursor) {
this.properties = [firstProperty]
this.recursor = recursor
this.remainder = null
}
collectAll () {
do {
const next = this.recursor()
if (next && next.isProperty === true) { // All properties will have symbol keys
this.properties.push(next)
} else {
return next
}
} while (true)
}
createRecursor () {
return recursorUtils.singleValue(new Comparable(this.properties))
}
}
Object.defineProperty(Collector.prototype, 'isSymbolPropertiesCollector', { value: true })
exports.Collector = Collector