diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2d8d66e --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +npm-debug.log +.grunt diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..2261467 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,14 @@ +language: node_js +node_js: + - "0.8" +before_install: + - "export DISPLAY=:99.0" + - "sh -e /etc/init.d/xvfb start" + - sleep 3 # give xvfb some time to start + - "wget http://selenium.googlecode.com/files/selenium-server-standalone-2.31.0.jar" + - "java -jar selenium-server-standalone-2.31.0.jar &" + - sleep 3 # give some time to bind to sockets, etc +before_script: + - npm install -g grunt-cli + - npm install grunt grunt-contrib-jshint grunt-contrib-uglify grunt-webdriver grunt-contrib-connect +script: grunt -v diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000..7f7f73d --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,61 @@ +module.exports = function(grunt) { + grunt.initConfig({ + + connect: { + server: { + options: { + port: 9001, + base: '.' + } + } + }, + + webdriver: { + pathjs: { + options: { + logLevel: 'silent', + browser: 'firefox', + binary: null + }, + url: 'http://localhost:9001/tests/path.js.test.html', + tests: ['./tests/spec/pathjsSpec.js'] + }, + pathjs_min: { + options: { + logLevel: 'silent', + browser: 'firefox', + binary: null + }, + url: 'http://localhost:9001/tests/path.min.js.test.html', + tests: ['./tests/spec/pathjsSpec.js'] + } + }, + + uglify: { + my_target: { + files: { + 'path.min.js': ['path.js'] + } + } + }, + + jshint: { + options: { + "globals": { + "exports": true, + "buster": true + } + }, + all: ['Gruntfile.js', 'path.js', 'tests/spec/**/*.js'] + } + + }); + + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-contrib-connect'); + grunt.loadNpmTasks('grunt-webdriver'); + + grunt.registerTask('default', ['jshint', 'uglify', 'connect', 'webdriver']); + +}; diff --git a/path.js b/path.js index d56a2d8..66e6a7a 100644 --- a/path.js +++ b/path.js @@ -41,7 +41,7 @@ var Path = { window.onpopstate = Path.history.popState; } else { if(Path.history.fallback){ - for(route in Path.routes.defined){ + for( var route in Path.routes.defined){ if(route.charAt(0) != "#"){ Path.routes.defined["#"+route] = Path.routes.defined[route]; Path.routes.defined["#"+route].path = "#"+route; @@ -105,7 +105,7 @@ var Path = { } }, 'listen': function () { - var fn = function(){ Path.dispatch(location.hash); } + var fn = function(){ Path.dispatch(location.hash); }; if (location.hash === "") { if (Path.routes.root !== null) { @@ -162,7 +162,7 @@ Path.core.route.prototype = { }, 'partition': function () { var parts = [], options = [], re = /\(([^}]+?)\)/g, text, i; - while (text = re.exec(this.path)) { + while( !!(text = re.exec(this.path)) ) { parts.push(text[1]); } options.push(this.path.split("(")[0]); diff --git a/tests/path.js.test.html b/tests/path.js.test.html index 9d870fa..0f11936 100644 --- a/tests/path.js.test.html +++ b/tests/path.js.test.html @@ -4,144 +4,101 @@ PathJS Test -
-

Test Suite

+
+

Test Suite

- Path.js uses a very straightforward method of testing. We manually construct + Path.js uses a very straightforward method of testing. We manually construct a series of method calls that the library should execute under normal working conditions. We then use JavaScript to simulate the URL changes, and compare the final result with what the result should actually be. If the end result @@ -149,7 +106,7 @@

Test Suite

is not suitable for use. The expected test results are as follows:

- + @@ -176,16 +133,12 @@

Test Suite

- +
Token Reason
Token Reason
F[enter] Enter method of F, as it is root
F[action] True action of F, as it is root
A[enter] Enter method of A, as it is looped
H(one=N/A, two=N/A) Optional parameters with only the require part submitted
H(one=10, two=N/A) Optional parameters with one optional part submitted
H(one=10, two=20) Optional parameters two levels deep
H(one=10, two=N/A) Testing "back" functionality
H(one=10, two=N/A) Testing "back" functionality


