Skip to content

Commit

Permalink
Don't require array-like subtypes to have the same constructor in ord…
Browse files Browse the repository at this point in the history
…er to be equal
  • Loading branch information
papandreou committed Jul 10, 2023
1 parent e1d2aa2 commit 3ff8d27
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 36 deletions.
71 changes: 35 additions & 36 deletions lib/types.js
Expand Up @@ -453,50 +453,49 @@ module.exports = function (expect) {
equal(a, b, equal) {
if (a === b) {
return true;
} else if (a.constructor === b.constructor && a.length === b.length) {
let i;
} else if (a.length !== b.length) {
return false;
} else if (expect.findTypeOf(a) !== expect.findTypeOf(b)) {
return false;
}

// compare numerically indexed elements
for (i = 0; i < a.length; i += 1) {
if (!equal(this.valueForKey(a, i), this.valueForKey(b, i))) {
return false;
}
let i;

// compare numerically indexed elements
for (i = 0; i < a.length; i += 1) {
if (!equal(this.valueForKey(a, i), this.valueForKey(b, i))) {
return false;
}
}

// compare non-numerical keys if enabled for the type
if (!this.numericalPropertiesOnly) {
const aKeys = this.getKeysNonNumerical(a).filter((key) => {
// include keys whose value is not undefined
return typeof this.valueForKey(a, key) !== 'undefined';
});
const bKeys = this.getKeysNonNumerical(b).filter((key) => {
// include keys whose value is not undefined on either LHS or RHS
return (
typeof this.valueForKey(b, key) !== 'undefined' ||
typeof this.valueForKey(a, key) !== 'undefined'
);
});
// compare non-numerical keys if enabled for the type
if (!this.numericalPropertiesOnly) {
const aKeys = this.getKeysNonNumerical(a).filter((key) => {
// include keys whose value is not undefined
return typeof this.valueForKey(a, key) !== 'undefined';
});
const bKeys = this.getKeysNonNumerical(b).filter((key) => {
// include keys whose value is not undefined on either LHS or RHS
return (
typeof this.valueForKey(b, key) !== 'undefined' ||
typeof this.valueForKey(a, key) !== 'undefined'
);
});

if (aKeys.length !== bKeys.length) {
return false;
}
if (aKeys.length !== bKeys.length) {
return false;
}

for (i = 0; i < aKeys.length; i += 1) {
if (
!equal(
this.valueForKey(a, aKeys[i]),
this.valueForKey(b, bKeys[i])
)
) {
return false;
}
for (i = 0; i < aKeys.length; i += 1) {
if (
!equal(this.valueForKey(a, aKeys[i]), this.valueForKey(b, bKeys[i]))
) {
return false;
}
}

return true;
} else {
return false;
}

return true;
},
prefix(output) {
return output.text('[');
Expand Down
32 changes: 32 additions & 0 deletions test/types/array-like-type.spec.js
Expand Up @@ -144,6 +144,38 @@ describe('array-like type', () => {
}
);
}

it('should treat identical instances of the same subtype as equal, even though they have different constructors', () => {
clonedExpect.addType({
name: 'subtypeOfSimpleArrayLike',
base: 'simpleArrayLike',
identify(value) {
return value && value._subtypeOfSimpleArrayLike;
},
});

class MyArray extends Array {
constructor(value) {
super(value);
this._subtypeOfSimpleArrayLike = true;
}
}

class MyOtherArray extends Array {
constructor(value) {
super(value);
this._subtypeOfSimpleArrayLike = true;
}
}

const a = new MyArray();
a.push(123);
const b = new MyOtherArray();
b.push(123);

clonedExpect(a, 'to equal', b);
clonedExpect(b, 'to equal', a);
});
});

describe('with a subtype that disables indentation', () => {
Expand Down

0 comments on commit 3ff8d27

Please sign in to comment.