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 [17/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/RunCodeEvent.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/RunCodeEvent.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/RunCodeEvent.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/RunCodeEvent.as Wed May  2 22:44:38 2012
@@ -0,0 +1,61 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.events.Event;
+
+/**
+ *  The event passed into any code being
+ *  run in a RunCode step.  It supplies
+ *  some useful references
+ */
+public class RunCodeEvent extends Event
+{
+	public function RunCodeEvent(type:String, application:Object, context:UnitTester, testCase:TestCase, testResult:TestResult)
+	{
+		super(type);
+		this.context = context;
+		this.application = application;
+		this.testCase = testCase;
+		this.testResult = testResult;
+	}
+
+	/**
+	 *  The test script where any variables in the script block can be found
+	 */
+	public var context:UnitTester;
+
+	/**
+	 *  The application being tested
+	 */
+	public var application:Object;
+
+	/**
+	 *  The testCase being tested
+	 */
+	public var testCase:TestCase;
+
+	/**
+	 *  The application being tested
+	 */
+	public var testResult:TestResult;
+
+}
+
+}

Propchange: incubator/flex/trunk/mustella/as3/src/mustella/RunCodeEvent.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/mustella/as3/src/mustella/RunnerPortAlt.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/RunnerPortAlt.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/RunnerPortAlt.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/RunnerPortAlt.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 RunnerPortAlt
+{
+
+	/**
+	 *  Mixin callback that gets everything ready to go.
+	 *  The UnitTester waits for an event before starting
+	 */
+	public static function init(root:DisplayObject):void
+	{
+		UnitTester.runnerPort = 10001;
+	}
+
+
+}
+}

Propchange: incubator/flex/trunk/mustella/as3/src/mustella/RunnerPortAlt.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/mustella/as3/src/mustella/SaveBitmapFailures.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/SaveBitmapFailures.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/SaveBitmapFailures.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/SaveBitmapFailures.as Wed May  2 22:44:38 2012
@@ -0,0 +1,62 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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;
+
+[Mixin]
+/**
+ *  A "marker" class that causes test scripts to write out
+ *  bitmaps to the urls if the comparison fails.
+ */
+public class SaveBitmapFailures
+{
+
+	/**
+	 *  Mixin callback 
+	 */
+	public static function init(root:DisplayObject):void
+	{
+		CompareBitmap.fileSuffix = ".bad.png";
+		UnitTester.bitmapServerPrefix = "http://localhost:9998/baselines/baseline.jsp?filename=";
+		UnitTester.serverCopy = "http://flexqa01/FlexFiles/Uploader.upbmp?";
+
+		if (UnitTester.isVettingRun)
+			UnitTester.bitmapServerPrefix = "http://localhost:9995/baselines/baseline.jsp?filename=";
+	}
+
+
+	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;
+
+
+
+	}
+
+}
+
+}

Propchange: incubator/flex/trunk/mustella/as3/src/mustella/SaveBitmapFailures.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/mustella/as3/src/mustella/SaveBitmapFailuresDistServer.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/SaveBitmapFailuresDistServer.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/SaveBitmapFailuresDistServer.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/SaveBitmapFailuresDistServer.as Wed May  2 22:44:38 2012
@@ -0,0 +1,62 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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;
+
+[Mixin]
+/**
+ *  A "marker" class that causes test scripts to write out
+ *  bitmaps to the urls if the comparison fails.
+ */
+public class SaveBitmapFailuresDistServer
+{
+
+	/**
+	 *  Mixin callback 
+	 */
+	public static function init(root:DisplayObject):void
+	{
+		CompareBitmap.fileSuffix = ".bad.png";
+		UnitTester.bitmapServerPrefix = "http://localhost:8700/baselines/baseline.jsp?filename=";
+		UnitTester.serverCopy = "http://flexqa01/FlexFiles/Uploader.upbmp?";
+
+		if (UnitTester.isVettingRun)
+			UnitTester.bitmapServerPrefix = "http://localhost:9995/baselines/baseline.jsp?filename=";
+	}
+
+
+	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;
+
+
+
+	}
+
+}
+
+}

Propchange: incubator/flex/trunk/mustella/as3/src/mustella/SaveBitmapFailuresDistServer.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/mustella/as3/src/mustella/ScriptRunner.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/ScriptRunner.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/ScriptRunner.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/ScriptRunner.as Wed May  2 22:44:38 2012
@@ -0,0 +1,53 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.events.Event;
+import flash.events.EventDispatcher;
+
+public class ScriptRunner extends EventDispatcher
+{
+
+	public var scripts:Array;
+	public var currentScript:int = 0;
+
+	public function isDone():Boolean
+	{
+		return (currentScript == scripts.length) || (UnitTester.hasRTE);
+	}
+
+	public function runScripts():void
+	{
+		while (currentScript < scripts.length)
+		{
+			var script:UnitTester = scripts[currentScript++];
+			script.addEventListener("testComplete", testCompleteHandler);
+			script.startTests();
+			return;
+		}
+		dispatchEvent(new Event("scriptsComplete"));
+	}
+
+	private function testCompleteHandler(event:Event):void
+	{
+		UnitTester.callback = runScripts;
+	}
+}
+
+}

Propchange: incubator/flex/trunk/mustella/as3/src/mustella/ScriptRunner.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/mustella/as3/src/mustella/SendFormattedResultsToLog.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/SendFormattedResultsToLog.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/SendFormattedResultsToLog.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/SendFormattedResultsToLog.as Wed May  2 22:44:38 2012
@@ -0,0 +1,115 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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]
+/**
+ * Write formatted results to log for easy parsing
+ */
+public class SendFormattedResultsToLog
+{
+
+	/**
+	 *  Mixin callback that gets everything ready to go.
+	 *  The UnitTester waits for an event before starting
+	 */
+	public static function init(root:DisplayObject):void
+	{
+		TestOutput.getInstance().addEventListener ("result", outputWriter);
+	}
+
+
+	public static var midURL:String  = "";
+
+
+	public static var regExp5:RegExp = /%3D/g;
+
+
+
+	/**
+  	 * the way out for the result data
+	 */
+	public static function outputWriter (event:Event):void 
+	{ 
+
+		var s:String = (event as MustellaLogEvent).msg;
+
+
+		var loc:uint;
+		var final:String = "";
+
+		var skip:Boolean = false;
+		var noSend:Boolean = false;
+
+		/// this should be something like |, because it is confusing this way
+		/// putting it on, taking it off
+		s=s.replace (" msg=", "|msg=");
+
+		s=s.replace (" result=", "|result=");
+		s=s.replace (" phase=", "|phase=");
+		s=s.replace (" id=", "|id=");
+		s=s.replace (" elapsed=", "|elapsed=");
+		s=s.replace (" started=", "|started=");
+		s=s.replace (" extraInfo=", "|extraInfo=");
+
+		var hdrs:Array = s.split ("|");
+	
+		var i:uint;
+			// rebuild url encoded 
+		for (i=0;i<hdrs.length;i++) 
+		{ 
+			if (final == "")
+				final += hdrs[i];	
+			else
+				final+="&" + hdrs[i];
+		}
+	
+		final = final.replace (regExp5, "=");
+
+		trace (final);
+
+
+		// exitWhenDone mixin doesn't really work with browsers. 
+		// Tell the Runner that we're ending
+		if (s.indexOf ("ScriptComplete") != -1 ) 
+		{
+
+			trace ("Send ScriptComplete to runner block");
+			var u:URLLoader = new URLLoader ();
+			u.addEventListener("complete", httpEvents);
+			u.addEventListener("ioError", httpEvents);
+			u.load(new URLRequest ("http://localhost:" + UnitTester.runnerPort + "/ScriptComplete"));
+		}
+	
+		
+
+	}
+	public static function httpEvents (e:Event):void  {
+		trace (e);
+	}
+
+
+
+}
+}

