Skip to content

Commit 5e6783b

Browse files
fix(ArrayType): fix .equals for array types
Closes #1538
1 parent 3d0b121 commit 5e6783b

File tree

2 files changed

+44
-9
lines changed

2 files changed

+44
-9
lines changed

src/urlMatcherFactory.js

+24-9
Original file line numberDiff line numberDiff line change
@@ -499,22 +499,37 @@ Type.prototype.$asArray = function(mode, isSearch) {
499499
};
500500
}
501501

502-
function arrayHandler(callback, reducefn) {
503-
// Wraps type functions to operate on each value of an array
502+
function toArray(val) { return isArray(val) ? val : [ val ] }
503+
function fromArray(val) { return mode === "auto" && val && val.length === 1 ? val[0] : val; }
504+
function falsey(val) { return !val; }
505+
506+
// Wraps type (.is/.encode/.decode) functions to operate on each value of an array
507+
function arrayHandler(callback, alltrue) {
504508
return function handleArray(val) {
505-
if (!isArray(val)) val = [ val ];
509+
val = toArray(val);
506510
var result = map(val, callback);
507-
if (reducefn)
508-
return result.reduce(reducefn, true);
509-
return (result && result.length == 1 && mode === "auto") ? result[0] : result;
511+
if (alltrue === true)
512+
return result.filter(falsey).length === 0;
513+
return fromArray(result);
514+
};
515+
}
516+
517+
// Wraps type (.equals) functions to operate on each value of an array
518+
function arrayEqualsHandler(callback) {
519+
return function handleArray(val1, val2) {
520+
var left = toArray(val1), right = toArray(val2);
521+
if (left.length !== right.length) return false;
522+
for (var i = 0; i < left.length; i++) {
523+
if (!callback(left[i], right[i])) return false;
524+
}
525+
return true;
510526
};
511527
}
512528

513-
function alltruthy(val, memo) { return val && memo; }
514529
this.encode = arrayHandler(bindTo(this, type.encode));
515530
this.decode = arrayHandler(bindTo(this, type.decode));
516-
this.equals = arrayHandler(bindTo(this, type.equals), alltruthy);
517-
this.is = arrayHandler(bindTo(this, type.is), alltruthy);
531+
this.is = arrayHandler(bindTo(this, type.is), true);
532+
this.equals = arrayEqualsHandler(bindTo(this, type.equals));
518533
this.pattern = type.pattern;
519534
this.$arrayMode = mode;
520535
}

test/urlMatcherFactorySpec.js

+20
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,26 @@ describe("UrlMatcher", function () {
182182

183183

184184
describe("multivalue-query-parameters", function() {
185+
it("should handle .is() for an array of values", inject(function($location) {
186+
var m = new UrlMatcher('/foo?{param1:int}');
187+
expect(m.params.param1.type.is([1, 2, 3])).toBe(true);
188+
expect(m.params.param1.type.is([1, "2", 3])).toBe(false);
189+
}));
190+
191+
it("should handle .equals() for two arrays of values", inject(function($location) {
192+
var m = new UrlMatcher('/foo?{param1:int}&{param2:date}');
193+
expect(m.params.param1.type.equals([1, 2, 3], [1, 2, 3])).toBe(true);
194+
expect(m.params.param1.type.equals([1, 2, 3], [1, 2 ])).toBe(false);
195+
expect(m.params.param2.type.equals(
196+
[new Date(2014, 11, 15), new Date(2014, 10, 15)],
197+
[new Date(2014, 11, 15), new Date(2014, 10, 15)])
198+
).toBe(true);
199+
expect(m.params.param2.type.equals(
200+
[new Date(2014, 11, 15), new Date(2014, 9, 15)],
201+
[new Date(2014, 11, 15), new Date(2014, 10, 15)])
202+
).toBe(false);
203+
}));
204+
185205
it("should conditionally be wrapped in an array by default", inject(function($location) {
186206
var m = new UrlMatcher('/foo?param1');
187207

0 commit comments

Comments
 (0)