UNPKG

dojo

Version:

Dojo core is a powerful, lightweight library that makes common tasks quicker and easier. Animate elements, manipulate the DOM, and query with easy CSS syntax, all without sacrificing performance.

414 lines (350 loc) 11.2 kB
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); } }); });