Repository: flex-sdk Updated Branches: refs/heads/develop bb3914ed9 -> 2afdbe885
FLEX-34088 Added unit test to reproduce the bug. Currently it passes, but I tested locally with some modifications to DropDownController and can certify it does indeed fail when it should - namely, when both the fix for FLEX-34088 and FLEX-34078 are removed. In other words, the fix for FLEX-34078 also fixes this issue, making the current fix superfluous. I'll remove it in the next commit. Project: http://git-wip-us.apache.org/repos/asf/flex-sdk/repo Commit: http://git-wip-us.apache.org/repos/asf/flex-sdk/commit/e6e2e445 Tree: http://git-wip-us.apache.org/repos/asf/flex-sdk/tree/e6e2e445 Diff: http://git-wip-us.apache.org/repos/asf/flex-sdk/diff/e6e2e445 Branch: refs/heads/develop Commit: e6e2e445973d01fd00ebf93020c0a6f8c1f248c3 Parents: bb3914e Author: Mihai Chira <mih...@apache.org> Authored: Fri Sep 9 13:41:41 2016 +0200 Committer: Mihai Chira <mih...@apache.org> Committed: Fri Sep 9 13:41:41 2016 +0200 ---------------------------------------------------------------------- .../components/supportClasses/ButtonBase.as | 2 +- .../CalloutButton_FLEX_34088_Tests.as | 146 +++++++++++++++++++ 2 files changed, 147 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/e6e2e445/frameworks/projects/spark/src/spark/components/supportClasses/ButtonBase.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/spark/src/spark/components/supportClasses/ButtonBase.as b/frameworks/projects/spark/src/spark/components/supportClasses/ButtonBase.as index 26bdf02..df08bdf 100644 --- a/frameworks/projects/spark/src/spark/components/supportClasses/ButtonBase.as +++ b/frameworks/projects/spark/src/spark/components/supportClasses/ButtonBase.as @@ -1345,7 +1345,7 @@ public class ButtonBase extends SkinnableComponent implements IFocusManagerCompo // There are two possibilities for being here: // 1) mouseCaptured wasn't set to true (meaning this is the first click) // 2) mouseCaptured was true (meaning a click operation hadn't finished - // and we find ourselves in here again--perhaps it was a doublet tap). + // and we find ourselves in here again--perhaps it was a double tap). // In either case, let's make sure that down state shows up for a little bit // before going back to the up state. http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/e6e2e445/frameworks/projects/spark/tests/spark/components/supportClasses/CalloutButton_FLEX_34088_Tests.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/spark/tests/spark/components/supportClasses/CalloutButton_FLEX_34088_Tests.as b/frameworks/projects/spark/tests/spark/components/supportClasses/CalloutButton_FLEX_34088_Tests.as new file mode 100644 index 0000000..e084124 --- /dev/null +++ b/frameworks/projects/spark/tests/spark/components/supportClasses/CalloutButton_FLEX_34088_Tests.as @@ -0,0 +1,146 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// + +package spark.components.supportClasses { + import flash.display.DisplayObject; + import flash.events.Event; + import flash.events.EventDispatcher; + import flash.events.MouseEvent; + + import mx.collections.ArrayCollection; + + import org.flexunit.asserts.assertFalse; + import org.flexunit.asserts.assertTrue; + import org.flexunit.async.Async; + import org.fluint.uiImpersonation.UIImpersonator; + + import spark.components.CalloutButton; + import spark.components.DropDownList; + + public class CalloutButton_FLEX_34088_Tests + { + private static const NO_ENTER_FRAMES_TO_ALLOW:int = 1; + private static var noEnterFramesRemaining:int = NaN; + private static const _finishNotifier:EventDispatcher = new EventDispatcher(); + + private static var _sut:CalloutButton; + private static var _dropDownList:DropDownListInspectable; + + [Before] + public function setUp():void + { + _sut = new CalloutButton(); + + _dropDownList = new DropDownListInspectable(); + _dropDownList.dataProvider = new ArrayCollection([{label:"Hello"}, {label:"World"}]); + _sut.calloutContent = [_dropDownList]; + } + + [After] + public function tearDown():void + { + _sut = null; + } + + [Test(async, timeout=1000)] + public function test_dropdown_doesnt_close_when_item_selected_from_DropDownList():void + { + //given + UIImpersonator.addElement(_sut); + + //when + _sut.dispatchEvent(new MouseEvent(MouseEvent.ROLL_OVER)); + _sut.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_DOWN)); + + //then - wait a frame + noEnterFramesRemaining = NO_ENTER_FRAMES_TO_ALLOW; + UIImpersonator.testDisplay.addEventListener(Event.ENTER_FRAME, onEnterFrame); + Async.handleEvent(this, _finishNotifier, Event.COMPLETE, then_open_drop_down, 300); + } + + private function then_open_drop_down(event:Event, passThroughData:Object):void + { + //then + assertTrue(_sut.isDropDownOpen); + + //when + _dropDownList.openButton.dispatchEvent(new MouseEvent(MouseEvent.ROLL_OVER)); + _dropDownList.openButton.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_DOWN)); + + //then - wait a frame + noEnterFramesRemaining = NO_ENTER_FRAMES_TO_ALLOW; + UIImpersonator.testDisplay.addEventListener(Event.ENTER_FRAME, onEnterFrame); + Async.handleEvent(this, _finishNotifier, Event.COMPLETE, then_select_item_in_drop_down, 300); + } + + private function then_select_item_in_drop_down(event:Event, passThroughData:Object):void + { + //then + assertTrue("DropDownList should be open", _dropDownList.isDropDownOpen); + assertTrue("DropDownList should be open", _dropDownList.owns(DisplayObject(_dropDownList.lastRenderer))); + + //when + _dropDownList.lastRenderer.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_DOWN)); + + //then - wait a frame + noEnterFramesRemaining = NO_ENTER_FRAMES_TO_ALLOW; + UIImpersonator.testDisplay.addEventListener(Event.ENTER_FRAME, onEnterFrame); + Async.handleEvent(this, _finishNotifier, Event.COMPLETE, then_assert_callout_still_open, 300); + } + + private function then_assert_callout_still_open(event:Event, passThroughData:Object):void + { + //then + assertFalse(_dropDownList.isDropDownOpen); + assertTrue("Callout should still be open", _sut.isDropDownOpen); + } + + private static function onEnterFrame(event:Event):void + { + if(!--noEnterFramesRemaining) + { + UIImpersonator.testDisplay.removeEventListener(Event.ENTER_FRAME, onEnterFrame); + _finishNotifier.dispatchEvent(new Event(Event.COMPLETE)); + } + } + } +} + +import mx.core.IVisualElement; + +import spark.components.DropDownList; +import spark.events.RendererExistenceEvent; +import spark.skins.spark.DropDownListSkin; + +class DropDownListInspectable extends DropDownList +{ + public var lastRenderer:IVisualElement; + + public function DropDownListInspectable() + { + super(); + this.setStyle("skinClass", DropDownListSkin); + } + + override protected function dataGroup_rendererAddHandler(event:RendererExistenceEvent):void + { + lastRenderer = event.renderer; + super.dataGroup_rendererAddHandler(event); + } +} \ No newline at end of file