Repository: baianat/vee-validate
Pull request #851 (2017-09-26 14:42:41)

Support scope value equals 0
Hi, Working with vee-validate, I created several scopes using an object position in an array.
Trying to validate with those scopes, some validations failed because of different scope type String vs Number.
I noticed that the first element was using a String scope '0' and the rest numbers 1..n

The change in this PR checked the scope validity, but still allows for the 0 value.



Patch:
diff --git a/src/core/generator.js b/src/core/generator.js
index 7918be3d..5a751eb6 100644
--- a/src/core/generator.js
+++ b/src/core/generator.js
@@ -1,4 +1,4 @@
-import { getScope, getDataAttribute, isObject, toArray, find, getPath, hasPath } from './utils';
+import { getScope, getDataAttribute, isObject, toArray, find, getPath, hasPath, isNullOrUndefined } from './utils';
 
 /**
  * Generates the options required to construct a field.
@@ -31,9 +31,9 @@ export default class Generator {
   }
 
   /**
-   * 
-   * @param {*} el 
-   * @param {*} binding 
+   *
+   * @param {*} el
+   * @param {*} binding
    */
   static resolveRules (el, binding) {
     if (!binding || !binding.expression) {
@@ -52,7 +52,7 @@ export default class Generator {
   }
 
   /**
-   * @param {*} vnode 
+   * @param {*} vnode
    */
   static resolveInitialValue (vnode) {
     const model = vnode.data.model || find(vnode.data.directives, d => d.name === 'model');
@@ -62,7 +62,7 @@ export default class Generator {
 
   /**
    * Creates a non-circular partial VM instance from a Vue instance.
-   * @param {*} vm 
+   * @param {*} vm
    */
   static makeVM (vm) {
     return {
@@ -93,8 +93,8 @@ export default class Generator {
 
   /**
    * Resolves the alias for the field.
-   * @param {*} el 
-   * @param {*} vnode 
+   * @param {*} el
+   * @param {*} vnode
    * @return {Function} alias getter
    */
   static resolveAlias (el, vnode) {
@@ -129,7 +129,7 @@ export default class Generator {
       scope = vnode.child.$attrs && vnode.child.$attrs['data-vv-scope'];
     }
 
-    return scope || getScope(el);
+    return !isNullOrUndefined(scope) ? scope : getScope(el);
   }
 
   /**


Test patch:
diff --git a/tests/generator.js b/tests/generator.js
index eb814e79..e17828b1 100644
--- a/tests/generator.js
+++ b/tests/generator.js
@@ -25,10 +25,10 @@ test('resolves the bound model', () => {
   // unwatchable model because it does not exist on the vm (context).
   vnode = { context: {}, data: { model: { expression: 'email' } } };
   expect(Generator.resolveModel({ arg: null, value: null }, vnode)).toBe(null);
-  
+
   // Part of a `v-for` cannot be watched by the $watch API.
   vnode = { context: {}, data: { model: { expression: 'emails[0]' } } };
-  expect(Generator.resolveModel({ arg: null, value: null }, vnode)).toBe(null);  
+  expect(Generator.resolveModel({ arg: null, value: null }, vnode)).toBe(null);
 });
 
 test('resolves the input scope', () => {
@@ -53,6 +53,9 @@ test('resolves the input scope', () => {
   el = document.querySelector('#el');
   expect(Generator.resolveScope(el, { arg: null, value: { scope: 's3'} })).toBe('s3');
 
+  el = document.querySelector('#el');
+  expect(Generator.resolveScope(el, { arg: null, value: { scope: 0} })).toBe(0);
+
   // defined in a components $attrs.
   el = document.querySelector('#el');
   vnode = { child: { $attrs: { 'data-vv-scope': 's4' } } };
@@ -85,7 +88,7 @@ test('resolves events', () => {
   expect(Generator.resolveEvents(el, {})).toBe('input');
   el = { getAttribute: () => null };
 
-  expect(Generator.resolveEvents(el, vnode)).toBe('focus');  
+  expect(Generator.resolveEvents(el, vnode)).toBe('focus');
 });
 
 test('resolves alias', () => {
@@ -97,7 +100,7 @@ test('resolves alias', () => {
   expect(Generator.resolveAlias(el, {})()).toBe('myAlias');
   el = { getAttribute: () => null };
 
-  expect(Generator.resolveAlias(el, vnode)()).toBe('alias'); 
+  expect(Generator.resolveAlias(el, vnode)()).toBe('alias');
 });
 
 describe('resolves the value getters', () => {
@@ -144,7 +147,7 @@ describe('resolves the value getters', () => {
       getter()
     ).toBe('other');
 
-    
+
     els[2].checked = true;
     expect(
       getter()
@@ -179,7 +182,7 @@ describe('resolves the value getters', () => {
     expect(
       getter()
     ).toEqual(['some', 'other']);
-    
+
     els[2].checked = true;
     expect(
       getter()
@@ -199,7 +202,7 @@ describe('resolves the value getters', () => {
     const getter = Generator.resolveGetter(el, vnode);
     expect(getter()).toBe('2');
   });
-  
+
   test('resolves for select multiple field', () => {
     document.body.innerHTML = `
       <select type="text" name="field" id="el" multiple>
@@ -254,7 +257,7 @@ describe('resolves the value getters', () => {
     vnode.child.value = 'changed';
     expect(getter()).toBe('changed');
     delete vnode.child.value;
-  
+
     vnode.child.$attrs = { 'data-vv-value-path': 'third' };
     expect(Generator.resolveGetter(el, vnode)()).toBe(33);
   });