Repository: TechnologyAdvice/obey (js)

Issue:
'default' validator doesn't work for booleans
Specifically when the default is `true`, but the record's value is `false`:
```
obey.model({
  enabled: { type: 'boolean', default: true }
})

// then elsewhere
validate({ enabled: false }) ==> { enabled: true }
```
Need to add a type check before returning the final value (for numbers as well, in case of `0`).

Pull request description:
Fix/bool default
Closes #68 

Patch:
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index e4190d0..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-sudo: required
-  
-language: node_js
-node_js:
-  - "6"
-  
-notifications:
-  email:
-    on_success: never
-    on_failure: never
-
-install:
-  - npm install
-
-script:
-  - npm run ci
-  
-after_success:
-  - npm install -g codeclimate-test-reporter
-  - codeclimate-test-reporter < coverage/lcov.info
\ No newline at end of file
diff --git a/README.md b/README.md
index e14801f..2ec0246 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
 
 Asynchronous Data Modelling and Validation.
 
-[![Travis branch](https://img.shields.io/travis/TechnologyAdvice/obey/master.svg)](https://travis-ci.org/TechnologyAdvice/obey)
+[![CircleCI](https://img.shields.io/circleci/project/TechnologyAdvice/obey/master.svg)](https://circleci.com/gh/TechnologyAdvice/obey)
 [![Code Climate](https://img.shields.io/codeclimate/github/TechnologyAdvice/obey.svg)](https://codeclimate.com/github/TechnologyAdvice/obey)
 [![Test Coverage](https://img.shields.io/codeclimate/coverage/github/TechnologyAdvice/obey.svg)](https://codeclimate.com/github/TechnologyAdvice/obey/coverage)
 ![Dependencies](https://img.shields.io/david/technologyadvice/obey.svg)
@@ -12,7 +12,7 @@ Asynchronous Data Modelling and Validation.
 
 - [Introduction](#introduction)
 - [Installation](#installation)
-- [API Documentation](#api-documentation)
+- [API Documentaion](#api-documentation)
 - [Rules](#rules)
 - [Models](#models)
 - [Validation](#validation)
diff --git a/circle.yml b/circle.yml
new file mode 100644
index 0000000..2d014bc
--- /dev/null
+++ b/circle.yml
@@ -0,0 +1,15 @@
+machine:
+  node:
+    version: 6
+dependencies:
+  override:
+    - npm install -g codeclimate-test-reporter
+    - npm install
+general:
+  artifacts:
+    - "coverage/lcov.info"
+test:
+  override:
+    - npm run ci
+  post:
+    - codeclimate-test-reporter < coverage/lcov.info
\ No newline at end of file
diff --git a/package.json b/package.json
index ba04de6..4e3d31b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "obey",
-  "version": "1.7.3",
+  "version": "1.7.2",
   "description": "Data modelling and validation library",
   "main": "index.js",
   "files": [
diff --git a/src/lib/validators.js b/src/lib/validators.js
index 31f3739..9975778 100644
--- a/src/lib/validators.js
+++ b/src/lib/validators.js
@@ -11,6 +11,9 @@ const validators = {
    * @param {*} value The value being validated
    */
   default: function(def, value) {
+    if (/^(number|boolean)$/.test(def.type)) {
+      if (value === 0 || value === false) return value
+    }
     return value || def.default
   },
 
diff --git a/src/typeStrategies/array.js b/src/typeStrategies/array.js
index 7039df6..5c1dea1 100644
--- a/src/typeStrategies/array.js
+++ b/src/typeStrategies/array.js
@@ -16,7 +16,7 @@ const array = {
       return context.fail('Value must not be empty array')
     }
     // Specific array sub-validation
-    if (!context.def.values) return context.value
+    if (!context.def.values) return true
     const promises = context.value.map((elem, idx) => {
       return rules.validate(context.def.values, elem, context.def.opts, `${context.key}[${idx}]`, context.errors, false, context.initData)
     })


Test patch:
diff --git a/test/src/lib/validators.spec.js b/test/src/lib/validators.spec.js
index 2a6403b..f7b634b 100644
--- a/test/src/lib/validators.spec.js
+++ b/test/src/lib/validators.spec.js
@@ -21,6 +21,22 @@ describe('validators', () => {
       const actual = validators.default(def, 'bar')
       expect(actual).to.equal('bar')
     })
+    it('uses falsey value for boolean type if value is already set', () => {
+      const def = {
+        type: 'boolean',
+        default: true
+      }
+      const actual = validators.default(def, false)
+      expect(actual).to.equal(false)
+    })
+    it('uses falsey value for number type if value is already set', () => {
+      const def = {
+        type: 'number',
+        default: 3
+      }
+      const actual = validators.default(def, 0)
+      expect(actual).to.equal(0)
+    })
   })
   describe('allow', () => {
     it('passes if value is in allow (object)', () => {
diff --git a/test/src/typeStrategies/array.spec.js b/test/src/typeStrategies/array.spec.js
index 18df495..4440d49 100644
--- a/test/src/typeStrategies/array.spec.js
+++ b/test/src/typeStrategies/array.spec.js
@@ -16,9 +16,8 @@ describe('type:array', () => {
       fail: sinon.spy(),
       def: {}
     }
-    const actual = array.default(context)
+    array.default(context)
     expect(context.fail).to.not.be.called
-    expect(actual).to.deep.equal(context.value)
   })
   it('allows an empty array to pass if empty flag is set to true', () => {
     const context = {