Skip to content
This repository has been archived by the owner on Oct 24, 2023. It is now read-only.

Commit

Permalink
Merge pull request #24 from mstade/and
Browse files Browse the repository at this point in the history
And
  • Loading branch information
mstade committed Jan 31, 2015
2 parents 61cac6a + a22e94d commit db9c055
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 31 deletions.
3 changes: 2 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module.exports =
{ apply : require('./lib/apply')
{ and : require('./lib/and')
, apply : require('./lib/apply')
, assert : require('./lib/assert')
, call : require('./lib/call')
, compose : require('./lib/compose')
Expand Down
20 changes: 20 additions & 0 deletions lib/and.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module.exports = require('./variadic')(and)

function and(x, rest) {
if (x === undefined && isEmpty(rest)) return true

var result = val(x)

if (isnt(result) || isnt(rest)) return result

rest.every(function(x) {
return is(result = val(x))
})

return result
}

const isEmpty = require('./isEmpty')
, isnt = require('./isnt')
, val = require('./val')
, is = require('./is')
65 changes: 36 additions & 29 deletions lib/variadic.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,46 @@ function variadic(fn) {

switch (argc) {
case -1 : return fn
case 0 : return function (rest) { return apply(fn, this, argc, slice(arguments)) }
case 1 : return function (a, rest) { return apply(fn, this, argc, slice(arguments)) }
case 2 : return function (a, b, rest) { return apply(fn, this, argc, slice(arguments)) }
case 3 : return function (a, b, c, rest) { return apply(fn, this, argc, slice(arguments)) }
case 4 : return function (a, b, c, d, rest) { return apply(fn, this, argc, slice(arguments)) }
case 5 : return function (a, b, c, d, e, rest) { return apply(fn, this, argc, slice(arguments)) }
case 6 : return function (a, b, c, d, e, f, rest) { return apply(fn, this, argc, slice(arguments)) }
case 7 : return function (a, b, c, d, e, f, g, rest) { return apply(fn, this, argc, slice(arguments)) }
case 8 : return function (a, b, c, d, e, f, g, h, rest) { return apply(fn, this, argc, slice(arguments)) }
case 9 : return function (a, b, c, d, e, f, g, h, i, rest) { return apply(fn, this, argc, slice(arguments)) }
case 10 : return function (a, b, c, d, e, f, g, h, i, j, rest) { return apply(fn, this, argc, slice(arguments)) }
case 11 : return function (a, b, c, d, e, f, g, h, i, j, k, rest) { return apply(fn, this, argc, slice(arguments)) }
case 12 : return function (a, b, c, d, e, f, g, h, i, j, k, l, rest) { return apply(fn, this, argc, slice(arguments)) }
case 13 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, rest) { return apply(fn, this, argc, slice(arguments)) }
case 14 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, rest) { return apply(fn, this, argc, slice(arguments)) }
case 15 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, rest) { return apply(fn, this, argc, slice(arguments)) }
case 16 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, rest) { return apply(fn, this, argc, slice(arguments)) }
case 17 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, rest) { return apply(fn, this, argc, slice(arguments)) }
case 18 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, rest) { return apply(fn, this, argc, slice(arguments)) }
case 19 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, rest) { return apply(fn, this, argc, slice(arguments)) }
case 20 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, rest) { return apply(fn, this, argc, slice(arguments)) }
case 21 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, rest) { return apply(fn, this, argc, slice(arguments)) }
case 22 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, rest) { return apply(fn, this, argc, slice(arguments)) }
case 23 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, rest) { return apply(fn, this, argc, slice(arguments)) }
case 24 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, rest) { return apply(fn, this, argc, slice(arguments)) }
case 25 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, rest) { return apply(fn, this, argc, slice(arguments)) }
default : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, rest) { return apply(fn, this, argc, slice(arguments)) }
case 0 : return function (rest) { return apply(fn, this, argc, arguments) }
case 1 : return function (a, rest) { return apply(fn, this, argc, arguments) }
case 2 : return function (a, b, rest) { return apply(fn, this, argc, arguments) }
case 3 : return function (a, b, c, rest) { return apply(fn, this, argc, arguments) }
case 4 : return function (a, b, c, d, rest) { return apply(fn, this, argc, arguments) }
case 5 : return function (a, b, c, d, e, rest) { return apply(fn, this, argc, arguments) }
case 6 : return function (a, b, c, d, e, f, rest) { return apply(fn, this, argc, arguments) }
case 7 : return function (a, b, c, d, e, f, g, rest) { return apply(fn, this, argc, arguments) }
case 8 : return function (a, b, c, d, e, f, g, h, rest) { return apply(fn, this, argc, arguments) }
case 9 : return function (a, b, c, d, e, f, g, h, i, rest) { return apply(fn, this, argc, arguments) }
case 10 : return function (a, b, c, d, e, f, g, h, i, j, rest) { return apply(fn, this, argc, arguments) }
case 11 : return function (a, b, c, d, e, f, g, h, i, j, k, rest) { return apply(fn, this, argc, arguments) }
case 12 : return function (a, b, c, d, e, f, g, h, i, j, k, l, rest) { return apply(fn, this, argc, arguments) }
case 13 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, rest) { return apply(fn, this, argc, arguments) }
case 14 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, rest) { return apply(fn, this, argc, arguments) }
case 15 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, rest) { return apply(fn, this, argc, arguments) }
case 16 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, rest) { return apply(fn, this, argc, arguments) }
case 17 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, rest) { return apply(fn, this, argc, arguments) }
case 18 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, rest) { return apply(fn, this, argc, arguments) }
case 19 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, rest) { return apply(fn, this, argc, arguments) }
case 20 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, rest) { return apply(fn, this, argc, arguments) }
case 21 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, rest) { return apply(fn, this, argc, arguments) }
case 22 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, rest) { return apply(fn, this, argc, arguments) }
case 23 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, rest) { return apply(fn, this, argc, arguments) }
case 24 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, rest) { return apply(fn, this, argc, arguments) }
case 25 : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, rest) { return apply(fn, this, argc, arguments) }
default : return function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, rest) { return apply(fn, this, argc, arguments) }
}
}

