-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is intrinsically linked to the route parsing, but it shouldn't really be in the same place.
- Loading branch information
Showing
2 changed files
with
264 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
var qs = require('querystring'); | ||
|
||
module.exports = (function() { | ||
var isStaticUrl = function (statics, pathWithQueryString) { | ||
if (! ~pathWithQueryString.indexOf('.') || !! ~pathWithQueryString.indexOf('?')) { | ||
return false; | ||
} | ||
|
||
for (var i = statics.length; i--; ) { | ||
var st = pathWithQueryString.indexOf(statics[i]); | ||
if (!st) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
}; | ||
|
||
var parseParameters = function (patterns, pathWithQs) { | ||
var split = pathWithQs.split('?'); | ||
if (!split.length) { | ||
return {}; | ||
} | ||
|
||
|
||
var path = split[0]; | ||
if (path.substr(-1) != '/') { | ||
path += '/'; | ||
} | ||
|
||
var queryStringData = qs.parse(split[1] || ''); | ||
var pattern; | ||
var output; | ||
|
||
for (var i = patterns.length; i--; ) { | ||
pattern = patterns[i]; | ||
fn = pattern.func; | ||
|
||
output = fn(path); | ||
if (!output) { | ||
continue; | ||
} | ||
|
||
Utils.extend(output, pattern.data); | ||
Utils.extend(output, queryStringData); | ||
|
||
output._isStatic = false; | ||
return output; | ||
} | ||
|
||
return {}; | ||
}; | ||
|
||
var UrlParser = function (routes, statics, pathWithQueryString) { | ||
var isStatic = isStaticUrl(statics, pathWithQueryString); | ||
if (isStatic) { | ||
return { | ||
_isStatic: true | ||
}; | ||
} | ||
|
||
return parseParameters(routes, pathWithQueryString); | ||
}; | ||
|
||
// Expose some functions for unit testing. | ||
UrlParser.isStaticUrl = isStaticUrl; | ||
UrlParser.parseParameters = parseParameters; | ||
|
||
return UrlParser; | ||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
// This is heplful for some of the tests. | ||
Utils = require('../../Utilities/utils'); | ||
|
||
describe('UrlParser', function() { | ||
var urlParser; | ||
beforeEach(function() { | ||
urlParser = require('../../Routes/urlParser'); | ||
}); | ||
|
||
describe('isStaticUrl', function() { | ||
it('should return false if the URL is dynamic.', function() { | ||
var result = urlParser.isStaticUrl(['/test'], '/test.html?test=1'); | ||
|
||
result.should.be.false; | ||
}); | ||
|
||
it('should return false if the URL is not a file.', function() { | ||
var result = urlParser.isStaticUrl(['/test'], '/test/test2'); | ||
|
||
result.should.be.false; | ||
}); | ||
|
||
it('should return true if the URL matches a static path.', function() { | ||
var result = urlParser.isStaticUrl(['/test'], '/test/test2.js'); | ||
|
||
result.should.be.true; | ||
}); | ||
|
||
it('should return true if the URL matches one of many static paths.', function() { | ||
var result = urlParser.isStaticUrl(['/test', '/tes', '/t', '/hello', '/content'], '/test/test2.js'); | ||
|
||
result.should.be.true; | ||
}); | ||
|
||
it('should return false if the URL matches a static path not at the root level.', function() { | ||
var result = urlParser.isStaticUrl(['/test'], '/hello/test/test2.js'); | ||
|
||
result.should.be.false; | ||
}); | ||
}); | ||
|
||
describe('#parseParameters()', function() { | ||
it('should return an empty object for a blank URL.', function() { | ||
var result = urlParser.parseParameters([], ''); | ||
|
||
result.should.eql({}); | ||
}); | ||
|
||
it('should return an empty object when no route matches.', function() { | ||
var result = urlParser.parseParameters([], '/test'); | ||
|
||
result.should.eql({}); | ||
}); | ||
|
||
it('should gain parameters based on the matched route\'s additional parameters.', function() { | ||
var routeFunction = function() { | ||
return {}; | ||
}; | ||
|
||
var routeData = { | ||
someData: 'yes' | ||
}; | ||
|
||
var result = urlParser.parseParameters([{ | ||
func: routeFunction, | ||
data: routeData | ||
} | ||
], '/'); | ||
|
||
result.should.eql({ | ||
someData: 'yes', | ||
_isStatic: false | ||
}); | ||
}); | ||
|
||
it('should gain parameters from the query string.', function() { | ||
var routeFunction = function() { | ||
return {}; | ||
}; | ||
|
||
var routeData = {}; | ||
|
||
var result = urlParser.parseParameters([{ | ||
func: routeFunction, | ||
data: routeData | ||
} | ||
], '/?testData=test'); | ||
|
||
result.should.eql({ | ||
testData: 'test', | ||
_isStatic: false | ||
}); | ||
}); | ||
|
||
it('should override default parameters with query string parameters.', function() { | ||
var routeFunction = function() { | ||
return {}; | ||
}; | ||
|
||
var routeData = { | ||
testData: 'original data.' | ||
}; | ||
|
||
var result = urlParser.parseParameters([{ | ||
func: routeFunction, | ||
data: routeData | ||
} | ||
], '/?testData=test'); | ||
|
||
result.should.eql({ | ||
testData: 'test', | ||
_isStatic: false | ||
}); | ||
}); | ||
|
||
it('should only gain parameters from a matching route.', function() { | ||
var routeFunction = function() { | ||
return {}; | ||
}; | ||
|
||
var failedRouteFunction = function() { | ||
return false; | ||
}; | ||
|
||
var routeData = { | ||
testData: 'original data.' | ||
}; | ||
|
||
var failedRouteData = { | ||
otherTestData: 'original failed route data.' | ||
}; | ||
|
||
var result = urlParser.parseParameters([{ | ||
func: failedRouteFunction, | ||
data: failedRouteData | ||
}, { | ||
func: routeFunction, | ||
data: routeData | ||
}, { | ||
func: failedRouteFunction, | ||
data: failedRouteData | ||
} | ||
], '/test'); | ||
|
||
result.should.eql({ | ||
testData: 'original data.', | ||
_isStatic: false | ||
}); | ||
}); | ||
}); | ||
|
||
describe('public interface', function() { | ||
it('should return an object with only the _isStatic property if the URL matches a static path.', function() { | ||
var path = urlParser([], ['/test'], '/test/test.html'); | ||
|
||
path.should.eql({ | ||
_isStatic: true | ||
}); | ||
}); | ||
|
||
it('should ignore matching routes if a static path is available.', function() { | ||
var path = urlParser([{ | ||
func: function() { | ||
return {}; | ||
}, | ||
data: { | ||
test: 'data' | ||
} | ||
} | ||
], ['/test'], '/test/test.html'); | ||
|
||
path.should.eql({ | ||
_isStatic: true | ||
}); | ||
}); | ||
|
||
it('should use a route if no static path matches.', function() { | ||
var path = urlParser([{ | ||
func: function() { | ||
return {}; | ||
}, | ||
data: { | ||
test: 'data' | ||
} | ||
} | ||
], ['/Content'], '/test/test.html'); | ||
|
||
path.should.eql({ | ||
test: 'data', | ||
_isStatic: false | ||
}); | ||
}); | ||
}); | ||
}); |