Evan You 11 лет назад
Родитель
Сommit
695a6d48e9
5 измененных файлов с 223 добавлено и 18 удалено
  1. 12 2
      src/filters/index.js
  2. 1 1
      src/parse/directive.js
  3. 15 15
      src/util/lang.js
  4. 189 0
      test/unit/specs/filters_spec.js
  5. 6 0
      test/unit/specs/util/lang_spec.js

+ 12 - 2
src/filters/index.js

@@ -1,6 +1,16 @@
 var _ = require('../util')
 var filters = module.exports = Object.create(null)
 
+/**
+ * Stringify value.
+ *
+ * @param {Number} indent
+ */
+
+filters.json = function (value, indent) {
+  return JSON.stringify(value, null, indent || 2)
+}
+
 /**
  * 'abc' => 'Abc'
  */
@@ -68,8 +78,8 @@ filters.currency = function (value, sign) {
 filters.pluralize = function (value) {
   var args = _.toArray(arguments, 1)
   return args.length > 1
-    ? (args[value - 1] || args[args.length - 1])
-    : (args[value - 1] || args[0] + 's')
+    ? (args[value % 10 - 1] || args[args.length - 1])
+    : (args[0] + (value === 1 ? '' : 's'))
 }
 
 /**

+ 1 - 1
src/parse/directive.js

@@ -121,7 +121,7 @@ exports.parse = function (s) {
       // an object literal or a ternary expression.
       if (argRE.test(arg)) {
         argIndex = i + 1
-        dir.arg = _.stripQuotes(arg)
+        dir.arg = _.stripQuotes(arg) || arg
       }
     } else if (
       c === 0x7C && // pipe

+ 15 - 15
src/util/lang.js

@@ -12,21 +12,6 @@ exports.guard = function (value) {
     : value
 }
 
-/**
- * Strip quotes from a string
- *
- * @param {String} str
- * @return {String}
- */
-
-exports.stripQuotes = function (str) {
-  var a = str.charCodeAt(0)
-  var b = str.charCodeAt(str.length - 1)
-  return a === b && (a === 0x22 || a === 0x27)
-    ? str.slice(1, -1)
-    : str
-}
-
 /**
  * Check and convert possible numeric numbers before
  * setting back to data
@@ -44,6 +29,21 @@ exports.guardNumber = function (value) {
     : Number(value)
 }
 
+/**
+ * Strip quotes from a string
+ *
+ * @param {String} str
+ * @return {String | false}
+ */
+
+exports.stripQuotes = function (str) {
+  var a = str.charCodeAt(0)
+  var b = str.charCodeAt(str.length - 1)
+  return a === b && (a === 0x22 || a === 0x27)
+    ? str.slice(1, -1)
+    : false
+}
+
 /**
  * Simple bind, faster than native
  *

+ 189 - 0
test/unit/specs/filters_spec.js

@@ -0,0 +1,189 @@
+var Vue = require('../../../src/vue')
+var filters = require('../../../src/filters')
+
+describe('Filters', function () {
+
+  it('json', function () {
+    var filter = filters.json
+    var obj = {a:{b:2}}
+    expect(filter(obj)).toBe(JSON.stringify(obj, null, 2))
+    expect(filter(obj, 4)).toBe(JSON.stringify(obj, null, 4))
+  })
+  
+  it('capitalize', function () {
+    var filter = filters.capitalize
+    var res = filter('fsefsfsef')
+    expect(res.charAt(0)).toBe('F')
+    expect(res.slice(1)).toBe('sefsfsef')
+    assertNumberAndFalsy(filter)
+  })
+
+  it('uppercase', function () {
+    var filter = filters.uppercase
+    expect(filter('fsefef')).toBe('FSEFEF')
+    assertNumberAndFalsy(filter)
+  })
+
+  it('lowercase', function () {
+    var filter = filters.lowercase
+    expect(filter('AWEsoME')).toBe('awesome')
+    assertNumberAndFalsy(filter)
+  })
+
+  it('pluralize', function () {
+    var filter = filters.pluralize
+    // single arg
+    var arg = 'item'
+    expect(filter(0, arg)).toBe('items')
+    expect(filter(1, arg)).toBe('item')
+    expect(filter(2, arg)).toBe('items')
+    // multi args
+    expect(filter(0, 'st', 'nd', 'rd', 'th')).toBe('th')
+    expect(filter(1, 'st', 'nd', 'rd', 'th')).toBe('st')
+    expect(filter(2, 'st', 'nd', 'rd', 'th')).toBe('nd')
+    expect(filter(3, 'st', 'nd', 'rd', 'th')).toBe('rd')
+    expect(filter(4, 'st', 'nd', 'rd', 'th')).toBe('th')
+  })
+
+  it('currency', function () {
+    var filter = filters.currency
+    // default
+    expect(filter(1234)).toBe('$1,234.00')
+    expect(filter(1234.45)).toBe('$1,234.45')
+    expect(filter(123443434.4343434)).toBe('$123,443,434.43')
+    // sign arg
+    expect(filter(2134, '@')).toBe('@2,134.00')
+    // falsy and 0
+    expect(filter(0)).toBe('$0.00')
+    expect(filter(false)).toBe('')
+    expect(filter(null)).toBe('')
+    expect(filter(undefined)).toBe('')
+  })
+
+  it('key', function () {
+    var filter = filters.key
+    expect(filter(null)).toBeUndefined()
+    var spy = jasmine.createSpy('filter:key')
+    var handler = filter(spy, 'enter')
+    handler({ keyCode: 0 })
+    expect(spy).not.toHaveBeenCalled()
+    handler({ keyCode: 13 })
+    expect(spy).toHaveBeenCalled()
+    // direct keycode
+    spy = jasmine.createSpy('filter:key')
+    handler = filter(spy, 13)
+    handler({ keyCode: 0 })
+    expect(spy).not.toHaveBeenCalled()
+    handler({ keyCode: 13 })
+    expect(spy).toHaveBeenCalled()
+  })
+
+  it('objToArray', function () {
+    var filter = filters._objToArray
+    var res = filter({a:1, b:2})
+    expect(res._converted).toBe(true)
+    expect(res[0].key).toBe('a')
+    expect(res[0].value).toBe(1)
+    expect(res[1].key).toBe('b')
+    expect(res[1].value).toBe(2)
+    // array
+    var arr = []
+    expect(filter(arr)).toBe(arr)
+    // non object/array
+    spyOn(Vue.util, 'warn')
+    expect(filter(123)).toBeUndefined()
+    expect(Vue.util.warn).toHaveBeenCalled()
+  })
+
+  it('filterBy', function () {
+    var filter = filters.filterBy
+    var arr = [
+      { a: 1, b: { c: 'hello' }},
+      { a: 1, b: 'hello'},
+      { a: 1, b: 2 }
+    ]
+    var vm = new Vue({
+      data: {
+        search: {
+          key: 'hello',
+          datakey: 'b.c'
+        }
+      }
+    })
+    var res
+    // normal
+    res = filter.call(vm, arr, 'search.key')
+    expect(res.length).toBe(2)
+    expect(res[0]).toBe(arr[0])
+    expect(res[1]).toBe(arr[1])
+    // data key
+    res = filter.call(vm, arr, 'search.key', 'search.datakey')
+    expect(res.length).toBe(1)
+    expect(res[0]).toBe(arr[0])
+    // quotes
+    res = filter.call(vm, arr, "'hello'", "'b.c'")
+    expect(res.length).toBe(1)
+    expect(res[0]).toBe(arr[0])
+    // delimiter
+    res = filter.call(vm, arr, 'search.key', 'in', 'search.datakey')
+    expect(res.length).toBe(1)
+    expect(res[0]).toBe(arr[0])
+    // no search key
+    res = filter.call(vm, arr, 'abc')
+    expect(res).toBe(arr)
+  })
+
+  it('orderBy', function () {
+    var filter = filters.orderBy
+    var arr = [
+      { a: { b: 0 }, c: 'b'},
+      { a: { b: 2 }, c: 'c'},
+      { a: { b: 1 }, c: 'a'}
+    ]
+    var res
+    // sort key
+    res = filter.call(new Vue({
+      data: {
+        sortby: 'a.b',
+      }
+    }), arr, 'sortby')
+    expect(res.length).toBe(3)
+    expect(res[0].a.b).toBe(0)
+    expect(res[1].a.b).toBe(1)
+    expect(res[2].a.b).toBe(2)
+    // reverse key
+    res = filter.call(new Vue({
+      data: { sortby: 'a.b', reverse: true }
+    }), arr, 'sortby', 'reverse')
+    expect(res.length).toBe(3)
+    expect(res[0].a.b).toBe(2)
+    expect(res[1].a.b).toBe(1)
+    expect(res[2].a.b).toBe(0)
+    // literal args
+    res = filter.call(new Vue(), arr, "'c'", '-1')
+    expect(res.length).toBe(3)
+    expect(res[0].c).toBe('c')
+    expect(res[1].c).toBe('b')
+    expect(res[2].c).toBe('a')
+    // negate reverse
+    res = filter.call(new Vue({
+      data: { reverse: true }
+    }), arr, "'c'", '!reverse')
+    expect(res.length).toBe(3)
+    expect(res[0].c).toBe('a')
+    expect(res[1].c).toBe('b')
+    expect(res[2].c).toBe('c')
+    // no sort key
+    res = filter.call(new Vue(), arr, 'abc')
+    expect(res).toBe(arr)
+  })
+})
+
+function assertNumberAndFalsy (filter) {
+  // should stringify numbers
+  expect(filter(12345)).toBe('12345')
+  expect(filter(0)).toBe('0')
+  expect(filter(undefined)).toBe('')
+  expect(filter(null)).toBe('')
+  expect(filter(false)).toBe('')
+}

+ 6 - 0
test/unit/specs/util/lang_spec.js

@@ -17,6 +17,12 @@ describe('Util - Language Enhancement', function () {
     expect(_.guardNumber('hello')).toBe('hello')
   })
 
+  it('strip quotes', function () {
+    expect(_.stripQuotes('"123"')).toBe('123')
+    expect(_.stripQuotes("'fff'")).toBe('fff')
+    expect(_.stripQuotes("'fff")).toBe(false)
+  })
+
   it('bind', function () {
     var original = function (a) {
       return this.a + a