You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ah...@apache.org on 2012/05/03 00:45:08 UTC
svn commit: r1333232 [18/34] - in /incubator/flex/trunk: ./
frameworks/tests/ frameworks/tests/basicTests/
frameworks/tests/basicTests/dmv/ frameworks/tests/basicTests/dmv/scripts/
frameworks/tests/basicTests/dmv/views/ frameworks/tests/basicTests/fxg/...
Added: incubator/flex/trunk/mustella/as3/src/mustella/TestResult.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/TestResult.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/TestResult.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/TestResult.as Wed May 2 22:44:38 2012
@@ -0,0 +1,156 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 {
+
+import flash.display.DisplayObject;
+import flash.utils.*;
+
+/**
+ * The class that collects TestResults for a TestCase
+ */
+public class TestResult
+{
+
+ public static const PASS:int = 0;
+ public static const FAIL:int = 1;
+ public static const ERROR:int = 2;
+
+ public static const SETUP:int=0;
+ public static const BODY:int=1;
+ public static const CLEANUP:int=2;
+
+ /**
+ * testID
+ */
+ public var testID:String;
+
+ /**
+ * begin time
+ */
+ public var beginTime:Number;
+
+ /**
+ * end time
+ */
+ public var endTime:Number;
+
+ /**
+ * hang on to the context, ie, the script
+ */
+ public var context:UnitTester;
+
+ /**
+ * result
+ */
+ public var result:int = -1; // "pass", "fail", "error"
+
+ /**
+ * message. Failures often have messages
+ */
+ public var message:String = "";
+
+ /**
+ * extraInfo: failures may have a file associated
+ */
+ public var extraInfo:String = "";
+
+ /**
+ * Name of the Script associated with this result
+ */
+ public var scriptName:String = "";
+
+ /**
+ * phase. how far the test finished. setup, body, cleanup
+ */
+ public var phase:int = -1;
+
+ /**
+ * get printable version of phase
+ */
+ public static function getPhaseString(val:int):String {
+ if (val == CLEANUP) {
+ return "cleanup";
+ }else if (val == BODY) {
+ return "body";
+ }else if (val == SETUP) {
+ return "setup";
+
+ }
+ return "no phase set";
+ }
+
+ /**
+ * get printable version of result
+ */
+ public static function getResultString(val:int):String {
+ if (val == PASS) {
+ return "pass";
+ }else if (val == FAIL) {
+ return "fail";
+ }else if (val == ERROR) {
+ return "error";
+ }
+ return null;
+ }
+
+
+ /**
+ * default output look
+ */
+ public function toString():String
+ {
+
+ var className:String = getQualifiedClassName (context);
+
+ return "RESULT: scriptName="+context.testDir + className+" id="+ testID + " result=" + getResultString(result) + " elapsed=" + (endTime-beginTime) + " phase=" + getPhaseString(phase) + " started=" + beginTime + " extraInfo=" + extraInfo + " msg=" + message ;
+ }
+
+
+ public function hasStatus():Boolean {
+ return (result != -1);
+ }
+
+
+ public function doFail (msg:String, extraInfo:String=null):void {
+ // first failure is the one we keep
+ if (UnitTester.noFail)
+ {
+ return;
+
+ }
+ if (this.result != FAIL)
+ {
+ this.result = FAIL;
+ // this.message = msg;
+ if (UnitTester.run_id == "-1")
+ {
+ var tmp:String = UnitTester.lastStep.toString().substr(0,UnitTester.lastStep.toString().indexOf (":")) + "(" +getPhaseString(phase) + ":step " + (UnitTester.lastStepLine+1) + ") ";
+ this.message = tmp + " " + msg;
+ }
+ else
+ {
+ this.message = msg;
+ }
+ this.extraInfo = extraInfo;
+ }
+ }
+
+
+}
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/TestResult.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/TestStep.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/TestStep.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/TestStep.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/TestStep.as Wed May 2 22:44:38 2012
@@ -0,0 +1,177 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 {
+
+import flash.display.DisplayObject;
+import flash.events.Event;
+import flash.events.EventDispatcher;
+import flash.events.IEventDispatcher;
+import flash.utils.getTimer;
+
+/**
+ * The abstract base class for all steps in a test case. TestStep
+ * cannot be used directly, instead its subclasses must be used
+ * such as SetProperty, RunCode, Assert, etc.
+ */
+public class TestStep extends EventDispatcher
+{
+ /**
+ * Called by the TestCase when it is time to start this step
+ * The default implementation checks for a wait event and
+ * returns true if there isn't one and false if there is.
+ */
+ public function execute(root:DisplayObject, context:UnitTester, testCase:TestCase, testResult:TestResult):Boolean
+ {
+ var tryLater:Boolean = false;
+
+ this.root = root;
+ this.context = context;
+ this.testCase = testCase;
+ this.testResult = testResult;
+
+ if (waitEvent)
+ {
+ var actualTarget:IEventDispatcher = context.stringToObject(waitTarget) as IEventDispatcher;
+ if (!actualTarget)
+ {
+ // its ok if the target isn't here yet, it may be created during this step
+ tryLater = true;
+ }
+ else
+ {
+ actualTarget.addEventListener(waitEvent, waitEventHandler);
+ testCase.setExpirationTime(getTimer() + timeout);
+ }
+ }
+
+ if (!UnitTester.hasRTE)
+ doStep();
+
+ // if test failed, don't bother waiting, just bail
+ if (testResult.hasStatus() || UnitTester.hasRTE)
+ {
+ if (UnitTester.hasRTE)
+ {
+ testResult.result = 1;
+ testResult.message = UnitTester.RTEMsg;
+ dispatchEvent(new Event("runComplete"));
+ return true;
+ }
+
+ if (waitEvent)
+ {
+ actualTarget = context.stringToObject(waitTarget) as IEventDispatcher;
+ actualTarget.removeEventListener(waitEvent, waitEventHandler);
+ testCase.setExpirationTime(0);
+ }
+ return true;
+ }
+
+ if (tryLater && waitEvent)
+ {
+ actualTarget = context.stringToObject(waitTarget) as IEventDispatcher;
+ if (!actualTarget)
+ {
+ testResult.doFail("Target " + waitTarget + " not found");
+ return true;
+ }
+ actualTarget.addEventListener(waitEvent, waitEventHandler);
+ testCase.setExpirationTime(getTimer() + timeout);
+ }
+
+ return (waitEvent == null);
+ }
+
+ /**
+ * The name of the object to listen for an event we're waiting on
+ */
+ public var waitTarget:String;
+
+ /**
+ * The name of the event to listen for on the waitTarget
+ */
+ public var waitEvent:String;
+
+ /**
+ * The number of milliseconds to wait before giving up
+ */
+ public var timeout:int = 3000;
+
+ /**
+ * The TestResult for this TestCase
+ */
+ protected var testResult:TestResult;
+
+ /**
+ * The TestCase that this step belongs to
+ */
+ protected var testCase:TestCase;
+
+ /**
+ * The UnitTester that this step belongs to
+ */
+ protected var context:UnitTester;
+
+ /**
+ * The root for the SWF
+ */
+ protected var root:DisplayObject;
+
+ /**
+ * The method that gets called when it is time to perform the work in the step.
+ */
+ protected function doStep():void
+ {
+ }
+
+ /**
+ * The method that gets called back when the event we're waiting on fires
+ */
+ protected function waitEventHandler(event:Event):void
+ {
+ stepComplete();
+ }
+
+ /**
+ * The method that gets called when it is time to clean up the step.
+ */
+ protected function stepComplete():void
+ {
+ if (waitEvent)
+ {
+ var actualTarget:IEventDispatcher = context.stringToObject(waitTarget) as IEventDispatcher;
+ if (actualTarget) // can be null if object killed during step
+ actualTarget.removeEventListener(waitEvent, waitEventHandler);
+ testCase.setExpirationTime(0);
+ }
+ dispatchEvent(new Event("stepComplete"));
+ }
+
+ /**
+ * Called by the test case if you time out
+ */
+ public function timeoutCallback():void
+ {
+ testResult.doFail("Timeout waiting for " + waitEvent + " from " + waitTarget);
+ stepComplete();
+ }
+
+}
+
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/TestStep.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/TypeInfo.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/TypeInfo.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/TypeInfo.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/TypeInfo.as Wed May 2 22:44:38 2012
@@ -0,0 +1,89 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 {
+
+ import flash.utils.Dictionary;
+
+ /**
+ * Helper class useful for runtime object introspection.
+ * This object is generally cached by the TypeInfoCache
+ * and reused once constructed. Right now we only care about
+ * base types and interfaces but the class could easily be
+ * extended to properties and methods if desired.
+ */
+ public class TypeInfo
+ {
+ private var baseTypes:Dictionary = new Dictionary();
+ private var interfaces:Dictionary = new Dictionary();
+ public var className:String;
+
+ /**
+ * Constructor
+ */
+ public function TypeInfo(className:String):void
+ {
+ this.className = className;
+ describeType(className);
+ }
+
+ /**
+ * Initialization method used to populate the base types and the
+ * implemented interfaces for our type.
+ */
+ private function describeType(className:String):void
+ {
+ try
+ {
+ var definition:Object = flash.utils.getDefinitionByName(className);
+ }
+ catch(e:Error)
+ {
+ return;
+ }
+
+ var typeInfo:XMLList = flash.utils.describeType(definition).child("factory");
+
+ var types:XMLList = typeInfo.child("extendsClass").attribute("type");
+ for each (var name:String in types)
+ baseTypes[name] = true;
+
+ var interfaces:XMLList = typeInfo.child("implementsInterface").attribute("type");
+ for each (name in interfaces)
+ this.interfaces[name] = true;
+ }
+
+ /**
+ * Returns true if our type implements the given fully qualified interface.
+ */
+ public function implementsInterface(interfaceName:String):Boolean
+ {
+ return (interfaces[interfaceName] == true) ? true : false;
+ }
+
+ /**
+ * Returns true if our type is assignable to the type provided.
+ */
+ public function isAssignableTo(typeName:String):Boolean
+ {
+ return (interfaces[typeName] == true ||
+ baseTypes[typeName] == true ||
+ typeName == className) ? true : false;
+ }
+ }
+}
\ No newline at end of file
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/TypeInfo.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/UnitTester.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/UnitTester.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/UnitTester.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/UnitTester.as Wed May 2 22:44:38 2012
@@ -0,0 +1,1969 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 {
+
+import flash.display.BitmapData;
+import flash.display.DisplayObject;
+import flash.display.DisplayObjectContainer;
+import flash.display.InteractiveObject;
+import flash.display.Stage;
+import flash.events.Event;
+import flash.events.ErrorEvent;
+import flash.events.FocusEvent;
+import flash.events.EventDispatcher;
+import flash.events.IOErrorEvent;
+import flash.events.ProgressEvent;
+import flash.events.SecurityErrorEvent;
+import flash.events.UncaughtErrorEvent;
+import flash.geom.Point;
+import flash.geom.Matrix;
+import flash.geom.Rectangle;
+import flash.net.Socket;
+import flash.system.ApplicationDomain;
+import flash.system.Security;
+import flash.system.fscommand;
+import flash.utils.Dictionary;
+import flash.utils.getQualifiedClassName;
+import flash.utils.Timer;
+import flash.utils.setTimeout;
+import flash.net.URLRequest;
+import flash.net.URLLoader;
+import flash.net.URLLoaderDataFormat;
+
+import mx.core.mx_internal;
+use namespace mx_internal;
+
+[Mixin]
+/**
+ * The test engine for unit testing Flex framework components.
+ * A UnitTester gets linked in as a mixin and when initialized
+ * finds a set of tests to run and runs them.
+ *
+ * Test scripts are written as MXML components derived from
+ * this class, and contain a bunch of TestCases with TestStep-
+ * derived child tags. They must also be [Mixin] and call
+ * setScript.
+ */
+public class UnitTester extends EventDispatcher
+{
+ /**
+ * This holds settings which are considered in ConditionalValue
+ * work.
+ **/
+ public static var cv:ConditionalValue;
+
+ /**
+ * This tells whether to write baselines to disk.
+ * Set by MobileConfigWriter.
+ **/
+ public static var writeBaselinesToDisk:Boolean = false;
+
+ /**
+ * This tells UnitTester where it can write files.
+ * Set by MobileConfigWriter.
+ **/
+ public static var mustellaWriteLocation:String = "";
+
+ /**
+ * This is the name of the exclude file.
+ * Set by MobileConfigWriter.
+ **/
+ public static var excludeFile:String = "";
+
+ /**
+ * This is a placeholder. We don't do portrait and landscape runs right now
+ * and probablay won't. Delete.
+ **/
+ //public static var deviceOrientation:String = null;
+
+ /**
+ * port number that will be used by tests that require a webserver.
+ */
+ public static var portNumber : Number=80;
+
+ /**
+ * additional wait before exit for coverage
+ */
+ public static var coverageTimeout : Number = 0;
+
+ /**
+ * Last executed step
+ */
+ public static var lastStep:TestStep = null;
+
+ /**
+ * Step # of that last step
+ */
+ public static var lastStepLine:int = -1;
+
+ /**
+ * IGNORE all failures and only report passing.
+ * This allows creation of multiple .bad.png files in testcases
+ * where there are many CompareBitmap tags
+ * DANGEROUS flag, for obvious reasons
+ */
+ public static var noFail:Boolean = false;
+
+
+ /**
+ * a pixel tolerance multiplier that CompareBitmap will use to judge comparisons
+ */
+ public static var pixelToleranceMultiplier:Number = 1;
+
+
+ /**
+ * Mixin callback that gets everything ready to go.
+ * The UnitTester waits for an event before starting
+ */
+ public static function init(root:DisplayObject):void
+ {
+
+ // don't let child swfs override this
+ if (!_root)
+ _root = root;
+
+
+ /// set device if not set.
+ if (cv == null){
+ cv = new ConditionalValue();
+ }
+
+ if (cv.os == null)
+ {
+ cv.os = DeviceNames.getFromOS();
+
+ }
+
+ if(root.loaderInfo != null && root.loaderInfo.parameters != null)
+ {
+ for (var ix:String in root.loaderInfo.parameters)
+ {
+ if(ix == "port")
+ {
+ portNumber = Number(root.loaderInfo.parameters[ix]);
+ }
+ else if(ix == "pixelToleranceMultiplier")
+ {
+ pixelToleranceMultiplier = Number(root.loaderInfo.parameters[ix]);
+ }
+ }
+ }
+
+ // load a run id if not loaded (used in full runs)
+ if (!run_id_loaded)
+ {
+ /// esp. for MP, avoid doing this twice:
+ run_id_loaded=true;
+
+ /// avoid 304 returns from the web server:
+ var endBit:String = "?" + Math.random() + new Date().time;
+
+ reader = new URLLoader();
+ var req:URLRequest = new URLRequest();
+
+ /// by convention, we use the /staging alias for the vetting run workspace
+ if (isVettingRun)
+ {
+ req.url = "http://localhost:" + portNumber + "/staging/runid.properties" + endBit;
+ }
+ else
+ {
+ req.url = "http://localhost:" + portNumber + "/runid.properties" + endBit;
+ }
+
+ reader.dataFormat=URLLoaderDataFormat.TEXT;
+ reader.addEventListener(Event.COMPLETE, readCompleteHandler);
+ reader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, readErrorHandler);
+ reader.addEventListener(IOErrorEvent.IO_ERROR, readErrorHandler);
+ reader.load(req);
+
+
+ }
+
+ // load a run id if not loaded (used in full runs)
+ if (!timeout_plus_loaded)
+ {
+
+ timeout_reader = new URLLoader();
+ var req2:URLRequest = new URLRequest();
+
+ /// by convention, we use the /staging alias for the vetting run workspace
+ req2.url = "http://localhost:" + runnerPort + "/step_timeout";
+
+ timeout_reader.dataFormat=URLLoaderDataFormat.TEXT;
+ timeout_reader.addEventListener(Event.COMPLETE, timeout_readCompleteHandler);
+ timeout_reader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, timeout_readErrorHandler);
+ timeout_reader.addEventListener(IOErrorEvent.IO_ERROR, timeout_readErrorHandler);
+
+ timeout_reader.load(req2);
+
+
+ }
+
+ var mixins:Array = root["info"]()["mixins"];
+ var appdom:ApplicationDomain = root["info"]().currentDomain;
+ if (!appdom)
+ appdom = ApplicationDomain.currentDomain;
+ for (var i:int = 0; i < mixins.length; i++)
+ {
+ var c:Class = Class(appdom.getDefinition(mixins[i]));
+ var o:Object = new c();
+ if (o is UnitTester && mixins[i] != "UnitTester")
+ {
+ var eventScripts:Array = scripts[o.startEvent];
+ if (!eventScripts)
+ {
+ eventScripts = scripts[o.startEvent] = new Array();
+ root.addEventListener(o.startEvent, pre_startEventHandler);
+ }
+ eventScripts.push(o);
+ }
+ }
+
+ // if we're sandboxed and have no scripts, assume we're passive.
+ if (!(root.loaderInfo.parentAllowsChild && root.loaderInfo.childAllowsParent))
+ {
+ if (eventScripts == null)
+ {
+ sandboxed = true;
+ sandboxHelper = new UnitTester();
+ root.loaderInfo.sharedEvents.addEventListener(MustellaSandboxEvent.STRING_TO_OBJECT, sandboxStringToObjectHandler);
+ root.loaderInfo.sharedEvents.addEventListener(MustellaSandboxEvent.GET_BITMAP, sandboxGetBitmapHandler);
+ root.loaderInfo.sharedEvents.addEventListener(MustellaSandboxEvent.GET_EFFECTS, sandboxGetEffectsHandler);
+ root.loaderInfo.sharedEvents.addEventListener(MustellaSandboxEvent.GET_OBJECTS_UNDER_POINT, sandboxObjectsUnderPointHandler);
+ root.loaderInfo.sharedEvents.addEventListener(MustellaSandboxEvent.RESET_COMPONENT, sandboxResetComponentHandler);
+ root.loaderInfo.sharedEvents.addEventListener(MustellaSandboxEvent.MOUSEXY, sandboxMouseXYHandler);
+ root.loaderInfo.sharedEvents.addEventListener(MustellaSandboxEvent.GET_FOCUS, sandboxGetFocusHandler);
+ root.loaderInfo.sharedEvents.addEventListener(MustellaSandboxEvent.APP_READY, sandboxAppReadyHandler);
+ trace("sending mustellaStarted");
+ root.loaderInfo.sharedEvents.dispatchEvent(new MustellaSandboxEvent(MustellaSandboxEvent.MUSTELLA_STARTED));
+ root.addEventListener("applicationComplete", applicationCompleteHandler);
+ root.addEventListener("enterFrame", enterFrameHandler, false, -9999);
+ return;
+ }
+ }
+ else if(root.parent != root.stage && root.loaderInfo.applicationDomain != root.parent.parent.loaderInfo.applicationDomain)
+ {
+ root.loaderInfo.sharedEvents.addEventListener(MustellaSandboxEvent.GET_EFFECTS, sandboxGetEffectsHandler);
+ root.loaderInfo.sharedEvents.addEventListener(MustellaSandboxEvent.MOUSEXY, sandboxMouseXYHandler);
+ root.addEventListener("applicationComplete", applicationCompleteHandler);
+ root.loaderInfo.sharedEvents.addEventListener(MustellaSandboxEvent.APP_READY, sandboxAppReadyHandler);
+ }
+
+ root.loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, uncaughtErrorHandler);
+
+
+ /* uncaught exceptions should be grabbd by the global handler, making this
+ obsolete
+ try
+ {
+ if (RTESocketAddress)
+ {
+ RTESocket = new Socket();
+ RTESocket.connect(RTESocketAddress, 2561);
+ RTESocket.addEventListener(ProgressEvent.SOCKET_DATA, RTEDefaultHandler, false, -1);
+ RTESocket.addEventListener(IOErrorEvent.IO_ERROR, RTEIOErrorHandler);
+ RTESocket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, RTEIOErrorHandler);
+ }
+ }
+ catch (e:Error)
+ {
+ }
+ */
+
+ var g:Class = Class(appdom.getDefinition("mx.core.UIComponentGlobals"));
+ if (g)
+ g["catchCallLaterExceptions"] = true;
+
+ if (eventScripts != null)
+ {
+ try
+ {
+ _root.stage.addEventListener("enterFrame", enterFrameHandler, false, -9999);
+ }
+ catch (e:Error)
+ {
+ _root.addEventListener("enterFrame", enterFrameHandler, false, -9999);
+ }
+ _root.addEventListener("focusIn", focusBlockingHandler, true);
+ _root.addEventListener("focusOut", focusBlockingHandler, true);
+ _root.addEventListener("deactivate", activateBlockingHandler, true);
+ _root.addEventListener("activate", activateBlockingHandler, true);
+ }
+ }
+
+ /**
+ * Repeat variables. Used in leak testing. Set by mixin.
+ */
+ public static var repeat:int = 0;
+ public static var repeatCount:int = 0;
+
+
+ /**
+ * A test run id. This is loaded from a web served file. No id by default.
+ */
+ public static var run_id:String = "-1";
+
+ /**
+ * Indicate the run as vetting
+ */
+ public static var isVettingRun:Boolean = false;
+
+ /**
+ * flag to skip reloading run id
+ */
+ public static var run_id_loaded:Boolean = false;
+
+ /**
+ * flag to skip rechecking for timeout extender
+ */
+ public static var timeout_plus_loaded:Boolean = false;
+
+ /**
+ * value to extend each test step timeout
+ */
+ public static var timeout_plus:int = 0;
+
+ /**
+ * the URL loader for the run id
+ */
+ public static var reader:URLLoader;
+
+ /**
+ * the URL loader for the run id
+ */
+ public static var timeout_reader:URLLoader;
+
+
+ /**
+ * The directory that this test lives in
+ */
+ public var testDir:String;
+
+ /**
+ * Whether or not we've seen the applicationComplete event
+ */
+ public static var applicationComplete:Boolean = false;
+
+ /**
+ * Whether or not we're subordinate to another UnitTester in another sandbox
+ */
+ public static var sandboxed:Boolean = false;
+
+ /**
+ * UnitTester used for sandbox work
+ */
+ public static var sandboxHelper:UnitTester;
+
+ /**
+ * cache of known swfLoaders
+ */
+ public static var swfLoaders:Dictionary = new Dictionary(true);
+
+ /**
+ * note if an RTE has been detected
+ */
+ public static var hasRTE:Boolean = false;
+
+ /**
+ * The RTE trace
+ */
+ public static var RTEMsg:String = "";
+
+ /**
+ * For mini_run, we want to show the RTE
+ */
+ public static var showRTE:Boolean = false;
+
+
+ private static function uncaughtErrorHandler(e:flash.events.UncaughtErrorEvent):void
+ {
+ hasRTE = true;
+
+ /// Not yet seen
+ if (e is Error)
+ {
+ RTEMsg = format(e.error.getStackTrace());
+ }
+ else if (e is ErrorEvent)
+ {
+ RTEMsg = format(e.error.getStackTrace());
+ }
+
+
+ e.stopImmediatePropagation();
+
+ // preventDefault will swallow the dialog pop up that shows the RTE
+ // for mini run, we want to show that; for server runs, just swallow it
+ if (!showRTE)
+ {
+ e.preventDefault();
+ }
+
+ }
+
+
+ private static function format(msg0:String):String
+ {
+ var tmp:Array = null;
+
+ var ret:String = "";
+
+ /// collapse newlines in the messages:
+ //// TEST ON MAC
+ var culprit:String = "\n";
+
+ var replaceChar:String = "^";
+
+
+ var fileSepPat:RegExp = /\\/g;
+ var msg:String = msg0.replace (fileSepPat, "/");
+
+ if (msg.indexOf (culprit) != -1)
+ {
+ tmp = msg.split (culprit);
+ for (var i:int = 0;i<tmp.length;i++)
+ {
+
+ if (ret != "")
+ {
+ ret = ret + replaceChar + tmp[i];
+ }
+ else
+ {
+ ret = tmp[i];
+ }
+
+ }
+ }
+ else
+ {
+ return msg;
+ }
+
+ return ret;
+
+ }
+
+
+
+
+ private static function readCompleteHandler(event:Event):void
+ {
+ run_id_loaded=true;
+ run_id = reader.data;
+
+ if (run_id.indexOf ("=") != -1)
+ {
+ run_id = run_id.substring (run_id.indexOf ("=")+1);
+ }
+
+ }
+
+ private static function readErrorHandler(event:Event):void
+ {
+ trace ("runid.properties ERROR handler with: " + event);
+ run_id_loaded=true;
+ }
+
+
+
+ private static function timeout_readCompleteHandler(event:Event):void
+ {
+ timeout_plus_loaded=true;
+ var tmp:String = timeout_reader.data;
+
+ if (tmp.indexOf ("=") != -1)
+ {
+ timeout_plus = new int(tmp.substring (tmp.indexOf ("=")+1))
+ } else {
+ timeout_plus = new int(tmp);
+ }
+ TestOutput.logResult("timeout_plus is: " + timeout_plus);
+ }
+
+ private static function timeout_readErrorHandler(event:Event):void
+ {
+ timeout_plus_loaded=true;
+ }
+
+
+ /**
+ * set mouseXY in other SWFLoaders
+ */
+ public static function getFocus():InteractiveObject
+ {
+ for (var p:* in swfLoaders)
+ {
+ var swfLoader:Object = p;
+ if (swfLoader)
+ {
+ var e:MustellaSandboxEvent = new MustellaSandboxEvent(MustellaSandboxEvent.GET_FOCUS);
+ swfLoader.contentHolder.contentLoaderInfo.sharedEvents.dispatchEvent(e);
+ if (e["obj"] != null)
+ return e["obj"];
+ }
+ }
+ return null;
+ }
+
+ /**
+ * set mouseXY in other SWFLoaders
+ */
+ public static function setMouseXY(stagePt:Point):void
+ {
+ for (var p:* in swfLoaders)
+ {
+ var swfLoader:Object = p;
+ if (swfLoader)
+ {
+ try
+ {
+ if (stagePt)
+ {
+ var pt:Point = swfLoader.content.globalToLocal(stagePt);
+ swfLoader.content[mouseX] = pt.x;
+ swfLoader.content[mouseY] = pt.y;
+ }
+ else
+ {
+ swfLoader.content[mouseX] = undefined;
+ swfLoader.content[mouseY] = undefined;
+ }
+ }
+ catch (se:SecurityError)
+ {
+ var e:MustellaSandboxEvent = new MustellaSandboxEvent(MustellaSandboxEvent.MOUSEXY);
+ e.obj = stagePt;
+ swfLoader.contentHolder.contentLoaderInfo.sharedEvents.dispatchEvent(e);
+ }
+ catch (ee:Error)
+ {
+ }
+ }
+ }
+ }
+
+ /**
+ * ask other sandboxes for objects underneath them
+ */
+ public static function getObjectsUnderPoint(target:DisplayObject, pt:Point):Array
+ {
+ var arr:Array = [];
+ var root:DisplayObject = target.root;
+ if (root != _root && !(root is Stage))
+ {
+ try
+ {
+ // Walk up as high as you can get
+ while (!(root.parent is Stage))
+ {
+ root = root.parent.root;
+ }
+ }
+ catch (e:Error)
+ {
+ // in another sandbox, start from our root.
+ // probably won't work in an AIR window with
+ // loaded content.
+ root = _root;
+ }
+ }
+ _getObjectsUnderPoint(root, pt, arr);
+
+ return arr;
+ }
+
+ private static var effectsInEffect:QName = new QName(mx_internal, "effectsInEffect");
+ private static var activeTweens:QName = new QName(mx_internal, "activeTweens");
+
+ /**
+ * ask other sandboxes if they are running effects
+ */
+ public static function getSandboxedEffects():Boolean
+ {
+ for (var p:* in swfLoaders)
+ {
+ var swfLoader:Object = p;
+ if (swfLoader)
+ {
+ var e:MustellaSandboxEvent = new MustellaSandboxEvent(MustellaSandboxEvent.GET_EFFECTS);
+ if ("contentLoaderInfo" in swfLoader.contentHolder)
+ {
+ swfLoader.contentHolder.contentLoaderInfo.sharedEvents.dispatchEvent(e);
+ if (e.obj)
+ {
+ return e.obj;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * get the trusted appdom from one of the loaded swfs
+ */
+ public static function getApplicationDomain(target:String, actualTarget:Object, className:String):ApplicationDomain
+ {
+ var appdom:ApplicationDomain = _root["info"]().currentDomain;
+ if (!appdom)
+ appdom = ApplicationDomain.currentDomain;
+
+ if (appdom.hasDefinition(className))
+ {
+ var c:Class = Class(appdom.getDefinition(className));
+ if (actualTarget is c)
+ return appdom;
+ // try again to handle some cases in existing mustella tests that
+ // reset to a different class
+ var cn:String = getQualifiedClassName(actualTarget);
+ if (appdom.hasDefinition(cn))
+ {
+ c = Class(appdom.getDefinition(cn));
+ if (actualTarget is c)
+ return appdom;
+ }
+ }
+
+ for (var p:* in swfLoaders)
+ {
+ var swfLoader:Object = p;
+ if (swfLoader)
+ {
+ try
+ {
+ // if parent is null, then this is a sandboxed app loaded from file::
+ // and we don't want to return its appdom
+ if (swfLoader.content.parent)
+ {
+ if (swfLoader.content["info"]().currentDomain.hasDefinition(className))
+ {
+ c = Class(swfLoader.content["info"]().currentDomain.getDefinition(className));
+ if (actualTarget is c)
+ return swfLoader.content["info"]().currentDomain;
+ }
+ }
+ }
+ catch (se:SecurityError)
+ {
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * reset a component in another sandbox
+ */
+ public static function resetSandboxedComponent(target:String, className:String):void
+ {
+ for (var p:* in swfLoaders)
+ {
+ var swfLoader:Object = p;
+ var path:String = swfLoaders[p];
+ if (swfLoader)
+ {
+ // find the right one based on path
+ var c:int = target.indexOf(path);
+ if (c == 0)
+ {
+ // clip off swfloader from path
+ target = target.substr(path.length + 1, target.length);
+ var e:MustellaSandboxEvent = new MustellaSandboxEvent(MustellaSandboxEvent.RESET_COMPONENT);
+ e.string = target;
+ e.obj = className;
+ swfLoader.contentHolder.contentLoaderInfo.sharedEvents.dispatchEvent(e);
+ return;
+ }
+ }
+ }
+ }
+
+ /**
+ * ask other sandboxes for their images
+ */
+ public static function getSandboxBitmaps():Array
+ {
+ var arr:Array = new Array();
+
+ for (var p:* in swfLoaders)
+ {
+ var swfLoader:Object = p;
+ if (swfLoader)
+ {
+ var e:MustellaSandboxEvent = new MustellaSandboxEvent(MustellaSandboxEvent.GET_BITMAP);
+ e.obj = getSWFLoaderVisibleBounds(swfLoader as DisplayObject);
+ swfLoader.contentHolder.contentLoaderInfo.sharedEvents.dispatchEvent(e);
+ if (e.obj is Array && e.obj.length > 0)
+ {
+ arr = arr.concat(e.obj as Array);
+ }
+ }
+ }
+ return arr;
+ }
+
+ /**
+ * hide all sandboxed SWFLoaders
+ */
+ public static function hideSandboxes():void
+ {
+ for (var p:* in swfLoaders)
+ {
+ var swfLoader:Object = p;
+ if (swfLoader)
+ {
+ swfLoader.removeChildAt(0);
+ }
+ }
+ }
+
+ /**
+ * hide all sandboxed SWFLoaders
+ */
+ public static function showSandboxes():void
+ {
+ for (var p:* in swfLoaders)
+ {
+ var swfLoader:Object = p;
+ if (swfLoader)
+ {
+ swfLoader.addChildAt(swfLoader.contentHolder, 0);
+ }
+ }
+ }
+
+ private static function getSWFLoaderVisibleBounds(obj:DisplayObject):Object
+ {
+ var pt:Point = obj.localToGlobal(new Point(0, 0));
+ var rect:Rectangle = new Rectangle(pt.x, pt.y, obj.width, obj.height);
+ var p:DisplayObject = obj.parent;
+ while (rect.width && rect.height)
+ {
+ pt = p.localToGlobal(new Point(0, 0));
+ var prect:Rectangle = new Rectangle(pt.x, pt.y, p.width, p.height);
+ if ("viewMetrics" in p)
+ {
+ var o:Object = p;
+ o = o.viewMetrics;
+ prect.x += o.left;
+ prect.y += o.top;
+ prect.width -= o.right;
+ prect.height -= o.bottom;
+ }
+ rect = prect.intersection(rect);
+ p = p.parent;
+ if (p == _root)
+ break;
+ }
+ return { width: rect.width, height: rect.height };
+
+ }
+
+ /**
+ * see if sandbox has focus
+ */
+ private static function applicationCompleteHandler(event:Event):void
+ {
+ applicationComplete = true
+ }
+
+ /**
+ * see if sandbox has focus
+ */
+ private static function sandboxAppReadyHandler(event:Event):void
+ {
+ // if we sent it, ignore it
+ if (event is MustellaSandboxEvent)
+ return;
+
+ if (applicationComplete)
+ {
+ event["obj"] = true;
+ return;
+ }
+ }
+
+ /**
+ * see if sandbox has focus
+ */
+ private static function sandboxGetFocusHandler(event:Event):void
+ {
+ // if we sent it, ignore it
+ if (event is MustellaSandboxEvent)
+ return;
+
+ if (_root.stage.focus)
+ {
+ event["obj"] = _root.stage.focus;
+ return;
+ }
+
+ var focus:InteractiveObject = getFocus();
+ if (focus)
+ event["obj"] = focus;
+ }
+
+ /**
+ * reset component in sandbox
+ */
+ private static function sandboxMouseXYHandler(event:Event):void
+ {
+ // if we sent it, ignore it
+ if (event is MustellaSandboxEvent)
+ return;
+
+ var eventObj:Object = event;
+ var stagePt:Point = Point(eventObj.obj);
+ if (stagePt)
+ {
+ var pt:Point = _root.globalToLocal(stagePt);
+ _root[mouseX] = pt.x;
+ _root[mouseY] = pt.y;
+ }
+ else
+ {
+ _root[mouseX] = undefined;
+ _root[mouseY] = undefined;
+ }
+ }
+
+ /**
+ * reset component in sandbox
+ */
+ private static function sandboxResetComponentHandler(event:Event):void
+ {
+ // if we sent it, ignore it
+ if (event is MustellaSandboxEvent)
+ return;
+
+ var rc:ResetComponent = new ResetComponent();
+ rc.target = Object(event).string;
+ rc.className = Object(event).obj;
+ sandboxHelper.startTests();
+
+ rc.execute(_root, sandboxHelper, new TestCase(), new TestResult());
+ }
+
+ /**
+ * get bitmap as bytearray
+ */
+ private static function sandboxGetBitmapHandler(event:Event):void
+ {
+ // if we sent it, ignore it
+ if (event is MustellaSandboxEvent)
+ return;
+
+ var arr2:Array = [];
+
+ var data:Object = {};
+ var pt:Point = _root.localToGlobal(new Point(0, 0));
+ data.x = pt.x;
+ data.y = pt.y;
+ var bm:BitmapData = new BitmapData(event["obj"].width, event["obj"].height);
+ try
+ {
+ bm.draw(_root, new Matrix(1, 0, 0, 1, 0, 0));
+ }
+ catch (se:SecurityError)
+ {
+ hideSandboxes();
+ bm = new BitmapData(event["obj"].width, event["obj"].height);
+ showSandboxes();
+ arr2 = getSandboxBitmaps();
+ }
+ var arr:Array = [];
+ data.bits = bm.getPixels(new Rectangle(0, 0, bm.width, bm.height));
+ data.bits.position = 0;
+ data.width = bm.width;
+ data.height = bm.height;
+ arr.push(data);
+ event["obj"] = arr.concat(arr2);
+ }
+
+ /**
+ * get bitmap as bytearray
+ */
+ private static function sandboxGetEffectsHandler(event:Event):void
+ {
+ // if we sent it, ignore it
+ if (event is MustellaSandboxEvent)
+ return;
+
+ var effects:Boolean = false;
+
+ var effectMgr:Class = Class(_root["topLevelSystemManager"]["info"]().currentDomain.getDefinition("mx.effects.EffectManager"));
+ if (effectMgr)
+ {
+ effects = effectMgr[effectsInEffect]();
+ }
+ if (!effects)
+ {
+ effectMgr = Class(_root["topLevelSystemManager"]["info"]().currentDomain.getDefinition("mx.effects.Tween"));
+ if (effectMgr)
+ {
+ effects = effectMgr[activeTweens].length > 0;
+ }
+ }
+ if (!effects)
+ effects = UnitTester.getSandboxedEffects();
+
+ if (effects)
+ event["obj"] = true;
+ }
+
+ /**
+ * Handle request from main Mustella UnitTester
+ */
+ private static function sandboxStringToObjectHandler(event:Event):void
+ {
+ // if we sent it, ignore it
+ if (event is MustellaSandboxEvent)
+ return;
+
+ // we got here because someone tried to access .content which is the
+ // systemManager so we prepend that since stringToObject always starts
+ // with the root.document
+ event["obj"] = sandboxHelper.stringToObject(event["string"].length == 0 ? "" : "systemManager." + event["string"]);
+ }
+
+ /**
+ * Handle request from main Mustella UnitTester
+ */
+ private static function sandboxObjectsUnderPointHandler(event:Event):void
+ {
+ // if we sent it, ignore it
+ if (event is MustellaSandboxEvent)
+ return;
+
+ var pt:Point = Object(event).obj as Point;
+ var arr:Array = new Array();
+ _getObjectsUnderPoint(_root, pt, arr);
+ Object(event).obj = arr;
+ }
+
+ /**
+ * Player doesn't handle this correctly so we have to do it ourselves
+ */
+ private static function _getObjectsUnderPoint(obj:DisplayObject, pt:Point, arr:Array):void
+ {
+ if (!obj.visible)
+ return;
+
+ try
+ {
+ if (!obj[$visible])
+ return;
+ }
+ catch (e:Error)
+ {
+ }
+
+ if (obj.hitTestPoint(pt.x, pt.y, true))
+ {
+ arr.push(obj);
+ if (obj is DisplayObjectContainer)
+ {
+ var doc:DisplayObjectContainer = obj as DisplayObjectContainer;
+ if ("rawChildren" in doc)
+ {
+ var rc:Object = doc["rawChildren"];
+ n = rc.numChildren;
+ for (i = 0; i < n; i++)
+ {
+ _getObjectsUnderPoint(rc.getChildAt(i), pt, arr);
+ }
+ }
+ else
+ {
+ if (doc.numChildren)
+ {
+ var n:int = doc.numChildren;
+ for (var i:int = 0; i < n; i++)
+ {
+ var child:DisplayObject = doc.getChildAt(i);
+ if (swfLoaders[doc] && child is flash.display.Loader)
+ {
+ // if sandboxed then ask it for its targets
+ var e:MustellaSandboxEvent = new MustellaSandboxEvent(MustellaSandboxEvent.GET_OBJECTS_UNDER_POINT);
+ e.obj = pt;
+ flash.display.Loader(child).contentLoaderInfo.sharedEvents.dispatchEvent(e);
+ if (e.obj is Array && e.obj.length > 0)
+ {
+ // add them and we're done
+ var objs:Array = e.obj as Array;
+ while (objs.length)
+ arr.push(objs.shift());
+ }
+ else
+ _getObjectsUnderPoint(child, pt, arr);
+ }
+ else
+ _getObjectsUnderPoint(child, pt, arr);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Whether or not to block focus events
+ */
+ public static var blockFocusEvents:Boolean = true;
+
+
+ /**
+ * Whether to wait for Excludes to load from a file
+ */
+ public static var waitForExcludes:Boolean = false;
+
+ /**
+ * Whether to wait for Includes to load from a file
+ */
+ public static var waitForIncludes:Boolean = false;
+
+ /**
+ * The handler for blocking focus events
+ */
+ private static function focusBlockingHandler(event:FocusEvent):void
+ {
+ if (blockFocusEvents && event.relatedObject == null)
+ {
+ event.stopImmediatePropagation();
+ // attempt restore focus
+ if (event.type == "focusOut")
+ _root.stage.focus = InteractiveObject(event.target);
+ }
+ }
+
+ /**
+ * Whether or not to block activation events
+ */
+ public static var blockActivationEvents:Boolean = true;
+
+ /**
+ * The handler for blocking activation events
+ */
+ private static function activateBlockingHandler(event:Event):void
+ {
+ if (blockActivationEvents)
+ {
+ event.stopImmediatePropagation();
+ }
+ }
+
+ /**
+ * A simplified callLater mechanism for running our tests
+ */
+ public static var callback:Function;
+
+ /**
+ * The handler for the enter frame
+ */
+ private static function enterFrameHandler(event:Event):void
+ {
+ if (callback != null)
+ {
+ var cb:Function = callback;
+ callback = null;
+ cb();
+ }
+ }
+
+ /**
+ * holder of startEvent occurence
+ */
+ public static var sawStartEvent:Boolean = false;
+
+ /**
+ * holder of the event to pass to the real start
+ */
+ private static var saveEvent:Event = null;
+
+ public static function pre_startEventHandler(event:Event):void
+ {
+ _root["topLevelSystemManager"].addEventListener("callLaterError", callLaterErrorDefaultHandler, false, -1);
+
+ if (event.type == "applicationComplete")
+ {
+ sawStartEvent=true;
+ saveEvent= event;
+ }
+
+ if (sawStartEvent && !waitForExcludes && !waitForIncludes)
+ {
+ startEventHandler (saveEvent);
+ }
+ }
+
+ /**
+ * The handler for the start event that starts the sequence
+ * of tests.
+ */
+ public static function startEventHandler(event:Event):void
+ {
+ var eventScripts:Array = scripts[event.type];
+ var actualScripts:Array = [];
+
+ var n:int = eventScripts.length;
+ for (var i:int = 0; i < n; i++)
+ {
+ var name:String = eventScripts[i].scriptName;
+ if (includeList)
+ {
+ if (!includeList[name])
+ {
+ TestOutput.logResult("Script: " + name + " not in include list but we don't care");
+ // continue;
+ }
+ }
+ if (excludeList)
+ {
+ if (excludeList[name])
+ {
+ TestOutput.logResult("Script: " + name + " in exclude list");
+ continue;
+ }
+ }
+ actualScripts.push(eventScripts[i]);
+ }
+ var scriptRunner:ScriptRunner = new ScriptRunner();
+ scriptRunner.addEventListener("scriptsComplete", scriptsCompleteHandler);
+ scriptRunner.scripts = actualScripts;
+ if (isApollo && waitForWindow)
+ {
+ callback = waitForWindowFunction;
+ waitForWindowScripts = scriptRunner.runScripts;
+ }
+ else
+ callback = scriptRunner.runScripts;
+ }
+
+ /**
+ * The handler for when the script runner finishes
+ */
+ private static function scriptsCompleteHandler(event:Event):void
+ {
+ var allDone:Boolean = true;
+ var n:int = scripts.length;
+ for (var i:int = 0; i < n; i++)
+ {
+ if (!scripts[i].isDone())
+ {
+ allDone = false;
+ break;
+ }
+ }
+ if (originalRoot)
+ _root = originalRoot;
+
+ TestOutput.logResult("ScriptComplete: completely done");
+ _root[mouseX] = undefined;
+ _root[mouseY] = undefined;
+ setMouseXY(null);
+ _root.removeEventListener("focusIn", focusBlockingHandler, true);
+ _root.removeEventListener("focusOut", focusBlockingHandler, true);
+ _root.removeEventListener("deactivate", activateBlockingHandler, true);
+ _root.removeEventListener("activate", activateBlockingHandler, true);
+
+ /*
+ try
+ {
+ if (RTESocket)
+ RTESocket.close();
+ }
+ catch (e:Error)
+ {
+ }
+ */
+
+ if (exitWhenDone)
+ {
+ setTimeout(exit, UnitTester.coverageTimeout);
+ }
+ }
+
+ private static var frameCounter:int = 0;
+
+ /**
+ * the callback that waits for an air window to be created
+ */
+ private static function waitForWindowFunction():void
+ {
+ var window:Object = new UnitTester().stringToObject(waitForWindow);
+ if (window)
+ {
+ window.addEventListener("windowComplete", windowCompleteHandler);
+ callback = waitForWindowFunction;
+ frameCounter++;
+ if (frameCounter > 2) // see code in Window.as enterFrameHandler
+ {
+ callback = waitForWindowScripts;
+ window.removeEventListener("windowComplete", windowCompleteHandler);
+ originalRoot = _root;
+ _root = window["systemManager"];
+ }
+ }
+ else
+ callback = waitForWindowFunction;
+ }
+
+ /**
+ * the callback that waits for an air window to be ready
+ */
+ private static function windowCompleteHandler(event:Event):void
+ {
+ callback = waitForWindowScripts;
+ event.target.removeEventListener("windowComplete", windowCompleteHandler);
+ originalRoot = _root;
+ _root = event.target["systemManager"];
+ }
+
+ public static var exit:Function = function ():void { fscommand ("quit"); };
+
+ private static var layoutManager:QName = new QName(mx_internal, "layoutManager");
+ private static var getTextField:QName = new QName(mx_internal, "getTextField");
+ private static var getTextInput:QName = new QName(mx_internal, "getTextInput");
+ private static var getLabel:QName = new QName(mx_internal, "getLabel");
+
+ private static var mouseX:QName = new QName(mx_internal, "_mouseX");
+ private static var mouseY:QName = new QName(mx_internal, "_mouseY");
+ private static var $visible:QName = new QName(mx_internal, "$visible");
+
+ /**
+ * The list of tests to run by start event
+ */
+ private static var scripts:Array = new Array();
+
+ /**
+ * Whether we're running on Apollo. If true,
+ * a mixin will set this variable and
+ * CompareBitmaps will use a static call to Apollo methods
+ * to resolve baseline URLs
+ */
+ public static var isApollo:Boolean = false;
+
+ /**
+ * If isApollo=true, then if this is set to a dot-path
+ * we will wait for the expression to become valid
+ * and wait for a windowComplete event from the
+ * object before actually running the test
+ */
+ public static var waitForWindow:String;
+
+ /**
+ * function to call to run scripts when window is ready
+ */
+ private static var waitForWindowScripts:Function;
+
+ /**
+ * remember the original root
+ */
+ private static var originalRoot:DisplayObject;
+
+ /**
+ * Whether to check to see if the test is using
+ * embedded fonts. This is set by mixin and is expensive
+ * so it should only be used when new tests are created.
+ * This is checked by CompareBitmap.
+ */
+ public static var checkEmbeddedFonts:Boolean = false;
+
+ /**
+ * Whether to save out the bitmaps or compare them
+ * Default is false, bitmaps are read in from the
+ * url and compared to the target.
+ * Include the CreateBitmapReferences class to
+ * cause all scripts to write out the target's bitmap
+ * to the url.
+ */
+ public static var createBitmapReferences:Boolean = false;
+
+ /**
+ * Whether to display additional information during the
+ * running of a test
+ */
+ public static var verboseMode:Boolean = false;
+
+ /**
+ * Which port to talk to the Runner on
+ *
+ */
+ public static var runnerPort:int = 9999;
+
+
+ /**
+ * Whether to close the Standalone player when done
+ * running the tests
+ */
+ public static var exitWhenDone:Boolean = false;
+
+ /**
+ * Control over the running of a test
+ */
+ public static var playbackControl:String = "play";
+
+ /**
+ * When saving out bitmaps, the server to talk to
+ * to save them
+ */
+ public static var bitmapServerPrefix:String;
+
+ /**
+ * To upload failed bitmaps, this is the url to talk. Set by SaveBitmapFailure mixin
+ */
+ public static var serverCopy:String;
+
+
+ /**
+ * To upload failed bitmaps, this is function assembles the url
+ */
+ public static function urlAssemble (type:String, testDir:String, testFile:String, testCase:String, run_id:String):String
+ {
+
+ testDir=encodeURIComponent(testDir);
+ testFile = encodeURIComponent(testFile);
+ testCase = encodeURIComponent(testCase);
+
+ var back:String = "type=" + type + "&testFile="+ testDir + testFile + "&testCase=" + testCase + "&runid=" + run_id;
+
+ return UnitTester.serverCopy + back;
+
+
+
+ }
+
+ /**
+ * currentTestID - a holder for other guys to know what's current
+ */
+ public static var currentTestID:String;
+
+ /**
+ * currentScript - a holder for other guys to know what's current
+ */
+ public static var currentScript:String;
+
+
+ /**
+ * the root display object (SystemManager)
+ */
+ public static var _root:DisplayObject;
+
+ /**
+ * the list of tests to run (if not specified, runs all tests)
+ */
+ public static var includeList:Object;
+
+ /**
+ * the list of tests not to run (if not specified, runs all tests)
+ */
+ public static var excludeList:Object;
+
+ /**
+ * constructor
+ */
+ public function UnitTester()
+ {
+ super();
+ scriptName = getQualifiedClassName(this);
+ if (scriptName.indexOf("::") >= 0)
+ scriptName = scriptName.substring(scriptName.indexOf("::") + 2);
+
+
+ }
+
+ /**
+ * The name of the script
+ */
+ public var scriptName:String;
+
+ /**
+ * The name of the swf this script test
+ */
+ public var testSWF:String;
+
+ /**
+ * The event to wait for before starting this script
+ */
+ public var startEvent:String = "applicationComplete";
+
+ /**
+ * The list of TestCases
+ */
+ public var testCases:Array;
+
+ /**
+ * The last event object captured in an AssertEvent
+ */
+ public var lastEvent:Event;
+
+ /**
+ * The index into the list of TestCases that we are currently running
+ */
+ private var currentIndex:int = 0;
+
+ /**
+ * overall count of cases excluded, across scripts. Sent with ScriptDone to Runner
+ * if used.
+ */
+ public static var excludedCount:int = 0;
+
+ /**
+ * The total number of testCases to run
+ */
+ private var numTests:int;
+
+ /**
+ * a shortcut to the application's variables
+ */
+ public function get application():Object
+ {
+ return _root["document"];
+ }
+
+ /**
+ * take an expression, find the object.
+ * handles mx_internal:propName
+ * a.b.c
+ * getChildAt()
+ */
+ public function stringToObject(s:*):Object
+ {
+ if (s == null || s == "")
+ return _root["document"];
+
+ var original:String = s;
+
+ try
+ {
+ var propName:* = s;
+ if (s.indexOf("mx_internal:") == 0)
+ propName = new QName(mx_internal, s.substring(12));
+ if (s.indexOf("getChildAt(") == 0 && s.indexOf(".") == -1)
+ {
+ s = s.substring(11);
+ s = s.substring(0, s.indexOf(")"));
+ return _root["document"].getChildAt(parseInt(s));
+ }
+ if (s.indexOf("getLayoutElementAt(") == 0 && s.indexOf(".") == -1)
+ {
+ s = s.substring(19);
+ s = s.substring(0, s.indexOf(")"));
+ return _root["document"].getLayoutElementAt(parseInt(s));
+ }
+ if (s.indexOf("getElementAt(") == 0 && s.indexOf(".") == -1)
+ {
+ s = s.substring(13);
+ s = s.substring(0, s.indexOf(")"));
+ return _root["document"].getElementAt(parseInt(s));
+ }
+ if (s.indexOf("script:") == 0)
+ {
+ propName = s.substring(7);
+ return this[propName];
+ }
+ return _root["document"][propName];
+ }
+ catch (e:Error)
+ {
+ // maybe it is a class
+ var dot:int;
+ var test:Object;
+ var c:int;
+ var cc:int = s.indexOf("::");
+ var gd:int = -1;
+ var className:String = s;
+ var obj:Object = _root["document"];
+ if (cc > 0)
+ {
+ gd = s.indexOf("getDefinition");
+ if (gd == -1)
+ {
+ dot = s.indexOf(".", cc);
+ if (dot >= 0)
+ {
+ className = s.substring(0, dot);
+ s = s.substring(dot + 1);
+ }
+ else
+ s = "";
+ }
+ }
+ else
+ dot = s.indexOf(".");
+
+ try
+ {
+ if (gd == -1)
+ {
+ var appdom:ApplicationDomain = _root["info"]().currentDomain;
+ if (!appdom)
+ appdom = ApplicationDomain.currentDomain;
+ obj = appdom.getDefinition(className);
+ }
+ }
+ catch (e:Error)
+ {
+ if (dot == -1)
+ return null;
+ }
+ if (dot == -1 && gd == -1)
+ return obj;
+
+ var q:QName = new QName(mx_internal, "contentHolder");
+ var list:Array = s.split(".");
+ if (list[0].indexOf("script:") == 0)
+ {
+ obj = this;
+ list[0] = list[0].substring(7);
+ }
+ while (list.length)
+ {
+ try
+ {
+ s = list.shift();
+ if (s.indexOf("mx_internal:") == 0)
+ s = new QName(mx_internal, s.substring(12));
+ if (s is String && s.indexOf("getChildAt(") == 0)
+ {
+ s = s.substring(11);
+ s = s.substring(0, s.indexOf(")"));
+ obj = obj.getChildAt(parseInt(s));
+ }
+ else if (s is String && s.indexOf("getLayoutElementAt(") == 0)
+ {
+ s = s.substring(19);
+ s = s.substring(0, s.indexOf(")"));
+ obj = obj.getLayoutElementAt(parseInt(s));
+ }
+ else if (s is String && s.indexOf("getElementAt(") == 0)
+ {
+ s = s.substring(13);
+ s = s.substring(0, s.indexOf(")"));
+ obj = obj.getElementAt(parseInt(s));
+ }
+ else if (s is String && s == "getTextField()")
+ {
+ obj = obj[getTextField]();
+ }
+ else if (s is String && s == "getTextInput()")
+ {
+ obj = obj[getTextInput]();
+ }
+ else if (s is String && s == "getLabel()")
+ {
+ obj = obj[getLabel]();
+ }
+ else if (s is String && s == "getTextFormat()")
+ {
+ obj = obj.getTextFormat();
+ }
+ else if (s is String && s == "info()")
+ {
+ obj = obj.info();
+ }
+ else if (s is String && s.indexOf("getDefinition(") == 0)
+ {
+ s = s.substring(14);
+ dot = s.indexOf(")");
+ while (dot == -1)
+ {
+ s += "." + list.shift();
+ dot = s.indexOf(")");
+ }
+ s = s.substring(0, dot);
+ obj = obj.getDefinition(s);
+ }
+ else
+ obj = obj[s];
+ }
+ catch (se:SecurityError)
+ {
+ try
+ {
+ test = obj[q];
+ }
+ catch (e:Error)
+ {
+ return null;
+ }
+ var event:MustellaSandboxEvent = new MustellaSandboxEvent(MustellaSandboxEvent.STRING_TO_OBJECT);
+ event.string = list.join(".");
+ if (!swfLoaders[obj])
+ {
+ // cache known swfloaders, associate with string path
+ c = original.lastIndexOf(event.string);
+ swfLoaders[obj] = original.substr(0, c);
+ }
+ test.contentLoaderInfo.sharedEvents.dispatchEvent(event);
+ return event.obj;
+ }
+ catch (e:Error)
+ {
+ return null;
+ }
+ // hunt for other swfloaders with other application domains
+ // we shouldn't get here if the object is in another security domain
+ // unless the object is sandboxed but the loading app is coming from file::
+ // This also assumes that the test script will access the SWFLoader's contentHolder
+ // before doing any steps that require the swfLoaders list to be set up properly
+ try
+ {
+ test = obj[q];
+ if (test is flash.display.Loader)
+ {
+ if (!swfLoaders[obj])
+ {
+ var path:String = list.join(".");
+ // cache known swfloaders, associate with string path
+ c = original.lastIndexOf(path);
+ swfLoaders[obj] = original.substr(0, c) + "content";
+ }
+ }
+ }
+ catch (e:Error)
+ {
+ }
+ }
+ return obj;
+ }
+ return null;
+ }
+
+ /**
+ * storage for value property
+ */
+ private var _value:Object;
+
+ /**
+ * A variable used to hold results from valueExpressions
+ */
+ public function get value():Object
+ {
+ return _value;
+ }
+
+ /**
+ * A variable used to hold results from valueExpressions
+ */
+ public function set value(v:Object):void
+ {
+ _value = v;
+ valueChanged = true;
+ }
+
+ /**
+ * Whether or not the value changed
+ */
+ mx_internal var valueChanged:Boolean;
+
+ /**
+ * Whether or not the value changed
+ */
+ mx_internal function resetValue():void
+ {
+ valueChanged = false;
+ _value = null;
+
+ }
+
+ /**
+ * The set of display objects at the start of the script.
+ * Used to clean up by ResetComponent
+ */
+ public var knownDisplayObjects:Dictionary = new Dictionary(true);
+
+ /**
+ * A timer used by TestCases to know when to give up waiting for something
+ */
+ private var timer:Timer;
+
+ /**
+ * Create a timer that can check every second to see
+ * if we're hung, and then run the test cases
+ */
+ public function startTests():void
+ {
+ var r:Object = _root;
+ r = r["topLevelSystemManager"];
+ r = r.rawChildren;
+ var n:int = r.numChildren;
+ for (var i:int = 0; i < n; i++)
+ {
+ knownDisplayObjects[r.getChildAt(i)] = 1;
+ }
+
+ if (!timer)
+ {
+ timer = new Timer(1000);
+ timer.start();
+ }
+
+
+ // if (RTESocket)
+ // RTESocket.addEventListener(ProgressEvent.SOCKET_DATA, RTEHandler);
+
+ _root["topLevelSystemManager"].addEventListener("callLaterError", callLaterErrorHandler);
+
+ if (testCases)
+ numTests = testCases.length;
+
+ TestOutput.logResult("LengthOfTestcases: " + numTests);
+
+
+ if (runTests())
+ testComplete();
+ }
+
+ /**
+ * The current test that is running
+ */
+ public function get currentTest():TestCase
+ {
+ return testCases[currentIndex];
+ }
+
+ /**
+ * Run the test cases
+ * Returns false if we have to wait for the TestCase to complete.
+ * Returns true if no tests required waiting.
+ */
+ private function runTests():Boolean
+ {
+
+
+ if (testDir == null || testDir == "" )
+ {
+ testDir="";
+
+ }
+
+ while (currentIndex < numTests)
+ {
+
+
+ if (hasRTE)
+ {
+ break;
+ }
+
+ var testCase:TestCase = testCases[currentIndex];
+
+ currentTestID = testCase.testID;
+
+ var testName:String = testDir + scriptName + "$" + testCase.testID;
+ currentScript = scriptName;
+ if (includeList)
+ {
+ if (!includeList[testName])
+ {
+ currentIndex++;
+ continue;
+ }
+ }
+ if (excludeList)
+ {
+ if (excludeList[testName])
+ {
+ currentIndex++;
+ excludedCount++;
+ continue;
+ }
+ }
+
+
+ // TestOutput.logResult("TestCase Start: " + testCase.testID);
+ TestOutput.logResult("TestCase Start: " + testName);
+ // add listener early. If runTest catches an exception it will call
+ // runCompleteHandler before returning
+ testCase.addEventListener("runComplete", runCompleteHandler);
+ if (testCase.runTest(_root, timer, this))
+ {
+ testCase.removeEventListener("runComplete", runCompleteHandler);
+ var tr:TestResult = currentTest.testResult;
+ if (!tr.hasStatus())
+ tr.result = TestResult.PASS;
+ tr.endTime = new Date().time;
+ TestOutput.logResult (tr.toString());
+ if (hasRTE)
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ currentIndex++;
+
+ }
+ return true;
+ }
+
+ /**
+ * The handler that receives notice from the current TestCase that it
+ * is done
+ */
+ private function runCompleteHandler(event:Event):void
+ {
+
+ var tr:TestResult = currentTest.testResult;
+ if (!tr.hasStatus())
+ tr.result = TestResult.PASS;
+ tr.endTime = new Date().time;
+ TestOutput.logResult (tr.toString());
+ currentIndex++;
+ if (UnitTester.playbackControl == "play")
+ UnitTester.callback = runMoreTests;
+ else
+ UnitTester.callback = pauseHandler;
+ }
+
+ private function runMoreTests():void
+ {
+ if (runTests())
+ testComplete();
+ }
+
+ /**
+ * called when test script is finished
+ */
+ private function testComplete():void
+ {
+ // if (RTESocket)
+ // RTESocket.removeEventListener(ProgressEvent.SOCKET_DATA, RTEHandler);
+
+ _root["topLevelSystemManager"].removeEventListener("callLaterError", callLaterErrorHandler);
+ TestOutput.logResult("testComplete");
+ dispatchEvent(new Event("testComplete"));
+ }
+
+ /**
+ * Determines which set of steps (setup, body, cleanup) to run next
+ */
+ private function pauseHandler():void
+ {
+ if (UnitTester.playbackControl == "step")
+ {
+ UnitTester.playbackControl = "pause";
+ runMoreTests();
+ }
+ else if (UnitTester.playbackControl == "play")
+ runMoreTests();
+ else
+ UnitTester.callback = pauseHandler;
+ }
+
+ private function RTEHandler(event:Event):void
+ {
+ var s:String = RTESocket.readUTFBytes(RTESocket.bytesAvailable);
+ TestOutput.logResult("Exception caught by RTE Monitor.");
+ var tr:TestResult = currentTest.testResult;
+ tr.doFail (s);
+ event.stopImmediatePropagation();
+
+ }
+
+ private static function RTEDefaultHandler(event:Event):void
+ {
+ var s:String = RTESocket.readUTFBytes(RTESocket.bytesAvailable);
+ TestOutput.logResult("Exception caught by RTE Monitor when no tests running.");
+ TestOutput.logResult(s);
+ }
+
+ private function callLaterErrorHandler(event:Event):void
+ {
+ var o:Object = event;
+ var s:String = o["error"].getStackTrace();
+ TestOutput.logResult("Exception caught by CallLater Monitor.");
+ var tr:TestResult = currentTest.testResult;
+ tr.doFail (s);
+ event.stopImmediatePropagation();
+
+ var appdom:ApplicationDomain = _root["info"]().currentDomain;
+ if (!appdom)
+ appdom = ApplicationDomain.currentDomain;
+
+ var g:Class = Class(appdom.getDefinition("mx.core.UIComponentGlobals"));
+ if (g)
+ {
+ o = g[layoutManager];
+
+ while (true)
+ {
+ try
+ {
+ o.validateNow();
+ break;
+ }
+ catch (e:Error)
+ {
+ }
+ }
+ }
+
+ }
+
+ private static function callLaterErrorDefaultHandler(event:Event):void
+ {
+ var o:Object = event;
+ var s:String = o["error"].getStackTrace();
+ TestOutput.logResult("Exception caught by CallLater Monitor when no tests running.");
+ TestOutput.logResult(s);
+ }
+
+ private static function RTEIOErrorHandler(event:Event):void
+ {
+
+ }
+
+ private static var typeInfoCache:Dictionary;
+
+ /**
+ * Helper used for object introspection.
+ */
+ public function getTypeInfo(object:*):TypeInfo
+ {
+ if (UnitTester.typeInfoCache == null)
+ {
+ UnitTester.typeInfoCache = new Dictionary();
+ }
+ var className:String = flash.utils.getQualifiedClassName(object);
+ var typeInfo:TypeInfo = UnitTester.typeInfoCache[className];
+ if (typeInfo == null)
+ {
+ typeInfo = new TypeInfo(className);
+ UnitTester.typeInfoCache[className] = typeInfo;
+ }
+ return typeInfo;
+ }
+
+ /**
+ * Socket used by RTE monitor
+ */
+ public static var RTESocket:Socket;
+
+ /**
+ * Socket used by RTE monitor
+ */
+ public static var RTESocketAddress:String;
+
+}
+
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/UnitTester.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/Util.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/Util.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/Util.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/Util.as Wed May 2 22:44:38 2012
@@ -0,0 +1,40 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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
+{
+ import flash.text.*;
+
+ /**
+ * This is a class to store utility methods.
+ **/
+ public class Util{
+ /**
+ * Rounds to 160, 240, or 320 using Flex's code from RuntimeDPIProvider.as.
+ **/
+ public static function roundDeviceDensity( dpi:int ):int{
+ if ( dpi < 200 )
+ return 160;
+
+ if (dpi <= 280)
+ return 240;
+
+ return 320;
+ }
+ }
+}
\ No newline at end of file
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/Util.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/VerboseMode.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/VerboseMode.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/VerboseMode.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/VerboseMode.as Wed May 2 22:44:38 2012
@@ -0,0 +1,46 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 {
+
+import flash.display.DisplayObject;
+import flash.net.*;
+import flash.events.Event;
+
+[Mixin]
+/**
+ * A "marker" class that causes test scripts to write out
+ * bitmaps to the urls instead of reading and comparing
+ * so that baselines/reference-points can be created for
+ * future comparing.
+ */
+public class VerboseMode
+{
+
+ /**
+ * Mixin callback that gets everything ready to go.
+ * The UnitTester waits for an event before starting
+ */
+ public static function init(root:DisplayObject):void
+ {
+ UnitTester.verboseMode = true;
+ }
+
+
+}
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/VerboseMode.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/WaitForEffectsToEnd.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/WaitForEffectsToEnd.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/WaitForEffectsToEnd.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/WaitForEffectsToEnd.as Wed May 2 22:44:38 2012
@@ -0,0 +1,125 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 {
+
+import flash.display.DisplayObject;
+import flash.system.ApplicationDomain;
+import flash.utils.getTimer;
+
+import mx.core.mx_internal;
+use namespace mx_internal;
+
+/**
+ * The test step that sets a property to some value
+ * MXML attributes:
+ * timeout (optional)
+ */
+public class WaitForEffectsToEnd extends TestStep
+{
+ private static var effectsInEffect:QName = new QName(mx_internal, "effectsInEffect");
+ private static var activeTweens:QName = new QName(mx_internal, "activeTweens");
+
+ /**
+ * @private
+ */
+ override public function execute(root:DisplayObject, context:UnitTester, testCase:TestCase, testResult:TestResult):Boolean
+ {
+ super.execute(root, context, testCase, testResult);
+
+ var appDom:ApplicationDomain = root["topLevelSystemManager"]["info"]().currentDomain;
+ if (!appDom)
+ appDom = ApplicationDomain.currentDomain;
+
+ var effects:Boolean = false;
+
+ var effectMgr:Class = Class(appDom.getDefinition("mx.effects.EffectManager"));
+ if (effectMgr)
+ {
+ effects = effectMgr[effectsInEffect]();
+ }
+ if (!effects)
+ {
+ effectMgr = Class(appDom.getDefinition("mx.effects.Tween"));
+ if (effectMgr)
+ {
+ effects = effectMgr[activeTweens].length > 0;
+ }
+ }
+ if (!effects)
+ effects = UnitTester.getSandboxedEffects();
+
+ if (effects)
+ {
+ UnitTester.callback = checkEffects;
+ testCase.setExpirationTime(getTimer() + timeout);
+ }
+ return !effects;
+ }
+
+ /**
+ * Set the target's property to the specified value
+ */
+ private function checkEffects():void
+ {
+ var effects:Boolean = false;
+
+ var appDom:ApplicationDomain = root["topLevelSystemManager"]["info"]().currentDomain;
+ if (!appDom)
+ appDom = ApplicationDomain.currentDomain;
+
+ var effectMgr:Class = Class(appDom.getDefinition("mx.effects.EffectManager"));
+ if (effectMgr)
+ {
+ effects = effectMgr[effectsInEffect]();
+ }
+ if (!effects)
+ {
+ effectMgr = Class(appDom.getDefinition("mx.effects.Tween"));
+ if (effectMgr)
+ {
+ effects = effectMgr[activeTweens].length > 0;
+ }
+ }
+ if (!effects)
+ effects = UnitTester.getSandboxedEffects();
+
+ if (effects)
+ {
+ UnitTester.callback = checkEffects;
+ testCase.setExpirationTime(getTimer() + timeout);
+ }
+ else
+ {
+ testCase.setExpirationTime(0);
+ stepComplete();
+ }
+
+ }
+
+ /**
+ * customize string representation
+ */
+ override public function toString():String
+ {
+ var s:String = "WaitForEffectsToEnd";
+ return s;
+ }
+}
+
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/WaitForEffectsToEnd.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/WaitForEvent.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/WaitForEvent.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/WaitForEvent.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/WaitForEvent.as Wed May 2 22:44:38 2012
@@ -0,0 +1,211 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 {
+
+import flash.display.DisplayObject;
+import flash.display.IBitmapDrawable;
+import flash.utils.*;
+import flash.net.*;
+import flash.events.*;
+import flash.display.*;
+import flash.geom.Matrix;
+
+/**
+ * WaitForEvent - waits for an event before continuing
+ * MXML attributes:
+ * target
+ * eventName
+ * numExpectedEvents
+ * timeout (optional)
+ */
+public class WaitForEvent extends TestStep
+{
+
+ private var eventListenerListening:Boolean = false;
+
+
+ /**
+ * Test the value of a property, log result if failure.
+ */
+ override public function execute(root:DisplayObject, context:UnitTester, testCase:TestCase, testResult:TestResult):Boolean
+ {
+
+ this.root = root;
+ this.context = context;
+ this.testCase = testCase;
+ this.testResult = testResult;
+
+ waitEvent = eventName;
+ waitTarget = target;
+
+
+ var actualTarget:Object = context.stringToObject(target);
+ if (actualTarget)
+ {
+ actualTarget.addEventListener(eventName, eventListener);
+ eventListenerListening = true;
+ }
+
+
+ if (numEvents < numExpectedEvents )
+ {
+
+ testCase.setExpirationTime (getTimer() + timeout);
+ if (!eventListenerListening)
+ {
+ actualTarget.addEventListener(eventName, eventListener);
+ eventListenerListening = true;
+ testCase.cleanupAsserts.push(this);
+ }
+ doStep();
+ waitEvent = eventName;
+ waitTarget = target;
+ return false;
+ }
+ else
+ {
+ testCase.setExpirationTime (0);
+ stepComplete();
+ return true;
+ }
+
+ return super.execute(root, context, testCase, testResult);
+ }
+
+
+ /**
+ * Test the value of a property, log result if failure.
+ */
+ override protected function doStep():void
+ {
+ var actualTarget:Object = context.stringToObject(target);
+ if (!actualTarget)
+ {
+ testResult.doFail("Target " + target + " not found");
+ return;
+ }
+
+ }
+
+ public function doTimeout ():void
+ {
+ testResult.doFail("Timeout waiting for " + waitEvent + " on " + target);
+
+ }
+
+ /**
+ * The object to set a property on
+ */
+ public var target:String;
+
+
+ /**
+ * The name of the event to watch for
+ */
+ public var eventName:String;
+
+ /**
+ * The class of the event, e.g. mx.events.DataGridEvent
+ */
+ public var eventClass:String;
+
+ /**
+ * Storage for numEvents
+ */
+ protected var numEvents:int = 0;
+
+ /**
+ * Number of expected events (must be > 0), use AssertNoEvent for 0.
+ * Set to -1 if you want to see at least one event and don't care if there's more.
+ */
+ public var numExpectedEvents:int = 1;
+
+ /**
+ * The event object
+ */
+ private var lastEvent:Event;
+
+ /**
+ * The event listener
+ */
+ protected function eventListener(event:Event):void
+ {
+ testCase.setExpirationTime(0);
+
+ lastEvent = event;
+ numEvents++;
+
+ waitEventHandler (event);
+
+ }
+
+ /**
+ * Test the value of a property, log result if failure.
+ */
+ public function cleanup():void
+ {
+ var actualTarget:Object = context.stringToObject(target);
+ if (actualTarget) // might be null if object was killed
+ actualTarget.removeEventListener(eventName, eventListener);
+ }
+
+ /**
+ * customize string representation
+ */
+ override public function toString():String
+ {
+ var s:String = "WaitForEvent";
+ if (target)
+ s += ": target = " + target;
+ if (eventName)
+ s += ", eventName = " + eventName;
+ return s;
+ }
+
+ /**
+ * The method that gets called back when the event we're waiting on fires
+ */
+ override protected function waitEventHandler(event:Event):void
+ {
+
+ // we can rely on eventListener to update lastEvent and numEvents
+
+ // keep waiting if there aren't enough events
+ if (numExpectedEvents != -1 && numEvents < numExpectedEvents)
+ {
+ return;
+ }
+
+ if (numExpectedEvents == numEvents)
+ {
+ cleanup();
+ testCase.setExpirationTime (0);
+ stepComplete();
+ return;
+
+ }
+
+ waitEvent = eventName;
+ waitTarget = target;
+ super.waitEventHandler(event);
+
+ }
+}
+
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/WaitForEvent.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/WaitForSandboxApp.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/WaitForSandboxApp.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/WaitForSandboxApp.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/WaitForSandboxApp.as Wed May 2 22:44:38 2012
@@ -0,0 +1,106 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 {
+
+import flash.display.DisplayObject;
+import flash.utils.getTimer;
+
+import mx.core.mx_internal;
+use namespace mx_internal;
+
+/**
+ * The test step that sets a property to some value
+ * MXML attributes:
+ * target
+ * timeout (optional);
+ */
+public class WaitForSandboxApp extends TestStep
+{
+ /**
+ * @private
+ */
+ override public function execute(root:DisplayObject, context:UnitTester, testCase:TestCase, testResult:TestResult):Boolean
+ {
+ super.execute(root, context, testCase, testResult);
+ return false;
+ }
+
+ /**
+ * Set the target's property to the specified value
+ */
+ override protected function doStep():void
+ {
+ var actualTarget:Object = context.stringToObject(target);
+ if (!actualTarget)
+ {
+ testResult.doFail("Target " + target + " not found");
+ return;
+ }
+
+ UnitTester.callback = waitForApp;
+
+ testCase.setExpirationTime(getTimer() + timeout);
+ }
+
+ private function waitForApp():void
+ {
+
+ var actualTarget:Object = context.stringToObject(target);
+ if (actualTarget.bytesLoaded < actualTarget.bytesTotal)
+ {
+ UnitTester.callback = waitForApp;
+ return;
+ }
+
+ try
+ {
+ var e:MustellaSandboxEvent = new MustellaSandboxEvent(MustellaSandboxEvent.APP_READY);
+ actualTarget.contentHolder.contentLoaderInfo.sharedEvents.dispatchEvent(e);
+ if (e.obj)
+ {
+ testCase.setExpirationTime(0);
+ stepComplete();
+ }
+ else
+ UnitTester.callback = waitForApp;
+ }
+ catch (e:Error)
+ {
+ UnitTester.callback = waitForApp;
+ }
+ }
+
+ /**
+ * The SWFLoader that loads the untrusted app
+ */
+ public var target:String;
+
+ /**
+ * customize string representation
+ */
+ override public function toString():String
+ {
+ var s:String = "WaitForSandboxApp";
+ if (target)
+ s += ": target = " + target;
+ return s;
+ }
+}
+
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/WaitForSandboxApp.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/WaitForWindow.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/WaitForWindow.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/WaitForWindow.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/WaitForWindow.as Wed May 2 22:44:38 2012
@@ -0,0 +1,46 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 {
+
+import flash.display.DisplayObject;
+import flash.net.*;
+import flash.events.Event;
+
+[Mixin]
+/**
+ * A "marker" class that causes test scripts to write out
+ * bitmaps to the urls instead of reading and comparing
+ * so that baselines/reference-points can be created for
+ * future comparing.
+ */
+public class WaitForWindow
+{
+
+ /**
+ * Mixin callback that gets everything ready to go.
+ * The UnitTester waits for an event before starting
+ */
+ public static function init(root:DisplayObject):void
+ {
+ UnitTester.waitForWindow = "myWhatever";
+ }
+
+
+}
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/WaitForWindow.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/datagrid_properties_columns_2.png
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/datagrid_properties_columns_2.png?rev=1333232&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/datagrid_properties_columns_2.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: incubator/flex/trunk/mustella/as3/src/mustella/datagrid_properties_columns_2.png.bad.png
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/datagrid_properties_columns_2.png.bad.png?rev=1333232&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/datagrid_properties_columns_2.png.bad.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: incubator/flex/trunk/mustella/as3/src/mustella/image.png
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/image.png?rev=1333232&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/image.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream