FLEX-35321 LayoutManager.validateNow() doesn't use phased instantiation, so it wasn't the best idea to test it with that, at least the test where we fake a user request for the removal of the component in the next frame. Also added a test that tries to make sure that objects removed from stage and then readded are indeed validated and initialized.
Project: http://git-wip-us.apache.org/repos/asf/flex-sdk/repo Commit: http://git-wip-us.apache.org/repos/asf/flex-sdk/commit/f475aed9 Tree: http://git-wip-us.apache.org/repos/asf/flex-sdk/tree/f475aed9 Diff: http://git-wip-us.apache.org/repos/asf/flex-sdk/diff/f475aed9 Branch: refs/heads/master Commit: f475aed995adc5206a27ad6fc8cf80224ed425fb Parents: 5ea79a2 Author: Mihai Chira <mih...@apache.org> Authored: Sat Jun 10 10:33:28 2017 +0200 Committer: Mihai Chira <mih...@apache.org> Committed: Sat Jun 10 10:33:28 2017 +0200 ---------------------------------------------------------------------- .../managers/LayoutManager_FLEX_35321_Tests.as | 104 ++++++++++++++++--- 1 file changed, 88 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/f475aed9/frameworks/projects/framework/tests/mx/managers/LayoutManager_FLEX_35321_Tests.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/framework/tests/mx/managers/LayoutManager_FLEX_35321_Tests.as b/frameworks/projects/framework/tests/mx/managers/LayoutManager_FLEX_35321_Tests.as index 47d5f14..a23d002 100644 --- a/frameworks/projects/framework/tests/mx/managers/LayoutManager_FLEX_35321_Tests.as +++ b/frameworks/projects/framework/tests/mx/managers/LayoutManager_FLEX_35321_Tests.as @@ -6,7 +6,8 @@ package mx.managers { import mx.core.mx_internal; import mx.events.FlexEvent; - import org.flexunit.asserts.assertFalse; + import org.flexunit.asserts.assertEquals; + import org.flexunit.asserts.assertNotNull; import org.flexunit.asserts.assertNull; import org.flexunit.async.Async; import org.fluint.uiImpersonation.UIImpersonator; @@ -19,14 +20,15 @@ package mx.managers { private static const _finishNotifier:EventDispatcher = new EventDispatcher(); private var _objectWhichIsRemovedOnSizeValidation:SomeComponent; - private var _creationCompleteCalled:Boolean; + private var _creationCompleteCalls:int; [Before] public function setUp():void { - _creationCompleteCalled = false; + _creationCompleteCalls = 0; _objectWhichIsRemovedOnSizeValidation = new SomeComponent(); - UIImpersonator.addChild(_objectWhichIsRemovedOnSizeValidation); + _objectWhichIsRemovedOnSizeValidation.addEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete); + UIImpersonator.addElement(_objectWhichIsRemovedOnSizeValidation); } [After] @@ -41,14 +43,14 @@ package mx.managers { { //given UIComponentGlobals.mx_internal::layoutManager.usePhasedInstantiation = false; - _objectWhichIsRemovedOnSizeValidation.addEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete); + _objectWhichIsRemovedOnSizeValidation.removeFromStageOnValidateProperties = true; //when _objectWhichIsRemovedOnSizeValidation.validateNow(); //then assertNull("The object was actually not removed from stage. Huh?", _objectWhichIsRemovedOnSizeValidation.parent); - assertFalse("Yep, this is the bug. Why call initialized=true on an object that's not on stage?", _creationCompleteCalled); + assertEquals("Yep, this is the bug. Why call initialized=true on an object that's not on stage?", 0, _creationCompleteCalls); } [Test(async, timeout=500)] @@ -56,25 +58,79 @@ package mx.managers { { //given UIComponentGlobals.mx_internal::layoutManager.usePhasedInstantiation = true; - _objectWhichIsRemovedOnSizeValidation.addEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete); + _objectWhichIsRemovedOnSizeValidation.removeFromStageOnValidateProperties = false; //when - _objectWhichIsRemovedOnSizeValidation.validateNow(); - _objectWhichIsRemovedOnSizeValidation.pretendUserAskedForComponentRemoval(); + _objectWhichIsRemovedOnSizeValidation.invalidateDisplayList(); + _objectWhichIsRemovedOnSizeValidation.invalidateProperties(); + _objectWhichIsRemovedOnSizeValidation.invalidateSize(); + + //then wait 1 frame + noEnterFramesRemaining = 1; + UIImpersonator.testDisplay.addEventListener(Event.ENTER_FRAME, onEnterFrame); + Async.handleEvent(this, _finishNotifier, Event.COMPLETE, then_remove_from_stage_in_next_frame, 300); + } + + private function then_remove_from_stage_in_next_frame(event:Event, passThroughData:Object):void + { + //when + _objectWhichIsRemovedOnSizeValidation.pretendUserAskedForComponentRemovalInNextFrame(); //then wait 2 frames noEnterFramesRemaining = 2; UIImpersonator.testDisplay.addEventListener(Event.ENTER_FRAME, onEnterFrame); - Async.handleEvent(this, _finishNotifier, Event.COMPLETE, then_assert, 300); + Async.handleEvent(this, _finishNotifier, Event.COMPLETE, then_assert_not_initialized, 300); + } + + private function then_assert_not_initialized(event:Event, passThroughData:Object):void + { + //then + assertNull("The object was actually not removed from stage. Huh?", _objectWhichIsRemovedOnSizeValidation.parent); + assertEquals("Yep, this is the bug. Why call initialized=true on an object that's not on stage?", 0, _creationCompleteCalls); + } + + + [Test(async, timeout=750)] + public function test_object_removed_from_stage_then_readded_is_initialized_once():void + { + //given + UIComponentGlobals.mx_internal::layoutManager.usePhasedInstantiation = true; + _objectWhichIsRemovedOnSizeValidation.removeFromStageOnValidateProperties = false; + + //when + _objectWhichIsRemovedOnSizeValidation.validateNow(); + _objectWhichIsRemovedOnSizeValidation.pretendUserAskedForComponentRemovalInNextFrame(); + + //then wait 1 frame + noEnterFramesRemaining = 1; + UIImpersonator.testDisplay.addEventListener(Event.ENTER_FRAME, onEnterFrame); + Async.handleEvent(this, _finishNotifier, Event.COMPLETE, then_readd_object, 200); } - private function then_assert(event:Event, passThroughData:Object):void + private function then_readd_object(event:Event, passThroughData:Object):void { //then assertNull("The object was actually not removed from stage. Huh?", _objectWhichIsRemovedOnSizeValidation.parent); - assertFalse("Yep, this is the bug. Why call initialized=true on an object that's not on stage?", _creationCompleteCalled); + + //when + UIImpersonator.addElement(_objectWhichIsRemovedOnSizeValidation); + + //then wait 4 frames, to make sure validation is done + noEnterFramesRemaining = 4; + UIImpersonator.testDisplay.addEventListener(Event.ENTER_FRAME, onEnterFrame); + Async.handleEvent(this, _finishNotifier, Event.COMPLETE, then_assert_one_initialization_only, 400); + } + + private function then_assert_one_initialization_only(event:Event, passThroughData:Object):void + { + //then + assertNotNull("The object should be on stage...", _objectWhichIsRemovedOnSizeValidation.parent); + assertEquals("When validation is interrupted half-way it should be complete once the object is re-added to stage", 1, _creationCompleteCalls); } + + + private static function onEnterFrame(event:Event):void { if(!--noEnterFramesRemaining) @@ -86,7 +142,7 @@ package mx.managers { private function onCreationComplete(event:FlexEvent):void { - _creationCompleteCalled = true; + _creationCompleteCalls++; } } } @@ -99,12 +155,23 @@ import mx.core.UIComponent; class SomeComponent extends UIComponent { - private var _timer:Timer = new Timer(1, 1); + private var _removeFromStageOnValidateProperties:Boolean = false; + + override public function validateProperties():void + { + super.validateProperties(); + if(_removeFromStageOnValidateProperties) + removeFromStage(); + } override public function validateSize(recursive:Boolean = false):void { super.validateSize(recursive); - removeFromStage(); + } + + override public function validateDisplayList():void + { + super.validateDisplayList(); } private function removeFromStage():void @@ -118,8 +185,13 @@ class SomeComponent extends UIComponent } } - public function pretendUserAskedForComponentRemoval():void + public function pretendUserAskedForComponentRemovalInNextFrame():void { callLater(removeFromStage); } + + public function set removeFromStageOnValidateProperties(value:Boolean):void + { + _removeFromStageOnValidateProperties = value; + } } \ No newline at end of file