Arrays passed to .keys()
assertions are sorted (unexpectedly) by side-effect
#359
Conversation
c0f7b76
to
ed77323
(updated PR for style. Hard to find prior art on anons/closures in the tests!) |
Fantastic issue @gregglind! I wish every issue was as detailed as this |
expect(obj).keys(expected); | ||
expect(expected).deep.equal(backup); | ||
})() | ||
|
keithamus
Feb 5, 2015
Member
Stylistically I think these can just be inlined - I dont think there is a need for a closure. If you want to you could create a new it()
test instead.
Stylistically I think these can just be inlined - I dont think there is a need for a closure. If you want to you could create a new it()
test instead.
gregglind
Feb 5, 2015
Author
Contributor
- Thanks for the compliments!
Chai
is super useful on my most recent project at Mozilla.
- Closure it because
- it seemed a little gross no matter where I put it.
- I don't want to leak any of the vars out, and want to
- make it clear it's part of
keys(array)
testing.
- Nested 'it' isn't called, afaict (so sad!), so tried this:
it.only("keys(array), array should keep original order (#359)", function () {
var expected = [ 'b', "a" ];
var backup = expected.slice(0);
var obj = { "b": 1, "a" :1 };
expect(expected).deep.equal(backup);
expect(obj).keys(expected);
expect(expected).deep.equal(backup);
});
It's clearer, but less elegant.
As an inline alternative.
var issue359 = {
original: ['b', 'a'],
expected: [ 'b', "a" ],
obj: { "b": 1, "a" : 1 };
}
expect(issue359.expected).deep.equal(issue359.original);
expect(issue359.obj).keys(issue359.expected);
expect(issue359.expected, "keys should maintain original order").deep.equal(issue359.backup);
Or
var keys_maintain_original_order_issue359 = function () {
var expected = [ 'b', 'a' ];
var original_order = expected.slice(0);
var obj = { "b": 1, "a" :1 };
expect(expected).deep.equal(original_order);
expect(obj).keys(original_order);
expect(expected, "sorting happened unexpectedly in keys()")
.deep.equal(original_order);
}
keys_maintain_original_order_issue359();
Anyway, this is a weird case. I think I lean toward the last style. And this is probably more time on this than is really needed :) (But fun to consider alternatives!)
(pull updated to reflect last)
- Thanks for the compliments!
Chai
is super useful on my most recent project at Mozilla. - Closure it because
- it seemed a little gross no matter where I put it.
- I don't want to leak any of the vars out, and want to
- make it clear it's part of
keys(array)
testing.
- Nested 'it' isn't called, afaict (so sad!), so tried this:
it.only("keys(array), array should keep original order (#359)", function () {
var expected = [ 'b', "a" ];
var backup = expected.slice(0);
var obj = { "b": 1, "a" :1 };
expect(expected).deep.equal(backup);
expect(obj).keys(expected);
expect(expected).deep.equal(backup);
});
It's clearer, but less elegant.
As an inline alternative.
var issue359 = {
original: ['b', 'a'],
expected: [ 'b', "a" ],
obj: { "b": 1, "a" : 1 };
}
expect(issue359.expected).deep.equal(issue359.original);
expect(issue359.obj).keys(issue359.expected);
expect(issue359.expected, "keys should maintain original order").deep.equal(issue359.backup);
Or
var keys_maintain_original_order_issue359 = function () {
var expected = [ 'b', 'a' ];
var original_order = expected.slice(0);
var obj = { "b": 1, "a" :1 };
expect(expected).deep.equal(original_order);
expect(obj).keys(original_order);
expect(expected, "sorting happened unexpectedly in keys()")
.deep.equal(original_order);
}
keys_maintain_original_order_issue359();
Anyway, this is a weird case. I think I lean toward the last style. And this is probably more time on this than is really needed :) (But fun to consider alternatives!)
(pull updated to reflect last)
ed77323
to
d26d39f
(updated patch) |
.deep.equal(original_order); | ||
} | ||
keys_maintain_original_order_issue359(); | ||
|
keithamus
Feb 5, 2015
Member
Sorry @gregglind, I don't think I made myself clear in the last message. There is no need for these assertions to be made inside a new function scope at all. Line 606, 614 and 615 can be completely removed, so as to keep the code inline with the other assertions - at the same indentation level. Alternatively if you feel like separating the test, it should go in a new it()
e.g.
it('keys(array) does not mutate array'. function () {
...
})
If you do a new it()
test, it will need to be on the same indentation level as the other it()
s.
Sorry @gregglind, I don't think I made myself clear in the last message. There is no need for these assertions to be made inside a new function scope at all. Line 606, 614 and 615 can be completely removed, so as to keep the code inline with the other assertions - at the same indentation level. Alternatively if you feel like separating the test, it should go in a new it()
e.g.
it('keys(array) does not mutate array'. function () {
...
})
If you do a new it()
test, it will need to be on the same indentation level as the other it()
s.
d26d39f
to
68f3c02
All right, went with new |
Thanks so much @gregglind for sticking with it. Code is perfect now, fantastic job |
Arrays passed to `.keys()` assertions are sorted (unexpectedly) by side-effect
- *before* didn't throw on too many args for Array. Claim in bug to do so for Object. So throw on both? Neither?
- *before* didn't throw on too many args for Array. Claim in bug to do so for Object. So throw on both? Neither?
- `.keys(object)n => .keys(Object.keys(Object)` - added exceptions for 'if first arg is non-string, then it must be only arg. => `.keys(Array|Object, ...)` Warning: `Object.keys` must exist on systems to use this functionality.
- `.keys(object)n => .keys(Object.keys(Object)` - added exceptions for 'if first arg is non-string, then it must be only arg. => `.keys(Array|Object, ...)` Warning: `Object.keys` must exist on systems to use this functionality.
- `.keys(object)n => .keys(Object.keys(Object)` - added exceptions for 'if first arg is non-string, then it must be only arg. => `.keys(Array|Object, ...)` Warning: `Object.keys` must exist on systems to use this functionality.
Example
This is caused by the
.sort()
at https://github.com/chaijs/chai/blob/master/lib/chai/core/assertions.js#L1070Possible Repairs
sort
()expected
list earlier in the function.Other implications
sort
issues. I didn't see any.Action Request
If this sounds good, I can write up a PR tomorrow with whichever solution makes the most sense.