Propchange: incubator/flex/trunk/mustella/as3/src/mustella/SendFormattedResultsToLog.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/mustella/as3/src/mustella/SendResultsToRunner.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/SendResultsToRunner.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/SendResultsToRunner.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/SendResultsToRunner.as Wed May  2 22:44:38 2012
@@ -0,0 +1,158 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 SendResultsToRunner 
+{
+
+	/**
+	 *  Mixin callback that gets everything ready to go.
+	 *  The UnitTester waits for an event before starting
+	 */
+	public static function init(root:DisplayObject):void
+	{
+		TestOutput.getInstance().addEventListener ("result", urlSender);
+	}
+
+
+	public static var midURL:String  = "";
+
+
+	public static var regExp5:RegExp = /%3D/g;
+
+
+
+	/**
+  	 * the way out for the result data
+	 */
+	public static function urlSender (event:Event):void 
+	{ 
+
+		var s:String = (event as MustellaLogEvent).msg;
+
+		var baseURL:String  = "http://localhost:" + UnitTester.runnerPort;
+
+		/// trace it anyway
+		trace (s);
+
+		/// Notice what we've got. Send along to Runner if relevant
+		var loc:uint;
+		var final:String = "";
+
+		var skip:Boolean = false;
+		var noSend:Boolean = false;
+
+		if ( (loc =  s.indexOf ("RESULT: ")) != -1) { 
+			s = s.substr (loc + 8);
+			midURL = "/testCaseResult";
+		} else if ( (loc =  s.indexOf ("ScriptComplete:")) != -1) { 
+			midURL = "/ScriptComplete";
+			final = "?" + UnitTester.excludedCount;
+			skip = true;
+		} else if ( (loc =  s.indexOf ("LengthOfTestcases:")) != -1) { 
+			midURL = "/testCaseLength?";
+			final = s.substring (loc+ "LengthOfTestcases:".length+1);
+			skip = true;
+		} else if ( (loc = s.indexOf ("TestCase Start:")) != -1) { 
+			/// not relevant
+			s = s.substr (loc + 15);
+			s = s.replace (" ", "");
+			midURL = "/testCaseStart?" + s ;
+			skip = true;
+		} else  { 
+			noSend = true;
+		}
+
+
+		if (!skip) { 
+
+			/// this should be something like |, because it is confusing this way
+			/// putting it on, taking it off
+			s=s.replace (" msg=", "|msg=");
+			s=s.replace (" result=", "|result=");
+			s=s.replace (" phase=", "|phase=");
+			s=s.replace (" id=", "|id=");
+			s=s.replace (" elapsed=", "|elapsed=");
+			s=s.replace (" started=", "|started=");
+			s=s.replace (" extraInfo=", "|extraInfo=");
+	
+			var hdrs:Array = s.split ("|");
+	
+			var i:uint;
+			// rebuild url encoded 
+			for (i=0;i<hdrs.length;i++) { 
+		
+				if (final =="")
+					final="?" + escape(hdrs[i]);
+				else
+					final+="&" + escape(hdrs[i]);
+			}
+	
+			final = final.replace (regExp5, "=");
+	
+		}
+
+		/**
+		 * Probably we don't need to use URLLoader, since we don't care 
+		 * about the response, but for now, for debugging, using it
+		 */
+		if (!noSend) { 
+			trace ("sending: " + baseURL + midURL + final + " at: " + new Date());
+			// var u:String= baseURL + midURL + final;
+			var u:URLLoader = new URLLoader (new URLRequest (baseURL + midURL + final));
+
+			/*	
+			var sock:Socket = new Socket ("localhost",  UnitTester.runnerPort);
+			sock.writeUTFBytes(u);
+			sock.flush();
+			sock.flush();
+			*/
+		
+			u.addEventListener("complete", httpEvents);
+			u.addEventListener("ioError", httpEvents);
+			u.addEventListener("open", httpEvents);
+			u.addEventListener("progress", httpEvents);
+			u.addEventListener("httpStatus", httpEvents);
+			u.addEventListener("securityError", httpEvents);
+			u.load (new URLRequest (baseURL + midURL + final));
+		}
+
+		
+
+	}
+
+
+	public static function httpEvents (e:Event):void  {
+		trace (e);
+	}
+
+}
+}

Propchange: incubator/flex/trunk/mustella/as3/src/mustella/SendResultsToRunner.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/mustella/as3/src/mustella/SendResultsToSnifferClient.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/SendResultsToSnifferClient.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/SendResultsToSnifferClient.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/SendResultsToSnifferClient.as Wed May  2 22:44:38 2012
@@ -0,0 +1,83 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.StatusEvent;
+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 SendResultsToSnifferClient
+{
+
+	/**
+	 *  Mixin callback that gets everything ready to go.
+	 *  The UnitTester waits for an event before starting
+	 */
+	public static function init(root:DisplayObject):void
+	{
+		TestOutput.getInstance().addEventListener ("result", snifferSender);
+
+		/// other required:
+  		connection = new LocalConnection();
+		connection.allowDomain("*");
+  		connection.addEventListener(StatusEvent.STATUS, statusHandler);
+	}
+
+ 	private static function statusHandler(event:Event):void
+	{
+	}
+
+   /**
+     *  @private
+	 *  The local connection to the remote client
+     */
+    private static var connection:LocalConnection;
+
+	/**
+  	 * the way out for the result data
+	 */
+	public static function snifferSender (event:Event):void 
+	{ 
+
+		var s:String = (event as MustellaLogEvent).msg;
+
+//		connection.send("_EventSniffer", "appendLog", "Mustella_Output", "Mustella_Output", s, "");
+
+	    var info:Object = new Object();
+	    
+	    info.dataSource = "Mustella_Output";
+	    info.target = "Mustella_Output";
+	    info.eventName = s;
+	    info.event = "";
+	    
+	    connection.send("_EventSniffer", "appendLog", info);
+
+	}
+
+
+}
+}

Propchange: incubator/flex/trunk/mustella/as3/src/mustella/SendResultsToSnifferClient.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/mustella/as3/src/mustella/SetProperty.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/SetProperty.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/SetProperty.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/SetProperty.as Wed May  2 22:44:38 2012
@@ -0,0 +1,142 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 mx.core.mx_internal;
+use namespace mx_internal;
+
+/**
+ *  Instead of a property, we use an event so the MXML
+ *  compiler will wrap the code in a function for us
+ */
+[Event(name="valueExpression", type="flash.events.Event")]
+
+/**
+ *  The test step that sets a property to some value
+ *  MXML attributes:
+ *  target
+ *  propertyName
+ *  value
+ *  waitTarget (optional)
+ *  waitEvent (optional)
+ *  timeout (optional);
+ */
+public class SetProperty extends TestStep
+{
+	/**
+	 *  @private
+	 */
+	override public function execute(root:DisplayObject, context:UnitTester, testCase:TestCase, testResult:TestResult):Boolean
+	{
+		if (waitEvent && waitTarget == null)
+			waitTarget = target;
+		return super.execute(root, context, testCase, testResult);
+	}
+
+	/**
+	 *  Set the target's property to the specified value
+	 */
+	override protected function doStep():void
+	{
+		if (expectError)
+			testCase.lastError = null;
+
+		var actualTarget:Object = context.stringToObject(target);
+		if (!actualTarget)
+		{
+			testResult.doFail("Target " + target + " not found");
+			return;
+		}
+		try
+		{
+			if (hasEventListener("valueExpression"))
+			{
+				context.resetValue();
+				dispatchEvent(new RunCodeEvent("valueExpression", root["document"], context, testCase, testResult));
+				value = context.value;
+				if (!context.valueChanged)
+					TestOutput.logResult("WARNING: value was not set by valueExpression.  'value=' missing from expression?");
+			}
+		}
+		catch (e:Error)
+		{
+			TestOutput.logResult("Exception thrown evaluating value expression.");
+			testResult.doFail (e.getStackTrace());	
+			return;
+		}
+
+		try
+		{
+			actualTarget[propertyName] = value;
+		}
+		catch (e1:Error)
+		{
+			if (expectError)
+				testCase.lastError = e1;
+			else
+			{
+				if (!(propertyName in actualTarget))
+				{
+					testResult.doFail ("target does not have property " + propertyName);
+					return;
+				}
+		
+				TestOutput.logResult("Exception thrown setting property.");
+				testResult.doFail (e1.getStackTrace());	
+			}
+		}
+	}
+
+	/**
+	 *  The object to set a property on
+	 */
+	public var target:String;
+
+	/**
+	 *  The name of the property to set
+	 */
+	public var propertyName:String;
+
+	/**
+	 *  The value to set
+	 */
+	public var value:Object;
+
+	/**
+	 *  If we should expect an error
+	 */
+	public var expectError:Boolean;
+
+	/**
+	 *  customize string representation
+	 */
+	override public function toString():String
+	{
+		var s:String = "SetProperty";
+		if (target)
+			s += ": target = " + target;
+		if (propertyName)
+			s += ", propertyName = " + propertyName;
+		return s;
+	}
+}
+
+}

