boogy v1.2.1
Boogy
Boogy is a module which you can use to determine if two objects are equal - either shallow or deep - to each others.
It offers two modes - loose and strict, and the loose mode is somewhat similar to the deepEqual algoithm found in the
NodeJS core assert module.
This module is designed to fix all known bugs found in various deepEqual algorithms online, and support everything
that is possible to support. ES2015 and ES2016 included.
ES2017 is still at the draft stage, but will be supported continuously.
It's safe to use this module in production - over 380 tests (not included subtests) proves that Boogy is battle tested.
Features
- 100% reliable
- 100% NodeJS core assert module compatible in
loosemode - ES2016 and ES2017 (still draft) support in
strictmode - Equal support for
NodeJS 4.xandNodeJS 6.x- unlikeNodeJS core assert module - Follows ECMA standards
- Handle complex datasets
- Supports 2 different modes -
looseandstrict - RegExp equality checks are extended to also support
stickyandunicode. - High performance
- 37% faster then native
NodejSsolution.
Compatibility
- NodeJS 4.0+
Install
$ npm install --save boogyThen in your project...
// Node 5.x or newer.
var { strict, loose } = require('boogy');or
import { strict, loose } from 'boogy';API
Boogy let you import two different functions, so you can choose between either strict and loose mode when you include this module into your project.
Each of the functions takes two arguments of any type, and returns a boolean result. Primitive types are equal if they are ===.
While composite types, i.e. Objects and Arrays, are considered equal if they have both the same structure and each sub-value is also equal.
Circular references in composite structures are supported.
loose(actual, expected)
actual- Value to compare againstactualexpected- Value to compare againstexpected
Returns: Boolean indicating whether or not actual is the same as expected.
Same for strict mode.
Differences between loose and strict mode
The differences between loose and strict mode are mainly the use of tripple equals. And also that the strict mode does a deeply nested sameValue
equality between two objects of any type, and performs a SameValueZero comparison
between two values to determine if they are equivalent.
loose({}, []) // => true
strict({}, []) // => false
loose({ 0: 'a', 1: 'b' }, ['a', 'b']) // => true
strict({ 0: 'a', 1: 'b' }, ['a', 'b']) // => false
loose(1, '1') // => true
strict(1, '1') // => falseDifferences between Boogy and NodejS core assert module
The core assert module are basicly using == for all equality checks, wich include a complicated logic for type conversion that
often can lead to bugs, or give you results you wouldn't expect.
Boogy's loose mode is approximately 100% compatible with the NodejS core assert module except there is
a small deviation in some areas where current code is either enhanced or extended.
This is done to avoid giving you unexpected results, or encounter bugs. The loose mode also supports Features that isn't supported in the core assert module, and some features that only works for NodeJS 6.x such as TypedArray.prototype.subarray() is also working with NodeJS 4.x with Boogy.
Here are a few strange results that is kept as is in Boogy:
loose([1], true) // => true
loose('0', false) // => true
loose([[]], false) // => true
loose([], false) // => true
loose([], {}) // => true
loose(new Buffer('abc'), new Buffer('xyz')) // => true
loose('\r\n\t', 0) // => trueWith Boogys strict mode this strange behaviour are non-existent - one of the main purposes with the strict mode.
Boogy vs. other deepEqual algorithms
The differences between Boogy and other similiar algorithms are too many that I can list them all here,
but basicly Boogy is a better algorithm that fixes all flaws in similar algorithms, and also have build
in support for the new ES2015 collection. And ES2016 support soon to come.
Around 37% of all tests for this module will fail with other algorithms.
The bugs found in similar modules are mostly related to circular references - and RegExp. Or
[] === {} wich returns true. However this is what the NodejS Core assert module does as well. And
the same behaviour have Boogy adopted in loose mode.
AVA wich using the not-so-shallow module doesn't have the mentioned issues, but still have it's own
issues. One obvious issue is this:
Error('a') === Error('b') // => trueAnd the Chai library have some "really nice bugs" related to circular references, and also this strange behavior:
var symbol1 = Symbol('x');
expect(symbol1, Object(symbol1)).to.be.false; // => TypeError: Cannot convert a Symbol value to a string
vs. Boogy
loose(symbol1, Object(symbol1); // => falseSome examples
Same structure:
loose({ a : [ 2, 3 ], b : [ 4 ] }, { a : [ 2, 3 ], b : [ 4 ] }) // => true
strict({ a : [ 2, 3 ], b : [ 4 ] }, { a : [ 2, 3 ], b : [ 4 ] }) // => trueDifferent structure:
loose({ x : 2016, y : [2017] }, { x : 2016}) // => false
struct({ x : 2016, y : [2017] }, { x : 2016}) // => falseSame structure, different values:
loose( { x : 2016, y : [6] }, { x : 2017}) // => false
strict( { x : 2016, y : [6] }, { x : 2017}) // => falsePrimitives:
loose({ x : 5, y : [6] },{ x : 5}) // => false
strict({ x : 5, y : [6] },{ x : 5}) // => falseECMA:
loose(function() {}, () => {}) // => false
strict(function() {}, () => {}) // => falseMixed
loose(a, 'b') // false
loose({a: 0}, {a: '0'}, 'strict') // false
loose({a: 1}, {a: 1}) // true
loose({a: 1, b: 2}, {b: 2, a: 1}) // true
// Both of this will return true in the NodejS core module
loose(Error('a'), Error('a')) // true
loose(Error('a'), Error('b')) // false
strict(Error('a'), Error('b')) // false
let s = Symbol();
loose(s, s); // trueBugs?
If you find any bugs, feel free to open an issue ticket.
Contribution
You are welcome to contribute at any time :)
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago