Skip to content

Commit

Permalink
Throw errors when route generation would result in problems with reco…
Browse files Browse the repository at this point in the history
…gnition.
  • Loading branch information
nathanhammond committed Oct 14, 2016
1 parent 51e823b commit 18b75cc
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 3 deletions.
21 changes: 18 additions & 3 deletions lib/route-recognizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,19 @@ function isArray(test) {
return Object.prototype.toString.call(test) === "[object Array]";
}

function getParam(params, key) {
if (typeof params !== "object" || params === null) {
throw new Error("You must pass an object as the second argument to `generate`.");
}
if (!params.hasOwnProperty(key)) {
throw new Error("You must provide param `" + key + "` to `generate`.");
}
if (("" + params[key]).length === 0) {
throw new Error("You must provide a param `" + key + "`.");
}

return params[key];
}

// A Segment represents a segment in the original route description.
// Each Segment type provides an `eachChar` and `regex` method.
Expand Down Expand Up @@ -63,10 +76,12 @@ DynamicSegment.prototype = {
},

generate: function(params) {
var value = getParam(params, this.name);

if (RouteRecognizer.ENCODE_AND_DECODE_PATH_SEGMENTS) {
return encodePathSegment(params[this.name]);
return encodePathSegment(value);
} else {
return params[this.name];
return value;
}
}
};
Expand All @@ -82,7 +97,7 @@ StarSegment.prototype = {
},

generate: function(params) {
return params[this.name];
return getParam(params, this.name);
}
};

Expand Down
75 changes: 75 additions & 0 deletions tests/recognizer-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -909,6 +909,81 @@ globGenerationValues.forEach(function(value) {
});
});

test("Throws when generating dynamic routes with an empty string", function() {
var router = new RouteRecognizer();
router.add([{ "path": "/posts", "handler": "posts" }, { "path": "/*secret/create", "handler": "create" }], { as: "create" });
router.add([{ "path": "/posts", "handler": "posts" }, { "path": "/:secret/edit", "handler": "edit" }], { as: "edit" });

QUnit.throws(function() {
router.generate("create", { secret: "" });
}, /You must provide a param `secret`./);
QUnit.throws(function() {
router.generate("edit", { secret: "" });
}, /You must provide a param `secret`./);
});

test("Fails reasonably when bad params passed to dynamic segment", function() {
var router = new RouteRecognizer();
router.add([{ "path": "/posts", "handler": "posts" }, { "path": "/*secret/create", "handler": "create" }], { as: "create" });
router.add([{ "path": "/posts", "handler": "posts" }, { "path": "/:secret/edit", "handler": "edit" }], { as: "edit" });

QUnit.throws(function() {
router.generate("edit");
}, /You must pass an object as the second argument to `generate`./, "No argument passed.");

QUnit.throws(function() {
router.generate("edit", false);
}, /You must pass an object as the second argument to `generate`./, "Boolean passed.");

QUnit.throws(function() {
router.generate("edit", null);
}, /You must pass an object as the second argument to `generate`./, "`null` passed.");

QUnit.throws(function() {
router.generate("edit", "123");
}, /You must pass an object as the second argument to `generate`./, "String passed.");

QUnit.throws(function() {
router.generate("edit", new String("foo"));
}, /You must provide param `secret` to `generate`./, "`new String()` passed.");

QUnit.throws(function() {
router.generate("edit", []);
}, /You must provide param `secret` to `generate`./, "Array passed.");

QUnit.throws(function() {
router.generate("edit", {});
}, /You must provide param `secret` to `generate`./, "Object without own property passed.");

QUnit.throws(function() {
router.generate("create");
}, /You must pass an object as the second argument to `generate`./, "No argument passed.");

QUnit.throws(function() {
router.generate("create", false);
}, /You must pass an object as the second argument to `generate`./, "Boolean passed.");

QUnit.throws(function() {
router.generate("create", null);
}, /You must pass an object as the second argument to `generate`./, "`null` passed.");

QUnit.throws(function() {
router.generate("create", "123");
}, /You must pass an object as the second argument to `generate`./, "String passed.");

QUnit.throws(function() {
router.generate("create", new String("foo"));
}, /You must provide param `secret` to `generate`./, "`new String()` passed.");

QUnit.throws(function() {
router.generate("create", []);
}, /You must provide param `secret` to `generate`./, "Array passed.");

QUnit.throws(function() {
router.generate("create", {});
}, /You must provide param `secret` to `generate`./, "Object without own property passed.");
});

test("Parsing and generation results into the same input string", function() {
var query = "filter%20data=date";
equal(router.generateQueryString(router.parseQueryString(query)), '?' + query);
Expand Down

0 comments on commit 18b75cc

Please sign in to comment.