Skip to content

Commit

Permalink
fix lang.exists() corner case and add unit tests, fixes #16291
Browse files Browse the repository at this point in the history
  • Loading branch information
wkeese committed May 8, 2014
1 parent 37233ca commit 84cbaf9
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 12 deletions.
33 changes: 22 additions & 11 deletions _base/lang.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,33 @@ define(["./kernel", "../has", "../sniff"], function(dojo, has){
_extraLen = _extraNames.length,

getProp = function(/*Array*/parts, /*Boolean*/create, /*Object*/context){
var p, i = 0, dojoGlobal = dojo.global;
if(!context){
if(!parts.length){
return dojoGlobal;
if(parts[0] && dojo.scopeMap[parts[0]]) {
// Voodoo code from the old days where "dojo" or "dijit" maps to some special object
// rather than just window.dojo
context = dojo.scopeMap[parts.shift()][1];
}else{
p = parts[i++];
try{
context = dojo.scopeMap[p] && dojo.scopeMap[p][1];
}catch(e){}
context = context || (p in dojoGlobal ? dojoGlobal[p] : (create ? dojoGlobal[p] = {} : undefined));
context = dojo.global;
}
}
while(context && (p = parts[i++])){
context = (p in context ? context[p] : (create ? context[p] = {} : undefined));

try{
for(var i = 0; i < parts.length; i++){
var p = parts[i];
if(!(p in context)){
if(create){
context[p] = {};
}else{
return; // return undefined
}
}
context = context[p];
}
return context; // mixed
}catch(e){
// "p in context" throws an exception when context is a number, boolean, etc. rather than an object,
// so in that corner case just return undefined (by having no return statement)
}
return context; // mixed
},

opts = Object.prototype.toString,
Expand Down
54 changes: 53 additions & 1 deletion tests/_base/lang.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,58 @@
define(["doh/main", "dojo/_base/array", "dojo/_base/lang"], function(doh, array, lang){
define(["doh/main", "dojo/_base/array", "dojo/_base/lang", "dojo/_base/kernel"
], function(doh, array, lang, kernel){

doh.register("tests._base.lang", [
function exists(t){
var test = {
foo : 0
};
t.assertTrue(lang.exists("foo", test), 'lang.exists("foo", test)');
t.assertFalse(lang.exists("foo.bar", test), 'lang.exists("foo.bar", test)');

// global tests
t.assertFalse(lang.exists("_existsTest"), 'lang.exists("_existsTest") #1');
kernel.global._existsTest = false;
t.assertTrue(lang.exists("_existsTest"), 'lang.exists("_existsTest") #2');
t.assertFalse(lang.exists("_existsTest.bar"), 'lang.exists("_existsTest.bar")');

// scopeMap tests
t.assertTrue(lang.exists("dojo.dijit"), 'lang.exists("dojo.dijit")');
t.assertFalse(lang.exists("dojo.foo"), 'lang.exists("dojo.foo")');
},

function getObject(t){
var test = {
foo : {}
};
t.assertEqual(test.foo, lang.getObject("foo", false, test), 'lang.getObject("foo", false, test)');
t.assertEqual("undefined", typeof lang.getObject("foo.bar", false, test), // don't create
'typeof lang.getObject("foo.bar", false, test)');
t.assertEqual({}, lang.getObject("foo.bar", true, test), // do create
'lang.getObject("foo.bar", true, test)');
test.foo.bar.baz = "test";
t.assertEqual(test.foo.bar, lang.getObject("foo.bar", false, test),
'lang.getObject("foo.bar", false, test)');

// global tests
t.assertEqual("undefined", typeof lang.getObject("_getObjectTest.bar", false), // don't create
'typeof lang.getObject("_getObjectTest.bar", false)');
kernel.global._getObjectTest = {};
t.assertEqual(kernel.global._getObjectTest, lang.getObject("_getObjectTest", false), // don't create
'lang.getObject("_getObjectTest", false)');
t.assertEqual({}, lang.getObject("_getObjectTest.bar", true), 'lang.getObject("_getObjectTest.bar", true)'); // do create

// strangely, parser does this
t.assertEqual("undefined", typeof lang.getObject("./TestWidget"), 'typeof lang.getObject("./TestWidget")');
},

function setObject(t){
var test = {
foo : 0
};
t.assertTrue(lang.setObject("foo", {bar : "test"}, test));
t.assertEqual({bar : "test"}, lang.getObject("foo", false, test));
},

function mixin(t){
t.assertEqual("object", typeof lang.mixin());
t.assertEqual("object", typeof lang.mixin(undefined));
Expand Down

0 comments on commit 84cbaf9

Please sign in to comment.