Skip to content
This repository was archived by the owner on Sep 3, 2021. It is now read-only.

Commit 127745e

Browse files
achingbrainvmx
authored andcommitted
fix: allow CIDs to be compared through deep equality
The changes in #131 broke the tests of IPFS and probably quite a few other modules. This sort of thing used to work, now does not: ```js expect(ipfs.bitswap.unwant.calledWith(new CID(cidStr), defaultOptions)).to.be.true() ``` The reason it breaks is because internally `calledWith` does a `deepEqual` on the args which compares (among other things) the properties of the passed objects. We used to use `Object.defineProperty` to create cached versions of expensive to calculate fields which makes fields non-enumerable by default so they are skipped during the `deepEqual` check. Now we just set the fields on the object which means instances have different fields depending on which constructor branch was hit or worse, if the instances properties have been accessed.
1 parent 26c436d commit 127745e

File tree

3 files changed

+51
-3
lines changed

3 files changed

+51
-3
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"uint8arrays": "^1.1.0"
4646
},
4747
"devDependencies": {
48+
"@sinonjs/samsam": "^5.3.0",
4849
"aegir": "^29.0.1",
4950
"multihashing-async": "^2.0.1"
5051
},

src/index.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ class CID {
9595
this.multibaseName = 'base58btc'
9696
}
9797
CID.validateCID(this)
98-
this.string = version
98+
Object.defineProperty(this, 'string', { value: version })
9999
return
100100
}
101101

@@ -164,6 +164,7 @@ class CID {
164164
*
165165
*/
166166
get bytes () {
167+
// @ts-ignore
167168
let bytes = this._bytes
168169

169170
if (!bytes) {
@@ -179,7 +180,7 @@ class CID {
179180
}
180181

181182
// Cache this Uint8Array so it doesn't have to be recreated
182-
this._bytes = bytes
183+
Object.defineProperty(this, '_bytes', { value: bytes })
183184
}
184185

185186
return bytes
@@ -248,7 +249,9 @@ class CID {
248249
* @returns {string}
249250
*/
250251
toBaseEncodedString (base = this.multibaseName) {
252+
// @ts-ignore non enumerable cache property
251253
if (this.string && this.string.length !== 0 && base === this.multibaseName) {
254+
// @ts-ignore non enumerable cache property
252255
return this.string
253256
}
254257
let str
@@ -264,7 +267,7 @@ class CID {
264267
}
265268
if (base === this.multibaseName) {
266269
// cache the string value
267-
this.string = str
270+
Object.defineProperty(this, 'string', { value: str })
268271
}
269272
return str
270273
}

test/index.spec.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const multihashing = require('multihashing-async')
88
const uint8ArrayFromString = require('uint8arrays/from-string')
99
const uint8ArrayToString = require('uint8arrays/to-string')
1010
const CID = require('../src')
11+
const { deepEqual } = require('@sinonjs/samsam')
1112

1213
describe('CID', () => {
1314
let hash
@@ -448,4 +449,47 @@ describe('CID', () => {
448449
expect(cid.toBaseEncodedString()).to.equal(base32String)
449450
})
450451
})
452+
453+
describe('equality', () => {
454+
it('should be deeply equal', () => {
455+
const cid1 = new CID('QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n')
456+
const cid2 = new CID('QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n')
457+
458+
expect(deepEqual(cid1, cid2)).to.be.true()
459+
})
460+
461+
it('should be deeply equal when constructed from another CID', () => {
462+
const cid1 = new CID('QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n')
463+
const cid2 = new CID(cid1)
464+
465+
expect(deepEqual(cid1, cid2)).to.be.true()
466+
})
467+
468+
it('should be deeply equal when constructed from an Uint8Array', () => {
469+
const cid1 = new CID('QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n')
470+
const cid2 = new CID(cid1.multihash)
471+
472+
expect(deepEqual(cid1, cid2)).to.be.true()
473+
})
474+
475+
it('should still be deeply equal after turning one into a base encoded string', () => {
476+
const cid1 = new CID('QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n')
477+
const cid2 = new CID(cid1.multihash)
478+
const cid3 = new CID(cid1.multihash)
479+
480+
cid3.toBaseEncodedString()
481+
482+
expect(deepEqual(cid2, cid3)).to.be.true()
483+
})
484+
485+
it('should still be deeply equal after turning one into bytes', () => {
486+
const cid1 = new CID('QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n')
487+
const cid2 = new CID(cid1.multihash)
488+
const cid3 = new CID(cid1.multihash)
489+
490+
cid3.bytes // eslint-disable-line no-unused-expressions
491+
492+
expect(deepEqual(cid2, cid3)).to.be.true()
493+
})
494+
})
451495
})

0 commit comments

Comments
 (0)