Skip to content

Commit

Permalink
Merge pull request #2279 from canjs/2277-omit-unserialized
Browse files Browse the repository at this point in the history
Omit unserialized route map properties from string coercion.
  • Loading branch information
daffl committed Feb 19, 2016
2 parents 55e7db9 + 8c77bd6 commit 91d2931
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 79 deletions.
1 change: 1 addition & 0 deletions .jshintrc
Expand Up @@ -14,6 +14,7 @@
"equal": true,
"notEqual": true,
"deepEqual": true,
"propEqual": true,
"notDeepEqual": true,
"strictEqual": true,
"notStrictEqual": true,
Expand Down
33 changes: 16 additions & 17 deletions route/route.js
Expand Up @@ -117,11 +117,21 @@ steal('can/util', 'can/map', 'can/list','can/util/string/deparam', function (can
// A dummy events object used to dispatch url change events on.
eventsObject = can.extend({}, can.event),
// everything in the backing Map is a string
// change type coercion during Map setter to coerce all values to strings
// add type coercion during Map setter to coerce all values to strings
stringCoercingMapDecorator = function(map) {
var typeSuper = map.__type;
map.__type = function() {
return stringify(typeSuper.apply(map, arguments));
var attrSuper = map.attr;

map.attr = function(prop, val) {
var serializable = this.define === undefined || this.define[prop] === undefined || !!this.define[prop].serialize,
args;

if (serializable) { // if setting non-str non-num attr
args = stringify(Array.apply(null, arguments));
} else {
args = arguments;
}

return attrSuper.apply(this, args);
};

return map;
Expand Down Expand Up @@ -632,19 +642,8 @@ steal('can/util', 'can/map', 'can/list','can/util/string/deparam', function (can
};
});

// everything in the backing Map is a string
// coerce attribute names to string or number
can.route.attr = function (attr, val) {
var type = typeof attr,
newArguments;

if (type !== "string" && type !== "number" && val !== undefined) { // if setting non-str non-num attr
newArguments = [stringify(attr), val];
} else {
newArguments = arguments;
}

return can.route.data.attr.apply(can.route.data, newArguments);
can.route.attr = function () {
return can.route.data.attr.apply(can.route.data, arguments);
};

//Allow for overriding of route batching by can.transaction
Expand Down
151 changes: 89 additions & 62 deletions route/route_test.js
@@ -1,5 +1,5 @@
/* jshint asi:true*/
steal("can/route", "can/test", "steal-qunit", function () {
steal("can/route", "can/test", "steal-qunit", "can/map/define", function () {
QUnit.module("can/route", {
setup: function () {
can.route._teardown();
Expand Down Expand Up @@ -747,7 +747,7 @@ steal("can/route", "can/test", "steal-qunit", function () {
expect(1);

setupRouteTest(function (iframe, route) {
var appVM = new can.Map({});
var appVM = new can.Map();

route.map(appVM);
route.ready();
Expand All @@ -761,7 +761,31 @@ steal("can/route", "can/test", "steal-qunit", function () {
// check after 30ms to see that we only have a single call
setTimeout(function() {
teardownRouteTest();
}, 30);
}, 5);
});
});

test("updating unserialized prop on bound can.Map causes single update without a coerced string value", function() {
expect(1);

setupRouteTest(function (iframe, route) {
var appVM = new (can.Map.extend({define: {
action: {serialize: false}
}}))();

route.map(appVM);
route.ready();

appVM.bind('action', function(ev, newVal) {
equal(typeof newVal, 'function');
});

appVM.attr('action', function() {});

// check after 30ms to see that we only have a single call
setTimeout(function() {
teardownRouteTest();
}, 5);
});
});

Expand Down Expand Up @@ -827,71 +851,74 @@ steal("can/route", "can/test", "steal-qunit", function () {
if (typeof require === 'undefined') {

test("correct stringing", function () {
var route = can.route;
setupRouteTest(function(iframe, route) {
route.routes = {};

route.routes = {};
route.attr('number', 1);
propEqual(route.attr(), {
'number': "1"
});

route.attr('number', 1);
deepEqual(route.attr(), {
'number': "1"
});
route.attr({
bool: true
}, true);

route.attr({
bool: true
}, true);

deepEqual(route.attr(), {
'bool': "true"
});
propEqual(route.attr(), {
'bool': "true"
});

route.attr({
string: "hello"
}, true);
deepEqual(route.attr(), {
'string': "hello"
});
route.attr({
string: "hello"
}, true);
propEqual(route.attr(), {
'string': "hello"
});

route.attr({
array: [1, true, "hello"]
}, true);
deepEqual(route.attr(), {
'array': ["1", "true", "hello"]
});
route.attr({
array: [1, true, "hello"]
}, true);
propEqual(route.attr(), {
'array': ["1", "true", "hello"]
});

route.attr({
number: 1,
bool: true,
string: "hello",
array: [2, false, "world"],
obj: {
number: 3,
array: [4, true]
}
}, true);

propEqual(route.attr(), {
number: "1",
bool: "true",
string: "hello",
array: ["2", "false", "world"],
obj: {
number: "3",
array: ["4", "true"]
}
});

route.routes = {};
route(":type/:id");

route.attr({
type: 'page',
id: 10,
sort_by_name: true
}, true);

propEqual(route.attr(), {
type: "page",
id: "10",
sort_by_name: "true"
});

route.attr({
number: 1,
bool: true,
string: "hello",
array: [2, false, "world"],
obj: {
number: 3,
array: [4, true]
}
}, true);

deepEqual(route.attr(), {
number: "1",
bool: "true",
string: "hello",
array: ["2", "false", "world"],
obj: {
number: "3",
array: ["4", "true"]
}
})

route.routes = {};
route(":type/:id");

route.attr({
type: 'page',
id: 10,
sort_by_name: true
}, true)
deepEqual(route.attr(), {
type: "page",
id: "10",
sort_by_name: "true"
teardownRouteTest();
});
});

Expand Down

0 comments on commit 91d2931

Please sign in to comment.