-

Expected

-
F[enter]::F[action]::A[enter]::A[action]::A[exit]::B[enter]::B[action]::C[action]::C[exit]::RESCUE::RESCUE::E[enter](parse id=1)::E[action](parse id=1)::E[enter](parse id=2)::E[action](parse id=2)::E[action](check id=3)::E[exit](check id=3)::F[enter]::F[action]::G[enter 1]::G[enter 2]::G[enter 3]::G[enter 4]::H(one=N/A, two=N/A)::H(one=10, two=N/A)::H(one=10, two=20)::H(one=10, two=N/A)

Actual

-

Grade

-
diff --git a/tests/path.min.js.test.html b/tests/path.min.js.test.html index bdcb2e1..c72052d 100644 --- a/tests/path.min.js.test.html +++ b/tests/path.min.js.test.html @@ -4,184 +4,141 @@ PathJS Test -
-

Test Suite

-

- Path.js uses a very straightforward method of testing. We manually construct - a series of method calls that the library should execute under normal working - conditions. We then use JavaScript to simulate the URL changes, and compare - the final result with what the result should actually be. If the end result - is anything but perfect, the test is a failure, and this version of Path.JS - is not suitable for use. The expected test results are as follows: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Token Reason
F[enter] Enter method of F, as it is root
F[action] True action of F, as it is root
A[enter] Enter method of A, as it is looped
A[action] True action of A, as it is looped
A[exit] Exit method of A, as we move to next route
B[enter] Enter method of B, as it is looped
B[action] True action of B, as it is looped
C[action] True action of C
C[exit] Exit method of C, as we move to next route
RESCUE Rescue a route that wasn't found (D1)
RESCUE Rescue a route that wasn't found (D2)
E[enter](parse) Enter method of a param parsed route
E[action](parse id=1) True action of the route, with param of id=1
E[enter](parse) Enter method of the same route again
E[action](parse id=2) True action of the route, with param of id=2
E[action](check id=3) True action of the next route, with param id=3
E[exit](check) Exit method of parameterized route
F[enter] Enter method of F again, our final route
F[action] True action of F, our final route
G[enter 1] First enter method of G
G[enter 2] Second enter method of G
G[enter 3] Third enter method of G
G[enter 4] Last enter method of G - Returns false, stops execution
H(one=N/A, two=N/A) Optional parameters with only the require part submitted
H(one=10, two=N/A) Optional parameters with one optional part submitted
H(one=10, two=20) Optional parameters two levels deep
H(one=10, two=N/A) Testing "back" functionality
+
+

Test Suite

+

+ Path.js uses a very straightforward method of testing. We manually construct + a series of method calls that the library should execute under normal working + conditions. We then use JavaScript to simulate the URL changes, and compare + the final result with what the result should actually be. If the end result + is anything but perfect, the test is a failure, and this version of Path.JS + is not suitable for use. The expected test results are as follows: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Token Reason
F[enter] Enter method of F, as it is root
F[action] True action of F, as it is root
A[enter] Enter method of A, as it is looped
A[action] True action of A, as it is looped
A[exit] Exit method of A, as we move to next route
B[enter] Enter method of B, as it is looped
B[action] True action of B, as it is looped
C[action] True action of C
C[exit] Exit method of C, as we move to next route
RESCUE Rescue a route that wasn't found (D1)
RESCUE Rescue a route that wasn't found (D2)
E[enter](parse) Enter method of a param parsed route
E[action](parse id=1) True action of the route, with param of id=1
E[enter](parse) Enter method of the same route again
E[action](parse id=2) True action of the route, with param of id=2
E[action](check id=3) True action of the next route, with param id=3
E[exit](check) Exit method of parameterized route
F[enter] Enter method of F again, our final route
F[action] True action of F, our final route
G[enter 1] First enter method of G
G[enter 2] Second enter method of G
G[enter 3] Third enter method of G
G[enter 4] Last enter method of G - Returns false, stops execution
H(one=N/A, two=N/A) Optional parameters with only the require part submitted
H(one=10, two=N/A) Optional parameters with one optional part submitted
H(one=10, two=20) Optional parameters two levels deep
H(one=10, two=N/A) Testing "back" functionality