Propchange: incubator/flex/trunk/mustella/as3/src/mustella/SetProperty.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/mustella/as3/src/mustella/SetShowRTE.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/SetShowRTE.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/SetShowRTE.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/SetShowRTE.as Wed May  2 22:44:38 2012
@@ -0,0 +1,43 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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;
+
+[Mixin]
+/**
+ *  A "marker" class that tells us to show RTEs
+ */
+public class SetShowRTE
+{
+
+	/**
+	 *  Mixin callback 
+	 */
+	public static function init(root:DisplayObject):void
+	{
+		UnitTester.showRTE = true;
+
+	}
+
+
+
+}
+
+}

Propchange: incubator/flex/trunk/mustella/as3/src/mustella/SetShowRTE.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/mustella/as3/src/mustella/SetStyle.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/SetStyle.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/SetStyle.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/SetStyle.as Wed May  2 22:44:38 2012
@@ -0,0 +1,118 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 mx.core.mx_internal;
+use namespace mx_internal;
+
+/**
+ *  Instead of a property, we use an event so the MXML
+ *  compiler will wrap the code in a function for us
+ */
+[Event(name="valueExpression", type="flash.events.Event")]
+
+/**
+ *  The test step that sets a property to some value
+ *  MXML attributes:
+ *  target
+ *  styleName
+ *  value
+ *  waitTarget (optional)
+ *  waitEvent (optional)
+ *  timeout (optional);
+ */
+public class SetStyle extends TestStep
+{
+
+	/**
+	 *  @private
+	 */
+	override public function execute(root:DisplayObject, context:UnitTester, testCase:TestCase, testResult:TestResult):Boolean
+	{
+		if (waitEvent && waitTarget == null)
+			waitTarget = target;
+		return super.execute(root, context, testCase, testResult);
+	}
+
+	/**
+	 *  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;
+		}
+
+		try
+		{
+			if (hasEventListener("valueExpression"))
+			{
+				context.resetValue();
+				dispatchEvent(new RunCodeEvent("valueExpression", root["document"], context, testCase, testResult));
+				value = context.value;
+				if (!context.valueChanged)
+					TestOutput.logResult("WARNING: value was not set by valueExpression.  'value=' missing from expression?");
+			}
+
+		}
+		catch (e:Error)
+		{
+			TestOutput.logResult("Exception thrown evaluating value expression.");
+			testResult.doFail (e.getStackTrace());	
+			return;
+		}
+
+		actualTarget.setStyle (styleName, value);
+	}
+
+	/**
+	 *  The object to set a property on
+	 */
+	public var target:String;
+
+	/**
+	 *  The name of the property to set
+	 */
+	public var styleName:String;
+
+	/**
+	 *  The value to set
+	 */
+	public var value:Object;
+
+	/**
+	 *  customize string representation
+	 */
+	override public function toString():String
+	{
+		var s:String = "SetStyle";
+		if (target)
+			s += ": target = " + target;
+		if (styleName)
+			s += ", styleName = " + styleName;
+		return s;
+	}
+}
+
+}

Propchange: incubator/flex/trunk/mustella/as3/src/mustella/SetStyle.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/mustella/as3/src/mustella/SetURL.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/SetURL.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/SetURL.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/SetURL.as Wed May  2 22:44:38 2012
@@ -0,0 +1,95 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.external.ExternalInterface;
+
+import mx.core.mx_internal;
+use namespace mx_internal;
+
+/**
+ *  Instead of a property, we use an event so the MXML
+ *  compiler will wrap the code in a function for us
+ */
+[Event(name="valueExpression", type="flash.events.Event")]
+
+/**
+ *  The test step that sets the browser to a specific URL
+ *  MXML attributes:
+ *  url
+ *  waitTarget (optional)
+ *  waitEvent (optional)
+ *  timeout (optional);
+ */
+public class SetURL extends TestStep
+{
+
+	/**
+	 *  Set the target's property to the specified value
+	 */
+	override protected function doStep():void
+	{
+		var count:int = 0;
+		if (url.indexOf("BACK") == 0)
+		{
+			if (url.length > 4)
+				count = parseInt(url.substring(4));
+
+			if (count > 0)
+				ExternalInterface.call("goForwardOrBackInHistory", -count);
+			else
+				ExternalInterface.call("backButton");
+
+		}
+		else if (url.indexOf("FORWARD") == 0)
+		{
+			if (url.length > 7)
+				count = parseInt(url.substring(7));
+
+			if (count > 0)
+				ExternalInterface.call("goForwardOrBackInHistory", count);
+			else
+				ExternalInterface.call("forwardButton");
+
+		}
+		else
+		{
+			ExternalInterface.call("setURL", url);
+		}
+	}
+
+	/**
+	 *  The url to navigate to.  Can also be "BACK" or "FORWARD"
+	 */
+	public var url:String;
+
+	/**
+	 *  customize string representation
+	 */
+	override public function toString():String
+	{
+		var s:String = "SetURL";
+		if (url)
+			s += ", url = " + url;
+		return s;
+	}
+}
+
+}

Propchange: incubator/flex/trunk/mustella/as3/src/mustella/SetURL.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/mustella/as3/src/mustella/SetVettingRun.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/SetVettingRun.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/SetVettingRun.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/SetVettingRun.as Wed May  2 22:44:38 2012
@@ -0,0 +1,44 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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;
+
+[Mixin]
+/**
+ *  A "marker" class that tells us this is a vetting run.
+ */
+public class SetVettingRun
+{
+
+	/**
+	 *  Mixin callback 
+	 */
+	public static function init(root:DisplayObject):void
+	{
+		UnitTester.isVettingRun = true;
+		UnitTester.bitmapServerPrefix = "http://localhost:9995/baselines/baseline.jsp?filename=";
+
+	}
+
+
+
+}
+
+}

Propchange: incubator/flex/trunk/mustella/as3/src/mustella/SetVettingRun.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/mustella/as3/src/mustella/SnifferCellRenderer.mxml
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/SnifferCellRenderer.mxml?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/SnifferCellRenderer.mxml (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/SnifferCellRenderer.mxml Wed May  2 22:44:38 2012
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?> 
+<!--
+
+  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.
+
+-->
+<mx:Label xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%">
+<mx:Script>        
+<![CDATA[
+    import mx.controls.*;
+    import mx.controls.dataGridClasses.*;
+
+    private var theData:Object;
+
+	override public function set data(obj:Object):void {
+
+	    theData = obj;
+	    
+		if (obj && obj.eventName) { 
+			text = obj.eventName as String;
+		}else{
+		    text = "";
+		}
+		
+		/**
+		if(obj){
+            trace ("Rendering item: ");
+            trace ("    obj.dataSource: " + obj.dataSource); // Event, Object, Mouse...
+            trace ("    obj.target: " + obj.target);
+            trace ("    obj.eventName: " + obj.eventName);
+            trace ("    obj.event: " + obj.event);
+		}
+		**/
+
+	}
+	
+	// Paint red if there's a failure.  Code lifted from Joan's blog.
+	override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
+
+        var g:Graphics = graphics;
+        var grid1:DataGrid = DataGrid(DataGridListData(listData).owner);
+        
+        super.updateDisplayList(unscaledWidth, unscaledHeight);
+        
+        g.clear();
+
+        if (grid1.isItemSelected(theData) || grid1.isItemHighlighted(theData))
+            return;
+        
+        if(theData && theData.eventName){
+    	    if(theData.eventName.indexOf ("result=fail") != -1){
+                g.beginFill(0xff0000);
+                g.drawRect(0, 0, unscaledWidth, unscaledHeight);
+                g.endFill();
+    	    }
+        }
+	}
+
+]]>    
+</mx:Script>        
+
+</mx:Label> 

