What's the best way to assert that the expected results matches the actual results when both are arrays of objects? My immediate thought was to use Array prototype filter and check that the intersection is the same size as expected, i.e.:
describe('select',function(){
it("should return selected columns", function(done) {
var query = "select lunchTime, name";
var actual = ... results of the query, an array of anonymous objects ...
// expected results
var expected = [{"lunchTime": "12:00:00", "name": "John"},
{"lunchTime": "12:00:00", "name": "Dave"},
{"lunchTime": "13:00:00", "name": "Sally"},
{"lunchTime": "12:00:00", "name": "Ben"},
{"lunchTime": "12:00:00", "name": "Dana"},
{"lunchTime": "13:00:00", "name": "Mike"}];
var intersection = actual.filter(function(n) {
return expected.indexOf(n) != -1
});
expect(intersection).to.have.length(expected.length);
expect(actual).to.have.length(expected.length);
});
});
Does this approach make sense? Is there a better way to assert the query results match expectations?
As you noted, for sets, you can use:
expect(actual).to.have.members(expected);
This will fail if there are any members in expected
that are not in actual
, and vice versa.
You can also do:
expect(actual).to.contain.members(expected);
Which will fail if there are members in expected
that are not in actual
, but will not fail if there are members in actual
that are not in expected
. (In other words, actual
must be a superset of expected
).
If you're comparing objects, you probably want to deep compare:
expect(actual).to.deep.have.same.members(expected);
e.g.:
expect([{a:'a'}, {a:'b'}]).to.deep.have.same.members([{a:'a'}, {a:'b'}]);
(edited: to.have.same.members()
is actually the same as to.have.members()
.)