function apply(fn, host, argc, argv) {
var rest = slice(argv, argc)
argv = slice(argv, 0, argc)
var rest = []

if (argv.length < argc) {
argv = slice(argv).concat(Array(argc - argv.length))
} else {
rest = slice(argv, argc)
argv = slice(argv, 0, argc)
}

argv.push(rest)

return fn.apply(host, argv)
Expand Down
50 changes: 50 additions & 0 deletions test/and.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const constantly = require('../lib/constantly')
, expect = require('must')
, and = require('../lib/and')

describe('`and`', function() {
describe('given zero arguments', function() {
it('should return `true`', function() {
expect(and()).to.equal(true)
})
})

describe('given one argument', function() {
it('should return the value of that argument', function() {
expect(and(1)).to.equal(1)
expect(and(0)).to.equal(0)
expect(and(false)).to.equal(false)
})

describe('and when that argument is a function', function() {
it('should return the value of calling that function', function() {
expect(and(constantly('wibble'))).to.equal('wibble')
})
})
})

describe('given two or more arguments', function() {
describe('when the values of all arguments are logically true', function() {
it('should return the last supplied value', function() {
expect(and(0, 1, 2, 3)).to.equal(3)
})
})

describe('when any one argument is logically false', function() {
it('should return the value that was logically false', function() {
expect(and(0, null, 1)).to.equal(null)
expect(and(false, true, 1)).to.equal(false)
expect(and(0, true, undefined)).to.equal(undefined)
})
})

describe('when an argument is a function', function() {
it('should call the function and evaluate its return value', function() {
var called = false

expect(and(0, function() { return (called = true) }, 1, 'yup')).to.equal('yup')
expect(called).to.be.true
})
})
})
})
22 changes: 21 additions & 1 deletion test/variadic.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ var variadic = require('../lib/variadic')
, slice = require('../lib/slice')
, each = require('../lib/each')
, src = require('../lib/src')
, is = require('../lib/is')

describe('`variadic`', function() {
describe('given an argument `fn`', function() {
Expand Down Expand Up @@ -32,6 +33,25 @@ describe('`variadic`', function() {
})
})

describe('of arity 1', function() {

it('should return a 1-arity function', function() {
var fn = variadic(function(rest) {})
expect(fn).to.have.length(1)
})

describe('when called without arguments', function() {
it('should set `rest` to an empty array', function(done) {
var fn = variadic(function(rest) {
is(Array, rest) && expect(rest).to.have.length(0)
done()
})

fn()
})
})
})

each(range(1, 28), function(n) {
describe('of arity '+n, function() {
var sig = slice('abcdefghijklmnopqrstuvwxyz', 0, n - 1).concat('rest')
Expand All @@ -49,7 +69,7 @@ describe('`variadic`', function() {

while (args.length) {
var fn = Function.apply(Function, sig.concat(
[ 'this.expect(arguments).to.have.length('+(args.length + 1)+')'
[ 'this.expect(arguments).to.have.length('+sig.length+')'
, 'this.expect(rest).to.be.empty'
].join('\n')
))
Expand Down

0 comments on commit db9c055

Please sign in to comment.