Propchange: incubator/flex/trunk/mustella/as3/src/mustella/SnifferCellRenderer.mxml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/mustella/as3/src/mustella/SnifferRemoteClient.mxml
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/SnifferRemoteClient.mxml?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/SnifferRemoteClient.mxml (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/SnifferRemoteClient.mxml Wed May  2 22:44:38 2012
@@ -0,0 +1,514 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+  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.
+
+-->
+<s:Application 
+            xmlns:fx="http://ns.adobe.com/mxml/2009"
+            xmlns:s="library://ns.adobe.com/flex/spark"
+            xmlns:mx="library://ns.adobe.com/flex/mx"
+            width="100%" height="800"
+            initialize="initApp()">
+
+    <fx:Script>
+    <![CDATA[
+
+        import mx.core.UIComponent;
+        import mx.collections.*;
+        import mx.core.mx_internal;
+        use namespace mx_internal;
+
+
+        [Bindable] private var theList:ArrayCollection = new ArrayCollection();
+        [Bindable] private var theListView:ListCollectionView = new ListCollectionView (theList);
+        private var iterator:int = 0;
+        private var connection:LocalConnection;
+        private var commandconnection:LocalConnection;
+        private var pixelconnection:LocalConnection;
+        private var pixelcommandconnection:LocalConnection;
+        private var mouseconnection:LocalConnection;
+        private var mousecommandconnection:LocalConnection;
+        private var objectconnection:LocalConnection;
+        private var objectcommandconnection:LocalConnection;
+        private var playbackconnection:LocalConnection;
+        private var playbackcommandconnection:LocalConnection;
+
+        private function initApp():void
+        {
+
+            theListView.filterFunction = filterData;
+
+            connection = new LocalConnection();
+            connection.allowDomain("*");
+            connection.client = this;
+
+            commandconnection = new LocalConnection();
+            commandconnection.allowDomain("*");
+            commandconnection.addEventListener(StatusEvent.STATUS, statusHandler);
+
+            pixelconnection = new LocalConnection();
+            pixelconnection.allowDomain("*");
+            pixelconnection.client = this;
+
+            pixelcommandconnection = new LocalConnection();
+            pixelcommandconnection.allowDomain("*");
+            pixelcommandconnection.addEventListener(StatusEvent.STATUS, statusHandler);
+
+            mouseconnection = new LocalConnection();
+            mouseconnection.allowDomain("*");
+            mouseconnection.client = this;
+
+            mousecommandconnection = new LocalConnection();
+            mousecommandconnection.allowDomain("*");
+            mousecommandconnection.addEventListener(StatusEvent.STATUS, statusHandler);
+
+            objectconnection = new LocalConnection();
+            objectconnection.allowDomain("*");
+            objectconnection.client = this;
+
+            objectcommandconnection = new LocalConnection();
+            objectcommandconnection.allowDomain("*");
+            objectcommandconnection.addEventListener(StatusEvent.STATUS, statusHandler);
+
+            playbackconnection = new LocalConnection();
+            playbackconnection.allowDomain("*");
+            playbackconnection.client = this;
+
+            playbackcommandconnection = new LocalConnection();
+            playbackcommandconnection.allowDomain("*");
+            playbackcommandconnection.addEventListener(StatusEvent.STATUS, statusHandler);
+
+            connect();
+            
+            toggleSniffersEnabled();
+        }
+
+        private function connect():void
+        {
+            try
+            {
+                connection.connect("_EventSniffer");
+            }
+            catch (e:Error)
+            {
+                appendLog("connection failed");
+            }
+
+            try
+            {
+                pixelconnection.connect("_PixelSniffer");
+            }
+            catch (e:Error)
+            {
+                appendLog("pixel connection failed");
+            }
+
+            try
+            {
+                mouseconnection.connect("_MouseSniffer");
+            }
+            catch (e:Error)
+            {
+                appendLog("mouse connection failed");
+            }
+
+            try
+            {
+                objectconnection.connect("_ObjectSniffer");
+            }
+            catch (e:Error)
+            {
+                appendLog("object connection failed");
+            }
+
+            try
+            {
+                playbackconnection.connect("_PlaybackSniffer");
+            }
+            catch (e:Error)
+            {
+                appendLog("playback connection failed");
+            }
+        }
+
+        private function statusHandler(event:Event):void
+        {
+        }
+
+        [Bindable]
+        public var enableLogging:Boolean = true;
+
+        public function enableSniffer():void
+        {
+            enableLogging = true;
+        }
+
+        public function disableSniffer():void
+        {
+            enableLogging = false;
+        }
+
+        /**
+        * Called by the sniffer.
+        **/
+        public function appendLog(info:Object):void
+        {
+            if (!enableLogging)
+                return;
+
+            /**
+                if (eventName==null) 
+                {
+                    eventName=" ";
+                }
+                if (event==null) 
+                {
+                    event=" ";
+                }
+            **/
+
+            iterator++;
+
+/**
+            trace ("RECEIVED item " + iterator + ":");
+            trace ("    dataSource: " + info.dataSource); // Event, Object, Mouse...
+            trace ("    target: " + info.target);
+            trace ("    eventName: " + info.eventName);
+            trace ("    event: " + info.event);
+**/
+                        
+            theList.addItem ({sequence:iterator, dataSource:info.dataSource, target:info.target, event:info.event, eventName:info.eventName});
+            /// call refresh
+            theListView.refresh();
+        }
+
+        public function filterData (o:Object):Boolean { 
+
+            // Do the easy event check before the more expensive ones.
+            if (o.dataSource == "Event"){
+                if (!eventsList.selected)
+                    return false;
+
+                if (rbIncludeEvents.selected && (eventMap[o.eventName] != 1 && !match(o.eventName, eventWildCards)))
+                    return false;
+    
+                if (rbExcludeEvents.selected && (eventMap[o.eventName] == 1 || match(o.eventName, eventWildCards)))
+                    return false;
+            }
+
+            if (!mouseList.selected && (o.dataSource == "Mouse" || o.dataSource == "Pixel" ))
+                return false;
+
+            if (!mustellaOutputList.selected && o.dataSource == "Mustella_Output")
+                return false;
+
+            if (!objectList.selected && o.dataSource == "Object")
+                return false;
+
+            if (rbIncludeTargets.selected && (targetMap[o.target] != 1 && !match(o.target, targetWildCards)))
+                return false;
+
+            if (rbExcludeTargets.selected && (targetMap[o.target] == 1 || match(o.target, targetWildCards)))
+                return false;
+
+            return true;
+        }
+
+        /**
+        * Enable or disable sniffers based on the checkboxes.
+        * This is called locally when the checkboxes are changed,
+        * and remotely by other sniffers when the SWF under test
+        * starts up.
+        **/
+        public function toggleSniffersEnabled():void{
+
+            if(eventsList.selected == true){
+                commandconnection.send("_EventSnifferCommands", "enableSniffer");
+            }else{
+                commandconnection.send("_EventSnifferCommands", "disableSniffer");
+            }
+
+            if(mouseList.selected == true){
+                mousecommandconnection.send("_MouseSnifferCommands", "enableSniffer");
+                pixelcommandconnection.send("_PixelSnifferCommands", "enableSniffer");
+            }else{
+                mousecommandconnection.send("_MouseSnifferCommands", "disableSniffer");
+                pixelcommandconnection.send("_PixelSnifferCommands", "disableSniffer");
+            }
+        }
+
+        private function scrollLog():void
+        {
+            if (log.maxVerticalScrollPosition != log.verticalScrollPosition)
+                log.verticalScrollPosition = log.maxVerticalScrollPosition;
+        }
+
+        private var _targetList:String;
+        private var targetListChanged:Boolean = false;
+
+        public function get targetList():String
+        {
+            var s:String = targets.text;
+            s = s.replace("\r", ",");
+            return s;
+        }
+
+        public function set targetList(s:String):void
+        {
+            _targetList = s;
+            targetListChanged = true;
+            invalidateProperties();
+        }
+
+        private var _eventList:String;
+        private var eventListChanged:Boolean = false;
+
+        public function get eventList():String
+        {
+            var s:String = events.text;
+            s = s.replace("\r", ",");
+            return s;
+        }
+
+        public function set eventList(s:String):void
+        {
+            _eventList = s;
+            eventListChanged = true;
+            invalidateProperties();
+        }
+
+        private var filterChanged:Boolean = false;
+
+        /**
+        * If the target or event include/exclude lists
+        * changed, process the new settings.
+        **/
+        override protected function commitProperties():void
+        {
+            var s:String;
+            var n:int;
+            var i:int;
+
+            if (eventListChanged)
+            {
+                eventListChanged = false;
+                s = _eventList.replace(",", "\r");
+                events.text = s;
+                filterChanged = true;
+            }
+
+            if (targetListChanged)
+            {
+                targetListChanged = false;
+                s = _targetList.replace(",", "\r");
+                targets.text = s;
+                filterChanged = true;
+            }
+
+            if (filterChanged)
+            {
+                filterChanged = false;
+
+                s = events.text;
+                var names:Array = s.split("\r");
+                n = names.length;
+                eventMap = {};
+                eventWildCards = [];
+                for (i = 0; i < n; i++)
+                {
+                    s = names[i];
+                    if (s.indexOf('*') >= 0)
+                        eventWildCards.push(s);
+                    else
+                        eventMap[names[i]] = 1;
+                }
+
+                s = targets.text;
+                names = s.split("\r");
+                n = names.length;
+                targetMap = {};
+                targetWildCards = [];
+                for (i = 0; i < n; i++)
+                {
+                    s = names[i];
+                    if (s.indexOf('*') >= 0)
+                        targetWildCards.push(new RegExp(s.replace("*", ".*")));
+                    else
+                        targetMap[names[i]] = 1;
+                }
+
+            }
+
+            super.commitProperties();
+            theListView.refresh();
+        }
+
+        private var eventMap:Object = {};
+        private var targetMap:Object = {};
+
+        private var eventWildCards:Array = [];
+        private var targetWildCards:Array = [];
+
+        private function changeFilter():void
+        {
+            filterChanged = true;
+            invalidateProperties();
+        }
+
+        private function match(target:String, wildCards:Array):Boolean
+        {
+            var n:int = wildCards.length;
+            for (var i:int = 0; i < n; i++)
+            {
+                if (RegExp(wildCards[i]).test(target))
+                    return true;
+            }
+            return false;
+        }
+
+        private function getAProperty():void
+        {
+            objectcommandconnection.send("_ObjectSnifferCommands", "dumpObject", target.text);
+        }
+
+        private function listAllProperties():void
+        {
+            objectcommandconnection.send("_ObjectSnifferCommands", "listProperties", target.text);
+        }
+
+        [Bindable]
+        public var paused:Boolean = true;
+
+        public function getPausedState():void
+        {
+            if (paused)            
+                pausePlayback();
+        }                
+
+        public function pausePlayback():void
+        {
+            paused = true;
+            playbackcommandconnection.send("_PlaybackCommands", "pause")
+        }
+
+        public function playback():void
+        {
+            paused = false;
+            playbackcommandconnection.send("_PlaybackCommands", "playback")
+        }
+
+        public function stepit():void
+        {
+            playbackcommandconnection.send("_PlaybackCommands", "step")
+        }
+
+        /**
+        * Someone has changed the Events, Mouse Stuff,
+        * Test Output, or Objects checkbox(es).
+        **/
+        private function handleSnifferListChange(e:Event):void{
+            theListView.refresh();
+            toggleSniffersEnabled();            
+        }
+    ]]>
+    </fx:Script>
+
+    <s:layout>
+        <s:VerticalLayout />
+    </s:layout>
+
+	<mx:Spacer width="1024" />
+
+    <!-- Each row of data looks like this: {sequence, dataSource, target, event, eventName} -->
+    <mx:DataGrid id="log" dataProvider="{theListView}" rowCount="20" width="100%" updateComplete="scrollLog()" > 
+           <mx:columns>
+                   <mx:DataGridColumn dataField="sequence" dataTipField="sequence" headerText="#" width="80" editable="false"/>
+                   <mx:DataGridColumn dataField="target" dataTipField="target" headerText="Target" width="1000" editable="false" itemRenderer="mx.controls.Label"/>
+                   <mx:DataGridColumn dataField="eventName" dataTipField="eventName" headerText="Event Name" width="1000" editable="false" itemRenderer="SnifferCellRenderer">
+            </mx:DataGridColumn>
+           </mx:columns>
+    </mx:DataGrid>
+
+    <mx:HBox width="100%" defaultButton="{events}" borderStyle="solid" paddingTop="1" paddingBottom="1" paddingLeft="1" paddingRight="1">
+        <mx:Label text="Filter by Type: "/>
+        <mx:CheckBox id="eventsList" selected="true" label="Events" change="handleSnifferListChange(event)" />
+        <mx:CheckBox id="mustellaOutputList" selected="true" label="Test Output"  change="handleSnifferListChange(event)" />
+        <mx:CheckBox id="objectList" selected="true" label="Objects"  change="handleSnifferListChange(event)" />
+        <mx:CheckBox id="mouseList" selected="false" label="Mouse Stuff" change="handleSnifferListChange(event)" />
+    </mx:HBox>
+
+    <mx:Box width="100%" borderStyle="solid" paddingTop="1" paddingBottom="1"
+                            paddingLeft="1" paddingRight="1" enabled="{eventsList.selected}" >
+        <mx:Label text="Filter by Target/Event: " />
+        <mx:HBox width="100%" >
+            <mx:HBox width="50%" borderStyle="solid" paddingTop="1" paddingBottom="1" paddingLeft="1" paddingRight="1">
+                <mx:Box width="20%">
+                <mx:RadioButton id="rbIncludeTargets" groupName="targetRB" label="include targets"/>
+                <mx:RadioButton id="rbExcludeTargets" groupName="targetRB" label="exclude targets" selected="true" />
+                </mx:Box>
+                <mx:Box width="80%">
+                <mx:TextArea id="targets" width="100%" height="100" focusOut="changeFilter()"/>
+                </mx:Box>
+            </mx:HBox>
+            <mx:HBox width="50%" borderStyle="solid" paddingTop="1" paddingBottom="1" paddingLeft="1" paddingRight="1">
+                <mx:Box width="20%">
+                <mx:RadioButton id="rbIncludeEvents" groupName="eventRB" label="include events"/>
+                <mx:RadioButton id="rbExcludeEvents" groupName="eventRB" label="exclude events" selected="true"/>
+                </mx:Box>
+                <mx:Box width="80%">
+                <mx:TextArea id="events" width="100%" height="100" focusOut="changeFilter()"/>
+                </mx:Box>
+            </mx:HBox>
+        </mx:HBox>
+    
+        <mx:Button label="Apply Filters"  click="changeFilter()" />    
+    </mx:Box>
+
+    <mx:HBox width="100%" defaultButton="{getProperty}" enabled="{objectList.selected}" >
+        <mx:TextInput width="100%" id="target"/>
+        <mx:Button id="getProperty" label="Get Property" click="getAProperty()" />
+        <mx:Button id="listProperties" label="List Properties" click="listAllProperties()" />
+    </mx:HBox>
+
+    <s:Group width="100%">
+        <s:Rect id="headerBackground" left="0" right="0" top="0" height="24">
+            <s:fill>
+                <s:SolidColor color="0xCCCCCC" />
+            </s:fill>
+        </s:Rect>
+
+        <s:HGroup width="100%">
+            <s:HGroup width="100%" paddingLeft="5">
+                <s:Label text="Playback Control:" paddingTop="5"/>
+                <s:Button id="pause" label="Pause" enabled="{!paused}" click="pausePlayback()" skinClass="skins.pauseButtonSkin" />
+                <s:Button id="play" label="Play" enabled="{paused}" click="playback()" skinClass="skins.playButtonSkin" />
+                <s:Button id="step" label="Step" enabled="{paused}" click="stepit()" skinClass="skins.stepButtonSkin" />
+            </s:HGroup>
+
+            <s:HGroup width="100%" >
+                <s:Label text="Logging:" paddingTop="5" />
+                <s:Button label="start" enabled="{!enableLogging}" click="enableSniffer()" />
+                <s:Button label="stop" enabled="{enableLogging}" click="disableSniffer()" />
+                <s:Button label="mark" click="appendLog({dataSource:'Marker', target:'------------ ' + getTimer() + ' -------------', event:'', eventName:''})" />
+                <s:Button label="clear" click="theList.removeAll(); iterator=0;" />
+                <s:Label id="pixel" text="Current Pixel Color" visible="false" />
+            </s:HGroup>
+    
+        </s:HGroup>
+    </s:Group>
+
+</s:Application>

Propchange: incubator/flex/trunk/mustella/as3/src/mustella/SnifferRemoteClient.mxml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/mustella/as3/src/mustella/SnifferRemoteClient.swf
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/SnifferRemoteClient.swf?rev=1333232&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/flex/trunk/mustella/as3/src/mustella/SnifferRemoteClient.swf
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/flex/trunk/mustella/as3/src/mustella/SnifferRemoteClient_3x.swf
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/SnifferRemoteClient_3x.swf?rev=1333232&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/flex/trunk/mustella/as3/src/mustella/SnifferRemoteClient_3x.swf
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/flex/trunk/mustella/as3/src/mustella/SocketAddress.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/SocketAddress.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/SocketAddress.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/SocketAddress.as Wed May  2 22:44:38 2012
@@ -0,0 +1,52 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 mx.core.UIComponentGlobals;
+import mx.core.mx_internal;
+
+use namespace mx_internal;
+
+[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 SocketAddress 
+{
+
+	/**
+	 *  Mixin callback that gets everything ready to go.
+	 *  The UnitTester waits for an event before starting
+	 */
+	public static function init(root:DisplayObject):void
+	{
+	}
+
+	function SocketAddress()
+	{
+		UnitTester.RTESocketAddress = "127.0.0.1";
+        // UnitTester.RTESocketAddress = "10.132.64.64";
+	}
+}
+
+}

Propchange: incubator/flex/trunk/mustella/as3/src/mustella/SocketAddress.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/mustella/as3/src/mustella/TargetConfigurations.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/TargetConfigurations.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/TargetConfigurations.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/TargetConfigurations.as Wed May  2 22:44:38 2012
@@ -0,0 +1,112 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 {
+
+
+/**
+ *  Configurations of environments where tests are run
+ *  are mapped to IDs.
+ *  
+ *  This can't be database stuff because we don't know
+ *  some of this info. until we are actually running.
+ *
+ *  Most tests will only differ with deviceDensity and OS, with a few differing by screenDPI.
+ *  We aren't embedding in this release, so the same deviceDensity basesline will differ across
+ *  OSs.  But that will probably change in Ultra, which is why the DPI is used in the config ID.
+ *
+ *  The color depth is just theoretical, and the osVersion has not been needed.
+ *
+ *  DEVICES:
+ *  
+ *  Device            deviceDensity    os        screenDPI    widthxheight    color    osVersion
+ *  win               160              win       160          320x455         -        -
+ *  Playbook          160              qnx       170          1024x600        -        -
+ *  win               240              win       240          480x762         -        -
+ *  Droid 2:          240              android   240          480x854         -        -
+ *  Droid X:          240              android   240          480x816         -        -
+ *  Nexus One:        240              android   240          480x762         -        -
+ *  Desire:           240              android   240          480x762         -        -
+ *  Nexus S:          240              android   240          480x762         -        -
+ *  win               320              win       320          640x960         -        -
+ *  iPodTouch4G:      320              ios       326          640x960         -        -
+ *
+ */
+
+import mx.core.FlexGlobals;
+
+public class TargetConfigurations
+{
+	public static var configs:Array = [
+		{ configID: "160_01", deviceDensity: 160, os: DeviceNames.WIN, screenDPI: 160, deviceWidth: 320, deviceHeight: 455, color: null, osVersion: null},
+		{ configID: "160_02", deviceDensity: 160, os: DeviceNames.MAC, screenDPI: 160, deviceWidth: 320, deviceHeight: 455, color: null, osVersion: null},		
+		{ configID: "160_03", deviceDensity: 160, os: DeviceNames.QNX, screenDPI: 170, deviceWidth: 1024, deviceHeight: 600, color: null, osVersion: null},
+		{ configID: "240_01", deviceDensity: 240, os: DeviceNames.WIN, screenDPI: 240, deviceWidth: 480, deviceHeight: 762, color: null, osVersion: null},
+		{ configID: "240_02", deviceDensity: 240, os: DeviceNames.MAC, screenDPI: 240, deviceWidth: 480, deviceHeight: 762, color: null, osVersion: null},		
+		{ configID: "240_03", deviceDensity: 240, os: DeviceNames.ANDROID, screenDPI: 240, deviceWidth: 480, deviceHeight: 816, color: null, osVersion: null},
+		{ configID: "240_04", deviceDensity: 240, os: DeviceNames.ANDROID, screenDPI: 240, deviceWidth: 480, deviceHeight: 854, color: null, osVersion: null},
+		{ configID: "240_05", deviceDensity: 240, os: DeviceNames.ANDROID, screenDPI: 240, deviceWidth: 480, deviceHeight: 762, color: null, osVersion: null},
+		{ configID: "320_01", deviceDensity: 320, os: DeviceNames.WIN, screenDPI: 320, deviceWidth: 640, deviceHeight: 960, color: null, osVersion: null},
+		{ configID: "320_02", deviceDensity: 320, os: DeviceNames.MAC, screenDPI: 320, deviceWidth: 640, deviceHeight: 960, color: null, osVersion: null},		
+		{ configID: "320_03", deviceDensity: 320, os: DeviceNames.IOS, screenDPI: 326, deviceWidth: 640, deviceHeight: 960, color: null, osVersion: null}
+	];
+	
+	/**
+	 * Returns the config ID which best matches the given ConditionalValue.
+	 * This config ID will get added to baselines.  e.g. MyGroovyTest@160_01.png
+	 **/
+	public static function getTargetConfigID( cv:ConditionalValue ):String{
+		var i:int = 0;
+
+		if( cv == null ){
+			return null;
+		}
+		
+		// Get these when a test is actually running.
+		if( cv.deviceWidth == -1 ){
+			cv.deviceWidth = FlexGlobals.topLevelApplication.width;
+		}
+	
+		if( cv.deviceHeight == -1 ){
+			cv.deviceHeight = FlexGlobals.topLevelApplication.height;
+		}
+		
+		for( i = 0; i < configs.length; ++i ){
+			if( cv.deviceDensity == configs[ i ].deviceDensity &&
+			    cv.os == configs[ i ].os &&
+			    cv.screenDPI == configs[ i ].screenDPI &&
+			    cv.deviceWidth == configs[ i ].deviceWidth &&
+			    cv.deviceHeight == configs[ i ].deviceHeight
+			    ){
+				return configs[ i ].configID;
+			}else{
+				//trace( "*********This did not match:**********" );
+				//trace( "deviceDensity: " + configs[ i ].deviceDensity + "!=" + cv.deviceDensity );
+				//trace( "os: " + configs[ i ].os + "!=" + cv.os );
+				//trace( "screenDPI: " + configs[ i ].screenDPI + "!=" + cv.screenDPI );
+				//trace( "deviceWidth: " + configs[ i ].deviceWidth + "!=" + cv.deviceWidth );
+				//trace( "deviceHeight: " + configs[ i ].deviceHeight + "!=" + cv.deviceHeight );				
+			}
+		}
+		
+		// No matches.
+		return null;
+
+	}
+} // end TargetConfigurations class
+} // end package

Propchange: incubator/flex/trunk/mustella/as3/src/mustella/TargetConfigurations.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/mustella/as3/src/mustella/TestCase.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/TestCase.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/TestCase.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/TestCase.as Wed May  2 22:44:38 2012
@@ -0,0 +1,501 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.getQualifiedClassName;
+import flash.utils.getTimer;
+import flash.utils.Timer;
+
+/**
+ *  A Test.  A Test script comprises several of these
+ *  TestCases.  Each TestCase consists of a
+ *  setup, body and cleanup section which are sets
+ *  of TestStep-derived classes like SetProperty,
+ *  RunCode, AssertPropertyValue, etc.
+ *
+ *  MXML Properties (not attributes)
+ *  setup
+ *  body
+ *  cleanup
+ */
+public class TestCase extends EventDispatcher
+{
+	/**
+	 *  The history of bugs that this test case has encountered
+	 */
+	public var bugs:Array;
+
+	/**
+	 *  The sequence of TestSteps that comprise the test setup
+	 */
+	public var setup:Array;
+
+	/**
+	 *  The sequence of TestSteps that comprise the test
+	 */
+	public var body:Array;
+
+	/**
+	 *  The sequence of TestSteps that restore the test environment
+	 */
+	public var cleanup:Array;
+
+	/**
+	 *  An identifier for the test
+	 */
+	public var testID:String;
+
+	/**
+	 *  A description of the test 
+	 */
+	public var description:String;
+
+	/**
+	 *  keywords, summarizing the tests
+	 */
+	public var keywords:String;
+
+	/**
+	 *  frequency, an estimate of the tests's intersection with real-world
+	 *  usage. 1 = most frequent usage; 2 somewhat common; 3 = unusual
+	 */
+	public var frequency:String;
+
+	/**
+	 *  The current set of steps (setup, body, cleanup) we are executing
+	 */
+	private var currentSteps:Array;
+
+	/**
+	 *  Which step we're currently executing (or waiting on an event for)
+	 */
+	private var currentIndex:int = 0;
+
+	/**
+	 *  Number of steps in currentSteps
+	 */
+	private var numSteps:int = 0;
+
+	/**
+	 *  The root of the SWF (SystemManager)
+	 */
+	private var root:DisplayObject;
+
+	/**
+	 *  The shared timer we listen to
+	 */
+	private var timer:Timer;
+
+	/**
+	 *  The unit tester
+	 */
+	private var context:UnitTester;
+
+	/**
+	 *  Whether we need to emit a runComplete event or not
+	 */
+	private var needCompleteEvent:Boolean = false;
+
+	/**
+	 *  If non-zero, the time when we'll give up on waiting
+	 */
+	private var expirationTime:int;
+
+	/**
+	 *  the last expected Error thrown by SetProperty
+	 */
+	public var lastError:Error;
+
+	/**
+	 *	Called by test steps looking for a timeout indicator
+	 */
+	public function setExpirationTime(time:int):void
+	{
+		expirationTime = time + UnitTester.timeout_plus;
+	}
+
+	/**
+	 *  Storage for the cleanupAsserts
+	 */
+	private var _cleanupAsserts:Array;
+
+	/**
+	 *  Steps we have to review at the end of the body to see if
+	 *  they failed or not.  These steps monitor activity like
+	 *  checking for duplicate events or making sure unwanted events
+	 *  don't fire.
+	 */
+	public function get cleanupAsserts():Array
+	{
+		return _cleanupAsserts;
+	}
+
+	/**
+	 *  Storage for this tests's result
+	 */
+	private var _testResult:TestResult;
+
+	/**
+	 *  This tests's result
+	 */
+	public function get testResult():TestResult 
+	{ 
+		_testResult.testID = testID;
+		return _testResult;
+	}
+
+	/**
+	 * Constructor. Create the TestResult associated with this TestCase
+	 */
+	public function TestCase() {
+
+		_testResult = new TestResult();
+		_testResult.testID = testID;
+
+		_cleanupAsserts = [];
+	}
+
+	/**
+	 *  Called by the UnitTester when it is time to execute
+	 *  this test case.
+	 *
+	 *  @param root The SystemManager
+	 *  @param timer The shared Timer;
+	 *  @param the UnitTester that contains these tests
+	 */
+	public function runTest(root:DisplayObject, timer:Timer, context:UnitTester):Boolean
+	{
+		
+		_testResult.beginTime = new Date().time;
+		_testResult.context = context;
+		this.timer = timer;
+		this.timer.addEventListener("timer", timerHandler);
+		this.root = root;
+		this.context = context;
+
+		if (UnitTester.hasRTE) 
+		{ 
+			return true;
+
+		}
+
+		// do a sanity test here
+		if (UnitTester.verboseMode)
+		{
+			var needWaitEvent:Boolean = false;
+			var i:int;
+			if (setup)
+			{
+				for (i = 0; i < setup.length; i++)
+				{
+					if (setup[i] is ResetComponent)
+						needWaitEvent = true;
+					if (needWaitEvent)
+					{
+						if (setup[i].waitEvent)
+						{
+							needWaitEvent = false;
+							break;
+						}
+					}
+				}
+				if (needWaitEvent)
+					TestOutput.logResult("WARNING: Test " + getQualifiedClassName(context) + "." + testID + " ResetComponent used without any setup steps using a waitEvent\n");
+			}
+			var allAsserts:Boolean = true;
+			needWaitEvent = false;
+			for (i = 0; i < body.length; i++)
+			{
+				if (body[i] is SetProperty || body[i] is SetStyle)
+					needWaitEvent = true;
+				if (!(body[i] is Assert))
+					allAsserts = false;
+				if (allAsserts && body[i] is AssertEvent)
+				{
+					TestOutput.logResult("WARNING: Test " + getQualifiedClassName(context) + "." + testID + " no non-Assert steps in body before AssertEvent\n");
+				}
+				if (needWaitEvent)
+				{
+					if (body[i].waitEvent)
+					{
+						needWaitEvent = false;
+						break;
+					}
+				}
+			}
+			if (needWaitEvent)
+				TestOutput.logResult("WARNING: Test " + getQualifiedClassName(context) + "." + testID + " tests setting values without a waitEvent\n");
+			
+		}
+
+		return runSetup();
+	}
+
+	/**
+	 *  Execute the setup portion of the test
+	 *
+	 *  @param continuing If true, don't reset the counter to zero
+	 *  and just continue on with the test at the currentIndex
+	 */
+	private function runSetup(continuing:Boolean = false):Boolean
+	{
+		if (!testResult.hasStatus()) 
+		{ 
+			if (setup)
+			{
+				testResult.phase = TestResult.SETUP;
+				currentSteps = setup;
+				if (!continuing)
+					currentIndex = 0;
+				numSteps = setup.length;
+				// return if we need to wait for something
+				if (!runSteps())
+					return false;
+
+			}
+		}
+		return runBody();
+	}
+
+	/**
+	 *  Execute the body portion of the test
+	 *
+	 *  @param continuing If true, don't reset the counter to zero
+	 *  and just continue on with the test at the currentIndex
+	 */
+	private function runBody(continuing:Boolean = false):Boolean
+	{
+		if (!testResult.hasStatus()) 
+		{ 
+			if (body)
+			{
+				testResult.phase = TestResult.BODY;
+				currentSteps = body;
+				if (!continuing)
+					currentIndex = 0;
+				numSteps = body.length;
+				// return if we need to wait for something
+				if (!runSteps())
+					return false;
+
+			}
+		}
+		return runCleanup();
+	}
+
+	/**
+	 *  Execute the cleanup portion of the test
+	 *
+	 *  @param continuing If true, don't reset the counter to zero
+	 *  and just continue on with the test at the currentIndex
+	 */
+	private function runCleanup(continuing:Boolean = false):Boolean
+	{
+		if (!testResult.hasStatus()) 
+		{ 
+			if (cleanup)
+			{
+				testResult.phase = TestResult.CLEANUP;
+				currentSteps = cleanup;
+				if (!continuing)
+					currentIndex = 0;
+				numSteps = cleanup.length;
+				// return if we need to wait for something
+				if (!runSteps())
+					return false;
+
+			}
+		}
+		return runComplete();
+	}
+
+	/**
+	 *  Clean up when all three phases are done.  Sends an event
+	 *  to the UnitTester harness to tell it that it can run
+	 *  the next test case.
+	 */
+	private function runComplete():Boolean
+	{
+		var n:int = cleanupAsserts.length;
+		for (var i:int = 0; i < n; i++)
+		{
+			var assert:Assert = cleanupAsserts[i];
+			assert.cleanup();
+		}
+
+		timer.removeEventListener("timer", timerHandler);
+		if (needCompleteEvent)
+			dispatchEvent(new Event("runComplete"));
+		return true;
+	}
+
+	/**
+	 *  Go through the currentSteps, executing each one.
+	 *  Returns true if no test steps required waiting.
+	 *  Returns false if we have to wait for an event before
+	 *  continuing.
+	 */
+	private function runSteps():Boolean
+	{
+		while (currentIndex < numSteps)
+		{
+			// return if a step failed
+			if (testResult.hasStatus()) 
+				return true;
+							
+			/* 
+			    The following lets you step each step but makes tests
+			    more sensitive to which step actually sends the event.
+				For example, cb.mouseDown/mouseUp, the tween starts on
+				mousedown and fires its event before you step.  Another
+				example is asserting with waitEvent=updateComplete.  It
+				could have fired a long time before you step
+			*/
+			if (UnitTester.playbackControl == "pause")
+			{
+				UnitTester.callback = pauseHandler;
+				needCompleteEvent = true;
+				return false;
+			}
+			else if (UnitTester.playbackControl == "step")
+				UnitTester.playbackControl = "pause";
+
+			var step:TestStep = currentSteps[currentIndex];
+			if (!(step is Assert))
+			{
+				// look at subsequent steps for Asserts and set them up early
+				for (var j:int = currentIndex + 1; j < numSteps; j++)
+				{
+					// scan following asserts for AssertEvents and set them up early
+					var nextStep:TestStep = currentSteps[j];
+					if (nextStep is Assert)
+					{
+						Assert(nextStep).preview(root, context, this, testResult);
+						// do a check to be sure folks are using AssertEventPropertyValue correctly
+						if (nextStep is AssertEventPropertyValue)
+						{
+							// AEPV must follow an AssertEvent or another AEPV
+							if (j == 0 || !(currentSteps[j-1] is AssertEvent || currentSteps[j-1] is AssertEventPropertyValue))
+								TestOutput.logResult("WARNING: AssertEventPropertyValue may be missing preceding AssertEvent");
+						}
+						else if (nextStep is AssertError)
+						{
+							if (step is SetProperty)
+								SetProperty(step).expectError = true;
+						}
+					}
+					else
+						break;
+				}
+			}
+			if (UnitTester.verboseMode)
+			{
+				TestOutput.logResult(step.toString());
+			}
+			UnitTester.lastStep = step;
+			UnitTester.lastStepLine = currentIndex;
+			step.addEventListener("stepComplete", stepCompleteHandler);
+			if (!step.execute(root, context, this, testResult))
+			{
+				needCompleteEvent = true;
+				return false;
+			}
+			step.removeEventListener("stepComplete", stepCompleteHandler);
+			currentIndex++;
+		}
+		return true;
+	}
+
+	private function stepCompleteHandler(event:Event):void
+	{
+		var step:TestStep = currentSteps[currentIndex];
+		step.removeEventListener("stepComplete", stepCompleteHandler);
+		if (UnitTester.playbackControl == "play")
+			UnitTester.callback = runNextSteps;
+		else
+		{
+			currentIndex++;
+			UnitTester.callback = pauseHandler;
+		}
+	}
+
+
+	/**
+	 *  Handler for timer events to see if we've waited too long
+	 */
+	private function timerHandler(event:Event):void
+	{
+		if (expirationTime > 0)
+			if (expirationTime < getTimer())
+			{
+				var step:TestStep = currentSteps[currentIndex];
+				step.timeoutCallback();
+			}
+	}
+
+	/**
+	 *  Determines which set of steps (setup, body, cleanup) to run next
+	 */
+	private function runNextSteps():void
+	{
+		currentIndex++;
+		if (currentSteps == setup)
+			runSetup(true);
+		else if (currentSteps == body)
+			runBody(true);
+		else if (currentSteps == cleanup)
+			runCleanup(true);
+		else
+			runComplete();
+	}
+
+	/**
+	 *  Determines which set of steps (setup, body, cleanup) to run next
+	 */
+	private function continueSteps():void
+	{
+		if (currentSteps == setup)
+			runSetup(true);
+		else if (currentSteps == body)
+			runBody(true);
+		else if (currentSteps == cleanup)
+			runCleanup(true);
+		else
+			runComplete();
+	}
+
+	/**
+	 *  Determines which set of steps (setup, body, cleanup) to run next
+	 */
+	private function pauseHandler():void
+	{
+		if (UnitTester.playbackControl == "step")
+			continueSteps();
+		else if (UnitTester.playbackControl == "play")
+			continueSteps();
+		else
+			UnitTester.callback = pauseHandler;
+	}
+}
+
+}

