Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Implemented 'in' parser

  • Loading branch information...
commit 9dae412329682c3ebcb9706be1d0d29849972b7a 1 parent c787880
Thiago de Arruda authored
Showing with 61 additions and 12 deletions.
  1. +28 −12 src/router.coffee
  2. +33 −0 test/router.coffee
40 src/router.coffee
View
@@ -7,7 +7,7 @@ escapeRegex = (s) -> s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')
absoluteUrl = (req, pathname, search) ->
protocol = 'http'
- if req.headers['X-Forwarded-Protocol'] == 'https'
+ if req.protocol == 'https'
protocol = 'https'
rv = [protocol, '://', req.headers.host]
if req.port
@@ -37,7 +37,7 @@ class RegexExtractor
extract: (requestPath) ->
m = @regex.exec(requestPath)
- if !m then return null
+ if ! m then return null
return m.slice(1)
test: (requestPath) -> @extract(requestPath) != null
@@ -66,7 +66,7 @@ class RuleExtractor extends RegexExtractor
extract: (requestPath) ->
m = @regex.exec(requestPath)
- if !m then return null
+ if ! m then return null
params = @params
parsers = @parsers
extractedArgs = []
@@ -98,7 +98,7 @@ class Compiler
if opts?.base
base = opts.base
rv = parseInt(str, base)
- if !isFinite(rv) || rv.toString(base) != str
+ if ! isFinite(rv) || rv.toString(base) != str
return null
if opts
if (isFinite(opts.min) && rv < opts.min) ||
@@ -109,7 +109,7 @@ class Compiler
float: (str, opts) ->
str = str.trim()
rv = parseFloat(str)
- if !isFinite(rv) || rv.toString() != str
+ if ! isFinite(rv) || rv.toString() != str
return null
if opts
if (isFinite(opts.min) && rv < opts.min) ||
@@ -120,6 +120,15 @@ class Compiler
str: (str, opts) -> defaultParser(str, opts)
path: (str) -> str
+
+ in: (str, opts) ->
+ args = opts['*args']
+ for i in [0...args.length]
+ if args[i].toString() == str then break
+ if i < args.length
+ return args[i]
+ return null
+
if parsers
for own k, v in parsers
@parsers[k] = v
@@ -142,8 +151,10 @@ class Compiler
parserOptRe:
///
- ([a-zA-Z_][a-zA-Z0-9_]*) # Capture option name
- \s*=\s* # Delimiters
+ (?:
+ ([a-zA-Z_][a-zA-Z0-9_]*) # Capture option name
+ \s*=\s* # Delimiters
+ )?
(?:
(true|false) # Capture boolean literal
| # OR
@@ -154,15 +165,20 @@ class Compiler
///g
parseOpts: (rawOpts) ->
- rv = {}
+ rv =
+ '*args': []
while match = @parserOptRe.exec(rawOpts)
- name = match[1]
+ name = null
+ if match[1]
+ name = match[1]
if match[2] # boolean
- rv[name] = Boolean(match[2])
+ value = Boolean(match[2])
else if match[3] # number
- rv[name] = parseFloat(match[3])
+ value = parseFloat(match[3])
else # string
- rv[name] = match[4]
+ value = match[4]
+ if name then rv[name] = value # Named argument
+ else rv['*args'].push(value) # Unamed argument
return rv
compile: (pattern) ->
33 test/router.coffee
View
@@ -180,6 +180,39 @@ describe 'Builtin integer parser', ->
.expect(404, done)
+describe "Builtin 'in' parser", ->
+ router = createRouter()
+ app = connect()
+ app.use(router.route)
+
+ router.get '/posts/<in(t1,t2,t3,true,5.2):tag>', (req, res) ->
+ res.write(JSON.stringify(req.params.tag))
+ res.end()
+
+ it 'should match if arg is inside list', (done) ->
+ app.request()
+ .get('/posts/t1')
+ .end (res) ->
+ JSON.parse(res.body).should.eql('t1')
+ done()
+
+ it 'should not match if arg is outside list', (done) ->
+ app.request()
+ .get('/posts/1')
+ .expect(404, done)
+
+ it 'should convert value if needed', (done) ->
+ app.request()
+ .get('/posts/true')
+ .end (res) ->
+ JSON.parse(res.body).should.eql(true)
+ app.request()
+ .get('/posts/5.2')
+ .end (res) ->
+ JSON.parse(res.body).should.eql(5.2)
+ done()
+
+
describe 'Accessing branch urls without trailing slash', ->
router = createRouter()
app = connect()
Please sign in to comment.
Something went wrong with that request. Please try again.