Skip to content

Commit

Permalink
Handle empty objects in EqualKeys
Browse files Browse the repository at this point in the history
Closes #34.
  • Loading branch information
ruimarinho committed Jan 3, 2016
1 parent 15d8e94 commit 697cc58
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 8 deletions.
20 changes: 15 additions & 5 deletions src/asserts/equal-keys-assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,23 @@
*/

import { Violation } from 'validator.js';
import { difference, isPlainObject } from 'lodash';
import { difference, intersection, isArray, isPlainObject } from 'lodash';

/**
* Export `EqualKeysAssert`.
*/

export default function equalKeysAssert(keys) {
export default function equalKeysAssert(...keys) {
/**
* Class name.
*/

this.__class__ = 'EqualKeys';

if (keys.length === 1 && isArray(keys[0])) {
keys = keys[0];
}

/**
* Keys.
*/
Expand All @@ -32,10 +36,16 @@ export default function equalKeysAssert(keys) {
throw new Violation(this, value, { value: 'must_be_a_plain_object' });
}

const diff = difference(Object.keys(value), this.keys);
const keys = Object.keys(value);

if (keys.length === 0 || this.keys.length > keys.length) {
throw new Violation(this, value, { difference: difference(this.keys, keys) });
}

const intersects = intersection(this.keys, keys);

if (diff.length > 0) {
throw new Violation(this, value, { difference: diff });
if (keys.length > this.keys.length || intersects.length !== keys.length) {
throw new Violation(this, value, { difference: difference(keys, this.keys) });
}

return true;
Expand Down
56 changes: 53 additions & 3 deletions test/asserts/equal-keys-assert_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe('EqualKeysAssert', () => {
});
});

it('should throw an error if an object does not have the expected keys', () => {
it('should throw an error if the object not have the expected keys', () => {
try {
new Assert().EqualKeys(['foo']).validate({ bar: 'biz', foo: 'qux' });

Expand All @@ -45,17 +45,57 @@ describe('EqualKeysAssert', () => {
}
});

it('should throw an error if the object is empty', () => {
try {
new Assert().EqualKeys(['foo']).validate({});

should.fail();
} catch (e) {
e.show().violation.difference.should.eql(['foo']);
}
});

it('should allow setting no keys', () => {
try {
new Assert().EqualKeys().validate({ foo: 'oof' });

should.fail();
} catch (e) {
e.show().violation.difference.should.eql(['foo']);
}
});

it('should allow setting keys as multiple arguments', () => {
try {
new Assert().EqualKeys('foo', 'bar').validate({ foo: 'oof' });

should.fail();
} catch (e) {
e.show().violation.difference.should.eql(['bar']);
}
});

it('should allow setting a single key as a string argument', () => {
try {
new Assert().EqualKeys('bar').validate({ foo: 'oof' });

should.fail();
} catch (e) {
e.show().violation.difference.should.eql(['foo']);
}
});

it('should expose `assert` equal to `EqualKeys`', () => {
try {
new Assert().EqualKeys().validate(123);
new Assert().EqualKeys(['foo']).validate(123);

should.fail();
} catch (e) {
e.show().assert.should.equal('EqualKeys');
}
});

it('should expose `difference` on the violation', () => {
it('should expose `difference` on the violation if object has extra keys', () => {
try {
new Assert().EqualKeys(['foo']).validate({ bar: 'biz', foo: 'qux' });

Expand All @@ -65,6 +105,16 @@ describe('EqualKeysAssert', () => {
}
});

it('should expose `difference` on the violation if object has missing keys', () => {
try {
new Assert().EqualKeys(['foo', 'biz']).validate({ foo: 'qux' });

should.fail();
} catch (e) {
e.show().violation.difference.should.eql(['biz']);
}
});

it('should accept an object with expected keys', () => {
new Assert().EqualKeys(['foo', 'bar']).validate({ bar: 'biz', foo: 'qux' });
});
Expand Down

0 comments on commit 697cc58

Please sign in to comment.