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.

964 lines (801 loc) 28.8 kB
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 () { delete window.tests; 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; delete window.foo; delete window.tests; } 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'); })); } }); });