You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
413 lines
11 KiB
413 lines
11 KiB
define([ |
|
'intern!object', |
|
'intern/chai!assert', |
|
'dojo/_base/array', |
|
'../../../_base/lang', |
|
'../../../_base/kernel', |
|
'dojo/has', |
|
'dojo/has!host-browser?dojo/domReady!' |
|
], function (registerSuite, assert, array, lang, kernel, has) { |
|
registerSuite({ |
|
name: 'dojo/_base/lang', |
|
|
|
'.exists': function () { |
|
var test = { |
|
foo: 0 |
|
}; |
|
assert.isTrue(lang.exists('foo', test), 'test.foo should exist'); |
|
assert.isFalse(lang.exists('foo.bar', test), 'test.foo.bar should not exist'); |
|
|
|
// global tests |
|
assert.isFalse(lang.exists('_existsTest'), '_existsTest should not exist'); |
|
kernel.global._existsTest = false; |
|
assert.isTrue(lang.exists('_existsTest'), '_existsTest should exist'); |
|
assert.isFalse(lang.exists('_existsTest.bar'), '_existsTest.bar should not exist'); |
|
|
|
// scopeMap tests |
|
assert.isTrue(lang.exists('dojo.dijit'), 'dojo.dijit should exist'); |
|
assert.isFalse(lang.exists('dojo.foo'), 'dojo.foo should not exist'); |
|
}, |
|
|
|
'.getObject': function () { |
|
var test = { |
|
foo: {} |
|
}; |
|
|
|
assert.strictEqual(lang.getObject('foo', false, test), test.foo); |
|
assert.strictEqual(typeof lang.getObject('foo.bar', false, test), 'undefined'); |
|
assert.strictEqual(typeof lang.getObject('foo.bar', true, test), 'object'); |
|
|
|
test.foo.bar.baz = 'test'; |
|
assert.strictEqual(lang.getObject('foo.bar', false, test), test.foo.bar); |
|
|
|
// global tests |
|
assert.strictEqual(typeof lang.getObject('_getObjectTest.bar', false), 'undefined'); |
|
kernel.global._getObjectTest = {}; |
|
assert.strictEqual(lang.getObject('_getObjectTest', false), kernel.global._getObjectTest); |
|
assert.strictEqual(typeof lang.getObject('_getObjectTest.bar', true), 'object'); |
|
|
|
// strangely, parser does this |
|
assert.strictEqual(typeof lang.getObject('./TestWidget'), 'undefined'); |
|
|
|
// empty path should return the same object |
|
assert.strictEqual(lang.getObject('', false, test), test); |
|
assert.strictEqual(lang.getObject('', false, null), null); |
|
assert.strictEqual(lang.getObject(''), undefined); |
|
}, |
|
|
|
'.setObject': function () { |
|
var test = { |
|
foo: 0 |
|
}; |
|
|
|
lang.setObject('foo', { bar: 'test' }, test); |
|
assert.deepEqual(test, { foo: { bar: 'test' } }); |
|
|
|
// CVE-2021-23450 tests |
|
// Test that you can't set fields on Object.prototype itself. |
|
const obj = {}; |
|
lang.setObject("__proto__.vuln", "polluted!", obj); |
|
assert.isUndefined("anything".vuln); |
|
|
|
// Test that you can't set fields on Object.constructor itself. |
|
lang.setObject("constructor.vuln", "polluted!", obj); |
|
assert.isUndefined("anything".constructor.vuln); |
|
|
|
// Test that you can still set normal fields in an obj. |
|
lang.setObject("foo.bar", "value for normal field", obj); |
|
assert.strictEqual(obj.foo.bar, "value for normal field"); |
|
}, |
|
|
|
'.mixin': function () { |
|
var src = { |
|
foo: function () { |
|
console.debug('foo'); |
|
}, |
|
bar: 'bar' |
|
}; |
|
var dest = {}; |
|
lang.mixin(dest, src); |
|
|
|
assert.typeOf(lang.mixin(), 'object'); |
|
assert.typeOf(lang.mixin(undefined), 'object'); |
|
assert.typeOf(lang.mixin(null), 'object'); |
|
assert.typeOf(dest.foo, 'function'); |
|
assert.typeOf(dest.bar, 'string'); |
|
}, |
|
|
|
'.extend': function () { |
|
var src = { |
|
foo: function () { |
|
console.debug('foo'); |
|
}, |
|
bar: 'bar' |
|
}; |
|
var test; |
|
function Dest() {} |
|
|
|
lang.extend(Dest, src); |
|
test = new Dest(); |
|
|
|
assert.typeOf(test.foo, 'function'); |
|
assert.typeOf(test.bar, 'string'); |
|
}, |
|
|
|
'.isFunction': function () { |
|
function test() {} |
|
|
|
assert.isTrue(lang.isFunction(new Function())); |
|
assert.isTrue(lang.isFunction(test)); |
|
|
|
if (has('host-browser')) { // test the Safari workaround for NodeList |
|
assert.isFalse(lang.isFunction(document.getElementsByName('html'))); |
|
assert.isFalse(lang.isFunction(document.createElement('object'))); |
|
} |
|
}, |
|
|
|
'.isObject': function () { |
|
assert.isFalse(lang.isObject(true)); |
|
assert.isFalse(lang.isObject(false)); |
|
assert.isFalse(lang.isObject('foo')); |
|
/*jshint -W053 */ |
|
assert.isTrue(lang.isObject(new String('foo'))); |
|
assert.isTrue(lang.isObject(null)); |
|
assert.isTrue(lang.isObject({})); |
|
assert.isTrue(lang.isObject([])); |
|
/*jshint -W009 */ |
|
assert.isTrue(lang.isObject(new Array())); |
|
}, |
|
|
|
'.isArray': function () { |
|
/*jshint -W009 */ |
|
assert.isTrue(lang.isArray([])); |
|
assert.isTrue(lang.isArray(new Array())); |
|
assert.isFalse(lang.isArray({})); |
|
assert.isFalse(lang.isArray('')); |
|
assert.isFalse(lang.isArray(0)); |
|
assert.isFalse(lang.isArray(NaN)); |
|
assert.isFalse(lang.isArray(null)); |
|
assert.isFalse(lang.isArray(undefined)); |
|
if (typeof window !== 'undefined') { |
|
assert.isFalse(lang.isArray(window)); |
|
} |
|
assert.isFalse(lang.isArray(Function)); |
|
function Tricky() {} |
|
Tricky.prototype = []; |
|
assert.isFalse(lang.isArray(new Tricky())); |
|
}, |
|
|
|
'.isArrayLike': function () { |
|
/*jshint -W009 */ |
|
assert.isFalse(lang.isArrayLike('thinger')); |
|
assert.isTrue(lang.isArrayLike(new Array())); |
|
assert.isFalse(lang.isArrayLike({})); |
|
assert.isTrue(lang.isArrayLike(arguments)); |
|
assert.isFalse(lang.isArrayLike('')); |
|
assert.isFalse(lang.isArrayLike(false)); |
|
assert.isFalse(lang.isArrayLike(NaN)); |
|
assert.isFalse(lang.isArrayLike(undefined)); |
|
assert.isFalse(lang.isArrayLike(null)); |
|
if(typeof window !== 'undefined'){ |
|
assert.isTrue(lang.isArrayLike(window)); |
|
} |
|
assert.isFalse(lang.isArrayLike(Function)); |
|
|
|
assert.isTrue(lang.isArrayLike({0: 1, 1: 2, length: 2})); |
|
function Tricky() {} |
|
Tricky.prototype = []; |
|
assert.isTrue(lang.isArrayLike(new Tricky())); |
|
}, |
|
|
|
'.isString': function () { |
|
/*jshint -W053 */ |
|
assert.isFalse(lang.isString(true)); |
|
assert.isFalse(lang.isString(false)); |
|
assert.isTrue(lang.isString('foo')); |
|
assert.isTrue(lang.isString(new String('foo'))); |
|
assert.isFalse(lang.isString(null)); |
|
assert.isFalse(lang.isString({})); |
|
assert.isFalse(lang.isString([])); |
|
}, |
|
|
|
'.partial': function () { |
|
var scope = { foo: 'bar' }; |
|
var st1; |
|
var st2; |
|
var st3; |
|
|
|
function thinger(arg1, arg2) { |
|
return [this.foo, arg1, arg2]; |
|
} |
|
|
|
st1 = lang.partial(thinger); |
|
assert.equal('bar', st1.call(scope)[0]); |
|
assert.equal(undefined, st1()[0]); |
|
|
|
st2 = lang.partial(thinger, 'foo', 'bar'); |
|
assert.equal('bar', st2()[2]); |
|
st3 = lang.partial(thinger, 'foo', 'bar'); |
|
}, |
|
|
|
'.partial nested': function () { |
|
var st1; |
|
var st2; |
|
|
|
function thinger(arg1, arg2) { |
|
return [arg1, arg2]; |
|
} |
|
|
|
st1 = lang.partial(thinger, 'foo'); |
|
assert.equal(undefined, st1()[1]); |
|
assert.equal('bar', st1('bar')[1]); |
|
|
|
// partials can accumulate |
|
st2 = lang.partial(st1, 'thud'); |
|
assert.equal('foo', st2()[0]); |
|
assert.equal('thud', st2()[1]); |
|
}, |
|
|
|
'.hitch': function () { |
|
var scope = { foo: 'bar' }; |
|
var scope2 = { foo: 'baz' }; |
|
var st1; |
|
var st2; |
|
|
|
function thinger() { |
|
return [this.foo, arguments.length]; |
|
} |
|
|
|
st1 = lang.hitch(scope, thinger); |
|
assert.equal('bar', st1()[0]); |
|
assert.equal(0, st1()[1]); |
|
|
|
st2 = lang.hitch(scope2, thinger); |
|
assert.equal('baz', st2()[0]); |
|
assert.equal(0, st1()[1]); |
|
assert.equal(1, st1('blah')[1]); |
|
|
|
// st2 should be "scope proof" |
|
assert.equal('baz', st2.call(scope)[0]); |
|
}, |
|
|
|
'.hitch with args': function () { |
|
var scope = { foo: 'bar' }; |
|
var scope2 = { foo: 'baz' }; |
|
var st1; |
|
var st2; |
|
|
|
function thinger() { |
|
return [this.foo, arguments.length]; |
|
} |
|
|
|
st1 = lang.hitch(scope, thinger, 'foo', 'bar'); |
|
assert.equal('bar', st1()[0]); |
|
assert.equal(2, st1()[1]); |
|
|
|
st2 = lang.hitch(scope2, thinger, 'foo', 'bar'); |
|
assert.equal('baz', st2()[0]); |
|
assert.equal(2, st2()[1]); |
|
}, |
|
|
|
'.hitch as partial': function () { |
|
var scope = { foo: 'bar' }; |
|
var st1; |
|
var st2; |
|
|
|
function thinger(arg1, arg2) { |
|
return [this.foo, arg1, arg2]; |
|
} |
|
|
|
st1 = lang.hitch(null, thinger); |
|
assert.equal('bar', st1.call(scope)[0]); |
|
assert.equal(undefined, st1()[0]); |
|
|
|
st2 = lang.hitch(null, thinger, 'foo', 'bar'); |
|
assert.equal('bar', st2()[2]); |
|
}, |
|
|
|
'.toArray': function () { |
|
var obj1 = [ 'foo', 'bar', 'spam', 'ham' ]; |
|
var obj2; |
|
var div; |
|
var result; |
|
|
|
function thinger() { |
|
return lang._toArray(arguments); |
|
} |
|
|
|
obj2 = thinger.apply(this, obj1); |
|
assert.equal(obj1[0], obj2[0]); |
|
|
|
if (has('host-browser')) { |
|
// test DomCollection |
|
div = document.createElement('div'); |
|
div.innerHTML = '<a href="#"">link</a>text'; |
|
result = lang._toArray(div.childNodes); |
|
assert.equal(2, result.length); |
|
} |
|
}, |
|
|
|
'.clone': function () { |
|
var obj1 = { |
|
foo: 'bar', |
|
answer: 42, |
|
jan102007: new Date(2007, 0, 10), |
|
baz: { |
|
a: null, |
|
b: [1, 'b', 2.3, true, false], |
|
c: { |
|
d: undefined, |
|
e: 99, |
|
f: function () { console.log(42); return 42; }, |
|
g: /\d+/gm |
|
} |
|
}, |
|
toString: function () { return 'meow'; } |
|
}; |
|
|
|
assert.deepEqual(obj1, lang.clone(obj1)); |
|
obj1.baz.b[6] = "c"; // intentional sparse populatation |
|
assert.deepEqual(obj1.baz.b, lang.clone(obj1).baz.b, "Sparse arrays should be equal"); |
|
}, |
|
|
|
'.delegate': function () { |
|
var a = { |
|
x: 1, |
|
y: function () { return 2; }, |
|
z1: 99 |
|
}; |
|
var b = { |
|
x: 11, |
|
y: function () { return 12; }, |
|
z2: 33, |
|
toString: function () { return 'bark!'; }, |
|
toLocaleString: function () { return 'le bark-s!'; } |
|
}; |
|
var c; |
|
|
|
assert.strictEqual(1, a.x); |
|
assert.strictEqual(2, a.y()); |
|
assert.strictEqual(99, a.z1); |
|
|
|
c = lang.delegate(a, b); |
|
|
|
assert.strictEqual(1, a.x); |
|
assert.strictEqual(2, a.y()); |
|
assert.strictEqual(99, a.z1); |
|
assert.strictEqual(11, c.x); |
|
assert.strictEqual(12, c.y()); |
|
assert.strictEqual('bark!', c.toString()); |
|
assert.strictEqual('le bark-s!', c.toLocaleString()); |
|
assert.strictEqual(99, c.z1); |
|
assert.strictEqual(33, c.z2); |
|
}, |
|
|
|
'.replace with object': function () { |
|
var objectContext = { |
|
nick: 'Bob', |
|
name: { |
|
first: 'Robert', |
|
middle: 'X', |
|
last: 'Cringely' |
|
} |
|
}; |
|
var s1 = lang.replace('Hello, {name.first} {name.last} AKA {nick}!', objectContext); |
|
assert.equal('Hello, Robert Cringely AKA Bob!', s1); |
|
}, |
|
|
|
'.replace with array context': function () { |
|
var arrayContext = ['Robert', 'X', 'Cringely']; |
|
var s2 = lang.replace('Hello, {0} {2}!', arrayContext); |
|
assert.equal('Hello, Robert Cringely!', s2); |
|
}, |
|
|
|
'.replace with function': function () { |
|
function sum(a) { |
|
var t = 0; |
|
array.forEach(a, function (x) { t += x; }); |
|
return t; |
|
} |
|
|
|
var s1 = lang.replace( |
|
'{count} payments averaging {avg} USD per payment.', |
|
lang.hitch( |
|
{ payments: [11, 16, 12] }, |
|
function (_, key) { |
|
switch (key) { |
|
case 'count': |
|
return this.payments.length; |
|
case 'avg': |
|
return sum(this.payments) / this.payments.length; |
|
} |
|
return ''; |
|
} |
|
)); |
|
assert.equal('3 payments averaging 13 USD per payment.', s1); |
|
}, |
|
|
|
'.replace with regex': function () { |
|
var s4 = lang.replace('Hello, ${0} ${2}!', ['Robert', 'X', 'Cringely'], /\$\{([^\}]+)\}/g); |
|
assert.equal('Hello, Robert Cringely!', s4); |
|
} |
|
}); |
|
});
|
|
|