diff --git a/lib/cat.js b/lib/cat.js index d8211a6..888a136 100644 --- a/lib/cat.js +++ b/lib/cat.js @@ -37,13 +37,14 @@ function cat(...predicates) { gen: () => tcg.array(pairs.map(([, p]) => gen(p))), describe: () => [cat.name, ...describe(predicates)], explain: function*(values, {via}) { - yield* explainLength(values, pairs, via); + yield* explainInsufficientInput(values, pairs, via); + yield* explainExtraInput(pairs, values, via); yield* explainInvalid(values, pairs, via); } }; } -function* explainLength(values, specs, via) { +function* explainInsufficientInput(values, specs, via) { // TODO: not correct for complicated cases. Use _conform if (values.length < specs.length) { const [key] = specs[values.length]; @@ -58,6 +59,19 @@ function* explainLength(values, specs, via) { } } +function* explainExtraInput(specs, values, via) { + if (values.length > specs.length) { + yield { + path: [], + reason: 'Extra input', + pred: ['cat', ...describe(specs)], + val: _.tail(values), + via, + 'in': [1] + }; + } +} + function* explainInvalid(values, specs, via) { if (values.length !== specs.length) return; diff --git a/test/cat.js b/test/cat.js index 996455e..fe0e4c3 100644 --- a/test/cat.js +++ b/test/cat.js @@ -64,7 +64,22 @@ describe('Test the cat function', () => { ] }); }); - + + xit('explainData should reject extra input', () => { + expect(s.explainData('::ingredient', [2, ':teaspoon', 13])).to.be.eql({ + problems: [ + { + path: [], + reason: 'Extra input', + pred: ['cat', ':quantity', 'isNumber', ':unit', 'isString'], + val: [true], + via: ['::bool-or-string'], + 'in': [1] + } + ] + }); + }); + it('explainData should report about wrong type', () => { expect(s.explainData('::ingredient', [2, 13])).to.eql({ problems: [