diff --git a/lib/contain.js b/lib/contain.js index 9afc464e..920d9d49 100755 --- a/lib/contain.js +++ b/lib/contain.js @@ -192,7 +192,7 @@ internals.object = function (ref, values, options) { } if (set.size) { - return !!options.part; + return options.part ? set.size < targets.length : false; } return true; @@ -254,7 +254,12 @@ internals.string = function (ref, values, options) { return false; } + let any = false; for (const match of map.values()) { + if (match.hits) { + any = true; + } + if (match.hits === match.allowed) { continue; } @@ -272,7 +277,7 @@ internals.string = function (ref, values, options) { } } - return true; + return !!any; }; diff --git a/test/index.js b/test/index.js index d2ab0419..516eb846 100755 --- a/test/index.js +++ b/test/index.js @@ -2136,6 +2136,9 @@ describe('contain()', () => { expect(Hoek.contain('ab', ['a', 'b', 'c'])).to.be.false(); expect(Hoek.contain('ab', ['a', 'b', 'c'], { only: true })).to.be.false(); expect(Hoek.contain('ab', ['a', 'b', 'c'], { only: true, once: true })).to.be.false(); + + expect(Hoek.contain('ab', ['c'], { part: true })).to.be.false(); + expect(Hoek.contain('ab', ['b'], { part: true })).to.be.true(); }); it('tests arrays', () => { @@ -2182,6 +2185,9 @@ describe('contain()', () => { expect(Hoek.contain(['a', 'b'], ['a', 'b', 'c'])).to.be.false(); expect(Hoek.contain(['a', 'b'], ['a', 'b', 'c'], { only: true })).to.be.false(); expect(Hoek.contain(['a', 'b'], ['a', 'b', 'c'], { only: true, once: true })).to.be.false(); + + expect(Hoek.contain(['a', 'b'], ['c'], { part: true })).to.be.false(); + expect(Hoek.contain(['a', 'b'], ['b'], { part: true })).to.be.true(); }); it('tests objects', () => { @@ -2226,6 +2232,9 @@ describe('contain()', () => { expect(Hoek.contain({ a: 'foo', b: 'bar' }, { a: 'foo', b: 'bar', c: 'x' })).to.be.false(); expect(Hoek.contain({ a: 'foo', b: 'bar' }, { a: 'foo', b: 'bar', c: 'x' }, { only: true })).to.be.false(); + expect(Hoek.contain({ a: 1, b: 2 }, ['c'], { part: true })).to.be.false(); + expect(Hoek.contain({ a: 1, b: 2 }, ['b'], { part: true })).to.be.true(); + // Getter check { @@ -2314,6 +2323,21 @@ describe('contain()', () => { expect(Hoek.contain([sym], Symbol())).to.be.false(); expect(Hoek.contain({ [sym]: 1 }, Symbol())).to.be.false(); }); + + it('compares error keys', () => { + + const error = new Error('test'); + expect(Hoek.contain(error, { x: 1 })).to.be.false(); + expect(Hoek.contain(error, { x: 1 }, { part: true })).to.be.false(); + + error.x = 1; + + expect(Hoek.contain(error, { x: 1 })).to.be.true(); + expect(Hoek.contain(error, { x: 1 }, { part: true })).to.be.true(); + + expect(Hoek.contain(error, { x: 1, y: 2 })).to.be.false(); + expect(Hoek.contain(error, { x: 1, y: 2 }, { part: true })).to.be.true(); + }); }); describe('flatten()', () => {