From 6354ca3058565e20d8ac4d20ce46ef69f8682509 Mon Sep 17 00:00:00 2001 From: fukudayasuo Date: Thu, 29 May 2014 21:46:17 +0900 Subject: [PATCH] =?UTF-8?q?#324=20=E3=83=86=E3=82=B9=E3=83=88=E3=82=B1?= =?UTF-8?q?=E3=83=BC=E3=82=B9=E3=81=AE=E3=83=AA=E3=83=95=E3=82=A1=E3=82=AF?= =?UTF-8?q?=E3=82=BF=20#330=20cache=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/webapp/test/h5.core.controller.js | 863 ++++++++++-------- hifive/src/main/webapp/test/testutils.js | 24 +- 2 files changed, 515 insertions(+), 372 deletions(-) diff --git a/hifive/src/main/webapp/test/h5.core.controller.js b/hifive/src/main/webapp/test/h5.core.controller.js index 000a5a14..b960e846 100644 --- a/hifive/src/main/webapp/test/h5.core.controller.js +++ b/hifive/src/main/webapp/test/h5.core.controller.js @@ -71,17 +71,6 @@ $(function() { h5.settings.aspects = null; } - // テストでバインドしたコントローラのdispose - // #qunit-fixture以下にバインドされているコントローラを全てdisposeする。 - function disposeQUnitFixtureController() { - var controllers = h5.core.controllerManager.getControllers('#qunit-fixture', { - deep: true - }); - for (var i = controllers.length - 1; i >= 0; i--) { - controllers[i].dispose(); - } - } - // タッチイベントの位置を設定する関数 function setPos(ev, pos) { if (ev.type.indexOf('touch') != -1) { @@ -1242,7 +1231,7 @@ $(function() { '
'); }, teardown: function() { - disposeQUnitFixtureController(); + testutils.clearController(); h5.settings.commonFailHandler = undefined; } }); @@ -1277,77 +1266,53 @@ $(function() { //============================= // Definition //============================= - module( - "Controller - controller", - { - setup: function() { - $('#qunit-fixture') - .append( - ''); - }, - teardown: function() { - disposeQUnitFixtureController(); - h5.settings.commonFailHandler = undefined; - h5.settings.dynamicLoading.retryInterval = this.originalRetryInterval; - h5.settings.dynamicLoading.retryCount = this.originalRetryCount; - }, - originalRetryInterval: h5.settings.dynamicLoading.retryInterval, - originalRetryCount: h5.settings.dynamicLoading.retryCount - }); + module("Controller - controller", { + setup: function() { + $('#qunit-fixture').append('
'); + }, + teardown: function() { + testutils.clearController(); + } + }); //============================= // Body //============================= - asyncTest('コントローラの作成と要素へのバインド(AOPなし)', 3, function() { - var cc = null; + asyncTest('コントローラの作成と要素へのバインド', 1, function() { + var result; var controller = { - __name: 'TestController', - 'input[type=button] click': function(context) { - cc = context.controller; - this.test(); - }, - test: function() { - $('#controllerResult').empty().text('ok'); - }, - - dblTest: function() { - $('#controllerResult').empty().text('dblok'); + result = true; } }; var testController = h5.core.controller('#controllerTest', controller); testController.readyPromise.done(function() { - $('#controllerTest input[type=button]').click(); - var clickResult = $('#controllerResult').text(); - - strictEqual(clickResult, 'ok', 'コントローラが要素にバインドされているか'); - ok(testController === cc, 'イベントコンテキストにコントローラの参照(context.controller)が格納されているか'); - - var result = []; - var outControllerBase = { - __name: 'OutController', - - '{body} click': function() { - result.push(0); - } - }; - - var outController = h5.core.controller('#controllerResult', outControllerBase); - outController.readyPromise.done(function() { + ok(result, 'コントローラが要素にバインドされていて、イベントハンドラが実行されること'); + start(); + }); + }); - $('body').click(); - ok(result.length, 'コントローラの外にある要素にイベントコールバックが設定できたか'); + //TODO 適切なモジュールを作って移動する + asyncTest('xxControllerがnull,関数,undefinedの場合は子コントローラとして扱わず、エラーにならない', 1, function() { + var result; + var controller = { + __name: 'TestController', + aController: null, + bControlelr: undefined, + cController:function(){} + }; - testController.unbind(); - outController.unbind(); - start(); - }); + var testController = h5.core.controller('#controllerTest', controller); + testController.readyPromise.done(function() { + ok(true); + start(); }); }); + test('__name属性のないオブジェクトをコントローラとしてバインドしようとするとエラーが出ること', function() { var errorCode = ERR.ERR_CODE_INVALID_CONTROLLER_NAME; var controller = { @@ -1414,63 +1379,6 @@ $(function() { } }); - asyncTest('[build#min]コントローラの作成と要素へのバインド(AOPあり)', 3, function() { - if (!h5.core.__compileAspects) { - expect(1); - ok(false, 'このテストは開発版(h5.dev.js)で実行してください。'); - start(); - return; - } - - var controller = { - __name: 'TestController', - - 'input[type=button] click': function(context) { - this.test(); - }, - test: function() { - $('#controllerResult').empty().text('ok'); - }, - - dblTest: function() { - $('#controllerResult').empty().text('dblok'); - } - }; - - var aop1 = { - interceptors: function(invocation) { - var rootElement = this.rootElement; - $(rootElement).append('
'); - invocation.proceed(); - } - }; - - var aop2 = { - interceptors: function(invocation) { - var rootElement = this.rootElement; - $(rootElement).append('
'); - - invocation.proceed(); - } - }; - - h5.core.__compileAspects([aop1, aop2]); - - var testController = h5.core.controller('#controllerTest', controller); - testController.readyPromise.done(function() { - $('#controllerTest input[type=button]').click(); - - strictEqual($('#controllerResult').text(), 'ok', 'コントローラが要素にバインドされているか'); - ok($('#controllerTest #aop1').length, 'AOP1は動作しているか'); - ok($('#controllerTest #aop2').length, 'AOP2は動作しているか'); - - testController.unbind(); - cleanAspects(); - start(); - }); - - }); - test('h5.core.controller() 不正な引数を渡した場合、及び指定された要素が存在しないまたは、複数ある場合にエラーが出ること', 9, function() { $('#controllerTest').append('
a
'); $('#controllerTest').append('
b
'); @@ -1526,7 +1434,6 @@ $(function() { }); test('存在しない要素・複数要素へのバインド', function() { - var controller = { __name: 'TestController' }; @@ -1548,79 +1455,29 @@ $(function() { strictEqual(err2.code, ERR.ERR_CODE_BIND_TOO_MANY_TARGET, 'バインド対象が複数ある場合エラーとなるか'); }); - asyncTest('コントローラ内のthis(AOPなし)', 1, function() { - var capturedController = null; + asyncTest('コントローラ内のthis', 3, function() { + var lifecycleThis, eventHandlerThis, methodThis; var controller = { __name: 'TestController', - - 'input[type=button] click': function(context) { - this.test(); + __construct: function() { + lifecycleThis = this; }, - - test: function() { - capturedController = this; - } - }; - var testController = h5.core.controller('#controllerTest', controller); - testController.readyPromise - .done(function() { - - $('#controllerTest input[type=button]').click(); - - strictEqual(capturedController.__name, 'TestController', - 'コントローラ内のthisはコントローラ自身を指しているか'); - - testController.unbind(); - capturedController = undefined; - start(); - }); - }); - - asyncTest('[build#min]コントローラ内のthis(AOPあり)', 1, function() { - var controllerContext = null; - var controller = { - __name: 'TestController', - - 'input[type=button] click': function(context) { - this.test(); + 'input click': function() { + eventHandlerThis = this; }, - - test: function() { - controllerContext = this; - } - }; - - var aop1 = { - interceptors: function(invocation) { - var rootElement = this.rootElement; - $(rootElement).append('
'); - invocation.proceed(); - } - }; - - var aop2 = { - interceptors: function(invocation) { - var rootElement = this.rootElement; - $(rootElement).append('
'); - - invocation.proceed(); + test: function(context) { + methodThis = this; } }; - h5.core.__compileAspects([aop1, aop2]); - - var testController = h5.core.controller('#controllerTest', controller); - testController.readyPromise - .done(function() { - - $('#controllerTest input[type=button]').click(); - - strictEqual(controllerContext.__name, 'TestController', - 'コントローラ内のthisはコントローラ自身を指しているか'); - - testController.unbind(); - cleanAspects(); - start(); - }); + var c = h5.core.controller('#controllerTest', controller); + c.readyPromise.done(function() { + strictEqual(lifecycleThis, c, '__construct内のthisはコントローラ自身を指しているか'); + $('#controllerTest input[type=button]').click(); + strictEqual(eventHandlerThis, c, 'イベントハンドラ内のthisはコントローラ自身を指しているか'); + this.test(); + strictEqual(methodThis, c, 'メソッド内のthisはコントローラ自身を指しているか'); + start(); + }); }); test('コントローラの循環参照チェックに引っかかるとエラーが発生するか', 1, function() { @@ -1647,8 +1504,11 @@ $(function() { __name: 'TestController' }; + var instance = new (function() { + //空コンストラクタ + })(); try { - h5.core.controller('#controllerTest', testController, '初期化パラメータ'); + h5.core.controller('#controllerTest', testController, instance); } catch (e) { strictEqual(e.code, ERR.ERR_CODE_CONTROLLER_INVALID_INIT_PARAM, '初期化パラメータがプレーンオブジェクトではない時にエラーが発生したか'); @@ -1668,8 +1528,6 @@ $(function() { equal(e.code, ERR.ERR_CODE_CONTROLLER_ALREADY_CREATED, 'コントローラ化済みのオブジェクトを渡すとエラーが発生したか'); } - - c.unbind(); start(); }); }); @@ -1684,159 +1542,378 @@ $(function() { var c = h5.core.controller('#controllerTest', testController); c.readyPromise.done(function() { ok(c, 'xxxControllerというプロパティの値が設定されていない時にエラーが発生せず処理が終了するか'); - c.unbind(); start(); }); + }); + //============================= + // Definition + //============================= + module("Controller - コントローラが上げるイベント", { + setup: function() { + $('#qunit-fixture').append('
'); + }, + teardown: function() { + testutils.clearController(); + } }); - asyncTest('h5controllerreadyイベントのevArgにコントローラが渡されること', 4, function() { - var order = 1; - var conIns = null; + //============================= + // Body +// //============================= +// asyncTest('h5controllerboundイベントの上がるタイミング', 3, function() { +// var callcount = 0; +// var controllerHandler = false; +// var controller = { +// __name: 'TestController', +// __ready: function() { +// strictEqual(callcount, 1, '__readyの前にh5controllerboundが呼ばれること'); +// ok(controllerHandler, +// 'イベントの発火はイベントバインドが終わった後なので、自身のh5controllerreadyイベントをを自身のイベントハンドラで拾えること'); +// }, +// __childController: { +// __name: 'ChildController' +// }, +// '{rootElement} h5controllerbound': function() { +// controllerHandler = true; +// start(); +// } +// }; +// function handler(event, c) { +// callcount++; +// $('body').unbind('h5controllerbound', handler); +// } +// var c = h5.core.controller('#controllerTest', controller); +// c.initPromise.done(function() { +// strictEqual(callcount, 0, 'initPromiseが終わった時点ではh5controllerboundは呼ばれていないこと'); +// }); +// c.readyPromise.done(function() { +// strictEqual(callcount, 0, 'readyPromiseが終わった時点ではh5controllerboundは呼ばれていないこと'); +// }); +// $('body').bind('h5controllerbound', handler); +// }); +// +// asyncTest('h5controllerboundイベントオブジェクト', 3, function() { +// var controller = { +// __name: 'TestController', +// __childController: { +// __name: 'ChildController' +// }, +// '{rootElement} h5controllerbound': function(context) { +// var event = context.event; +// strictEqual(event.type, 'h5controllerbound', +// 'イベントオブジェトのtypeがh5controllerboundであること'); +// strictEqual(event.target, $('#controllerTest')[0], +// 'イベントオブジェトのtargetがコントローラのバインド先であること'); +// strictEqual(context.evArg, this, 'イベントハンドラの引数にルートコントローラのインスタンスが渡されること'); +// start(); +// } +// }; +// h5.core.controller('#controllerTest', controller); +// }); +// +// asyncTest('__initで返したPromiseがrejectされた場合、h5controllerboundイベントは発生しないこと', 1, function() { +// var eventFired = false; +// var controller = { +// __name: 'TestController', +// '{rootElement} h5controllerbound': function(context) { +// eventFired = true; +// }, +// __init: function() { +// var df = this.deferred(); +// df.reject(); +// return df.promise(); +// }, +// __dispose: function() { +// ok(!eventFired, 'h5controllerreadyイベントが発生していないこと'); +// start(); +// } +// }; +// conIns = h5.core.controller('#controllerTest', controller); +// }); +// +// asyncTest('h5controllerreadyイベントの上がるタイミング', 3, function() { +// var callcount = 0; +// var controllerHandler = false; +// var controller = { +// __name: 'TestController', +// __childController: { +// __name: 'ChildController' +// }, +// '{rootElement} h5controllerready': function() { +// controllerHandler = true; +// } +// }; +// function handler(event, c) { +// callcount++; +// strictEqual(callcount, 1, 'readyPromiseが終わったらh5controllerreadyが呼ばれること'); +// ok(controllerHandler, +// 'イベントの発火はイベントバインドが終わった後なので、自身のh5controllerreadyイベントをを自身のイベントハンドラで拾えること'); +// +// $('body').unbind('h5controllerready', handler); +// start(); +// } +// h5.core.controller('#controllerTest', controller).readyPromise.done(function() { +// strictEqual(callcount, 0, 'readyPromise.doneの時点ではh5controllerreadyイベントは上がっていないこと'); +// }); +// $('body').bind('h5controllerready', handler); +// }); +// +// asyncTest('h5controllerreadyイベントオブジェクト', 3, function() { +// var controller = { +// __name: 'TestController', +// __childController: { +// __name: 'ChildController' +// }, +// '{rootElement} h5controllerready': function(context) { +// var event = context.event; +// strictEqual(event.type, 'h5controllerready', +// 'イベントオブジェトのtypeがh5controllerreadyであること'); +// strictEqual(event.target, $('#controllerTest')[0], +// 'イベントオブジェトのtargetがコントローラのバインド先であること'); +// strictEqual(context.evArg, this, 'イベントハンドラの引数にルートコントローラのインスタンスが渡されること'); +// start(); +// } +// }; +// h5.core.controller('#controllerTest', controller); +// }); +// +// asyncTest('__readyで返したPromiseがrejectされた場合、h5controllerreadyイベントは発生しないこと', 1, function() { +// var eventFired = false; +// var controller = { +// __name: 'TestController', +// '{rootElement} h5controllerready': function(context) { +// eventFired = true; +// }, +// __ready: function() { +// var df = this.deferred(); +// df.reject(); +// return df.promise(); +// }, +// __dispose: function() { +// ok(!eventFired, 'h5controllerreadyイベントが発生していないこと'); +// start(); +// } +// }; +// h5.core.controller('#controllerTest', controller); +// }); +// +// asyncTest('h5controllerunboundイベントの上がるタイミング', 3, function() { +// var callcount = 0; +// var controllerHandler = false; +// var controller = { +// __name: 'TestController', +// __ready: function() { +// strictEqual(callcount, 1, '__readyの前にh5controllerboundが呼ばれること'); +// ok(controllerHandler, +// 'イベントの発火はイベントバインドが終わった後なので、自身のh5controllerreadyイベントをを自身のイベントハンドラで拾えること'); +// start(); +// }, +// __childController: { +// __name: 'ChildController' +// }, +// '{rootElement} h5controllerunbound': function() { +// controllerHandler = true; +// } +// }; +// function handler(event, c) { +// callcount++; +// $('body').unbind('h5controllerunbound', handler); +// } +// var c = h5.core.controller('#controllerTest', controller); +// c +// c.readyPromise.done(function() { +// strictEqual(callcount, 1, 'initPromiseが終わった時点ではh5controllerboundは呼ばれていないこと'); +// }); +// $('body').bind('h5controllerunbound', handler); +// }); +// +// asyncTest('h5controllerboundイベントオブジェクト', 3, function() { +// var controller = { +// __name: 'TestController', +// __childController: { +// __name: 'ChildController' +// }, +// '{rootElement} h5controllerbound': function(context) { +// var event = context.event; +// strictEqual(event.type, 'h5controllerbound', +// 'イベントオブジェトのtypeがh5controllerboundであること'); +// strictEqual(event.target, $('#controllerTest')[0], +// 'イベントオブジェトのtargetがコントローラのバインド先であること'); +// strictEqual(context.evArg, this, 'イベントハンドラの引数にルートコントローラのインスタンスが渡されること'); +// start(); +// } +// }; +// h5.core.controller('#controllerTest', controller); +// }); + + //============================= + // Definition + //============================= + module("Controller - イベントハンドラ", { + setup: function() { + $('#qunit-fixture').append('
'); + }, + teardown: function() { + testutils.clearController(); + h5.settings.commonFailHandler = undefined; + h5.settings.dynamicLoading.retryInterval = this.originalRetryInterval; + h5.settings.dynamicLoading.retryCount = this.originalRetryCount; + }, + originalRetryInterval: h5.settings.dynamicLoading.retryInterval, + originalRetryCount: h5.settings.dynamicLoading.retryCount + }); + //============================= + // Body + //============================= + asyncTest('イベントハンドラの動作', 2, function() { + var $controllerTarget = $('#controllerTest'); + $controllerTarget.append(''); + var result; var controller = { __name: 'TestController', - '{rootElement} h5controllerready': function(context) { - equal(order, 2, '__readyのあとに発火すること'); - strictEqual(context.evArg, conIns, '引数にコントローラが返ってくること'); - equal(context.evArg.isReady, true, 'isReadyはtrueであること'); + __ready: function() { + this.$find('input[type=button]').trigger('click'); + ok(result, '__readyの時点でイベントハンドラが動作していること'); + this.unbind(); + result = false; + this.$find('input[type=button]').trigger('click'); + ok(!result, 'unbindするとイベントハンドラは動作しなくなること'); start(); }, - __ready: function() { - equal(conIns.isReady, false, 'isReadyはfalseであること'); - order++; + 'input[type=button] [click]': function(context) { + result = true; } }; - - conIns = h5.core.controller('#controllerTest', controller); + h5.core.controller($controllerTarget, controller); }); - asyncTest('__readyで返したPromiseがrejectされた場合、h5controllerreadyイベントは発生しないこと', 1, function() { - var conIns = null; - + asyncTest('イベントハンドラの動作 {}記法で外側の要素を含めて指定', 7, function() { + var $eventTarget1 = $('
'); + var $eventTarget2 = $('
'); + var $controllerTarget = $('#controllerTest'); + $controllerTarget.append($eventTarget1); + $controllerTarget.after($eventTarget2); + var result1 = false; + var result2 = false; var controller = { __name: 'TestController', - '{rootElement} h5controllerready': function(context) { - ok(false, 'h5controllerreadyイベントが発生したためテスト失敗'); - }, __ready: function() { - var df = this.deferred(); - df.reject(); - - return df.promise(); - }, - __dispose: function() { - equal(conIns.isReady, false, 'isReadyはfalseであること'); + $eventTarget1.click(); + ok(result1, '.event-targetにバインドしたイベントハンドラが動作していること'); + ok(result2, '{.event-target}にバインドしたイベントハンドラが動作していること'); + result1 = result2 = false; + $eventTarget2.click(); + ok(!result1, '.event-targetにバインドしたイベントハンドラは動作しないこと'); + ok(result2, '{.event-target}にバインドしたイベントハンドラが動作していること'); + this.unbind(); + result1 = result2 = false; + $eventTarget1.click(); + ok(!result1, 'unbindすると.event-targetにバインドしたイベントハンドラが動作しないこと'); + ok(!result2, 'unbindすると{.event-target}にバインドしたイベントハンドラが動作しないこと'); + result1 = result2 = false; + $eventTarget2.click(); + ok(!result2, 'unbindすると{.event-target}にバインドしたイベントハンドラが動作しないこと'); start(); + }, + '.event-target click': function() { + result1 = true; + }, + '{.event-target} click': function() { + result2 = true; } }; - - conIns = h5.core.controller('#controllerTest', controller); + h5.core.controller($controllerTarget, controller); }); - //============================= - // Definition - //============================= - module( - "Controller - イベントハンドラ", - { - setup: function() { - $('#qunit-fixture') - .append( - '
'); - }, - teardown: function() { - disposeQUnitFixtureController(); - h5.settings.commonFailHandler = undefined; - h5.settings.dynamicLoading.retryInterval = this.originalRetryInterval; - h5.settings.dynamicLoading.retryCount = this.originalRetryCount; - }, - originalRetryInterval: h5.settings.dynamicLoading.retryInterval, - originalRetryCount: h5.settings.dynamicLoading.retryCount - }); - - //============================= - // Body - //============================= - asyncTest('イベントハンドラの{}記法でオブジェクトを指定する時に2階層以上下のオブジェクトを指定できるか', function() { - window.test1 = { - test2: $('#controllerResult') - }; - var ret = false; + asyncTest('イベントハンドラの動作 {rootElement}を指定', 2, function() { + var $controllerTarget = $('#controllerTest'); + var result = false; var controller = { - __name: 'TestController', - - '{window.test1.test2} click': function(context) { - ret = true; + __ready: function() { + $controllerTarget.click(); + ok(result, '{rootElement}にバインドしたイベントハンドラが動作していること'); + this.unbind(); + result = false; + $controllerTarget.click(); + ok(!result, 'unbindするとイベントハンドラは動作しなくなること'); + + // テストで作成したwindow.test1を削除 + deleteProperty(window, 'test1'); + start(); + }, + '{rootElement} click': function(context) { + result = true; } }; - - var testController = h5.core.controller('#controllerTest', controller); - testController.readyPromise.done(function() { - $('#controllerResult').click(); - ok(ret, '{}記法で2階層以上下のオブジェクトを指定できたか'); - - testController.unbind(); - deleteProperty(window, 'test1'); - start(); - }); + h5.core.controller($controllerTarget, controller); }); - asyncTest('コントローラの作成と要素へのバインド セレクタ、イベントの前後にスペースがあってもイベントハンドリングできること', 9, function() { + asyncTest('イベントハンドラの動作 {}記法でオブジェクトを指定', 2, function() { + var $eventTarget = $('
'); + var $controllerTarget = $('#controllerTest'); + $controllerTarget.append($eventTarget); + window.test1 = { + target: $eventTarget + }; + var result = false; var controller = { - __name: 'TestController', - - ' input[type=button] click': function(context) { - this.test(0); - }, - ' input[type=button] dblclick ': function(context) { - this.dblTest(); - }, - ' #a .b click1': function(context) { - this.test(1); - }, - ' #a .b click2 ': function(context) { - this.test(2); - }, - ' #a .b click3': function(context) { - this.test(3); - }, - ' {#a .b} click4': function(context) { - this.test(4); - }, - ' { #a .b} click5': function(context) { - this.test(5); - }, - ' { #a .b} click6 ': function(context) { - this.test(6); - }, - ' { #a .b } click7 ': function(context) { - this.test(7); - }, - test: function(n) { - $('#controllerResult').empty().text(n); + __ready: function() { + this.$find('#target1').click(); + ok(result, '{window.test1.target}にバインドしたイベントハンドラが動作していること'); + this.unbind(); + result = false; + this.$find('#target1').click(); + ok(!result, 'unbindするとイベントハンドラは動作しなくなること'); + + // テストで作成したwindow.test1を削除 + deleteProperty(window, 'test1'); + start(); }, - - dblTest: function() { - $('#controllerResult').empty().text('dblok'); + '{window.test1.target} click': function(context) { + result = true; } }; + h5.core.controller($controllerTarget, controller); + }); - var testController = h5.core.controller('#controllerTest', controller); - testController.readyPromise.done(function() { - var $result = $('#controllerResult'); + asyncTest('コントローラの作成と要素へのバインド セレクタ、イベントの前後にスペースがあってもイベントハンドリングできること', 9, function() { + var $controllerTarget = $('#controllerTest'); + $controllerTarget.append('
'); + var result; + function handler() { + result = true; + } + var controller = { + __name: 'TestController', + ' input[type=button] click': handler, + ' input[type=button] dblclick ': handler, + ' #a .b click1': handler, + ' #a .b click2 ': handler, + ' #a .b click3': handler, + ' {#a .b} click4': handler, + ' { #a .b} click5': handler, + ' { #a .b} click6 ': handler, + ' { #a .b } click7 ': handler + }; + + h5.core.controller($controllerTarget, controller).readyPromise.done(function() { $('#controllerTest input[type=button]').click(); - strictEqual($result.text(), '0', 'コントローラが要素にバインドされているか'); + ok(result, '前後にスペースがあってもイベントハンドラが動作すること'); + result = false; $('#controllerTest input[type=button]').dblclick(); - strictEqual($result.text(), 'dblok', 'コントローラが要素にバインドされているか'); + ok(result, '前後にスペースがあってもイベントハンドラが動作すること'); + result = false; for (var i = 1; i <= 7; i++) { $('#controllerTest #a .b').trigger('click' + i); - strictEqual($result.text(), '' + i, 'コントローラが要素にバインドされているか'); + ok(result, '前後にスペースがあってもイベントハンドラが動作すること'); + result = false; } start(); }); @@ -2125,7 +2202,7 @@ $(function() { '
'); }, teardown: function() { - disposeQUnitFixtureController(); + testutils.clearController(); h5.settings.listenerElementType = this.originalListenerElementType; }, originalListenerElementType: h5.settings.listenerElementType @@ -2191,7 +2268,7 @@ $(function() { '
'); }, teardown: function() { - disposeQUnitFixtureController(); + testutils.clearController(); } }); @@ -2398,7 +2475,7 @@ $(function() { $('#qunit-fixture').append('
'); }, teardown: function() { - disposeQUnitFixtureController(); + testutils.clearController(); h5.settings.commonFailHandler = undefined; h5.settings.dynamicLoading.retryInterval = this.originalRetryInterval; h5.settings.dynamicLoading.retryCount = this.originalRetryCount; @@ -2508,49 +2585,6 @@ $(function() { }); }); - asyncTest('__metaで指定しているコントローラが無い場合', 1, function() { - var testController = { - __name: 'TestController', - __meta: { - childController: { - useHandlers: true - } - } - }; - - h5.core.controller('#controllerTest', testController).readyPromise.done(function() { - ok(false, 'テスト失敗。コントローラのバインドに成功'); - start(); - }).fail( - function(e) { - strictEqual(e.code, ERR.ERR_CODE_CONTROLLER_META_KEY_INVALID, - '__metaに設定された名前と一致するプロパティ名を持つ子コントローラがundefinedの場合にエラーが発生すること'); - start(); - }); - }); - - asyncTest('__metaで指定しているコントローラがnull', 1, function() { - var testController = { - __name: 'TestController', - childController: null, - __meta: { - childController: { - useHandlers: true - } - } - }; - - h5.core.controller('#controllerTest', testController).readyPromise.done(function() { - ok(false, 'テスト失敗。コントローラのバインドに成功'); - start(); - }).fail( - function(e) { - strictEqual(e.code, ERR.ERR_CODE_CONTROLLER_META_KEY_NULL, - '__metaに設定された名前と一致するプロパティ名を持つ子コントローラがundefinedの場合にエラーが発生するか'); - start(); - }); - }); - asyncTest('rootElementを指定', 1, function() { var $child = $('
'); $('#controllerTest').append($child); @@ -2619,7 +2653,7 @@ $(function() { } }, childController: { - __name: 'ChildController', + __name: 'ChildController1', __init: function() { childRootElm = this.rootElement; }, @@ -2629,7 +2663,7 @@ $(function() { } }, childController: { - __name: 'ChildController', + __name: 'ChildController2', __init: function() { grandChildRootElm = this.rootElement; } @@ -2754,7 +2788,7 @@ $(function() { '
'); }, teardown: function() { - disposeQUnitFixtureController(); + testutils.clearController(); h5.settings.commonFailHandler = undefined; h5.settings.dynamicLoading.retryInterval = this.originalRetryInterval; h5.settings.dynamicLoading.retryCount = this.originalRetryCount; @@ -2877,7 +2911,7 @@ $(function() { '
'); }, teardown: function() { - disposeQUnitFixtureController(); + testutils.clearController(); h5.settings.commonFailHandler = undefined; h5.settings.dynamicLoading.retryInterval = this.originalRetryInterval; h5.settings.dynamicLoading.retryCount = this.originalRetryCount; @@ -3064,7 +3098,7 @@ $(function() { '
'); }, teardown: function() { - disposeQUnitFixtureController(); + testutils.clearController(); h5.settings.commonFailHandler = undefined; h5.settings.dynamicLoading.retryInterval = this.originalRetryInterval; h5.settings.dynamicLoading.retryCount = this.originalRetryCount; @@ -3945,7 +3979,7 @@ $(function() { '
'); }, teardown: function() { - disposeQUnitFixtureController(); + testutils.clearController(); h5.settings.commonFailHandler = undefined; h5.settings.dynamicLoading.retryInterval = this.originalRetryInterval; h5.settings.dynamicLoading.retryCount = this.originalRetryCount; @@ -5581,7 +5615,7 @@ $(function() { '
'); }, teardown: function() { - disposeQUnitFixtureController(); + testutils.clearController(); h5.settings.commonFailHandler = undefined; h5.settings.dynamicLoading.retryInterval = this.originalRetryInterval; h5.settings.dynamicLoading.retryCount = this.originalRetryCount; @@ -5822,7 +5856,7 @@ $(function() { // Definition //============================= module( - "Controller - アスペクト", + "[build#min]Controller - アスペクト", { setup: function() { $('#qunit-fixture') @@ -5830,7 +5864,7 @@ $(function() { '
'); }, teardown: function() { - disposeQUnitFixtureController(); + testutils.clearController(); h5.settings.commonFailHandler = undefined; h5.settings.dynamicLoading.retryInterval = this.originalRetryInterval; h5.settings.dynamicLoading.retryCount = this.originalRetryCount; @@ -5842,6 +5876,99 @@ $(function() { //============================= // Body //============================= + asyncTest('コントローラの作成と要素へのバインド(AOPあり)', 3, function() { + if (!h5.core.__compileAspects) { + expect(1); + ok(false, 'このテストは開発版(h5.dev.js)で実行してください。'); + start(); + return; + } + + var controller = { + __name: 'TestController', + + 'input[type=button] click': function(context) { + this.test(); + }, + test: function() { + $('#controllerResult').empty().text('ok'); + }, + + dblTest: function() { + $('#controllerResult').empty().text('dblok'); + } + }; + + var aop1 = { + interceptors: function(invocation) { + var rootElement = this.rootElement; + $(rootElement).append('
'); + invocation.proceed(); + } + }; + + var aop2 = { + interceptors: function(invocation) { + var rootElement = this.rootElement; + $(rootElement).append('
'); + + invocation.proceed(); + } + }; + + h5.core.__compileAspects([aop1, aop2]); + + var testController = h5.core.controller('#controllerTest', controller); + testController.readyPromise.done(function() { + $('#controllerTest input[type=button]').click(); + + strictEqual($('#controllerResult').text(), 'ok', 'コントローラが要素にバインドされているか'); + ok($('#controllerTest #aop1').length, 'AOP1は動作しているか'); + ok($('#controllerTest #aop2').length, 'AOP2は動作しているか'); + + testController.unbind(); + cleanAspects(); + start(); + }); + + }); + asyncTest('コントローラ内のthis', 3, function() { + var lifecycle, eventHandlerThis, methodThis; + var controller = { + __name: 'TestController', + __construct: function() { + lifecycleThis = this; + }, + 'input click': function() { + eventHandlerThis = this; + }, + test: function(context) { + methodThis = this; + } + }; + var aop1 = { + interceptors: function(invocation) { + invocation.proceed(); + } + }; + + var aop2 = { + interceptors: function(invocation) { + invocation.proceed(); + } + }; + h5.core.__compileAspects([aop1, aop2]); + var c = h5.core.controller('#controllerTest', controller); + c.readyPromise.done(function() { + strictEqual(lifecycleThis, c, '__construct内のthisはコントローラ自身を指しているか'); + $('#controllerTest input[type=button]').click(); + strictEqual(eventHandlerThis, c, 'イベントハンドラ内のthisはコントローラ自身を指しているか'); + this.test(); + strictEqual(methodThis, c, 'メソッド内のthisはコントローラ自身を指しているか'); + start(); + }); + }); + asyncTest('[build#min]アスペクトの動作1', function() { var ret = []; var controller = { @@ -6083,7 +6210,7 @@ $(function() { '
'); }, teardown: function() { - disposeQUnitFixtureController(); + testutils.clearController(); h5.settings.commonFailHandler = undefined; h5.settings.dynamicLoading.retryInterval = this.originalRetryInterval; h5.settings.dynamicLoading.retryCount = this.originalRetryCount; @@ -6614,7 +6741,7 @@ $(function() { onerrorHandler = window.onerror; }, teardown: function() { - disposeQUnitFixtureController(); + testutils.clearController(); $('#qunit-fixture #controllerTest').remove(); // window.onerrorを元に戻す window.onerror = onerrorHandler; @@ -6900,7 +7027,7 @@ $(function() { '
'); }, teardown: function() { - disposeQUnitFixtureController(); + testutils.clearController(); $('#scrollable').remove(); h5.settings.commonFailHandler = undefined; h5.settings.dynamicLoading.retryInterval = this.originalRetryInterval; @@ -7025,7 +7152,7 @@ $(function() { } }; var childController = { - __name: 'TestController', + __name: 'ChildController', '{rootElement} click': function() { var indicator = this.triggerIndicator(); @@ -7900,7 +8027,7 @@ $(function() { '
'); }, teardown: function() { - disposeQUnitFixtureController(); + testutils.clearController(); } }); @@ -8232,7 +8359,7 @@ $(function() { '
'); }, teardown: function() { - disposeQUnitFixtureController(); + testutils.clearController(); } }); //============================= @@ -8309,7 +8436,7 @@ $(function() { }); }, teardown: function() { - disposeQUnitFixtureController(); + testutils.clearController(); // iframe内のコントローラをdispose var iframeControllers = h5.core.controllerManager.getControllers(this.ifDoc, { deep: true @@ -8460,7 +8587,7 @@ $(function() { $('#qunit-fixture').append('
'); }, teardown: function() { - disposeQUnitFixtureController(); + testutils.clearController(); } }); diff --git a/hifive/src/main/webapp/test/testutils.js b/hifive/src/main/webapp/test/testutils.js index 1e07c780..cef3c0d6 100644 --- a/hifive/src/main/webapp/test/testutils.js +++ b/hifive/src/main/webapp/test/testutils.js @@ -93,7 +93,8 @@ function gate(param) { var gateFunction = param.gateFunction; var maxWait = param.maxWait != null ? param.maxWait : testutils.settings.GATE_MAX_WAIT; - var interval = param.interval != null ? param.interval : testutils.settings.GATE_CHECK_INTERVAL; + var interval = param.interval != null ? param.interval + : testutils.settings.GATE_CHECK_INTERVAL; var failMsg = param.failMsg; var dfd = $.Deferred(); @@ -129,15 +130,30 @@ start(); }); } - return dfd.promise(); } + /** + * #qunit-fixtur内にバインドされているコントローラをdisposeして、コントローラキャッシュ、ロジックキャッシュをクリアする + */ + function clearController() { + var controllers = h5.core.controllerManager.getControllers('#qunit-fixture', { + deep: true + }); + for (var i = controllers.length - 1; i >= 0; i--) { + controllers[i].dispose(); + } + h5.core.cacheManager.clearAll(); + } + /** * @name testutils.async * @namespace */ - expose('testutils.async', { - gate: gate + expose('testutils', { + async: { + gate: gate + }, + clearController: clearController }); })(); \ No newline at end of file