Skip to content

Commit c12f7ab

Browse files
author
Evan You
committed
More robust directive parsing
- Changed the char for splitting expressions from "," to "&" - Regex for matching the key now takes into account quoted strings and escaped chars - Added tests for the above special cases
1 parent 622570f commit c12f7ab

File tree

2 files changed

+28
-19
lines changed

2 files changed

+28
-19
lines changed

src/directive.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ var config = require('./config'),
55

66
// Regexes!
77
// regex to split multiple directive expressions
8-
SPLIT_RE = /(?:['"](?:\\.|[^'"])*['"]|\\.|[^,])+/g,
9-
KEY_RE = /^[^\|]+/,
8+
SPLIT_RE = /(?:['"](?:\\.|[^'"])*['"]|\\.|[^&]|&&)+/g,
9+
KEY_RE = /^(?:['"](?:\\.|[^'"])*['"]|\\.|[^\|]|\|\|)+/,
1010
ARG_RE = /^([\w- ]+):(.+)$/,
1111
FILTERS_RE = /\|[^\|]+/g,
1212
FILTER_TOKEN_RE = /[^\s']+|'[^']+'/g,
@@ -51,7 +51,7 @@ function Directive (definition, expression, rawKey, compiler, node) {
5151

5252
this.isExp = !SINGLE_VAR_RE.test(this.key)
5353

54-
var filterExps = expression.match(FILTERS_RE)
54+
var filterExps = this.expression.slice(rawKey.length).match(FILTERS_RE)
5555
if (filterExps) {
5656
this.filters = []
5757
var i = 0, l = filterExps.length, filter

test/unit/specs/directive.js

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ describe('UNIT: Directive', function () {
2222
it('should return array with the string if it\'s a single clause', function () {
2323
var e,
2424
test1 = 'fsef',
25-
test2 = 'ffsef + "fse,fsef"',
25+
test2 = 'ffsef + "fse&fsef"',
2626
test3 = 'fsef + \'fesfsfe\'',
27-
test4 = '\"fsefsf,fsef,fsef\"'
27+
test4 = '\"fsefsf&fsef&fsef\"'
2828

2929
e = Directive.split(test1)
3030
assert.strictEqual(e.length, 1)
@@ -45,28 +45,28 @@ describe('UNIT: Directive', function () {
4545

4646
it('should return split multiple clauses correctly', function () {
4747
var e,
48-
test1 = ['fsef', 'fsf:fsefsef'],
49-
test2 = ['asf-fsef:fsf', '"efs,sefsf"'],
50-
test3 = ['\'fsef,sef\'', 'fse:fsf'],
51-
test4 = ['\"fsef,fsef\"', 'sefsef\'fesfsf']
48+
test1 = ['fsef && ggg', 'fsf:fsefsef'],
49+
test2 = ['asf-fsef:fsf', '"efs&sefsf"'],
50+
test3 = ['\'fsef&sef\'', 'fse:fsf'],
51+
test4 = ['\"fsef&fsef\"', 'sefsef\'fesfsf']
5252

53-
e = Directive.split(test1.join(','))
54-
assert.strictEqual(e.length, 2)
53+
e = Directive.split(test1.join('&'))
54+
assert.strictEqual(e.length, 2, 'expression with &&')
5555
assert.strictEqual(e[0], test1[0])
5656
assert.strictEqual(e[1], test1[1])
5757

58-
e = Directive.split(test2.join(','))
59-
assert.strictEqual(e.length, 2)
58+
e = Directive.split(test2.join('&'))
59+
assert.strictEqual(e.length, 2, 'expression with double quotes')
6060
assert.strictEqual(e[0], test2[0])
6161
assert.strictEqual(e[1], test2[1])
6262

63-
e = Directive.split(test3.join(','))
64-
assert.strictEqual(e.length, 2)
63+
e = Directive.split(test3.join('&'))
64+
assert.strictEqual(e.length, 2, 'expression with single quotes')
6565
assert.strictEqual(e[0], test3[0])
6666
assert.strictEqual(e[1], test3[1])
6767

68-
e = Directive.split(test4.join(','))
69-
assert.strictEqual(e.length, 2)
68+
e = Directive.split(test4.join('&'))
69+
assert.strictEqual(e.length, 2, 'expression with escaped quotes')
7070
assert.strictEqual(e[0], test4[0])
7171
assert.strictEqual(e[1], test4[1])
7272
})
@@ -139,6 +139,15 @@ describe('UNIT: Directive', function () {
139139
assert.strictEqual(d.expression, exp.trim())
140140
})
141141

142+
it('should extract correct key', function () {
143+
var d = Directive.parse('sd-text', '"fsefse | fsefsef" && bc', compiler),
144+
e = Directive.parse('sd-text', '"fsefsf & fsefs" | test', compiler),
145+
f = Directive.parse('sd-text', '"fsef:fsefsf" || ff', compiler)
146+
assert.strictEqual(d.key, '"fsefse | fsefsef" && bc', 'pipe inside quotes and &&')
147+
assert.strictEqual(e.key, '"fsefsf & fsefs"', '& inside quotes with filter')
148+
assert.strictEqual(f.key, '"fsef:fsefsf" || ff', ': inside quotes and ||')
149+
})
150+
142151
it('should extract correct argument', function () {
143152
var d = Directive.parse('sd-text', 'todo:todos', compiler),
144153
e = Directive.parse('sd-text', 'todo:todos + abc', compiler),
@@ -190,15 +199,15 @@ describe('UNIT: Directive', function () {
190199
})
191200

192201
it('should extract correct filters (single filter)', function () {
193-
var d = Directive.parse('sd-text', 'abc | uppercase', compiler),
202+
var d = Directive.parse('sd-text', 'abc || a + "b|c" | uppercase', compiler),
194203
f = d.filters[0]
195204
assert.strictEqual(f.name, 'uppercase')
196205
assert.strictEqual(f.args, null)
197206
assert.strictEqual(f.apply('test'), 'TEST')
198207
})
199208

200209
it('should extract correct filters (single filter with args)', function () {
201-
var d = Directive.parse('sd-text', 'abc | pluralize item \'arg with spaces\'', compiler),
210+
var d = Directive.parse('sd-text', 'abc + \'b | c | d\' | pluralize item \'arg with spaces\'', compiler),
202211
f = d.filters[0]
203212
assert.strictEqual(f.name, 'pluralize', 'name')
204213
assert.strictEqual(f.args.length, 2, 'args length')

0 commit comments

Comments
 (0)