Propchange: incubator/flex/trunk/mustella/as3/src/mustella/TestCase.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/mustella/as3/src/mustella/TestOutput.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/TestOutput.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/TestOutput.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/TestOutput.as Wed May  2 22:44:38 2012
@@ -0,0 +1,65 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.EventDispatcher;
+import flash.events.Event;
+import flash.events.IEventDispatcher;
+
+/**
+ *  The class that handles redirectable output
+ *  The default here is trace, but you can
+ *  set the output handler to something else
+ */
+public class TestOutput extends EventDispatcher
+{
+	/** 
+	 *  Send the string to the output handler
+	 */
+	public static function logResult(result:String):void
+	{
+		getInstance().dispatchEvent(new MustellaLogEvent ("result", result));
+	}
+
+
+	private static var theInst:TestOutput = null;
+
+	public static function getInstance():TestOutput
+	{
+		if (theInst == null) {
+			theInst = new TestOutput();
+			trace ("Created new test output instance");
+		}
+
+		return theInst;
+		
+	}
+
+	
+
+	/**
+	 *  By default, here, send the output to trace. Mixin something else, and 
+	 *  with its own outputHandler function to override this.
+	 */
+	public static var outputHandler:Function = function(s:String):void {trace(s)};
+
+}
+
+}

Propchange: incubator/flex/trunk/mustella/as3/src/mustella/TestOutput.as
------------------------------------------------------------------------------
    svn:eol-style = native