Plato on Github
Report Home
dojo/tests/unit/parser/parser.js
Maintainability
70.09
Lines of code
959
Difficulty
41.85
Estimated Errors
10.78
Function weight
By Complexity
By SLOC
define([ 'intern!object', 'intern/chai!assert', '../../../parser', 'dojo/dom-construct', 'dojo/_base/array', 'dojo/aspect', 'dojo/_base/declare', 'dojo/dom', 'dojo/dom-attr', 'dojo/_base/lang', 'dojo/on', 'dojo/_base/window', 'dojo/date/stamp', 'dojo/Stateful', 'dojo/Evented', 'dojo/text!./parser.html', './support/util' ], function ( registerSuite, assert, parser, domConstruct, array, aspect, declare, dom, domAttr, lang, on, win, dstamp, Stateful, Evented, template, util ) { var container; /* global tests */ function setup(id, shouldReturn) { return function () { var MyNonDojoClass = window.MyNonDojoClass = function () {}; MyNonDojoClass.extend = function () { var args = arguments; return function () { this.expectedClass = true; this.params = args; }; }; declare('tests.parser.Widget', null, { constructor: function (args) { this.params = args; } }); declare('tests.parser.Class1', null, { constructor: function (args) { this.params = args; lang.mixin(this, args); }, preambleTestProp: 1, preamble: function () { this.preambleTestProp++; }, intProp: 1, callCount: 0, // for connect testing callInc: function () { this.callCount++; }, callCount2: 0, // for assignment testing strProp1: 'original1', strProp2: 'original2', arrProp: [], arrProp2: ['foo'], boolProp1: false, boolProp2: true, boolProp3: false, boolProp4: true, dateProp1: dstamp.fromISOString('2007-01-01'), dateProp2: dstamp.fromISOString('2007-01-01'), dateProp3: dstamp.fromISOString('2007-01-01'), funcProp: function () {}, funcProp2: function () {}, funcProp3: function () {}, onclick: function () { this.prototypeOnclick = true; } // FIXME: have to test dates!! // FIXME: need to test the args property!! }); declare('tests.parser.Class2', null, { constructor: function () { this.fromMarkup = false; }, fromMarkup: false, markupFactory: function () { var i = new tests.parser.Class2(); i.fromMarkup = true; return i; } }); declare('tests.parser.Class3', tests.parser.Class2, { fromMarkup: false, markupFactory: function (args, node, ClassCtor) { var i = new ClassCtor(); i.classCtor = ClassCtor; i.params = args; return i; } }); declare('tests.parser.InputClass', null, { constructor: function (args) { this.params = args; lang.mixin(this, args); }, // these attributes are special in HTML, they don't have a value specified disabled: false, readonly: false, checked: false, // other attributes native to HTML value: 'default value', title: 'default title', tabIndex: '0', // special because mixed case // custom widget attributes that don't match a native HTML attributes custom1: 123, custom2: 456 }); // Test that dir, lang, etc. attributes can be inherited from ancestor node declare('tests.parser.BidiClass', tests.parser.Widget, { constructor: function (args) { lang.mixin(this, args); }, dir: '', lang: '', textdir: '', name: '' }); // For testing that parser recurses correctly, except when the prototype has a // stopParser flag declare('tests.parser.NormalContainer', null, { constructor: function (args) { lang.mixin(this, args); } }); declare('tests.parser.ShieldedContainer', null, { constructor: function (args) { lang.mixin(this, args); }, // flag to tell parser not to instantiate nodes inside of me stopParser: true }); declare('tests.parser.HTML5Props', null, { constructor: function (args) { lang.mixin(this, args); }, simple: false, a: 2, b: null, c: null, d: null, e: null, f: null, afn: function () { return this.a * 2; } }); // not on .prototype: tests.parser.HTML5Props._aDefaultObj = { a: 1, b: 2, simple: true }; declare('tests.parser.HTML5withMethod', null, { constructor: function (args) { lang.mixin(this, args); }, baseValue: 10, someMethod: function () { return this.baseValue; }, diffMethod: function () { this._ran = true; } }); declare('tests.parser.StatefulClass', [Evented, Stateful], { strProp1: '', objProp1: {}, boolProp1: false, prototypeOnclick: false, onclick: function () { this.prototypeOnclick = true; } }); declare('tests.parser.MethodClass', null, { method1ran: false, method1after: false, method2ran: false, method2before: false, method2after: false, method3result: '', method4ran: false, method4after: false, method1: function () { this.method1ran = true; }, method2: function () { this.method2ran = true; }, method3: function (result) { this.method3result = result; }, method4: function () { this.method4ran = true; } }); declare('tests.parser.ClassForMixins', null, { classDone: true }); declare('tests.parser.Mixin1', null, { mixin1Done: true }); declare('tests.parser.Mixin2', null, { mixin2Done: true }); declare('tests.resources.AMDWidget', null, { constructor: function (args) { this.params = args; } }); declare('tests.resources.AMDWidget2', null, { constructor: function (args) { this.params = args; }, method1: function (value) { value++; return value; } }); declare('tests.resources.AMDWidget3', null, { constructor: function (args) { this.params = args; } }); window.deepTestProp = { blah: { thinger: 1 } }; tests.parser.FormClass = declare(tests.parser.Widget, { encType: '' }); window.foo = function () { this.fooCalled = true; }; container = domConstruct.place(util.fixScope(template), document.body); var el = id ? dom.byId(id) : null, ret = parser.parse(el); return shouldReturn && ret; }; } function teardown() { domConstruct.destroy(container); container = null; window.foo = undefined; } registerSuite({ name: 'dojo/parser basic tests', setup: setup('main', true), teardown: teardown, /* global obj */ 'data-dojo-id': function () { assert.isObject(obj); }, /* global obj3 */ 'JsId': function () { assert.isObject(obj3); }, 'string property': function () { assert.isString(obj.strProp1); assert.equal(obj.strProp1, 'text'); }, 'int property': function () { assert.isNumber(obj.intProp); assert.equal(obj.intProp, 5); }, 'array property': function () { assert.lengthOf(obj.arrProp, 3); assert.lengthOf(obj.arrProp[1], 3); assert.equal(obj.arrProp[1], 'bar'); }, 'boolean property': function () { // boolProp1 assert.isBoolean(obj.boolProp1); assert.isTrue(obj.boolProp1); // boolProp2 assert.isBoolean(obj.boolProp2); assert.isFalse(obj.boolProp2); // boolProp3 not specified (prototype says false) assert.isBoolean(obj.boolProp3); // assert.isFalse(obj.boolprop3); // boolProp4 not specified (prototype says true) // assert.isBoolean(obj.boolProp4); // assert.isTrue(obj.boolProp4); }, 'date property': function () { assert.equal(dstamp.toISOString(obj.dateProp1, { selector: 'date' }), '2006-01-01'); // dateProp2='', should map to NaN (a blank value on DateTextBox) assert.ok(isNaN(obj.dateProp2)); // dateProp3='now', should map to current date assert.equal(dstamp.toISOString(obj.dateProp3, { selector: 'date' }), dstamp.toISOString(new Date(), { selector: 'date' })); }, 'unwanted params': function () { // Make sure that parser doesn't pass any unwanted parameters to // widget constructor, especially 'toString' or 'constructor'. // Make exception for dir/lang which parser gleans from document itself. for (var param in obj.params) { assert.ok(array.indexOf( [ 'strProp1', 'strProp2', 'intProp', 'arrProp', 'arrProp2', 'boolProp1', 'boolProp2', 'dateProp1', 'dateProp2', 'dateProp3', 'funcProp2', 'funcProp3', 'preamble', 'callInc1', 'callInc2', 'dir', 'lang', 'textDir' ], param) >= 0, param + ' should not be in the parameters passed to the widget constructor'); } }, 'disabled flag': function () { /* global disabledObj */ assert.isBoolean(disabledObj.disabled); assert.isTrue(disabledObj.disabled); assert.isFalse(disabledObj.checked); }, 'checked flag': function () { /* global checkedObj */ assert.isBoolean(checkedObj.checked); assert.isFalse(checkedObj.disabled); assert.isTrue(checkedObj.checked); }, 'function property': function () { // make sure that unspecified functions (even with common names) // don't get overridden (bug #3074) obj.onclick(); assert.isTrue(obj.prototypeOnclick, 'prototypeOnClick'); // funcProp2='foo' obj.funcProp2(); assert.isTrue(obj.fooCalled, 'fooCalled'); // funcProp3='this.func3Called=true;' obj.funcProp3(); assert.isTrue(obj.func3Called, 'func3Called'); }, 'connect': function () { obj.callInc(); assert.equal(obj.callCount, 2); }, 'function assignment': function () { obj.callInc2(); assert.equal(obj.callCount2, 1); }, 'subnode parse': function () { assert.isFalse(lang.exists('obj2'), 'exists before parse'); var toParse = dom.byId('toParse'); parser.parse(toParse.parentNode); assert.isTrue(lang.exists('obj2'), 'exists after parse'); assert.equal(obj.declaredClass, 'tests.parser.Class1'); }, 'markup factory': function () { assert.isTrue(lang.exists('obj3'), 'obj3 exists'); assert.isTrue(obj3.fromMarkup); }, /* global obj4 */ 'markup factory class': function () { assert.isTrue(lang.exists('obj4'), 'obj4 exists'); assert.equal(obj4.classCtor, tests.parser.Class3); assert.instanceOf(obj4, tests.parser.Class3); assert.instanceOf(obj4, tests.parser.Class2); }, 'no start': function () { var started = false; declare('SampleThinger', null, { startup: function () { started = true; } }); domConstruct.create('div', { dojoType: 'SampleThinger' }, 'parsertest'); parser.parse('parsertest', { noStart: true }); assert.isFalse(started, 'first started check'); domConstruct.empty('parsertest'); started = false; domConstruct.create('div', { dojoType: 'SampleThinger' }, 'parsertest'); parser.parse('parsertest', { noStart: true, rootNode: 'parserTest' }); assert.isFalse(started, 'second started check'); }, // test the varios iterations of parser test // TODO: the following test doesn't acutally test anything because // the parser is calling dojo/query's function instead of dojo.query // This also causes other tests to fail because the aspect call replaces // dojo.query which has functions on it (like dojo.query.matches) /*'root test': function () { var tmp = aspect.after(dojo, 'query', function (sel, root) { assert.equal(root, 'parsertest2'); }); parser.parse('parsertest2'); parser.parse({ rootNode: 'parsertest2' }); parser.parse('parsertest2', { noStart: true }); tmp.remove(); },*/ // Test that when BorderContainer etc. extends _Widget, // parser is aware of the new parameters added (to _Widget // and all of it's subclasses) 'cache refresh': function () { // Add new node to be parsed, referencing a widget that the parser has already // dealt with (and thus cached) var wrapper = domConstruct.place( util.fixScope('<div><div ${dojo}Type="tests.parser.Class3" newParam=12345>hi</div></div>'), win.body(), 'last'); try { // Modify Class3's superclass widget to have new parameter (thus Class3 inherits it) lang.extend(tests.parser.Class2, { newParam: 0 }); // Run the parser and see if it reads in newParam var widgets = parser.parse({ rootNode: wrapper }); assert.lengthOf(widgets, 1); assert.equal(widgets[0].params.newparam || widgets[0].params.newParam, 12345); } finally { domConstruct.destroy(wrapper); } }, // Test that parser recurses correctly, except when there's a stopParser flag not to /* global container1, contained1, container2, contained2 */ 'recurse': function () { assert.isDefined(container1, 'normal container created'); assert.isDefined(container1.incr, 'script tag works too'); assert.isDefined(contained1, 'child widget also created'); assert.isDefined(contained2, 'child widget 2 also created'); assert.isDefined(container2, 'shielded container created'); assert.isDefined(container2.incr, 'script tag works too'); assert.isUndefined(window.contained3, 'child widget not created'); assert.isUndefined(window.contained4, 'child widget 2 not created'); }, /* global html5simple, html5simple2 */ 'simple HTML5': function () { assert.isObject(html5simple, 'data-dojo-id export'); assert.isObject(html5simple2, 'data-dojo-id export'); assert.isTrue(html5simple.simple, 'default respecified in props=""'); assert.isFalse(html5simple2.simple, 'default overridden by props=""'); // test data-dojo-props='simple:false, a:1, b:'two', c:[1,2,3], d:function(){ return this; }, e:{ f:'g' }' var it = html5simple2; assert.equal(it.a, 1, 'number in param'); assert.equal(it.b, 'two', 'string in param'); assert.isArray(it.c, 'array in param'); assert.lengthOf(it.c, 3, 'array sanity'); assert.equal(it.e.f, 'g', 'nested object with string'); // test the function assert.equal(it.d(), it, 'simple \'return this\' function'); }, /* global html5simple3 */ 'HTML5 inherited': function () { assert.isObject(html5simple3); var val = html5simple3.afn(); assert.equal(val, html5simple3.a * 2, 'afn() overrides default but calls inherited'); }, /* global htmldojomethod */ 'HTML5 with method': function () { // testing data-dojo-event and data-dojo-args support for dojo/method and dojo/connect assert.isObject(htmldojomethod); assert.isTrue(htmldojomethod._methodRan, 'plain dojo/method ran'); var x = htmldojomethod.someMethod(2, 2); assert.equal(x, 14, 'overridden dojo/method'); htmldojomethod.diffMethod(2); assert.isTrue(htmldojomethod._ran, 'ensures original was called first'); assert.equal(htmldojomethod._fromvalue, 2, 'ensures connected was executed in scope'); }, /* global objOnWatch */ 'test watch': function () { // testing script-type dojo/watch and dojo/on assert.isObject(objOnWatch); objOnWatch.set('strProp1', 'newValue1'); assert.equal(objOnWatch.arrProp.newValue, 'newValue1', 'ensures watch executed'); objOnWatch.onclick(); assert.isTrue(objOnWatch.prototypeOnclick, 'ensures original was called'); assert.isTrue(objOnWatch.boolProp1, 'ensure on executed in scope'); }, /* global on_form */ 'on': function () { /*jshint camelcase:false*/ // testing script-type dojo/on, when script comes after another element parser.parse('on'); assert.property(window, 'on_form', 'widget created'); on_form.emit('click'); assert.isTrue(on_form.clicked, 'on callback fired'); }, /* global objAspect */ 'aspect': function () { // testing script-type dojo/aspect assert.isObject(objAspect); assert.isFalse(objAspect.method1ran, 'ensures method unfired'); assert.isFalse(objAspect.method2ran, 'ensures method unfired'); assert.equal(objAspect.method3result, '', 'ensures method unfired'); assert.isFalse(objAspect.method4ran, 'ensures method unfired'); objAspect.method1(); objAspect.method2(); objAspect.method3('something'); objAspect.method4(); assert.isTrue(objAspect.method1ran, 'method fired'); assert.isTrue(objAspect.method1after, 'after advice fired'); assert.isTrue(objAspect.method2ran, 'method fired'); assert.isTrue(objAspect.method2before, 'around before advice fired'); assert.isTrue(objAspect.method2after, 'around after advice fired'); assert.equal(objAspect.method3result, 'before', 'before argument passed'); assert.isTrue(objAspect.method4ran, 'method fired'); assert.isTrue(objAspect.method4after, 'after advice fired'); }, /* global objAMDWidget */ 'mid': function () { // testing specifying data-dojo-type as mid assert.isObject(objAMDWidget); assert.equal(objAMDWidget.params.value, 'Value1', 'ensure object was properly parsed using MID'); } }); registerSuite({ name: 'bidi', setup: setup('main'), teardown: teardown, // Test that dir=rtl or dir=ltr setting trickles down from root node /* global setRtl, inheritRtl, inheritRtl2, inheritLtr, setLtr */ 'dir attribute': function () { parser.parse('dirSection1'); parser.parse('dirSection2'); assert.equal(setRtl.dir, 'rtl', 'direct setting of dir=rtl works'); assert.equal(inheritRtl.dir, 'rtl', 'inherited rtl works'); assert.equal(inheritLtr.dir, 'ltr', 'inherited ltr works (closest ancestor wins)'); assert.equal(inheritRtl2.dir, 'rtl', 'inherited rtl works, from grandparent'); assert.equal(setLtr.dir, 'ltr', 'direct setting of dir=ltr overrides inherited RTL'); }, /* global noLang, inheritedLang, specifiedLang */ 'lang attribute': function () { parser.parse('langSection'); assert.notProperty(noLang.params, 'lang', 'no lang'); assert.equal(inheritedLang.lang, 'it_it', 'inherited lang works'); assert.equal(specifiedLang.lang, 'en_us', 'direct setting of lang overrides inherited'); }, /* global noTextdir, inheritedTextdir, specifiedTextdir */ 'textDir attribute': function () { parser.parse('textDirSection'); assert.notProperty(noTextdir.params, 'textDir', 'no textdir'); assert.equal(inheritedTextdir.textDir, 'rtl', 'inherited textdir works'); assert.equal(specifiedTextdir.textDir, 'ltr', 'direct setting of textdir overrides inherited'); }, 'inheritance from HTML': function () { // Test that calling parser.parse(nodeX) will inherit dir/lang/etc. settings // even from <html> var textdirAttr = util.fixScope('data-${dojo}-textdir'); var attrs = { dir: 'rtl', lang: 'ja-jp' }; attrs[textdirAttr] = 'auto'; domAttr.set(win.doc.documentElement, attrs); parser.parse('bidiInheritanceFromHtml'); /* global inheritedFromHtml */ assert.equal(inheritedFromHtml.params.dir, 'rtl', 'dir'); assert.equal(inheritedFromHtml.params.lang, 'ja-jp', 'lang'); assert.equal(inheritedFromHtml.params.textDir, 'auto', 'textDir'); // teardown array.forEach(['dir', 'lang', textdirAttr], function (attr) { win.doc.documentElement.removeAttribute(attr); }); } }); registerSuite({ name: 'IE Attribute Detection', setup: setup('main'), teardown: teardown, 'input1': function () { var widgets = parser.instantiate([dom.byId('ieInput1')]); var params = widgets[0].params; assert.equal(params.type, 'checkbox', 'type'); assert.isTrue(params.disabled, 'disabled'); assert.isTrue(params.checked, 'checked'); assert.isTrue(params.readonly, 'readonly'); assert.equal(params.foo, 'bar', 'foo'); assert.equal(params.bar, 'zaz', 'bar'); assert.equal(params.bob, 'escaped\"dq', 'bob'); assert.equal(params.frank, 'escaped\'sq', 'frank'); //assert.isFalse('value' in params, 'value not specified'); // fails in IE8, thinks value=='on' }, 'input2': function () { var widgets = parser.instantiate([dom.byId('ieInput2')]); var params = widgets[0].params; assert.notProperty(params, 'type', 'type'); assert.notProperty(params, 'name', 'name'); assert.notProperty(params, 'value', 'value'); assert.notProperty(params, 'data-dojo-type', 'data-dojo-type'); assert.notProperty(params, 'data-dojo-props', 'data-dojo-props'); assert.equal(params.foo, 'hi', 'foo'); assert.notProperty(params, 'value', 'value not specified'); }, 'input3': function () { var widgets = parser.instantiate([dom.byId('ieInput3')]); var params = widgets[0].params; assert.equal(params.type, 'password', 'type'); assert.equal(params.name, 'test', 'name'); assert.equal(params.value, '123', 'value'); assert.equal(params['class'], 'myClass', 'class'); assert.equal(params.style.replace(/[ ;]/g, '').toLowerCase(), 'display:block', 'style'); assert.equal(params.tabIndex, '3', 'tabIndex'); }, 'textarea': function () { var widgets = parser.instantiate([dom.byId('ieTextarea')]); var params = widgets[0].params; assert.equal(params.value, 'attrVal', 'value'); }, 'button1': function () { var widgets = parser.instantiate([dom.byId('ieButton1')]); var params = widgets[0].params; assert.isTrue(params.checked, 'checked'); assert.equal(params.value, 'button1val', 'value'); }, 'button2': function () { var widgets = parser.instantiate([dom.byId('ieButton2')]); var params = widgets[0].params; assert.notProperty(params, 'checked', 'checked'); assert.notProperty(params, 'value', 'value'); }, 'button3': function () { var widgets = parser.instantiate([dom.byId('ieButton3')]); var params = widgets[0].params; assert.isTrue(params.checked, 'checked'); }, 'button4': function () { var widgets = parser.instantiate([dom.byId('ieButton4')]); var params = widgets[0].params; assert.notProperty(params, 'checked'); }, 'form1': function () { var widgets = parser.instantiate([dom.byId('ieForm1')]); var params = widgets[0].params; assert.equal(params.encType, 'foo', 'encType is specified'); }, 'form2': function () { var widgets = parser.instantiate([dom.byId('ieForm2')]); var params = widgets[0].params; assert.notProperty(params, 'encType', 'encType not specified'); }, 'li': function () { var widgets = parser.instantiate([dom.byId('li')]); var params = widgets[0].params; assert.equal(params.value, 'home'); } }); registerSuite({ name: 'mixed attribute specification', setup: setup('main'), teardown: teardown, /* global mixedObj */ 'mixed': function () { parser.parse(dom.byId('mixedContainer')); assert.isObject(mixedObj, 'widget created'); assert.equal(mixedObj.value, 'mixedValue', 'native attribute'); assert.equal(mixedObj.custom1, 999, 'data-dojo-props attribute'); assert.equal(mixedObj.title, 'custom title', 'data-dojo-props overrides native'); } }); registerSuite({ name: 'functions', setup: setup('main'), teardown: teardown, 'onclick': function () { declare('tests.parser.Button', null, { onClick: function () { console.log('prototype click'); }, constructor: function (args, node) { lang.mixin(this, args); this.domNode = node; aspect.after(this.domNode, 'onclick', lang.hitch(this, 'onClick')); } }); buttonClicked = function () { console.log('markup click'); }; // markup says onClick='buttonClicked' // Parse markup inside 'functions' div parser.parse('functions'); // Should have created an instance called 'button' where button.onClick == buttonClicked /* global button, buttonClicked */ assert.isObject(button, 'widget created'); assert.isFunction(button.onClick, 'created as function'); assert.isTrue(buttonClicked === button.onClick, 'points to specified function'); } }); registerSuite({ name: 'parser.construct()', setup: setup('main'), teardown: teardown, /* global objC1, objC2 */ 'construct1': function () { // var nodes = [dom.byId('objC1'), dom.byId('objC2')]; parser.construct(tests.parser.Class1, dom.byId('objC1')); assert.isObject(objC1, 'widget 1 created'); assert.equal(objC1.intProp, 5, 'objC1.intProp'); parser.construct(tests.parser.Class1, dom.byId('objC2')); assert.isObject(objC2, 'widget 2 created'); assert.equal(objC2.intProp, 5, 'objC2.intProp'); } }); registerSuite({ name: 'data-dojo-mixins support', setup: setup('mixins', true), teardown: teardown, 'mixins': function () { /* global resultMixins1, resultMixins2 */ assert.ok(resultMixins1, 'object using data-dojo-mixins created from an already parsed type'); assert.isTrue(resultMixins1.mixin1Done, 'mixin1 correctly mixed in'); assert.isTrue(resultMixins1.mixin2Done, 'mixin2 correctly mixed in'); assert.isTrue(resultMixins1.amdMixinDone, 'amd mixin correctly mixed in'); assert.ok(resultMixins2, 'object using data-dojo-mixins created from a non parsed type'); assert.isTrue(resultMixins2.classDone, 'class correctly created'); assert.isTrue(resultMixins2.mixin1Done, 'mixin1 correctly mixed in'); assert.isTrue(resultMixins2.mixin2Done, 'mixin2 correctly mixed in'); assert.isTrue(resultMixins2.amdMixinDone, 'amd mixin correctly mixed in'); /* global resultNonDojoMixin */ assert.isTrue(resultNonDojoMixin.expectedClass, 'correct class is returned for composeJS mixin'); assert.equal(resultNonDojoMixin.params.length, 2, 'correct # of params were passed to compose JS'); assert.equal(resultNonDojoMixin.params[0], tests.parser.Mixin1, 'correct param 1'); assert.equal(resultNonDojoMixin.params[1], tests.parser.Mixin2, 'correct param 2'); } }); registerSuite({ name: 'behavorial', setup: setup('main'), teardown: teardown, 'doubleConnect': function () { // Class used in 'behavioral' <div> /* global Behavioral1:true */ Behavioral1 = declare(null, { constructor: function (params, node) { on(node, 'click', lang.hitch(this, 'onClick')); if (typeof params.onClick !== 'function') { throw new Error('onClick not passed to constructor'); } lang.mixin(this, params); }, onClick: function () { console.log('original onnClick handler'); }, foo: '' }); parser.parse('behavioral'); // Setup global accessed by Behavioral1.onclick handler behavioralClickCounter = 0; // Trigger click event, and make sure that handler was only called once. on.emit(dom.byId('bh1'), 'click', {bubbles: true, cancelable: true}); /* global behavioralClickCounter */ assert.equal(behavioralClickCounter, 1, 'one click event processed'); assert.equal(dom.byId('bh1').getAttribute('foo'), 'bar', 'foo attribute not removed from widget DOMNode'); } }); registerSuite({ name: 'script type=dojo/require support', setup: setup('main'), teardown: teardown, 'declarativeRequire': function () { var td = this.async(); parser.parse('declarativeRequire').then(td.callback(function () { /* global dr1, dr2, dr3, dr4, dr5 */ assert.isObject(dr1, 'object using MID mapped to return var'); assert.equal(dr1.params.foo, 'bar', 'parameters set on instantiation'); assert.isObject(dr2, 'object using MID mapped to return var'); assert.equal(dr2.params.foo, 'bar', 'parameters set on instantiation'); assert.isObject(dr3, 'object using fully required'); assert.equal(dr3.params.foo, 'bar', 'parameters set on instantiation'); assert.equal(dr4.params.foo, 2, 'module loaded and executed'); assert.equal(dr5.method1(1), 3, 'declarative script has access to parser scope'); })); }, 'contextRequire': function () { var td = this.async(); parser.parse('contextRequire', { contextRequire: require }).then(td.callback(function () { /* global cr1, cr2, cr3, cr4 */ assert.isObject(cr1, 'object using relative MID mapped to return var'); assert.equal(cr1.params.foo, 'bar', 'parameters set on instantiation'); assert.isObject(cr2, 'object using relative MID mapped to return var'); assert.equal(cr2.params.foo, 'bar', 'parameters set on instantiation'); assert.isObject(cr3, 'object using relative MID mapped to return var'); assert.equal(cr3.params.foo, 'bar', 'parameters set on instantiation'); assert.isObject(cr4, 'object using relative MID mapped to return var'); assert.equal(cr4.params.foo, 'bar', 'parameters set on instantiation'); })); } }); registerSuite({ name: 'promise error handling support', setup: setup('main'), teardown: teardown, 'asyncError': function () { var td = this.async(); parser.parse('errorHandling').then(td.rejectOnError(function () { throw new Error('shouldn\'t get here'); }), td.callback(function (e) { assert.equal(typeof e, 'object', 'error object returned'); })); }, 'missingCtor': function () { var td = this.async(); parser.parse('missingCtor').then(td.rejectOnError(function () { throw new Error('shouldn\'t get here'); }), td.callback(function (e) { assert.equal(typeof e, 'object', 'error object returned'); assert.equal(e.toString(), 'Error: Unable to resolve constructor for: \'some.type\'', 'proper error value returned'); })); } }); });