-

Expected

-
F[enter]::F[action]::A[enter]::A[action]::A[exit]::B[enter]::B[action]::C[action]::C[exit]::RESCUE::RESCUE::E[enter](parse)::E[action](parse id=1)::E[enter](parse)::E[action](parse id=2)::E[action](check id=3)::E[exit](check)::F[enter]::F[action]::G[enter 1]::G[enter 2]::G[enter 3]::G[enter 4]::H(one=N/A, two=N/A)::H(one=10, two=N/A)::H(one=10, two=20)::H(one=10, two=N/A)
+

Expected

+
F[enter]::F[action]::A[enter]::A[action]::A[exit]::B[enter]::B[action]::C[action]::C[exit]::RESCUE::RESCUE::E[enter](parse)::E[action](parse id=1)::E[enter](parse)::E[action](parse id=2)::E[action](check id=3)::E[exit](check)::F[enter]::F[action]::G[enter 1]::G[enter 2]::G[enter 3]::G[enter 4]::H(one=N/A, two=N/A)::H(one=10, two=N/A)::H(one=10, two=20)::H(one=10, two=N/A)

Actual

Grade

diff --git a/tests/spec/pathjsSpec.js b/tests/spec/pathjsSpec.js new file mode 100644 index 0000000..263b391 --- /dev/null +++ b/tests/spec/pathjsSpec.js @@ -0,0 +1,80 @@ +var assertions = buster.assertions, + assert = assertions.assert, + refute = assertions.refute, + selector_console = "div#actual"; + +exports.name = "Simple Test"; +exports.tests = [ + { + name: "checks the following routes: root -> #A -> #B -> #C -> #D1 -> #D2 -> #E/params/1/parse -> #E/params/2/parse -> #E/params/3/check -> #F -> #G -> #H -> #H/10 -> #H/10/20", + func: function(done) { + exports.driver + .execute("return ''+location.protocol + '//' +location.host + location.pathname", null, function(error, result) { + + var host = result.value; + + exports.driver + .getTitle(function(error, title) { + assert.equals( title, 'PathJS Test' ); + }) + .getText(selector_console, function(error, text){ + assert.equals( text, 'F[enter]::F[action]' ); + }) + .url( host+"#A" ) + .getText(selector_console, function(error, text){ + assert.equals( text, 'F[enter]::F[action]::A[enter]::A[action]' ); + }) + .url( host+"#B" ) + .getText(selector_console, function(error, text){ + assert.equals( text, 'F[enter]::F[action]::A[enter]::A[action]::A[exit]::B[enter]::B[action]' ); + }) + .url( host+"#C" ) + .getText(selector_console, function(error, text){ + assert.equals( text, 'F[enter]::F[action]::A[enter]::A[action]::A[exit]::B[enter]::B[action]::C[action]' ); + }) + .url( host+"#D1" ) + .getText(selector_console, function(error, text){ + assert.equals( text, 'F[enter]::F[action]::A[enter]::A[action]::A[exit]::B[enter]::B[action]::C[action]::C[exit]::RESCUE' ); + }) + .url( host+"#D2" ) + .getText(selector_console, function(error, text){ + assert.equals( text, 'F[enter]::F[action]::A[enter]::A[action]::A[exit]::B[enter]::B[action]::C[action]::C[exit]::RESCUE::RESCUE' ); + }) + .url( host+"#E/params/1/parse" ) + .getText(selector_console, function(error, text){ + assert.equals( text, 'F[enter]::F[action]::A[enter]::A[action]::A[exit]::B[enter]::B[action]::C[action]::C[exit]::RESCUE::RESCUE::E[enter](parse id=1)::E[action](parse id=1)' ); + }) + .url( host+"#E/params/2/parse" ) + .getText(selector_console, function(error, text){ + assert.equals( text, 'F[enter]::F[action]::A[enter]::A[action]::A[exit]::B[enter]::B[action]::C[action]::C[exit]::RESCUE::RESCUE::E[enter](parse id=1)::E[action](parse id=1)::E[enter](parse id=2)::E[action](parse id=2)' ); + }) + .url( host+"#E/params/3/check" ) + .getText(selector_console, function(error, text){ + assert.equals( text, 'F[enter]::F[action]::A[enter]::A[action]::A[exit]::B[enter]::B[action]::C[action]::C[exit]::RESCUE::RESCUE::E[enter](parse id=1)::E[action](parse id=1)::E[enter](parse id=2)::E[action](parse id=2)::E[action](check id=3)' ); + }) + .url( host+"#F" ) + .getText(selector_console, function(error, text){ + assert.equals( text, 'F[enter]::F[action]::A[enter]::A[action]::A[exit]::B[enter]::B[action]::C[action]::C[exit]::RESCUE::RESCUE::E[enter](parse id=1)::E[action](parse id=1)::E[enter](parse id=2)::E[action](parse id=2)::E[action](check id=3)::E[exit](check id=3)::F[enter]::F[action]' ); + }) + .url( host+"#G" ) + .getText(selector_console, function(error, text){ + assert.equals( text, 'F[enter]::F[action]::A[enter]::A[action]::A[exit]::B[enter]::B[action]::C[action]::C[exit]::RESCUE::RESCUE::E[enter](parse id=1)::E[action](parse id=1)::E[enter](parse id=2)::E[action](parse id=2)::E[action](check id=3)::E[exit](check id=3)::F[enter]::F[action]::G[enter 1]::G[enter 2]::G[enter 3]::G[enter 4]' ); + }) + .url( host+"#H" ) + .getText(selector_console, function(error, text){ + assert.equals( text, 'F[enter]::F[action]::A[enter]::A[action]::A[exit]::B[enter]::B[action]::C[action]::C[exit]::RESCUE::RESCUE::E[enter](parse id=1)::E[action](parse id=1)::E[enter](parse id=2)::E[action](parse id=2)::E[action](check id=3)::E[exit](check id=3)::F[enter]::F[action]::G[enter 1]::G[enter 2]::G[enter 3]::G[enter 4]::H(one=N/A, two=N/A)' ); + }) + .url( host+"#H/10" ) + .getText(selector_console, function(error, text){ + assert.equals( text, 'F[enter]::F[action]::A[enter]::A[action]::A[exit]::B[enter]::B[action]::C[action]::C[exit]::RESCUE::RESCUE::E[enter](parse id=1)::E[action](parse id=1)::E[enter](parse id=2)::E[action](parse id=2)::E[action](check id=3)::E[exit](check id=3)::F[enter]::F[action]::G[enter 1]::G[enter 2]::G[enter 3]::G[enter 4]::H(one=N/A, two=N/A)::H(one=10, two=N/A)' ); + }) + .url( host+"#H/10/20" ) + .getText(selector_console, function(error, text){ + assert.equals( text, 'F[enter]::F[action]::A[enter]::A[action]::A[exit]::B[enter]::B[action]::C[action]::C[exit]::RESCUE::RESCUE::E[enter](parse id=1)::E[action](parse id=1)::E[enter](parse id=2)::E[action](parse id=2)::E[action](check id=3)::E[exit](check id=3)::F[enter]::F[action]::G[enter 1]::G[enter 2]::G[enter 3]::G[enter 4]::H(one=N/A, two=N/A)::H(one=10, two=N/A)::H(one=10, two=20)' ); + }) + .end(done); + + }); + } + } +];