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 [15/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/EffectTesting.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/EffectTesting.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/EffectTesting.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/EffectTesting.as Wed May 2 22:44:38 2012
@@ -0,0 +1,648 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.TimerEvent;
+ import flash.utils.Timer;
+ import flash.utils.getQualifiedClassName;
+
+ import mx.collections.ArrayCollection;
+ import mx.core.IVisualElement;
+ import mx.core.IVisualElementContainer;
+ import mx.core.UIComponent;
+ import mx.effects.CompositeEffect;
+ import mx.effects.Effect;
+ import mx.events.EffectEvent;
+ import mx.geom.TransformOffsets;
+ import mx.states.Transition;
+
+ import spark.primitives.supportClasses.GraphicElement;
+
+ /**
+ *
+ * This class provides some APIs that can be useful for writing Mustella effects
+ * and transitions tests. This will be instrumental in the Catalyst matrix tests.
+ *
+ * It might be useful to think about building a set of TestStep classes that wrap
+ * some of this functionality.
+ *
+ * @author Steven Shongrunden (stshongr@adobe.com)
+ *
+ */
+ public class EffectTesting
+ {
+ // whether to seek the effect on effectStart (default: false)
+ public static var requestedSeek:Boolean = false;
+
+ // what time to seek to in an effect (default: NaN - seek to the end of the effect)
+ public static var requestedSeekTime:Number = NaN;
+
+ // the current effect being played
+ [Bindable] public static var currentEffect:Effect;
+
+ // the document that ready events will be dispatched from and transitions will be pulled from
+ private static var rootDocument:UIComponent;
+
+ // the character used to separate the elements in the expected values string
+ private static var elementSeparator:String = "|";
+
+ // the character used to separate the values in the expected values string
+ private static var propertySeparator:String = ",";
+
+ // keep track of the details of the latest comparison to ease further investigation
+ private static var lastResult:ArrayCollection;
+
+ /**
+ * Sets up for an effect test. This allows you to seek to a specific time in an effect.
+ *
+ * Call this method after the ResetComponent in your (non-transition) effects test.
+ */
+ public static function setupEffectTest(document:Object, effect:Effect):String {
+
+ // reset the test properties
+ resetProperties(document);
+
+ // null check the effect
+ if (effect == null)
+ throw new Error("ERROR: You must provide a non-null effect to test.");
+
+ // set the current effect
+ currentEffect = effect;
+
+ // handle the effectEnd event
+ currentEffect.removeEventListener(EffectEvent.EFFECT_END, handleEffectEnd);
+ currentEffect.addEventListener(EffectEvent.EFFECT_END, handleEffectEnd);
+
+ // dispatches a setupComplete event and returns setupComplete String so you can
+ // use this with either an AssertMethodValue or RunCode in Mustella
+ rootDocument.dispatchEvent(new Event('setupComplete'));
+ return "setupComplete";
+ }
+
+ /**
+ * Sets up for a transitions test. This allows you to seek to a specific time in a transition.
+ *
+ * It parses all of the transitions in a document and sets up event listeners in a way that allows
+ * seeking to a specific time in the transition.
+ *
+ * Call this method after the ResetComponent in your transitions test.
+ */
+ public static function setupTransitionTest(document:Object):String {
+
+ resetProperties(document);
+
+ var transitions:Array = rootDocument.transitions;
+
+ // don't manage any listeners if there aren't any transitions
+ if (transitions == null)
+ throw new Error("ERROR: document has no transitions");
+
+ // add event listeners to each transition
+ for each (var t:Transition in transitions){
+
+ // remove the effectStart event listener and add it again so we don't pile them up
+ t.effect.removeEventListener(EffectEvent.EFFECT_START, handleEffectStart);
+ t.effect.addEventListener(EffectEvent.EFFECT_START, handleEffectStart);
+
+ // remove the effectEnd event listener and add it again so we don't pile them up
+ t.effect.removeEventListener(EffectEvent.EFFECT_END, handleEffectEnd);
+ t.effect.addEventListener(EffectEvent.EFFECT_END, handleEffectEnd);
+ }
+
+ // dispatches a setupComplete event and returns setupComplete String so you can
+ // use this with either an AssertMethodValue or RunCode in Mustella
+ rootDocument.dispatchEvent(new Event('setupComplete'));
+ return "setupComplete";
+ }
+
+ /**
+ * Called by the setup methods to reset the properties in this class
+ */
+ private static function resetProperties(document:Object):void {
+
+ // null checks
+ if (document == null)
+ throw new Error("ERROR: You must provide a non-null document.");
+
+ if (!(document is UIComponent))
+ throw new Error("ERROR: document must be a UIComponent");
+
+ // reset the rootDocument
+ rootDocument = document as UIComponent;
+
+ // reset the seek information
+ requestedSeek = false;
+ requestedSeekTime = NaN;
+ }
+
+ /**
+ * Called on effect start, kicks off the seek behavior if it is requested.
+ */
+ private static function handleEffectStart(event:EffectEvent):void {
+ trace('effect start');
+
+ currentEffect = event.target as Effect;
+
+ // seek if it was requested
+ if (requestedSeek){
+
+ // wait roughly a frame then pause the effect before seeking
+ var timer:Timer = new Timer(0);
+ timer.repeatCount = 1;
+ timer.addEventListener(TimerEvent.TIMER, function(e:Event):void{ seekCurrentEffect(); });
+ timer.start();
+ }
+ }
+
+ /**
+ * Pauses then seeks to the position in the current effect. Fires an event when that is done.
+ */
+ public static function seekCurrentEffect():void {
+ var seekTime:Number = requestedSeekTime;
+ var c:CompositeEffect = currentEffect as CompositeEffect;
+
+ // seek to the end if a specific seek time was not requested
+ if (isNaN(seekTime)){
+ // set the seekTime to the end of the effect
+ if (c){
+ // if its a Parallel/Sequence then use the compositeDuration that also handle startDelay
+ seekTime = c.compositeDuration;
+ } else {
+ // just a plain effect so use startDelay + duration
+ seekTime = currentEffect.startDelay + currentEffect.duration;
+ }
+ }
+
+ trace('effect seek to ' + seekTime);
+
+ // pause then seek
+ currentEffect.pause();
+ currentEffect.playheadTime = seekTime;
+
+ // dispatch a ready event on the document
+ rootDocument.dispatchEvent(new Event("seekAssertionReady"));
+ }
+
+ /**
+ * TODO: The inclusion of this method in the API is not fully baked.
+ * This method's name/signature/existance could change in the future
+ * when it is properly implemented.
+ */
+ public static function seekCurrentEffectTo(time:Number):void {
+ currentEffect.playheadTime = time;
+ rootDocument.dispatchEvent(new Event("seekAssertionReady"));
+ }
+
+ /**
+ * TODO: The inclusion of this method in the API is not fully baked.
+ * This method's name/signature/existance could change in the future
+ * when it is properly implemented.
+ */
+ public static function getCurrentEffectDuration():Number {
+ var c:CompositeEffect = currentEffect as CompositeEffect;
+
+ if (c){
+ // if its a Parallel/Sequence then use the compositeDuration that also handle startDelay
+ return c.compositeDuration;
+ } else {
+ // just a plain effect so use startDelay + duration
+ return currentEffect.startDelay + currentEffect.duration;
+ }
+ }
+
+ /**
+ * Resumes the current effect
+ */
+ public static function resumeCurrentEffect():void {
+ trace("effect resume");
+ currentEffect.resume();
+ }
+
+ /**
+ * Fires an event after the effectEnd event that signifies an assertion is now valid.
+ *
+ * In a transition this gets called after the state values have been slammed in.
+ */
+ private static function handleEffectEnd(e:EffectEvent):void {
+ trace('effect end');
+
+ // dispatch a ready event on the document
+ rootDocument.dispatchEvent(new Event("endAssertionReady"));
+ }
+
+ /**
+ * Given a root element it compares a set of properties across that element and any of its ancestors.
+ *
+ * Sample usage:
+ *
+ * assertPropertySet(test1, 'width, height', '70,22|10,10', 0)
+ * outputs: 'FAIL: test1.width: expected 70 +/- 0, but received 100')
+ *
+ * @param rootContainer - the root element to inspect
+ * @param propertyNameString - a string deliminated with a character that lists the properties to inspect
+ * @param expectedValuesString - a string deliminiated with a character that lists the values to expect
+ * @param tolerance - the amount of difference between actual and expected is allowed before failure
+ * @param depth - how deep to recurse in the rootContainer
+ *
+ * @return - a string of either "PASS" or "FAIL: ..." with a failure message
+ */
+ public static function assertPropertySet(rootContainer:IVisualElement, propertyNamesString:String,
+ expectedValuesString:String, tolerance:Number = 0, depth:int = -1):String {
+ return checkPropertySet(rootContainer, false, propertyNamesString, expectedValuesString, tolerance, depth);
+ }
+
+ /**
+ * Given a root element it compares a set of properties across that element and any of its ancestors
+ * using the postLayoutTransformOffsets object of those elements.
+ *
+ * Sample usage:
+ *
+ * assertPostLayoutPropertySet(test1, 'rotationX, rotationY', '45,45|0,0', 0)
+ * outputs: 'FAIL: test1.rotationX: expected 45 +/- 0, but received 0')
+ *
+ * Use null as an expected value if postLayoutTransformOffsets is null for example:
+ * - properties: 'rotationX,rotationY'
+ * - expected string: 'null,null|null,null'
+ *
+ * @param rootContainer - the root element to inspect
+ * @param propertyNameString - a string deliminated with a character that lists the properties to inspect
+ * @param expectedValuesString - a string deliminiated with a character that lists the values to expect
+ * @param tolerance - the amount of difference between actual and expected is allowed before failure
+ * @param depth - how deep to recurse in the rootContainer
+ *
+ * @return - a string of either "PASS" or "FAIL: ..." with a failure message
+ */
+ public static function assertPostLayoutPropertySet(rootContainer:IVisualElement, propertyNamesString:String,
+ expectedValuesString:String, tolerance:Number = 0, depth:int = -1):String {
+ return checkPropertySet(rootContainer, true, propertyNamesString, expectedValuesString, tolerance, depth);
+ }
+
+ /**
+ * Workhorse method that is exposed via the two public assert methods.
+ *
+ * Given a root element it compares a set of properties across that element and any of its ancestors
+ *
+ * @param rootContainer - the root element to inspect
+ * @param postLayout - whether to look at the postLayoutTransformOffsets object of an element
+ * @param propertyNameString - a string deliminated with a character that lists the properties to inspect
+ * @param expectedValuesString - a string deliminiated with a character that lists the values to expect
+ * @param tolerance - the amount of difference between actual and expected is allowed before failure
+ * @param depth - how deep to recurse in the rootContainer
+ *
+ * @return - a string of either "PASS" or "FAIL: ..." with a failure message
+ *
+ */
+ private static function checkPropertySet(rootContainer:IVisualElement, postLayout:Boolean, propertyNamesString:String,
+ expectedValuesString:String, tolerance:Number = 0, depth:int = -1):String {
+
+ // reset the result of the last comparison
+ // add to this collection at any point a comparison happens
+ lastResult = new ArrayCollection();
+
+ // get the list of elements to inspect properties of
+ var elementsToInspect:Array = getElementsToInspect(rootContainer, depth);
+
+ // get the list of properties to inspect on each element
+ var propertyNames:Array = getPropertyNames(propertyNamesString);
+
+ // split up the expectedValue string into values for each element
+ var expectedElementValues:Array = expectedValuesString.split(elementSeparator);
+
+ // string that represents the reason for fail
+ var failString:String = "";
+
+ if (elementsToInspect.length != expectedElementValues.length){
+ // this will also catch existance failures, for example if an
+ // element is supposed to be included or excluded from a state
+ failString = "FAIL: number of elements (" + elementsToInspect.length + ") != number of expected elements (" + expectedElementValues.length + ")";
+ logResult(failString);
+ return failString;
+ }
+
+ // Go through each of the elements recursively in the rootContainer
+ for (var i:int = 0; i < elementsToInspect.length; i++){
+ var element:IVisualElement = elementsToInspect[i];
+ var expectedPropertyValues:Array = expectedElementValues[i].split(propertySeparator);
+
+ // check for a malformed expected string
+ if (propertyNames.length != expectedPropertyValues.length){
+ failString = "FAIL: number of properties != number of expected values for " + getElementId(element);
+ logResult(failString);
+ return failString;
+ }
+
+ // log that we are checking this property
+ logResult(getElementId(element));
+
+ // check each property value
+ for (var j:int = 0; j < propertyNames.length; j++){
+
+ var propertyName:String = propertyNames[j];
+ var e:* = expectedPropertyValues[j];
+ var a:*;
+
+ // First need to decide whether to grab the property values from
+ // the element or its postLayoutTransformOffsets
+ if (postLayout){
+ if (element.postLayoutTransformOffsets){
+ a = element.postLayoutTransformOffsets[propertyName];
+ } else {
+ a = null;
+ }
+ } else {
+ a = element[propertyName];
+ }
+
+ // prepare the log object for this property
+ var logItem:Object = new Object();
+ logItem.target = getElementId(element);
+ logItem.propertyName = propertyName;
+ logItem.actual = a;
+ logItem.expected = e;
+ logItem.tolerance = tolerance;
+ logItem.postLayout = postLayout;
+ logItem.depth = "TODO"; // TODO: one day might want to keep track of the depth of this item
+ logItem.result = "Unknown";
+
+ //
+ // String comparison
+ //
+
+ // First just check if expected == actual via a simple string comparison.
+ // If so then move on to the next propertyName, otherwise investigate further
+ // via null and number comparisons.
+ if (String(e) == String(a)){
+ // this property passed
+
+ // log the pass
+ logResult("PASS", logItem);
+
+ continue;
+ }
+
+ //
+ // Null comparison
+ //
+
+ // expected == actual == null so this is fine, continue to next propertyName
+ if (e == 'null' && a == null){
+
+ // log the pass
+ logResult("PASS", logItem);
+
+ continue;
+ }
+
+ // expected or actual is null, but not both (because of above) so fail
+ if (e == 'null' || a == null){
+ failString = "FAIL: " + describeFailureLocation(element, propertyName, postLayout) + ": " + a + ", but expected " + e;
+
+ // log the fail
+ logResult(failString, logItem);
+
+ return failString;
+ }
+
+ //
+ // Number comparison
+ //
+
+ // This approach assumes that it's ok treating undefined and NaN the same.
+ // This is because Number(undefined) gets turned into NaN, if this is a limitation
+ // might have to revisit this in the future.
+ var expectedValue:Number = Number(e);
+ var actualValue:Number = Number(a);
+
+ //
+ // NaN comparison
+ //
+
+ // expected == actual == NaN, so this is fine, continue to next propertyName
+ if (isNaN(actualValue) && isNaN(expectedValue)){
+
+ // log the pass
+ logResult("PASS", logItem);
+
+ continue;
+ }
+
+ // expected or actual is NaN, but not both (because of above) so fail
+ if (isNaN(actualValue) || isNaN(expectedValue)){
+ failString = "FAIL: " + describeFailureLocation(element, propertyName, postLayout) + ": expected " +
+ expectedValue + ' plus or minus ' + tolerance + ", but received " + actualValue;
+
+ // log the fail
+ logResult(failString, logItem);
+
+ return failString;
+ }
+
+ //
+ // Number tolerance comparison
+ //
+
+ // expected differs from actual by more than the tolerance so fail
+ if (Math.abs(actualValue - expectedValue) > tolerance){
+ failString = "FAIL: " + describeFailureLocation(element, propertyName, postLayout) + ": expected " +
+ expectedValue + ' plus or minus ' + tolerance + ", but received " + actualValue;
+
+ // log the fail
+ logResult(failString, logItem);
+
+ return failString;
+ }
+
+ // at this point the property passed
+
+ // log the pass
+ logResult("PASS", logItem);
+ }
+ // at this point the element passed, no need to log here
+ }
+
+ return "PASS";
+ }
+
+ /**
+ * Adds a result to the log.
+ *
+ * @param result - a simple string to add to the log
+ * @param details - an object that if not null is added to the log after setting details.result equal to the first parameter
+ */
+ private static function logResult(result:String, details:Object = null):void {
+ if (details != null){
+ details.result = result;
+ lastResult.addItem(details);
+ } else {
+ lastResult.addItem(result);
+ }
+ }
+
+ /**
+ * Returns the log of the last assertion result
+ */
+ public static function getLastResult():ArrayCollection {
+ return lastResult;
+ }
+
+ /**
+ * Generates a string that describes what property of what element has failed.
+ *
+ * ex:
+ * target.width
+ * target.postLayoutTransformOffsets.width
+ */
+ private static function describeFailureLocation(element:IVisualElement, propertyName:String, postLayout:Boolean):String{
+ var output:String = "";
+
+ output += getElementId(element);
+
+ if (postLayout)
+ output += ".postLayoutTransformOffsets";
+
+ output += "." + propertyName;
+
+ return output;
+ }
+
+ /**
+ * Given a root element and a string of property names this returns the formatted string of
+ * each property value against that element and all descendants in a format that the assertion
+ * methods require.
+ *
+ * @param rootContainer
+ * @param propertyNamesString - ex: 'width, height, alpha'
+ * @param postLayout - set to true if you want to access the properties of the postLayoutTransformOffsets
+ * @param requestedDepth - the depth to recurse (-1 by default for full recursion)
+ *
+ * @return string
+ */
+ public static function generatePropertySet(rootContainer:IVisualElement, propertyNamesString:String, postLayout:Boolean = false, requestedDepth:int = -1):String {
+ // get the list of elements to inspect properties of
+ var elementsToInspect:Array = getElementsToInspect(rootContainer, requestedDepth);
+ var propertyNames:Array = getPropertyNames(propertyNamesString);
+ var output:String = "";
+
+ // for each element
+ for (var i:int = 0; i < elementsToInspect.length; i++){
+ var e:IVisualElement = elementsToInspect[i];
+
+ // for each property
+ for (var j:int = 0; j < propertyNames.length; j++){
+ // the property name
+ var propertyName:String = propertyNames[j];
+
+ // concatenate the value
+ if (postLayout){
+ if (e.postLayoutTransformOffsets){
+ // access the value via the transform offsets
+ output += e.postLayoutTransformOffsets[propertyName];
+ } else {
+ // the transform offsets are null
+ output += "null";
+ }
+ } else {
+ // access the value directly
+ output += e[propertyName];
+ }
+
+ // concatenate the value separator
+ if (j < propertyNames.length - 1)
+ output += ",";
+ }
+
+ // concatenate the element separator
+ if (i < elementsToInspect.length - 1)
+ output += elementSeparator;
+ }
+
+ return output;
+ }
+
+ /**
+ * Returns an array of property names parsed from a comma separated string with
+ * spaces removed.
+ */
+ private static function getPropertyNames(s:String):Array {
+ // strip spaces
+ while (s.indexOf(" ") != -1){
+ s = s.replace(' ','');
+ }
+
+ return s.split(propertySeparator);
+ }
+
+ /**
+ * Returns the id of an element, if one is not defined then it returns the class name
+ */
+ private static function getElementId(element:IVisualElement):String {
+ var s:String = String(Object(element).id);
+
+ return (s != "null") ? s : flash.utils.getQualifiedClassName(element).split("::")[1];
+ }
+
+ /**
+ * Returns an array of all elements in a root element. If the element is not a
+ * container then it just returns an array of that element.
+ */
+ public static function getElementsToInspect(root:IVisualElement, requestedDepth:int):Array {
+ var output:Array = new Array();
+
+ if (root is IVisualElementContainer){
+ // if its a container then recursively get all the elements to requestedDepth
+ output = getDescendants(root as IVisualElementContainer, requestedDepth);
+ } else {
+ // just return the element
+ output.push(root);
+ }
+
+ return output;
+ }
+
+ /**
+ * Recursively generates an array of all elements in a given container (including itself) to a requested depth
+ */
+ private static function getDescendants(rootContainer:IVisualElementContainer, requestedDepth:int, depth:int = 0):Array{
+ var output:Array = new Array();
+
+ // push the container element
+ output.push(rootContainer);
+
+ // return if we've gone past the requested depth (and a requestedDepth of not -1)
+ if (requestedDepth != -1 && (depth >= requestedDepth)){
+ return output;
+ }
+
+ for (var i:int = 0; i < rootContainer.numElements; i++){
+ var e:IVisualElement = rootContainer.getElementAt(i);
+ if (e is IVisualElementContainer){
+ // recursively get the elements of the container
+ output = output.concat(getDescendants(e as IVisualElementContainer, requestedDepth, depth+1));
+ } else {
+ // push the non-container element
+ output.push(e);
+ }
+ }
+
+ return output;
+ }
+
+ }
+}
\ No newline at end of file
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/EffectTesting.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/EnableRemoteImageDiff.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/EnableRemoteImageDiff.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/EnableRemoteImageDiff.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/EnableRemoteImageDiff.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 EnableRemoteImageDiff
+{
+
+ /**
+ * Mixin callback that gets everything ready to go.
+ * The UnitTester waits for an event before starting
+ */
+ public static function init(root:DisplayObject):void
+ {
+ CompareBitmap.useRemoteDiffer = true;
+ }
+
+
+}
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/EnableRemoteImageDiff.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/EventSnifferRemote.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/EventSnifferRemote.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/EventSnifferRemote.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/EventSnifferRemote.as Wed May 2 22:44:38 2012
@@ -0,0 +1,154 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.FocusEvent;
+import flash.events.KeyboardEvent;
+import flash.events.MouseEvent;
+import flash.events.StatusEvent;
+import flash.net.LocalConnection;
+
+import mx.core.FlexGlobals;
+import mx.core.IFlexDisplayObject;
+import mx.core.IMXMLObject;
+import mx.core.UIComponent;
+import mx.core.mx_internal;
+use namespace mx_internal;
+
+[Mixin]
+/**
+ * Traps most events and records them to SnifferRemoteClient.swf
+ */
+public class EventSnifferRemote
+{
+ public function EventSnifferRemote()
+ {
+ }
+
+ public static function init(root:Object):void
+ {
+ document = root;
+ if (document)
+ document.addEventListener("applicationComplete", initHandler);
+
+ connection = new LocalConnection();
+ connection.allowDomain("*");
+ connection.addEventListener(StatusEvent.STATUS, statusHandler);
+
+ commandconnection = new LocalConnection();
+ commandconnection.allowDomain("*");
+ commandconnection.client = EventSnifferRemote;
+ commandconnection.connect("_EventSnifferCommands");
+ }
+
+ // Turn on only if the SnifferRemoteClient app's checkbox
+ // for this item is checked.
+ private static function initHandler(event:Event):void
+ {
+ connection.send("_EventSniffer", "toggleSniffersEnabled");
+ }
+
+ private static function statusHandler(event:Event):void
+ {
+ }
+
+ /**
+ * @private
+ * The document containing a reference to this object
+ */
+ private static var document:Object;
+
+ /**
+ * @private
+ * The local connection to the remote client
+ */
+ private static var connection:LocalConnection;
+ private static var commandconnection:LocalConnection;
+
+ public static function enableSniffer():void
+ {
+ //trace("EventSnifferRemote enabled");
+
+ // hook UIComponent so we can see all events
+ UIComponent.dispatchEventHook = dispatchEventHook;
+ document.stage.addEventListener(MouseEvent.CLICK, uberListener, true);
+ document.stage.addEventListener(MouseEvent.DOUBLE_CLICK, uberListener, true);
+ document.stage.addEventListener(MouseEvent.MOUSE_DOWN, uberListener, true);
+ document.stage.addEventListener(MouseEvent.MOUSE_MOVE, uberListener, true);
+ document.stage.addEventListener(MouseEvent.MOUSE_OUT, uberListener, true);
+ document.stage.addEventListener(MouseEvent.MOUSE_OVER, uberListener, true);
+ document.stage.addEventListener(MouseEvent.MOUSE_UP, uberListener, true);
+ document.stage.addEventListener(MouseEvent.MOUSE_WHEEL, uberListener, true);
+ document.stage.addEventListener(MouseEvent.ROLL_OUT, uberListener, true);
+ document.stage.addEventListener(MouseEvent.ROLL_OVER, uberListener, true);
+ document.stage.addEventListener(KeyboardEvent.KEY_UP, uberListener, true);
+ document.stage.addEventListener(KeyboardEvent.KEY_DOWN, uberListener, true);
+ document.stage.addEventListener(FocusEvent.FOCUS_IN, uberListener, true);
+ document.stage.addEventListener(FocusEvent.FOCUS_OUT, uberListener, true);
+ }
+
+ public static function disableSniffer():void
+ {
+ //trace("EventSnifferRemote disabled");
+
+ // unhook UIComponent so we can see all events
+ UIComponent.dispatchEventHook = null;
+ document.stage.removeEventListener(MouseEvent.CLICK, uberListener, true);
+ document.stage.removeEventListener(MouseEvent.DOUBLE_CLICK, uberListener, true);
+ document.stage.removeEventListener(MouseEvent.MOUSE_DOWN, uberListener, true);
+ document.stage.removeEventListener(MouseEvent.MOUSE_MOVE, uberListener, true);
+ document.stage.removeEventListener(MouseEvent.MOUSE_OUT, uberListener, true);
+ document.stage.removeEventListener(MouseEvent.MOUSE_OVER, uberListener, true);
+ document.stage.removeEventListener(MouseEvent.MOUSE_UP, uberListener, true);
+ document.stage.removeEventListener(MouseEvent.MOUSE_WHEEL, uberListener, true);
+ document.stage.removeEventListener(MouseEvent.ROLL_OUT, uberListener, true);
+ document.stage.removeEventListener(MouseEvent.ROLL_OVER, uberListener, true);
+ document.stage.removeEventListener(KeyboardEvent.KEY_UP, uberListener, true);
+ document.stage.removeEventListener(KeyboardEvent.KEY_DOWN, uberListener, true);
+ document.stage.removeEventListener(FocusEvent.FOCUS_IN, uberListener, true);
+ document.stage.removeEventListener(FocusEvent.FOCUS_OUT, uberListener, true);
+ }
+
+ private static function uberListener(event:Event):void
+ {
+ dispatchEventHook(event, DisplayObject(event.target));
+ }
+
+ private static function dispatchEventHook(event:Event, target:DisplayObject):void
+ {
+
+ // connection.send("_EventSniffer", "appendLog", "Event", target.toString(), event.type, event.toString());
+
+ // This is the appendLog method in SnifferRemoteClient which will accept this:
+ // public function appendLog(dataSource:String = null, target:String=null, eventName:String = null, event:String = null):void
+
+ var info:Object = new Object();
+
+ info.dataSource = "Event";
+ info.target = target.toString();
+ info.eventName = event.type;
+ info.event = event.toString();
+
+ connection.send("_EventSniffer", "appendLog", info);
+ }
+}
+
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/EventSnifferRemote.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/ExcludeFileLocation.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/ExcludeFileLocation.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/ExcludeFileLocation.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/ExcludeFileLocation.as Wed May 2 22:44:38 2012
@@ -0,0 +1,224 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.URLLoader;
+import flash.net.URLRequest;
+import flash.events.Event;
+import flash.system.Capabilities;
+
+[Mixin]
+/**
+ * Location of a hash table of tests not to run.
+ * This mixin should find the excludes written to one of two locations.
+ * Browsers runs are picky about where they find the excludes, so, we serve them
+ * up via http (in a sibling location to the tests).
+ * The file is one test per line of the form ScriptName$TestID
+ * The location of the file is assumed to be c:/temp on windows,
+ * or /tmp on Unix.
+ */
+public class ExcludeFileLocation
+{
+
+ private static var loader:URLLoader;
+
+ public static var url:String;
+ public static var mustellaDir:String;
+
+ public static var frontURL:String;
+ public static var domain:String;
+
+ public static var excludeFile:String;
+
+ /**
+ * tell UnitTester it should wait for this load to complete
+ */
+ UnitTester.waitForExcludes = true;
+
+
+ public static var _root:DisplayObject;
+
+
+ public static var triedBrowser:Boolean = false;
+ public static var triedNormal:Boolean = false;
+
+ // we try the http spot, in case this is a browser run
+ public static function init(root:DisplayObject):void
+ {
+
+ trace ("Hello from excludes at: " + new Date());
+
+
+ var os:String = Capabilities.os;
+
+
+ if (os.indexOf ("Windows") != -1)
+ {
+ excludeFile = "ExcludeListWin.txt";
+ } else if (os.indexOf ("Mac") != -1)
+ {
+ excludeFile = "ExcludeListMac.txt";
+ } else if (os.indexOf ("Linux") != -1)
+ {
+ excludeFile = "ExcludeListLinux.txt";
+ } else
+ {
+ trace ("Excludes: bad: we didn't see an OS we liked: " + os);
+ excludeFile = "ExcludeListWin.txt";
+ }
+
+
+ _root = root;
+
+ url = root.loaderInfo.url;
+
+ mustellaDir = url.substring (0, url.indexOf ("mustella/tests")+14);
+
+ frontURL = url.substring (0, url.indexOf (":"));
+
+ domain = url.substring (url.indexOf (":")+3);
+ domain = domain.substring (0, domain.indexOf ("/"));
+
+ if (Capabilities.playerType == "PlugIn" || Capabilities.playerType == "ActiveX")
+ {
+ loadTryBrowser();
+ } else
+ {
+ loadTryNormal();
+
+ }
+
+ }
+
+
+
+ public static function loadTryBrowser():void
+ {
+ trace ("excludes loadTryBrowser at: " + new Date().toString());
+
+ triedBrowser = true;
+
+ var currentOS:String = Capabilities.os;
+
+ var useFile:String = "http://localhost/" + excludeFile;
+
+ trace ("try excludes from here: " + useFile);
+
+ var req:URLRequest = new URLRequest(useFile);
+ loader = new URLLoader();
+ loader.addEventListener("complete", completeHandler);
+ loader.addEventListener("securityError", errorHandler);
+ loader.addEventListener("ioError", errorHandler);
+ loader.load(req);
+
+ }
+
+ /// if it worked, all good
+ private static function completeHandler(event:Event):void
+ {
+ trace ("Excludes: from web server");
+ postProcessData(event);
+ }
+
+
+ /**
+ * A non-browser will get its results from the /tmp location.
+ * It should be a failure to get here; we try the browser case first
+ * because it throws a nasty seciry
+ *
+ */
+ public static function errorHandler(event:Event):void
+ {
+
+ trace ("Exclude: in the web read error handler");
+ if (!triedNormal)
+ {
+ loadTryNormal();
+
+ }
+
+ }
+ public static function loadTryNormal():void
+ {
+
+ triedNormal = true;
+
+ trace ("excludes loadTryFile " + new Date().toString());
+
+ var currentOS:String = Capabilities.os;
+
+ var useFile:String;
+
+ useFile = mustellaDir +"/" + excludeFile;
+
+ trace ("Exclude: try load from: " + useFile);
+
+ var req:URLRequest = new URLRequest(useFile);
+ loader = new URLLoader();
+ loader.addEventListener("complete", completeHandler2);
+ loader.addEventListener("ioError", errorHandler2);
+ loader.addEventListener("securityError", errorHandler2);
+ loader.load(req);
+
+ }
+
+ private static function errorHandler2(event:Event):void
+ {
+ trace ("Exclude: error in the exclude file load " +event);
+ if (!triedBrowser)
+ {
+ loadTryBrowser();
+ }
+
+ }
+
+
+ private static function completeHandler2(event:Event):void
+ {
+ trace ("Excludes: Reading from file system at "+mustellaDir );
+ postProcessData(event);
+ }
+ private static function postProcessData(event:Event):void
+ {
+ var data:String = loader.data;
+ // DOS end of line
+ var delimiter:RegExp = new RegExp("\r\n", "g");
+ data = data.replace(delimiter, ",");
+ // Unix end of line
+ delimiter = new RegExp("\n", "g");
+ data = data.replace(delimiter, ",");
+
+ UnitTester.excludeList = new Object();
+ var items:Array = data.split(",");
+ var n:int = items.length;
+ for (var i:int = 0; i < n; i++)
+ {
+ var s:String = items[i];
+ if (s.length)
+ UnitTester.excludeList[s] = 1;
+
+ }
+
+ UnitTester.waitForExcludes = false;
+ UnitTester.pre_startEventHandler(event);
+ }
+}
+
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/ExcludeFileLocation.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/ExcludeFileLocationApollo.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/ExcludeFileLocationApollo.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/ExcludeFileLocationApollo.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/ExcludeFileLocationApollo.as Wed May 2 22:44:38 2012
@@ -0,0 +1,285 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.URLLoader;
+import flash.net.URLRequest;
+import flash.events.Event;
+import flash.system.Capabilities;
+import flash.filesystem.File;
+
+[Mixin]
+/**
+ * Location of a hash table of tests not to run.
+ * This mixin should find the excludes written to one of two locations.
+ * Browsers runs are picky about where they find the excludes, so, we serve them
+ * up via http (in a sibling location to the tests).
+ * The file is one test per line of the form ScriptName$TestID
+ * The location of the file is assumed to be c:/temp on windows,
+ * or /tmp on Unix.
+ */
+public class ExcludeFileLocationApollo
+{
+
+ private static var loader:URLLoader;
+
+ private static var url:String;
+ private static var mustellaDir:String;
+
+ private static var frontURL:String;
+ private static var domain:String;
+
+ public static var excludeFile:String = "ExcludeList.txt";
+
+ /**
+ * tell UnitTester it should wait for this load to complete
+ */
+ UnitTester.waitForExcludes = true;
+
+
+ public static var _root:DisplayObject;
+
+
+ public static var triedBrowser:Boolean = false;
+ public static var triedNormal:Boolean = false;
+
+ // we try the http spot, in case this is a browser run
+ public static function init(root:DisplayObject):void
+ {
+
+ trace ("Hello from excludes at: " + new Date());
+
+ var os:String = Capabilities.os;
+
+ // This seems to be a timing issue which pops up on some machines.
+ if( UnitTester.cv == null ){
+ UnitTester.cv = new ConditionalValue();
+ }
+
+ if( (UnitTester.cv.os != null) && (UnitTester.cv.os.toLowerCase() == DeviceNames.ANDROID.toLowerCase()) ){
+ mustellaDir = "..";
+ excludeFile = UnitTester.excludeFile;
+ trace("Doing Android style exclude. Checking in " + mustellaDir + "/" + excludeFile);
+ }else if( (UnitTester.cv.os != null) && (UnitTester.cv.os.toLowerCase() == DeviceNames.IOS.toLowerCase()) ){
+ mustellaDir = File.documentsDirectory.url;
+ excludeFile = UnitTester.excludeFile;
+ }else if (os.indexOf ("QNX") > -1) {
+ mustellaDir = "..";
+ excludeFile = UnitTester.excludeFile;
+ trace("Doing QNX style exclude. Checking in " + mustellaDir + "/" + excludeFile);
+ }
+ else{
+
+ if (os.indexOf ("Windows") != -1)
+ {
+ excludeFile = "ExcludeListWin.txt";
+ } else if (os.indexOf ("Mac") != -1)
+ {
+ excludeFile = "ExcludeListMac.txt";
+ } else if (os.indexOf ("Linux") != -1)
+ {
+ excludeFile = "ExcludeListLinux.txt";
+ } else
+ {
+ trace ("Excludes: bad: we didn't see an OS we liked: " + os);
+ excludeFile = "ExcludeListWin.txt";
+ }
+
+ _root = root;
+
+ url = root.loaderInfo.url;
+
+ if (url.indexOf("app:")!=-1)
+ {
+ ApolloFilePath.init (root);
+ url = encodeURI2(ApolloFilePath.apolloAdjust(url));
+ trace ("Adjusting path for AIR to: " + url);
+ // url = adjustPath(url);
+ }
+
+ mustellaDir = url.substring (0, url.indexOf ("mustella/tests")+14);
+ frontURL = url.substring (0, url.indexOf (":"));
+ domain = url.substring (url.indexOf (":")+3);
+ domain = domain.substring (0, domain.indexOf ("/"));
+ }
+
+ loadTryNormal();
+ }
+
+ private static function apolloAdjust(url:String):String
+ {
+
+ var swf:String = _root.loaderInfo.url;
+ var f:File = new File (swf);
+ // clean it up:
+ var myPattern:RegExp = /\\/g;
+ var path:String = f.nativePath;
+ path = path.replace (myPattern, "/");
+ path = path.replace (":", "|");
+ // yank off the swfs directory, which we're in
+ path = path.substr (0, path.lastIndexOf ("/")-1);
+ path = path.substr (0, path.lastIndexOf ("/"));
+
+ if (url.indexOf ("../")==0)
+ url = url.substring (2);
+
+ if (url.indexOf ("/..")==0)
+ {
+ url = url.substring (3);
+ path = path.substr (0, path.lastIndexOf ("/"));
+ }
+
+ /// create the final url
+ path = path + url;
+
+ return "file:///" + path;
+ }
+
+ public static var adjustPath:Function = function(url:String):String { return url; };
+
+
+
+ private static function encodeURI2(s:String):String
+ {
+ var pos:int = s.lastIndexOf("/");
+ if (pos != -1)
+ {
+ var fragment:String = s.substring(pos + 1);
+ s = s.substring(0, pos + 1);
+ fragment= encodeURIComponent(fragment);
+ s = s + fragment;
+ }
+ return s;
+ }
+
+
+ public static function loadTryBrowser():void
+ {
+ trace ("excludes loadTryBrowser at: " + new Date().toString());
+
+ triedBrowser = true;
+
+ var currentOS:String = Capabilities.os;
+
+ var useFile:String = "http://localhost/" + excludeFile;
+
+ trace ("try excludes from here: " + useFile);
+
+ var req:URLRequest = new URLRequest(useFile);
+ loader = new URLLoader();
+ loader.addEventListener("complete", completeHandler);
+ loader.addEventListener("securityError", errorHandler);
+ loader.addEventListener("ioError", errorHandler);
+ loader.load(req);
+
+ }
+
+ /// if it worked, all good
+ private static function completeHandler(event:Event):void
+ {
+ trace ("Excludes: from web server");
+ postProcessData(event);
+ }
+
+
+ /**
+ * A non-browser will get its results from the /tmp location.
+ * It should be a failure to get here; we try the browser case first
+ * because it throws a nasty seciry
+ *
+ */
+ public static function errorHandler(event:Event):void
+ {
+
+ trace ("Exclude: in the web read error handler");
+ if (!triedNormal)
+ {
+ loadTryNormal();
+
+ }
+
+ }
+ public static function loadTryNormal():void
+ {
+
+ triedNormal = true;
+
+ trace ("excludes loadTryFile " + new Date().toString());
+
+ var currentOS:String = Capabilities.os;
+
+ var useFile:String;
+
+ useFile = mustellaDir +"/" + excludeFile;
+
+ trace ("Exclude: try load from: " + useFile);
+
+ var req:URLRequest = new URLRequest(useFile);
+ loader = new URLLoader();
+ loader.addEventListener("complete", completeHandler2);
+ loader.addEventListener("ioError", errorHandler2);
+ loader.addEventListener("securityError", errorHandler2);
+ loader.load(req);
+
+ }
+
+ private static function errorHandler2(event:Event):void
+ {
+ trace ("Exclude: error in the exclude file load " +event);
+ if (!triedBrowser)
+ {
+ loadTryBrowser();
+ }
+
+ }
+
+
+ private static function completeHandler2(event:Event):void
+ {
+ trace ("Excludes: Reading from file system at "+mustellaDir );
+ postProcessData(event);
+ }
+ private static function postProcessData(event:Event):void
+ {
+ var data:String = loader.data;
+ // DOS end of line
+ var delimiter:RegExp = new RegExp("\r\n", "g");
+ data = data.replace(delimiter, ",");
+ // Unix end of line
+ delimiter = new RegExp("\n", "g");
+ data = data.replace(delimiter, ",");
+
+ UnitTester.excludeList = new Object();
+ var items:Array = data.split(",");
+ var n:int = items.length;
+ for (var i:int = 0; i < n; i++)
+ {
+ var s:String = items[i];
+ if (s.length)
+ UnitTester.excludeList[s] = 1;
+
+ }
+
+ UnitTester.waitForExcludes = false;
+ UnitTester.pre_startEventHandler(event);
+ }
+}
+
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/ExcludeFileLocationApollo.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/ExcludeList.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/ExcludeList.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/ExcludeList.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/ExcludeList.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 hash table of tests not to run.
+ */
+public class ExcludeList
+{
+
+ /**
+ * Mixin callback that gets everything ready to go.
+ * Table is of form: ScriptName$TestID: 1,
+ */
+ public static function init(root:DisplayObject):void
+ {
+ UnitTester.excludeList = {
+ CBTester$myButtonTest1: 1,
+ CBTester$myTest2: 1
+ };
+ }
+
+}
+
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/ExcludeList.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/ExcludeList.txt
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/ExcludeList.txt?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/ExcludeList.txt (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/ExcludeList.txt Wed May 2 22:44:38 2012
@@ -0,0 +1 @@
+CBTester$myButtonTest1
\ No newline at end of file
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/ExcludeList.txt
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/ExcludeListTextFile.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/ExcludeListTextFile.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/ExcludeListTextFile.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/ExcludeListTextFile.as Wed May 2 22:44:38 2012
@@ -0,0 +1,71 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.URLLoader;
+import flash.net.URLRequest;
+import flash.events.Event;
+
+[Mixin]
+/**
+ * A hash table of tests not to run, read from ExcludeList.txt
+ * The file is one test per line of the form ScriptName$TestID
+ */
+public class ExcludeListTextFile
+{
+
+ private static var loader:URLLoader;
+
+ /**
+ * Mixin callback that gets everything ready to go.
+ * Table is of form: ScriptName$TestID: 1,
+ */
+ public static function init(root:DisplayObject):void
+ {
+ var req:URLRequest = new URLRequest("ExcludeList.txt");
+ loader = new URLLoader();
+ loader.addEventListener("complete", completeHandler);
+ loader.load(req);
+
+ }
+
+ private static function completeHandler(event:Event):void
+ {
+ var data:String = loader.data;
+ // DOS end of line
+ var delimiter:RegExp = new RegExp("\r\n", "g");
+ data = data.replace(delimiter, ",");
+ // Unix end of line
+ delimiter = new RegExp("\n", "g");
+ data = data.replace(delimiter, ",");
+
+ UnitTester.excludeList = new Object();
+ var items:Array = data.split(",");
+ var n:int = items.length;
+ for (var i:int = 0; i < n; i++)
+ {
+ var s:String = items[i];
+ if (s.length)
+ UnitTester.excludeList[s] = 1;
+ }
+ }
+}
+
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/ExcludeListTextFile.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/ExitWhenDone.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/ExitWhenDone.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/ExitWhenDone.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/ExitWhenDone.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 ExitWhenDone
+{
+
+ /**
+ * Mixin callback that gets everything ready to go.
+ * The UnitTester waits for an event before starting
+ */
+ public static function init(root:DisplayObject):void
+ {
+ UnitTester.exitWhenDone = true;
+ }
+
+
+}
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/ExitWhenDone.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/ImageDiffAIR-app.xml
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/ImageDiffAIR-app.xml?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/ImageDiffAIR-app.xml (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/ImageDiffAIR-app.xml Wed May 2 22:44:38 2012
@@ -0,0 +1,153 @@
+<?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.
+
+-->
+<application xmlns="http://ns.adobe.com/air/application/1.5">
+
+<!-- Adobe AIR Application Descriptor File Template.
+
+ Specifies parameters for identifying, installing, and launching AIR applications.
+
+ xmlns - The Adobe AIR namespace: http://ns.adobe.com/air/application/1.5
+ The last segment of the namespace specifies the version
+ of the AIR runtime required for this application to run.
+
+ minimumPatchLevel - The minimum patch level of the AIR runtime required to run
+ the application. Optional.
+-->
+
+ <!-- The application identifier string, unique to this application. Required. -->
+ <id>ImageDiff</id>
+
+ <!-- Used as the filename for the application. Required. -->
+ <filename>ImageDiff</filename>
+
+ <!-- The name that is displayed in the AIR application installer.
+ May have multiple values for each language. See samples or xsd schema file. Optional. -->
+ <name>ImageDiff</name>
+
+ <!-- An application version designator (such as "v1", "2.5", or "Alpha 1"). Required. -->
+ <version>v2</version>
+
+ <!-- Description, displayed in the AIR application installer.
+ May have multiple values for each language. See samples or xsd schema file. Optional. -->
+ <!-- <description></description> -->
+
+ <!-- Copyright information. Optional -->
+ <!-- <copyright></copyright> -->
+
+ <!-- Settings for the application's initial window. Required. -->
+ <initialWindow>
+ <!-- The main SWF or HTML file of the application. Required. -->
+ <!-- Note: In Flex Builder, the SWF reference is set automatically. -->
+ <content>ImageDiffAIR.swf</content>
+
+ <!-- The title of the main window. Optional. -->
+ <!-- <title></title> -->
+
+ <!-- The type of system chrome to use (either "standard" or "none"). Optional. Default standard. -->
+ <!-- <systemChrome></systemChrome> -->
+
+ <!-- Whether the window is transparent. Only applicable when systemChrome is none. Optional. Default false. -->
+ <!-- <transparent></transparent> -->
+
+ <!-- Whether the window is initially visible. Optional. Default false. -->
+ <!-- <visible></visible> -->
+
+ <!-- Whether the user can minimize the window. Optional. Default true. -->
+ <!-- <minimizable></minimizable> -->
+
+ <!-- Whether the user can maximize the window. Optional. Default true. -->
+ <!-- <maximizable></maximizable> -->
+
+ <!-- Whether the user can resize the window. Optional. Default true. -->
+ <!-- <resizable></resizable> -->
+
+ <!-- The window's initial width. Optional. -->
+ <!-- <width></width> -->
+
+ <!-- The window's initial height. Optional. -->
+ <!-- <height></height> -->
+
+ <!-- The window's initial x position. Optional. -->
+ <!-- <x></x> -->
+
+ <!-- The window's initial y position. Optional. -->
+ <!-- <y></y> -->
+
+ <!-- The window's minimum size, specified as a width/height pair, such as "400 200". Optional. -->
+ <!-- <minSize></minSize> -->
+
+ <!-- The window's initial maximum size, specified as a width/height pair, such as "1600 1200". Optional. -->
+ <!-- <maxSize></maxSize> -->
+ </initialWindow>
+
+ <!-- The subpath of the standard default installation location to use. Optional. -->
+ <!-- <installFolder></installFolder> -->
+
+ <!-- The subpath of the Programs menu to use. (Ignored on operating systems without a Programs menu.) Optional. -->
+ <!-- <programMenuFolder></programMenuFolder> -->
+
+ <!-- The icon the system uses for the application. For at least one resolution,
+ specify the path to a PNG file included in the AIR package. Optional. -->
+ <!-- <icon>
+ <image16x16></image16x16>
+ <image32x32></image32x32>
+ <image48x48></image48x48>
+ <image128x128></image128x128>
+ </icon> -->
+
+ <!-- Whether the application handles the update when a user double-clicks an update version
+ of the AIR file (true), or the default AIR application installer handles the update (false).
+ Optional. Default false. -->
+ <!-- <customUpdateUI></customUpdateUI> -->
+
+ <!-- Whether the application can be launched when the user clicks a link in a web browser.
+ Optional. Default false. -->
+ <!-- <allowBrowserInvocation></allowBrowserInvocation> -->
+
+ <!-- Listing of file types for which the application can register. Optional. -->
+ <!-- <fileTypes> -->
+
+ <!-- Defines one file type. Optional. -->
+ <!-- <fileType> -->
+
+ <!-- The name that the system displays for the registered file type. Required. -->
+ <!-- <name></name> -->
+
+ <!-- The extension to register. Required. -->
+ <!-- <extension></extension> -->
+
+ <!-- The description of the file type. Optional. -->
+ <!-- <description></description> -->
+
+ <!-- The MIME content type. -->
+ <!-- <contentType></contentType> -->
+
+ <!-- The icon to display for the file type. Optional. -->
+ <!-- <icon>
+ <image16x16></image16x16>
+ <image32x32></image32x32>
+ <image48x48></image48x48>
+ <image128x128></image128x128>
+ </icon> -->
+
+ <!-- </fileType> -->
+ <!-- </fileTypes> -->
+
+</application>
\ No newline at end of file
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/ImageDiffAIR-app.xml
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/ImageDiffAIR.air
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/ImageDiffAIR.air?rev=1333232&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/ImageDiffAIR.air
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: incubator/flex/trunk/mustella/as3/src/mustella/ImageDiffAIR.mxml
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/ImageDiffAIR.mxml?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/ImageDiffAIR.mxml (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/ImageDiffAIR.mxml Wed May 2 22:44:38 2012
@@ -0,0 +1,509 @@
+<?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:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" initialize="initLC()" creationComplete="doCreationComplete()">
+<mx:Script>
+ <![CDATA[
+ import flash.geom.Rectangle;
+ import mx.controls.Label;
+ import mx.core.UIComponent;
+
+ private var results:UIComponent;
+ private var image1Loaded:Boolean;
+ private var image2Loaded:Boolean;
+ private var digits:Array = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
+
+ private function initLC():void
+ {
+ for (var i:int = 0; i < 16; i++)
+ {
+ for (var j:int = 0; j < 16; j++)
+ {
+ byteTable[digits[i] + digits[j]] = i * 16 + j;
+ }
+ }
+ }
+
+ private function doCreationComplete():void{
+ nativeWindow.bounds = new Rectangle(0, 0, flash.system.Capabilities.screenResolutionX, flash.system.Capabilities.screenResolutionY);
+ }
+
+ private function statusHandler(event:Event):void
+ {
+ }
+
+ private var sbd:BitmapData;
+ private var sba:ByteArray;
+ public function startScreenData(w:int, h:int, length:int):void
+ {
+ sba = new ByteArray();
+ sbd = new BitmapData(w, h);
+ }
+ public function addScreenData(s:String):void
+ {
+ toByteArray(sba, s);
+ }
+
+ private var bbd:BitmapData;
+ private var bba:ByteArray;
+ public function startBaseData(w:int, h:int, length:int):void
+ {
+ bba = new ByteArray();
+ bbd = new BitmapData(w, h);
+ }
+ public function addBaseData(s:String):void
+ {
+ toByteArray(bba, s);
+ }
+
+ public function compareBitmaps():void
+ {
+ var bm1:Bitmap = new Bitmap();
+ var bm2:Bitmap = new Bitmap();
+ sba.position = 0;
+ bba.position = 0;
+ sbd.setPixels(sbd.rect, sba);
+ bbd.setPixels(bbd.rect, bba);
+ bm1.bitmapData = sbd;
+ bm2.bitmapData = bbd;
+ image1.load(bm1);
+ image2.load(bm2);
+ image1.scaleX = 1;
+ image1.scaleY = 1;
+ image2.scaleX = 1;
+ image2.scaleY = 1;
+ canvas1.width = sbd.width;
+ canvas1.height = sbd.height;
+ canvas2.width = bbd.width;
+ canvas2.height = bbd.height;
+
+ doCompare();
+ }
+
+ private var byteTable:Object = new Object();
+
+ private function toByteArray(ba:ByteArray, s:String):void
+ {
+ var arr:Array = s.split(",");
+
+ var n:int = arr.length;
+ for (var i:int = 0; i < n; i++)
+ {
+ var b:String = arr[i];
+ var byte:int = byteTable[b];
+ ba.writeByte(byte);
+ }
+ }
+
+ public function doCompare():void
+ {
+ var bm1:BitmapData = new BitmapData(image1.content.width, image1.content.height);
+ bm1.draw(image1.content, new Matrix());
+
+ var bm2:BitmapData = new BitmapData(image2.content.width, image2.content.height);
+ bm2.draw(image2.content, new Matrix());
+
+ if (results)
+ canvas3.removeChild(results);
+
+
+ var cmp:Object = bm1.compare(bm2);
+ var label:Label;
+
+ if (cmp == 0)
+ {
+ results = label = new Label();
+ label.text = "Same";
+ label.validateNow();
+ canvas3.addChild(results);
+ canvas3.width = results.width;
+ canvas3.height = results.height;
+ }
+ else if (cmp == -3)
+ {
+ results = label = new Label();
+ label.text = "Widths are Different: " + image1.content.width + " vs " + image2.content.width;
+ label.validateNow();
+ canvas3.addChild(results);
+ canvas3.width = results.width;
+ canvas3.height = results.height;
+ }
+ else if (cmp == -4)
+ {
+ results = label = new Label();
+ label.text = "Heights are Different: " + image1.content.height + " vs " + image2.content.height;
+ label.validateNow();
+ canvas3.addChild(results);
+ canvas3.width = results.width;
+ canvas3.height = results.height;
+ }
+ else
+ {
+ results = new UIComponent();
+ var bm:Bitmap = new Bitmap();
+ results.addChild(bm);
+ bm.bitmapData = BitmapData(cmp);
+ results.width = image1.content.width;
+ results.height = image1.content.height;
+ canvas3.addChild(results);
+ canvas3.width = results.width;
+ canvas3.height = results.height;
+ results.graphics.clear();
+ results.graphics.beginFill(bg.selectedColor);
+ results.graphics.drawRect(0, 0, results.width, results.height);
+ results.graphics.endFill();
+ }
+
+ }
+
+ // Show previous image.
+ private function prevHandler():void
+ {
+ if(--currentIndex < 0){
+ currentIndex = selectedImagesArray.length - 1;
+ }
+
+ initiateLoading();
+ }
+
+ // Show next image.
+ private function nextHandler():void
+ {
+ if(++currentIndex == selectedImagesArray.length){
+ currentIndex = 0;
+ }
+
+ initiateLoading();
+ }
+
+ // Start loading images. We continue with handleImage(1 or 2)Complete
+ private function initiateLoading():void{
+ image1Loaded = false;
+ image2Loaded = false;
+
+ image1.source = selectedImagesArray[currentIndex].url;
+ image2.source = selectedImagesArray[currentIndex].url.substring(0, selectedImagesArray[currentIndex].url.length - 8);
+
+ progressLabel.text = (currentIndex+1) + " of " + selectedImagesArray.length;
+ }
+
+ private function handleImage1Complete():void{
+ image1Loaded = true;
+ sizeCanvas1();
+
+ if(image1Loaded && image2Loaded){
+ doCompare();
+ }
+ }
+
+ private function handleImage2Complete():void{
+ image2Loaded = true;
+ sizeCanvas2();
+
+ if(image1Loaded && image2Loaded){
+ doCompare();
+ }
+ }
+
+ private function bgChanged():void
+ {
+ if (results)
+ {
+ results.graphics.clear();
+ results.graphics.beginFill(bg.selectedColor);
+ results.graphics.drawRect(0, 0, results.width, results.height);
+ results.graphics.endFill();
+ }
+ }
+
+ private function getPixel(target:UIComponent, x:int, y:int, lbl:Label, bg:UIComponent):void
+ {
+ var pt:Point = new Point(x, y);
+ var screenBits:BitmapData = new BitmapData(target.width, target.height);
+ screenBits.draw(target, new Matrix(1, 0, 0, 1, 0, 0));
+
+ var clr:uint = screenBits.getPixel(pt.x, pt.y);
+ var s:String = clr.toString(16);
+ while (s.length < 6)
+ {
+ s = "0" + s;
+ }
+ lbl.text = s.toUpperCase();
+ bg.graphics.beginFill(clr);
+ bg.graphics.drawRect(0, 0, bg.width, bg.height);
+ bg.graphics.endFill();
+ }
+
+ private function pixelTracking():void
+ {
+ if (cb.selected)
+ systemManager.addEventListener("mouseMove", pixelTracker);
+ else
+ systemManager.removeEventListener("mouseMove", pixelTracker);
+ }
+
+ private function pixelTracker(event:MouseEvent):void
+ {
+ if (image1.contains(event.target as DisplayObject))
+ {
+ updatePixels(image1, event.localX, event.localY, "1");
+ }
+ else if (image2.contains(event.target as DisplayObject))
+ {
+ updatePixels(image2, event.localX, event.localY, "2");
+ }
+ else if (results && results.contains(event.target as DisplayObject))
+ {
+ updatePixels(results, event.localX, event.localY, "3");
+ }
+ }
+
+ private function updatePixels(target:UIComponent, x:Number, y:Number, ui:String):void
+ {
+ var nsx:NumericStepper = this["img" + ui + "x"];
+ var nsy:NumericStepper = this["img" + ui + "y"];
+ nsx.value = x;
+ nsy.value = y;
+ var lbl:Label = this["pixel" + ui];
+ var bg:UIComponent = this["bg" + ui];
+ getPixel(target, x, y, lbl, bg);
+ }
+
+ private function sizeCanvas1():void
+ {
+ image1.scaleX = 1;
+ image1.scaleY = 1;
+ canvas1.width = image1.content.width;
+ canvas1.height = image1.content.height;
+ }
+
+ private function sizeCanvas2():void
+ {
+ image2.scaleX = 1;
+ image2.scaleY = 1;
+ canvas2.width = image2.content.width;
+ canvas2.height = image2.content.height;
+ }
+
+ private function zoomit():void
+ {
+ image1.scaleY = image1.scaleX = zoom.value;
+ image1.validateNow();
+ image2.scaleY = image2.scaleX = zoom.value;
+ image2.validateNow();
+ results.scaleY = results.scaleX = zoom.value;
+ results.validateNow();
+ if (canvas1.width < 100)
+ {
+ canvas1.width = Math.min(image1.width, 100);
+ canvas1.height= Math.min(image1.height, 100);
+ canvas2.width = Math.min(image2.width, 100);
+ canvas2.height= Math.min(image2.height, 100);
+ canvas3.width = Math.min(results.width, 100);
+ canvas3.height= Math.min(results.height, 100);
+ }
+ }
+ ]]>
+ </mx:Script>
+ <mx:Script>
+ <![CDATA[
+ import flash.filesystem.File;
+
+ [Bindable]
+ private var selectedImagesArray:Array = [];
+
+ [Bindable]
+ private var currentIndex:int = -1;
+
+ private function getImages():void
+ {
+ if (!fs.selectedItem)
+ return;
+
+ var dir:File = File(fs.selectedItem.isDirectory ? fs.selectedItem : fs.selectedItem.parent);
+
+ var filesArray:Array = [];
+
+ getFilesFromDir(dir, filesArray);
+
+ dg.dataProvider = filesArray;
+
+ accord.selectedIndex = 1;
+ }
+
+ private function getImages2():void
+ {
+ if (!dg.selectedItems)
+ return;
+
+ selectedImagesArray = dg.selectedItems;
+ currentIndex = -1;
+ nextHandler();
+ accord.selectedIndex = 2;
+ }
+
+ private function deleteImages2():void
+ {
+ if (!dg.selectedItems)
+ return;
+
+ for (var i:int=0; i<dg.selectedItems.length; i++) {
+ var file:File = File(dg.selectedItems[i]);
+ file.deleteFileAsync();
+ }
+ accord.selectedIndex = 0;
+ }
+
+ private function getFilesFromDir(dir:File, filesArray:Array):void
+ {
+ var files:Array = dir.getDirectoryListing();
+
+ for(var i:int=0; i<files.length; i++)
+ {
+ var file:File = File(files[i]);
+ if (file.isDirectory)
+ {
+ getFilesFromDir(file, filesArray);
+ }
+ else
+ {
+ if (file.url.indexOf(".png.bad.png") != -1)
+ {
+ filesArray.push(file);
+ }
+ }
+ }
+ }
+
+ private function getFileName(item:Object,blah:*=null):String
+ {
+ var file:File = File(item);
+ return getFileNameFromString(file.url);
+ }
+
+ private function getFileNameFromString(item:String):String
+ {
+ if(item == null)
+ return "";
+ var index:Number = item.indexOf("mustella");
+ if (index == -1)
+ return item;
+
+ return item.substr(index + 14);
+ }
+ ]]>
+ </mx:Script>
+ <mx:Accordion id="accord" width="100%" height="100%" creationPolicy="all">
+ <mx:VBox label="Select Directory" width="100%" height="100%" verticalAlign="center" horizontalAlign="center" backgroundColor="0x008888">
+
+ <!-- To do: load a local XML file for people to personalize.
+
+ <mx:RadioButtonGroup id="rbgTestDirs" itemClick="fs.directory = new File(rbgTestDirs.selectedValue as String)" />
+ <mx:HBox>
+ <mx:RadioButton groupName="rbgTestDirs" label="3.x Tests" value="/Users/rv/source/depot/flex/branches/3.x/qa/sdk/testsuites/mustella/tests" />
+ </mx:HBox>
+ <mx:HBox>
+ <mx:RadioButton groupName="rbgTestDirs" label="DataGrid" value="/Users/rv/source/depot/flex/qa/sdk/testsuites/mustella/tests/components/DataGrid" />
+ <mx:RadioButton groupName="rbgTestDirs" label="DataGridColumn" value="/Users/rv/source/depot/flex/qa/sdk/testsuites/mustella/tests/components/DataGridColumn" />
+ <mx:RadioButton groupName="rbgTestDirs" label="TileLayout" value="/Users/rv/source/depot/flex/qa/sdk/testsuites/mustella/tests/gumbo/layout/TileLayout" />
+ <mx:RadioButton groupName="rbgTestDirs" label="ShaderFilter" value="/Users/rv/source/depot/flex/qa/sdk/testsuites/mustella/tests/gumbo/filters/ShaderFilter" />
+ <mx:RadioButton groupName="rbgTestDirs" label="States" value="/Users/rv/source/depot/flex/qa/sdk/testsuites/mustella/tests/States" />
+ <mx:RadioButton groupName="rbgTestDirs" label="Spark WA" value="/Users/rv/source/depot/flex/qa/sdk/testsuites/mustella/tests/apollo/spark/components/WindowedApplication" />
+ <mx:RadioButton groupName="rbgTestDirs" label="Tests" value="/Users/rv/source/depot/flex/qa/sdk/testsuites/mustella/tests" />
+ </mx:HBox>
+ -->
+
+ <mx:FileSystemTree id="fs" width="100%" height="100%" />
+ <mx:Button label="Find Images" click="getImages()" />
+ <mx:Label text="{fs.selectedItem.url}" />
+ </mx:VBox>
+ <mx:VBox label="Select Images" width="100%" height="100%" verticalAlign="center" horizontalAlign="center" backgroundColor="0x008888">
+ <mx:DataGrid id="dg" width="100%" height="100%" allowMultipleSelection="true">
+ <mx:columns>
+ <mx:DataGridColumn headerText="File" labelFunction="getFileName" />
+ </mx:columns>
+ </mx:DataGrid>
+ <mx:Button click="getImages2()" label="Compare Selected Images" />
+ <mx:Button click="deleteImages2()" label="Delete Selected Images" />
+ </mx:VBox>
+ <mx:VBox label="Compare Images" width="100%" height="100%" verticalAlign="center" horizontalAlign="center" backgroundColor="0x008888">
+ <mx:HBox>
+ <mx:Button id="prevButton" click="prevHandler()" label="< Prev Image"/>
+ <mx:Label id="progressLabel" />
+ <mx:Button id="nextButton" click="nextHandler()" label="Next Image >"/>
+ </mx:HBox>
+ <mx:HBox>
+ <mx:VBox>
+ <mx:VBox>
+ <mx:Canvas id="canvas1" minHeight="0" minWidth="0" >
+ <mx:Image id="image1" complete="handleImage1Complete()" />
+ </mx:Canvas>
+ <mx:Label text="{getFileNameFromString(String(image1.source))}" />
+ </mx:VBox>
+ <mx:HBox>
+ <mx:Label text="x" />
+ <mx:NumericStepper id="img1x" width="60" maximum="4000" />
+ <mx:Label text="y" />
+ <mx:NumericStepper id="img1y" width="60" maximum="4000" />
+ <mx:Button label="get pixel" click="getPixel(image1, img1x.value, img1y.value, pixel1, bg1)" />
+ <mx:Label id="pixel1" />
+ <mx:UIComponent id="bg1" width="16" height="16" />
+ </mx:HBox>
+ </mx:VBox>
+ <mx:Spacer width="50" />
+ <mx:VBox>
+ <mx:VBox>
+ <mx:Canvas id="canvas2" minHeight="0" minWidth="0" >
+ <mx:Image id="image2" complete="handleImage2Complete()" />
+ </mx:Canvas>
+ <mx:Label text="{getFileNameFromString(String(image2.source))}" />
+ </mx:VBox>
+ <mx:HBox>
+ <mx:Label text="x" />
+ <mx:NumericStepper id="img2x" width="60" maximum="4000" />
+ <mx:Label text="y" />
+ <mx:NumericStepper id="img2y" width="60" maximum="4000" />
+ <mx:Button label="get pixel" click="getPixel(image2, img2x.value, img2y.value, pixel2, bg2)" />
+ <mx:Label id="pixel2" />
+ <mx:UIComponent id="bg2" width="16" height="16" />
+ </mx:HBox>
+ </mx:VBox>
+ </mx:HBox>
+ <mx:HBox>
+ <mx:CheckBox id="cb" label="Pixel Reading" click="pixelTracking()" />
+ <mx:Label text="Zoom" />
+ <mx:NumericStepper id="zoom" minimum="1" change="zoomit()" />
+ <mx:Label text="background" />
+ <mx:ColorPicker id="bg" change="bgChanged();" />
+ </mx:HBox>
+ <mx:Canvas id="canvas4" minHeight="0" minWidth="0" />
+ <mx:Canvas id="canvas3" minHeight="0" minWidth="0" />
+ <mx:HBox>
+ <mx:Label text="x" />
+ <mx:NumericStepper id="img3x" width="60" maximum="4000" />
+ <mx:Label text="y" />
+ <mx:NumericStepper id="img3y" width="60" maximum="4000" />
+ <mx:Button label="get pixel" click="getPixel(results, img3x.value, img3y.value, pixel3, bg3)" />
+ <mx:Label id="pixel3" />
+ <mx:UIComponent id="bg3" width="16" height="16" />
+ </mx:HBox>
+ </mx:VBox>
+ </mx:Accordion>
+
+</mx:WindowedApplication>
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/ImageDiffAIR.mxml
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/ImageDiffAIR.swf
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/ImageDiffAIR.swf?rev=1333232&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/ImageDiffAIR.swf
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream