Permalink
Browse files

added ohrl.js and qunit tests

  • Loading branch information...
mlouro committed Apr 15, 2011
1 parent 94efc10 commit c728c0c5c2142932132e0cf4193e6e3a3c8b4ade
Showing with 1,641 additions and 0 deletions.
  1. +135 −0 ohrl.js
  2. +73 −0 tests/ohrl_tests.js
  3. +155 −0 tests/qunit/qunit.css
  4. +1,261 −0 tests/qunit/qunit.js
  5. +17 −0 tests/test.html
View
135 ohrl.js
@@ -0,0 +1,135 @@
+/**
+ * Provides utilities to deal with website/app urls. Provides functionality
+ * for deep-linking Ajax calls, and a url mapper to generate dynamic urls.
+ * @module urls
+ */
+
+/**
+ * Utility for application urls
+ *
+ * @class urls
+ * @namespace ohrl
+ */
+
+ohrl = function() {
+
+ var _urls = {},
+ _compiled = {},
+ _lastHash = '',
+ _nameMatcher = new RegExp('<([a-zA-Z0-9-_%]{1,})>', 'g');
+
+ function _getArgs(urlName, path) {
+
+ var args = {},
+ name_matches = _urls[urlName].match(_nameMatcher),
+ value_matches = path.match(_compiled[urlName]);
+
+ if (name_matches) {
+ var i, len, arg;
+ for (i=0, len=name_matches.length; i<len; i+=1) {
+ arg = name_matches[i].substring(1, name_matches[i].length-1);
+ args[arg] = value_matches[i+1];;
+ }
+ }
+
+ return args;
+ };
+
+
+ function _getName(path) {
+ if (!path) {
+ return;
+ }
+ for (url in _compiled) {
+ if (path.match(_compiled[url])) {
+ return url;
+ }
+ }
+ return;
+ };
+
+
+ return {
+
+ /**
+ * Loads a set of urls names and paths
+ * @method load
+ * @static
+ * @param {Object} urls an Object literal with names and paths like
+ * {'taskEdit': '/task/edit/<taskId>/', 'taskCreate': '/task/create/'}
+ * @return {Object} this for method chaining
+ */
+ load: function(urls) {
+
+ for (url in urls) {
+ if (urls.hasOwnProperty(url)) {
+ _compiled[url] = new RegExp('^' + urls[url].replace(_nameMatcher, "([a-zA-Z0-9-_%]{0,})") + '$');
+ }
+ }
+ _urls = urls;
+ return this;
+ },
+
+ /**
+ * Returns a url from the list that matches the specified parameters.
+ * A non-existant url will raise an exception.
+ * @method get
+ * @static
+ * @param {string} name: url name to call
+ * @param {string} kwargs: an option object literal with key/value
+ that can be used to get urls that require parameters
+ * @return {String} url path
+ */
+ get: function(name, kwargs) {
+
+ var path = _urls[name];
+ if (!path) {
+ throw('URL not found: ' + name);
+ }
+
+ var _path = path;
+
+ var key;
+ for (key in kwargs) {
+ if (kwargs.hasOwnProperty(key)) {
+ if (!path.match('<' + key +'>')) {
+ throw('Invalid parameter ('+ key +') for '+ name);
+ }
+ path = path.replace('<' + key +'>', kwargs[key]);
+ }
+ }
+
+ var missing_args = path.match(_nameMatcher);
+ if (missing_args) {
+ throw('Missing arguments (' + missing_args.join(", ") + ') for url ' + _path);
+ }
+
+ return path;
+ },
+
+ /**
+ * Recieves a url path, and returns a url object with the name and
+ * variables if there is match in the url list
+ * @method resolve
+ * @static
+ * @param {String} path the url path
+ * @return {Object/undefined} url object or undefined
+ */
+ resolve: function(path) {
+ var url = {},
+ urlName,
+ kwargs;
+ urlName = _getName(path);
+ //olive.log(url + ' => ' + urlName);
+ if (urlName) {
+ kwargs = _getArgs(urlName, path);
+ url['name'] = urlName;
+ url['kwargs'] = kwargs;
+ return url;
+ }
+
+ return;
+ }
+ };
+
+}();
View
@@ -0,0 +1,73 @@
+
+module('URL Tests');
+
+var ohrlTests = {};
+ohrlTests.urls = {
+ 'dashboard': '/dashboard/',
+ 'time_edit': '/projects/<project_id>/time/save/<time_id>/',
+ 'task_edit': '/projects/<project_id>/task/save/<task_id>/'
+};
+
+/**
+ * Loading sample urls
+ */
+ohrl.load(ohrlTests.urls);
+
+test('ohrl', function() {
+ expect(9);
+ equals(ohrl.get('dashboard'), '/dashboard/', 'get() -> Expected value /dashboard/');
+ equals(ohrl.get('task_edit', {
+ 'project_id': 2,
+ 'task_id': 1
+ }), '/projects/2/task/save/1/', 'get() -> Expected value /projects/2/task/save/1/');
+
+ try {
+ ohrl.get('invalid-url');
+ }
+ catch (e) {
+ ok(e, 'remove()+get() -> Expected Error: ' + e);
+ }
+
+
+ same(ohrl.resolve('/dashboard/'), {'name': 'dashboard', 'kwargs': {}}, 'resolve() -> Expected value object');
+ same(ohrl.resolve('/projects/453453/time/save/fas12321/'),
+ {
+ 'name': 'time_edit',
+ 'kwargs': {'project_id': '453453', 'time_id': 'fas12321'}
+ }, 'resolve() -> Expected value object');
+ equals(ohrl.resolve('/projects/453453/time/push/fas12321/'), undefined, 'resolve() -> Expected value undefined');
+
+
+ /**
+ * Error cheking tests
+ */
+ try {
+ ohrl.get('non-existing-url');
+ }
+ catch (e) {
+ ok(e, 'get() -> Expected Error: ' + e);
+ }
+
+
+ try {
+ ohrl.get('task_edit', {
+ 'project_id': 2,
+ 'task_id': 1,
+ 'task_status': 'test'
+ });
+ }
+ catch (e) {
+ ok(e, 'get() -> Expected Error: ' + e);
+ }
+
+
+ try {
+ ohrl.get('task_edit', {
+ 'project_id': 2
+ });
+ }
+ catch (e) {
+ ok(e, 'get() -> Expected Error: ' + e);
+ }
+
+});
View
@@ -0,0 +1,155 @@
+/** Font Family and Sizes */
+
+#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
+ font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
+}
+
+#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
+#qunit-tests { font-size: smaller; }
+
+
+/** Resets */
+
+#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
+ margin: 0;
+ padding: 0;
+}
+
+
+/** Header */
+
+#qunit-header {
+ padding: 0.5em 0 0.5em 1em;
+
+ color: #fff;
+ text-shadow: rgba(0, 0, 0, 0.5) 4px 4px 1px;
+ background-color: #0d3349;
+
+ border-radius: 15px 15px 0 0;
+ -moz-border-radius: 15px 15px 0 0;
+ -webkit-border-top-right-radius: 15px;
+ -webkit-border-top-left-radius: 15px;
+}
+
+#qunit-header a {
+ text-decoration: none;
+ color: white;
+}
+
+#qunit-banner {
+ height: 5px;
+}
+
+#qunit-testrunner-toolbar {
+ padding: 0em 0 0.5em 2em;
+}
+
+#qunit-userAgent {
+ padding: 0.5em 0 0.5em 2.5em;
+ background-color: #2b81af;
+ color: #fff;
+ text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
+}
+
+
+/** Tests: Pass/Fail */
+
+#qunit-tests {
+ list-style-position: inside;
+}
+
+#qunit-tests li {
+ padding: 0.4em 0.5em 0.4em 2.5em;
+ border-bottom: 1px solid #fff;
+ list-style-position: inside;
+}
+
+#qunit-tests li strong {
+ cursor: pointer;
+}
+
+#qunit-tests ol {
+ margin-top: 0.5em;
+ padding: 0.5em;
+
+ background-color: #fff;
+
+ border-radius: 15px;
+ -moz-border-radius: 15px;
+ -webkit-border-radius: 15px;
+
+ box-shadow: inset 0px 2px 13px #999;
+ -moz-box-shadow: inset 0px 2px 13px #999;
+ -webkit-box-shadow: inset 0px 2px 13px #999;
+}
+
+/*** Test Counts */
+
+#qunit-tests b.counts { color: black; }
+#qunit-tests b.passed { color: #5E740B; }
+#qunit-tests b.failed { color: #710909; }
+
+#qunit-tests li li {
+ margin: 0.5em;
+ padding: 0.4em 0.5em 0.4em 0.5em;
+ background-color: #fff;
+ border-bottom: none;
+ list-style-position: inside;
+}
+
+/*** Passing Styles */
+
+#qunit-tests li li.pass {
+ color: #5E740B;
+ background-color: #fff;
+ border-left: 26px solid #C6E746;
+}
+
+#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
+#qunit-tests .pass .test-name { color: #366097; }
+
+#qunit-tests .pass .test-actual,
+#qunit-tests .pass .test-expected { color: #999999; }
+
+#qunit-banner.qunit-pass { background-color: #C6E746; }
+
+/*** Failing Styles */
+
+#qunit-tests li li.fail {
+ color: #710909;
+ background-color: #fff;
+ border-left: 26px solid #EE5757;
+}
+
+#qunit-tests .fail { color: #000000; background-color: #EE5757; }
+#qunit-tests .fail .test-name,
+#qunit-tests .fail .module-name { color: #000000; }
+
+#qunit-tests .fail .test-actual { color: #EE5757; }
+#qunit-tests .fail .test-expected { color: green; }
+
+#qunit-banner.qunit-fail,
+#qunit-testrunner-toolbar { background-color: #EE5757; }
+
+
+/** Footer */
+
+#qunit-testresult {
+ padding: 0.5em 0.5em 0.5em 2.5em;
+
+ color: #2b81af;
+ background-color: #D2E0E6;
+
+ border-radius: 0 0 15px 15px;
+ -moz-border-radius: 0 0 15px 15px;
+ -webkit-border-bottom-right-radius: 15px;
+ -webkit-border-bottom-left-radius: 15px;
+}
+
+/** Fixture */
+
+#qunit-fixture {
+ position: absolute;
+ top: -10000px;
+ left: -10000px;
+}
Oops, something went wrong.

0 comments on commit c728c0c

Please sign in to comment.