diff --git a/README.md b/README.md index c029456..7b11d83 100644 --- a/README.md +++ b/README.md @@ -122,13 +122,31 @@ expect(a).to.equal(b); Immutable data structures should only contain other immutable data structures (unlike `Array`s and `Object`s) to be considered immutable and properly work against `.equal()`. See -[this issue](https://github.com/astorije/chai-immutable/issues/24) for -more information. +[issue #24](https://github.com/astorije/chai-immutable/issues/24) for more +information. Also, note that `deep.equal` and `eql` are synonyms of `equal` when tested against immutable data structures, therefore they are aliases to `equal`. +### .referenceEqual(value) + +- **@param** _{Collection}_ value + +Asserts that the reference of the target is equivalent to the reference of +`collection`. This method preserves the original behavior of Chai's `equal`. + +See [issue #210](https://github.com/astorije/chai-immutable/issues/210) for +more details. + +```js +const a = List.of(1, 2, 3); +const b = a; +const c = List.of(1, 2, 3); +expect(a).to.referenceEqual(b); +expect(a).to.not.referenceEqual(c); +``` + ### .include(value) - **@param** _{ Mixed }_ val @@ -385,8 +403,27 @@ assert.equal(a, b); Immutable data structures should only contain other immutable data structures (unlike `Array`s and `Object`s) to be considered immutable and properly work against `.equal()`, `.strictEqual()` or `.deepEqual()`. See -[this issue](https://github.com/astorije/chai-immutable/issues/24) for -more information. +[issue #24](https://github.com/astorije/chai-immutable/issues/24) for more +information. + +### .referenceEqual(actual, expected) + +- **@param** _{Collection}_ actual +- **@param** _{Collection}_ expected + +Asserts that the reference of `actual` is equivalent to the reference of +`expected`. This method preserves the original behavior of Chai's `equal`. + +See [issue #210](https://github.com/astorije/chai-immutable/issues/210) for +more details. + +```js +const a = List.of(1, 2, 3); +const b = a; +const c = List.of(1, 2, 3); +assert.referenceEqual(a, b); +assert.throws(() => assert.referenceEqual(a, c)); +``` ### .notEqual(actual, expected) @@ -403,6 +440,25 @@ const b = List.of(4, 5, 6); assert.notEqual(a, b); ``` +### .notReferenceEqual(actual, expected) + +- **@param** _{Collection}_ actual +- **@param** _{Collection}_ expected + +Asserts that the reference of `actual` is not equivalent to the reference of +`expected`. This method preserves the original behavior of Chai's `notEqual`. + +See [issue #210](https://github.com/astorije/chai-immutable/issues/210) for +more details. + +```js +const a = List.of(1, 2, 3); +const b = a; +const c = List.of(1, 2, 3); +assert.throws(() => assert.notReferenceEqual(a, b)); +assert.notReferenceEqual(a, c); +``` + ### .sizeOf(collection, length) - **@param** _{ Collection }_ collection diff --git a/chai-immutable.js b/chai-immutable.js index 77f5842..5dd330f 100644 --- a/chai-immutable.js +++ b/chai-immutable.js @@ -77,8 +77,8 @@ * Immutable data structures should only contain other immutable data * structures (unlike `Array`s and `Object`s) to be considered immutable and * properly work against `.equal()`. See - * [this issue](https://github.com/astorije/chai-immutable/issues/24) for - * more information. + * [issue #24](https://github.com/astorije/chai-immutable/issues/24) for more + * information. * * Also, note that `deep.equal` and `eql` are synonyms of `equal` when * tested against immutable data structures, therefore they are aliases to @@ -120,6 +120,46 @@ Assertion.overwriteMethod('eql', assertCollectionEqual); Assertion.overwriteMethod('eqls', assertCollectionEqual); + /** + * ### .referenceEqual(value) + * + * Asserts that the reference of the target is equivalent to the reference of + * `collection`. This method preserves the original behavior of Chai's `equal`. + * + * See [issue #210](https://github.com/astorije/chai-immutable/issues/210) for + * more details. + * + * ```js + * const a = List.of(1, 2, 3); + * const b = a; + * const c = List.of(1, 2, 3); + * expect(a).to.referenceEqual(b); + * expect(a).to.not.referenceEqual(c); + * ``` + * + * @name referenceEqual + * @param {Collection} value + * @namespace BDD + * @api public + */ + + function assertCollectionReferenceEqual() { + return function(collection) { + const obj = this._obj; + + this.assert( + obj === collection, + 'expected #{act} reference to equal #{exp}', + 'expected #{act} reference to not equal #{exp}', + collection.toJS(), + obj.toJS(), + true + ); + }; + } + + Assertion.addMethod('referenceEqual', assertCollectionReferenceEqual); + /** * ### .include(value) * @@ -778,8 +818,8 @@ * Immutable data structures should only contain other immutable data * structures (unlike `Array`s and `Object`s) to be considered immutable and * properly work against `.equal()`, `.strictEqual()` or `.deepEqual()`. See - * [this issue](https://github.com/astorije/chai-immutable/issues/24) for - * more information. + * [issue #24](https://github.com/astorije/chai-immutable/issues/24) for more + * information. * * @name equal * @param {Collection} actual @@ -799,6 +839,32 @@ } }; + /** + * ### .referenceEqual(actual, expected) + * + * Asserts that the reference of `actual` is equivalent to the reference of + * `expected`. This method preserves the original behavior of Chai's `equal`. + * + * See [issue #210](https://github.com/astorije/chai-immutable/issues/210) for + * more details. + * + * ```js + * const a = List.of(1, 2, 3); + * const b = a; + * const c = List.of(1, 2, 3); + * assert.referenceEqual(a, b); + * assert.throws(() => assert.referenceEqual(a, c)); + * ``` + * + * @name referenceEqual + * @param {Collection} actual + * @param {Collection} expected + * @namespace Assert + * @api public + */ + + assert.referenceEqual = originalEqual; + /** * ### .notEqual(actual, expected) * @@ -827,6 +893,32 @@ } }; + /** + * ### .notReferenceEqual(actual, expected) + * + * Asserts that the reference of `actual` is not equivalent to the reference of + * `expected`. This method preserves the original behavior of Chai's `notEqual`. + * + * See [issue #210](https://github.com/astorije/chai-immutable/issues/210) for + * more details. + * + * ```js + * const a = List.of(1, 2, 3); + * const b = a; + * const c = List.of(1, 2, 3); + * assert.throws(() => assert.notReferenceEqual(a, b)); + * assert.notReferenceEqual(a, c); + * ``` + * + * @name notReferenceEqual + * @param {Collection} actual + * @param {Collection} expected + * @namespace Assert + * @api public + */ + + assert.notReferenceEqual = originalNotEqual; + /** * ### .sizeOf(collection, length) * diff --git a/test/test.js b/test/test.js index 9398ab1..e8f8833 100644 --- a/test/test.js +++ b/test/test.js @@ -186,6 +186,22 @@ describe('chai-immutable', function() { }); }); + describe('referenceEqual method', function() { + it('should pass for equal references', function() { + const list1 = List.of(1, 2, 3); + const list2 = list1; + + expect(list1).to.referenceEqual(list2); + }); + + it('should not pass for different immutable collections with equal values', function() { + const list1 = List.of(1, 2, 3); + const list2 = List.of(1, 2, 3); + + expect(list1).to.not.referenceEqual(list2); + }); + }); + describe('include method', function() { it('should pass given an existing value', function() { expect(new List([1, 2, 3])).to.include(2); @@ -930,6 +946,22 @@ describe('chai-immutable', function() { }); }); + describe('referenceEqual assertion', function() { + it('should pass for equal references', function() { + const list1 = List.of(1, 2, 3); + const list2 = list1; + + assert.referenceEqual(list1, list2); + }); + + it('should not pass for different immutable collections with equal values', function() { + const list1 = List.of(1, 2, 3); + const list2 = List.of(1, 2, 3); + + fail(() => assert.referenceEqual(list1, list2)); + }); + }); + describe('notEqual assertion', function() { it('should pass given different values', function() { assert.notEqual(list3, new List()); @@ -961,6 +993,22 @@ describe('chai-immutable', function() { }); }); + describe('notReferenceEqual assertion', function() { + it('should pass for different immutable collections with equal values', function() { + const list1 = List.of(1, 2, 3); + const list2 = List.of(1, 2, 3); + + assert.notReferenceEqual(list1, list2); + }); + + it('should not pass for different immutable collections with equal values', function() { + const list1 = List.of(1, 2, 3); + const list2 = list1; + + fail(() => assert.notReferenceEqual(list1, list2)); + }); + }); + describe('unoverridden strictEqual and deepEqual assertions', function() { it('should pass given equal values', function() { assert.strictEqual(list3, List.of(1, 2, 3));