busypeoples / spected

Validation library
MIT License
703 stars 32 forks source link

TypeError: predicate is not a function #6

Open bookercodes opened 7 years ago

bookercodes commented 7 years ago

In index.js,

const spected = require('spected').default

const isGreaterThan = num => num > 5
const hasCapitalLetter = text => true

const validationRules = {
  name: [
    [ isGreaterThan(5),
      `Minimum Name length of 6 is required.`
    ],
  ],
  random: [
    [ isGreaterThan(7), 'Minimum Random length of 8 is required.' ],
    [ hasCapitalLetter, 'Random should contain at least one uppercase letter.' ],
  ]
}

const inputData = { name: 'abcdef', random: 'z'}

const res = spected(validationRules, inputData)

console.log(res)

When I run node index.js, I get this error:

► Users/booker/Code/spected-experiment/node_modules/spected/lib/index.js:74
  return predicate(value, inputs // eslint-disable-line no-nested-ternary
         ^

TypeError: predicate is not a function
    at runPredicate (/Users/booker/Code/spected-experiment/node_modules/spected/lib/index.js:74:10)
    at /Users/booker/Code/spected-experiment/node_modules/spected/lib/index.js:94:16
    at _map (/Users/booker/Code/spected-experiment/node_modules/ramda/src/internal/_map.js:6:19)
    at map (/Users/booker/Code/spected-experiment/node_modules/ramda/src/map.js:57:14)
    at /Users/booker/Code/spected-experiment/node_modules/ramda/src/internal/_dispatchable.js:39:15
    at f2 (/Users/booker/Code/spected-experiment/node_modules/ramda/src/internal/_curry2.js:25:16)
    at XWrap.f (/Users/booker/Code/spected-experiment/node_modules/spected/lib/index.js:93:36)
    at XWrap.module.exports.XWrap.@@transducer/step (/Users/booker/Code/spected-experiment/node_modules/ramda/src/internal/_xwrap.js:10:17)
    at _arrayReduce (/Users/booker/Code/spected-experiment/node_modules/ramda/src/internal/_reduce.js:11:36)
    at _reduce (/Users/booker/Code/spected-experiment/node_modules/ramda/src/internal/_reduce.js:44:14)
busypeoples commented 7 years ago

Thanks for the feedback, will have a look.

busypeoples commented 7 years ago

You need to change the isGreaterThan function, which is being run immediately as you're calling it with isGreaterThan(5). Change it to accept two arguments like a => b => b > a.

const spected = require('spected').default

const isGreaterThan = a => b => b > a
const hasCapitalLetter = text => x => true

const validationRules = {
  name: [
    [ isGreaterThan(5),
      `Minimum Name length of 6 is required.`
    ],
  ],
  random: [
    [ isGreaterThan(7), 'Minimum Random length of 8 is required.' ],
    [ hasCapitalLetter, 'Random should contain at least one uppercase letter.' ],
  ]
}

const inputData = { name: 'abcdef', random: 'z'}

const res = spected(validationRules, inputData)

console.log(res)
bookercodes commented 7 years ago

Ah, I see what is happening, thanks!

What do you think about an internal check like,

if (typeof predicate != "function") {
   throw new Error("The validator you supplied is not a function")
}

?

Hard to tell at this early stage, but it seems like it could be a common error.

busypeoples commented 7 years ago

Yes, it makes sense to handle invalid rules. Instead of throwing an error we can handle it differently.

In dev mode we can issue a console warning. Added a warning function https://github.com/25th-floor/spected/blob/master/src/utils/warning.js

In any case we should skip validating and return true instead, treat it the same as if no predicate function was defined. Currently passing in { name: [] } will return valid. If no function is provided, we skip and return true.