Support differentiating -0 and +0 (sameValue assertion)
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 4k
- Forks
- 773
- PR merge metrics
- No merged PRs in 30d
Description
ECMAScript has two internal abstractions to compare values called sameValue and sameValueZero.
They are different than == and === as they return true for NaN values and compare -0 and +0.
Based on my experience with test262, and considering some personal goals I have for QUnit (still seeking funding for it) I believe it's fair to ship assertions that does the same comparisons, while I believe it's dangerous to simply modify strictEqual.
Object.is returns the exact result for sameValue, but that's an ES6 feature and not available on supported browsers. The results are the same as === but with special checks for NaN and bit precision zeros.
Here goes some data on how they would work:
| method | NaN, NaN | 0, -0 | -0, -0 | [1, 2], [1, 2] |
|---|---|---|---|---|
equal |
fail | pass | pass | fail |
strictEqual |
fail | pass | pass | fail |
deepEqual |
pass | pass | pass | pass |
propEqual |
pass | pass | pass | pass |
_.isEqual |
pass | pass | pass | pass |
sameValue |
pass | fail | pass | fail |
sameValueZero |
pass | pass | pass | fail |
The following code can provide some results, as it uses lodash's isEqual as well:
cc @jdalton
QUnit.assert.sameValue = function(a, b, message) {
var result;
if (a === b) {
// -0 vs +0
result = (a !== 0 || 1/a === 1/b);
} else
// NaN
if (a !== a && b !== b) {
result = true;
}
this.pushResult({
result,
actual: a,
expected: b,
message
});
};
QUnit.assert.sameValueZero = function(a, b, message) {
var result;
if (a === b) {
result = true;
} else
// NaN
if (a !== a && b !== b) {
result = true;
}
this.pushResult({
result,
actual: a,
expected: b,
message
});
};
var {test} = QUnit;
test("NaN", function(t) {
t.ok(_.isEqual(NaN, NaN), "lodash equals");
t.equal(NaN, NaN, "equal");
t.strictEqual(NaN, NaN, "strictEqual");
t.deepEqual(NaN, NaN, "deepEqual");
t.propEqual(NaN, NaN, "propEqual");
t.sameValue(NaN, NaN, "sameValue");
t.sameValueZero(NaN, NaN, "sameValueZero");
});
test("-0 vs +0", function(t) {
t.ok(_.isEqual(0, -0), "lodash equals");
t.equal(0, -0);
t.strictEqual(0, -0);
t.deepEqual(0, -0);
t.propEqual(0, -0);
t.sameValue(0, -0, "sameValue");
t.sameValueZero(0, -0);
});
test("-0", function(t) {
t.ok(_.isEqual(0, -0), "lodash equals");
t.equal(-0, -0);
t.strictEqual(-0, -0);
t.propEqual(-0, -0);
t.deepEqual(-0, -0);
t.sameValue(-0, -0);
t.sameValueZero(-0, -0);
});
test("arrays", function(t) {
t.ok(_.isEqual([1, 2], [1, 2]), "lodash equals");
t.equal([1, 2], [1, 2], "equal");
t.strictEqual([1, 2], [1, 2], "strictEqual");
t.propEqual([1, 2], [1, 2], "propEqual");
t.deepEqual([1, 2], [1, 2], "deepEqual");
t.sameValue([1, 2], [1, 2], "sameValue");
t.sameValueZero([1, 2], [1, 2], "sameValueZero");
});
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating QUnit's assertion API and its existing assertion tests; the issue names no specific files or test entry points. Compare the proposed sameValue and sameValueZero cases for NaN, signed zero, and arrays, then verify the assertions through the project's test suite.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- testing
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100