diff --git a/lib/alt.js b/lib/alt.js index d363f7c..04e7946 100644 --- a/lib/alt.js +++ b/lib/alt.js @@ -1,6 +1,7 @@ const _ = require('lodash'); const testcheck = require('testcheck'); +const tcg = testcheck.gen; const {gen} = require('./gen'); const isValid = require('./isValid'); @@ -9,13 +10,13 @@ function alt(...predicates) { const pairs = _.chunk(predicates, 2); return { - conform: values => { - const found = _.find(pairs, ([, predicate]) => isValid(predicate, values[0])); - return _.isUndefined(found) ? null : [found[0], values[0]]; + conform: ([value]) => { + const found = _.find(pairs, ([, predicate]) => isValid(predicate, value)); + return _.isUndefined(found) ? null : [found[0], value]; }, - gen: () => testcheck.gen.bind(testcheck.gen.null, () => { + gen: () => tcg.bind(tcg.null, () => { const result = gen(_.sample(pairs)[1]); - return testcheck.gen.array(result, 1); + return tcg.array(result, 1); }) }; } diff --git a/lib/conform.js b/lib/conform.js index 2e43d07..e8ec27f 100644 --- a/lib/conform.js +++ b/lib/conform.js @@ -5,13 +5,15 @@ const {getSpec} = require('./def'); const invalidString = ':node.spec/invalid'; function conform(spec, value) { + if (_.isFunction(spec)) { const result = spec(value); return result ? value : invalidString; } else { const predicate = getSpec(spec).conform; - + const result = predicate(value); + if (_.isBoolean(result)) { return result ? value : invalidString; } else { diff --git a/test/alt.js b/test/alt.js index c34f411..46e7bb5 100644 --- a/test/alt.js +++ b/test/alt.js @@ -23,15 +23,13 @@ describe('Test the alt function', () => { expect(s.conform('::bool-or-string', ['foo'])).to.eql([':s', 'foo']); }); - xit('should handle list of values', () => { - s.def('::opt', s.cat(':prop', isString, - ':val', s.alt(':s', isString, ':b', isBoolean))); - expect(s.conform('::opt', ['-verbose', true])).to.eql({':prop': '-verbose', ':val': [':b', true]}); + it('should handle list of values', () => { + s.def('::opt', s.cat(':prop', isString, ':val', '::bool-or-string')); + expect(s.conform('::opt', ['-verbose', [true]])).to.eql({':prop': '-verbose', ':val': [':b', true]}); }); xit('should handle list of values', () => { - s.def('::config', s.star(s.cat(':prop', isString, - ':val', s.alt(':s', isString, ':b', isBoolean)))); + s.def('::config', s.star(s.cat(':prop', isString,':val', '::bool-or-string'))); expect(s.conform('::config', ['-server', 'foo', '-verbose', true, 'user', 'joe'])).to.eql([]); }); diff --git a/test/cat.js b/test/cat.js index 8ed725b..3f0364a 100644 --- a/test/cat.js +++ b/test/cat.js @@ -23,6 +23,11 @@ describe('Test the cat function', () => { expect(s.conform('::ingredient', [2, ':teaspoon'])).to.eql({':quantity': 2, ':unit': ':teaspoon'}); }); + it('should handle nested concatenation', () => { + s.def('::named-ingredient', s.cat(':name', isString, ':ingredient', '::ingredient')); + expect(s.isValid('::named-ingredient', ['salt', [2, 'teaspoon']])).to.be.true; + }); + it('should implement a generator', () => { s.def('::ingredient', s.cat(':quantity', isInteger, ':unit', isString));