Skip to content

Commit

Permalink
fix(ArrayType): fix .equals for array types
Browse files Browse the repository at this point in the history
Closes #1538
  • Loading branch information
christopherthielen committed Nov 15, 2014
1 parent 3d0b121 commit 5e6783b
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 9 deletions.
33 changes: 24 additions & 9 deletions src/urlMatcherFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -499,22 +499,37 @@ Type.prototype.$asArray = function(mode, isSearch) {
};
}

function arrayHandler(callback, reducefn) {
// Wraps type functions to operate on each value of an array
function toArray(val) { return isArray(val) ? val : [ val ] }
function fromArray(val) { return mode === "auto" && val && val.length === 1 ? val[0] : val; }
function falsey(val) { return !val; }

// Wraps type (.is/.encode/.decode) functions to operate on each value of an array
function arrayHandler(callback, alltrue) {
return function handleArray(val) {
if (!isArray(val)) val = [ val ];
val = toArray(val);
var result = map(val, callback);
if (reducefn)
return result.reduce(reducefn, true);
return (result && result.length == 1 && mode === "auto") ? result[0] : result;
if (alltrue === true)
return result.filter(falsey).length === 0;
return fromArray(result);
};
}

// Wraps type (.equals) functions to operate on each value of an array
function arrayEqualsHandler(callback) {
return function handleArray(val1, val2) {
var left = toArray(val1), right = toArray(val2);
if (left.length !== right.length) return false;
for (var i = 0; i < left.length; i++) {
if (!callback(left[i], right[i])) return false;
}
return true;
};
}

function alltruthy(val, memo) { return val && memo; }
this.encode = arrayHandler(bindTo(this, type.encode));
this.decode = arrayHandler(bindTo(this, type.decode));
this.equals = arrayHandler(bindTo(this, type.equals), alltruthy);
this.is = arrayHandler(bindTo(this, type.is), alltruthy);
this.is = arrayHandler(bindTo(this, type.is), true);
this.equals = arrayEqualsHandler(bindTo(this, type.equals));
this.pattern = type.pattern;
this.$arrayMode = mode;
}
Expand Down
20 changes: 20 additions & 0 deletions test/urlMatcherFactorySpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,26 @@ describe("UrlMatcher", function () {


describe("multivalue-query-parameters", function() {
it("should handle .is() for an array of values", inject(function($location) {
var m = new UrlMatcher('/foo?{param1:int}');
expect(m.params.param1.type.is([1, 2, 3])).toBe(true);
expect(m.params.param1.type.is([1, "2", 3])).toBe(false);
}));

it("should handle .equals() for two arrays of values", inject(function($location) {
var m = new UrlMatcher('/foo?{param1:int}&{param2:date}');
expect(m.params.param1.type.equals([1, 2, 3], [1, 2, 3])).toBe(true);
expect(m.params.param1.type.equals([1, 2, 3], [1, 2 ])).toBe(false);
expect(m.params.param2.type.equals(
[new Date(2014, 11, 15), new Date(2014, 10, 15)],
[new Date(2014, 11, 15), new Date(2014, 10, 15)])
).toBe(true);
expect(m.params.param2.type.equals(
[new Date(2014, 11, 15), new Date(2014, 9, 15)],
[new Date(2014, 11, 15), new Date(2014, 10, 15)])
).toBe(false);
}));

it("should conditionally be wrapped in an array by default", inject(function($location) {
var m = new UrlMatcher('/foo?param1');

Expand Down

0 comments on commit 5e6783b

Please sign in to comment.