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 [12/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/MustellaResultsParser.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/MustellaResultsParser.java?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/MustellaResultsParser.java (added)
+++ incubator/flex/trunk/mustella/MustellaResultsParser.java Wed May 2 22:44:38 2012
@@ -0,0 +1,162 @@
+package mustella;
+
+import java.util.*;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.LineNumberReader;
+
+/**
+ * User: aharui
+ * Date: Jun 21, 2005
+ * Time: 2:55:16 PM
+ * read flashlog.txt, look for failures, return 0 if none, otherwise some exit code
+ */
+public class MustellaResultsParser {
+
+ public static void main(String args[]) {
+
+ String filename;
+ String flashlog = "/Macromedia/Flash Player/Logs/flashlog.txt";
+
+ String osname = System.getProperty("os.name");
+ if (osname.indexOf("Windows") != -1) {
+ filename = System.getProperty("APPDATA") + flashlog;
+ } else if (osname.indexOf("Mac OS") != -1) {
+ filename = System.getProperty("user.home") + "/Library/Preferences" + flashlog;
+ } else if (osname.indexOf("Unix") != -1 || osname.indexOf("Linux") != -1){
+ filename = System.getProperty("user.home") + "/.macromedia/Flash_Player/Logs/flashlog.txt";
+ } else {
+ filename = System.getProperty("APPDATA") + flashlog;
+ }
+
+
+ boolean result = false;
+
+ if (new File(filename).exists() == false) {
+ System.out.println("result file not found: " + filename);
+ } else {
+ try {
+ MustellaResultsParser p = new MustellaResultsParser(filename);
+ result = p.parse();
+ } catch(IOException e) {}
+ }
+ int exitValue = result ? 0 : 1;
+ System.out.println("results: "+(result?"PASSED":"FAILED"));
+
+ if (exitValue > 0)
+ System.exit(exitValue);
+ }
+
+ private File file;
+
+ public MustellaResultsParser(String filename) throws IOException {
+ file = new File(filename);
+ if (!file.isFile()) {
+ System.out.println("file " + filename + " not a file");
+ }
+ }
+
+ public boolean parse() {
+ boolean passed = true;
+
+ LineNumberReader lnr;
+ try {
+ lnr = new LineNumberReader(new FileReader(file));
+ } catch (FileNotFoundException fnfe) {
+ System.out.println("problem creating reader");
+ return false;
+ }
+
+ String s;
+ boolean scriptComplete = false;
+ int numResults = 0;
+
+ try {
+ while ((s = lnr.readLine()) != null) {
+ if (s.startsWith("RESULT: ")) {
+ numResults++;
+ int index = s.indexOf("result=") + 7;
+ String result = s.substring(index, index + 4);
+ if (!result.equals("pass")) {
+ passed = false;
+ index = s.indexOf("id=") + 3;
+ int endIndex = s.indexOf(" ", index);
+ result = s.substring(s.indexOf("id=") + 3, endIndex);
+ System.out.println("test case " + result + " failed");
+ }
+ }
+ else if (s.startsWith("OK: Root-level SWF loaded"))
+ {
+ }
+ else if (s.startsWith("TestCase Start:"))
+ {
+ }
+ else if (s.startsWith("requesting url:"))
+ {
+ }
+ else if (s.startsWith("testComplete"))
+ {
+ }
+ else if (s.startsWith("ScriptComplete:"))
+ {
+ scriptComplete = true;
+ }
+ else if (s.startsWith("Created new test output instance"))
+ {
+ }
+ else if (s.startsWith("Send ScriptComplete"))
+ {
+ }
+ else if (s.startsWith("Paused for"))
+ {
+ }
+ else if (s.startsWith("Warning:"))
+ {
+ }
+ else if (s.startsWith("LengthOfTestcases:"))
+ {
+ }
+ else if (s.startsWith("Created new test output"))
+ {
+ }
+ else if (s.startsWith("Send ScriptComplete"))
+ {
+ }
+ else if (s.startsWith("readPNG:requesting"))
+ {
+ }
+ else if (s.startsWith("runid.properties ERROR handler with: [IOErrorEvent"))
+ {
+ }
+ else if (s.startsWith("[IOErrorEvent type=\"ioError\"") && s.contains("localhost:9999/ScriptComplete"))
+ {
+ }
+ else if (s.trim().equals(""))
+ {
+ }
+ else
+ {
+ System.out.println("Unexpected Trace: " + s);
+ passed = false;
+ }
+ }
+ } catch (IOException e) {
+ System.out.println("ioerror");
+ }
+
+ if (numResults == 0)
+ {
+ System.out.println("No results. Is trace output enabled?");
+ passed = false;
+ }
+ else if (!scriptComplete)
+ {
+ System.out.println("Script did not complete");
+ passed = false;
+ }
+
+ return passed;
+ }
+}
Propchange: incubator/flex/trunk/mustella/MustellaResultsParser.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/AIR/CompareBitmap.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/AIR/CompareBitmap.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/AIR/CompareBitmap.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/AIR/CompareBitmap.as Wed May 2 22:44:38 2012
@@ -0,0 +1,996 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.*;
+import flash.events.*;
+import flash.filesystem.*;
+import flash.net.*;
+import flash.text.*;
+import flash.utils.*;
+import flash.filesystem.*;
+import flash.geom.*;
+import mx.core.mx_internal;
+use namespace mx_internal;
+
+/**
+* Vector of conditionalValue objects.
+**/
+[DefaultProperty("conditionalValues")]
+
+/**
+ * The test step that compares a bitmap against a reference bitmap
+ * MXML attributes:
+ * target
+ * url
+ * timeout (optional);
+ * stageText (optional)
+ * maxColorVariance
+ * numColorVariances
+ * waitTarget Do Not Use
+ * waitEvent Do Not Use
+ *
+ * Do not set waitEvent or waitTarget on this step. They are set internally
+ * to manage the loading of the reference bitmap. The step prior to this
+ * step must wait for the system to synch up.
+ *
+ * CompareBitmap will parse the url attribute for $testID, replacing with the current testID
+ */
+public class CompareBitmap extends Assert
+{
+ public static var useRemoteDiffer:Boolean = false;
+
+ public static var DEFAULT_MAX_COLOR_VARIANCE:int = 0;
+ public static var DEFAULT_NUM_COLOR_VARIANCES:int = 0;
+
+ // This is the default property.
+ public var conditionalValues:Vector.<ConditionalValue> = null;
+
+ /**
+ * The url of the file to read. If UnitTester.createBitmapReferences = true,
+ * the url to store the bitmap
+ */
+ public var url:String;
+
+
+ /**
+ * If the user tells us it's a stageText, we'll try to grab the bitmapdata
+ * via mx_internal call
+ */
+ public var stageText:Boolean
+
+ private var _maxColorVariance:int = 0;
+ /**
+ * The maximum color variation allowed in a bitmap compare.
+ * Some machines render slightly differently and thus we have
+ * to allow the the compare to not be exact.
+ */
+ public function get maxColorVariance():int
+ {
+ if (_maxColorVariance)
+ return _maxColorVariance;
+
+ return DEFAULT_MAX_COLOR_VARIANCE;
+ }
+ public function set maxColorVariance(value:int):void
+ {
+ _maxColorVariance = value;
+ }
+
+ private var _ignoreMaxColorVariance:Boolean = false;
+
+ /**
+ * Sometimes you have numColorVariance defined and you don't really care by how much the pixel really differ.
+ * as long as the number of mismatching pixels is <= numColorVariance
+ * Setting this to true will skip the maxColorVariance check (and take the guess work out of picture). default is false
+ */
+ public function get ignoreMaxColorVariance():Boolean
+ {
+ return _ignoreMaxColorVariance;
+ }
+
+ public function set ignoreMaxColorVariance(value:Boolean):void
+ {
+ _ignoreMaxColorVariance = value;
+ }
+
+
+ private var _numColorVariances:int = 0;
+ /**
+ * The number of color variation allowed in a bitmap compare.
+ * Some machines render slightly differently and thus we have
+ * to allow the the compare to not be exact.
+ */
+ public function get numColorVariances():int
+ {
+ if (_numColorVariances)
+ return _numColorVariances;
+
+ return DEFAULT_NUM_COLOR_VARIANCES;
+ }
+ public function set numColorVariances(value:int):void
+ {
+ _numColorVariances = value;
+ }
+
+ /**
+ * Suffix to add to the file being written out (the case of a compare failure)
+ */
+ public static var fileSuffix:String = "";
+
+ private var reader:Loader;
+ private var writer:URLLoader;
+
+ private static var connection:LocalConnection;
+ private static var commandconnection:LocalConnection;
+
+ private function statusHandler(event:Event):void
+ {
+ }
+
+ /**
+ * Constructor
+ */
+ public function CompareBitmap()
+ {
+ if (!connection)
+ {
+ connection = new LocalConnection();
+ connection.allowDomain("*");
+ connection.addEventListener(StatusEvent.STATUS, statusHandler);
+
+ commandconnection = new LocalConnection();
+ commandconnection.allowDomain("*");
+
+ try
+ {
+ commandconnection.connect("_ImageDifferCommands");
+ }
+ catch (e:Error)
+ {
+ trace("connection failed");
+ }
+ }
+
+ }
+
+ // We override execute here. In other TestSteps, we override doStep().
+ override public function execute(root:DisplayObject, context:UnitTester, testCase:TestCase, testResult:TestResult):Boolean
+ {
+ var cv:ConditionalValue = null;
+ var configID:String = null;
+
+ if( conditionalValues ){
+ // Use MultiResult to determine the proper URL.
+ cv = new MultiResult().chooseCV(conditionalValues);
+ if(cv){
+ // Use thet cv's url if it is set; otherwise, stick with the CompareBitmap's url (directory).
+ if( cv.url != null ){
+ url = cv.url;
+ }
+ }
+ }else{
+ // We do not have ConditionalValues. If the current config is unknown, it is probably
+ // a desktop AIR run, and we should just let things take the course they always have.
+ // If a config is known, then we want to use the new config ID suffix mechanism later.
+ configID = TargetConfigurations.getTargetConfigID( UnitTester.cv );
+ if( configID ){
+ trace( "CompareBitmap: No ConditionalValues found. configID is " + configID.toString() );
+ }else{
+ trace( "CompareBitmap: No ConditionalValues found. configID is " + configID );
+ }
+ }
+
+ if( url == null ){
+ if( cv == null ){
+ throw new Error("Found no url on the CompareBitmap for test case " + testCase.testID);
+ }else{
+ throw new Error("Found no url on the ConditionalValue for test case " + testCase.testID + ", ConditionalValue: " + cv.toString());
+ }
+ }
+
+ // See if url ends with .png. If not, create a file name.
+ if( url.lastIndexOf( ".png" ) != url.length - 4 ){
+ // Add a path separator if necessary.
+ if( url.lastIndexOf( "/" ) != url.length - 1 ){
+ url += "/";
+ }
+
+ // Decide on a file name.
+ if( conditionalValues ){
+ // If we ended up with a matching CV, ask it to create a file name.
+ // Otherwise, go with the test ID.
+ // Keep this path alive until (if ever) ConditionalValues in CompareBitmaps have all been removed.
+ if(cv){
+ trace( "CompareBitmap: Asking the ConditionalValue to create the file name." );
+ url += cv.createFilename( testCase.testID );
+ } else {
+ trace( "CompareBitmap: Creating the file name from the testID." );
+ url += testCase.testID + ".png";
+ }
+ }else if( configID ){
+ // We have no ConditionalValues and we're running a known config,
+ // so use the config id in the suffix.
+ trace( "CompareBitmap: Creating the file name from the configID." );
+ url += testCase.testID + "@" + configID + ".png";
+ }else{
+ trace( "There is no file name, there are no Conditional Values, and there is no configID. There's not much we can do now, is there?" );
+ }
+ }
+
+ if (url != null && url.indexOf ("$testID") != -1) {
+ trace ("Replacing $testID with " + UnitTester.currentTestID);
+ url = url.replace ("$testID", UnitTester.currentTestID);
+ trace ("result 2: " + url);
+ }
+
+ if (url == null)
+ trace ("URL was null at execute time");
+
+ if (commandconnection)
+ commandconnection.client = this;
+
+ var actualTarget:DisplayObject = DisplayObject(context.stringToObject(target));
+ if (!actualTarget)
+ {
+ testResult.doFail("Target " + target + " not found");
+ return true;
+ }
+
+ this.root = root;
+ this.context = context;
+ this.testResult = testResult;
+
+ if (UnitTester.createBitmapReferences)
+ {
+ if (UnitTester.checkEmbeddedFonts)
+ {
+ if (!checkEmbeddedFonts(actualTarget))
+ {
+ testResult.doFail ("Target " + actualTarget + " is using non-embedded or advanced anti-aliased fonts");
+ return true;
+ }
+ }
+
+ writePNG(actualTarget);
+ return false;
+ }
+ else
+ {
+ readPNG();
+ return false;
+ }
+
+ }
+
+ private function getTargetSize(target:DisplayObject):Point
+ {
+ var width:Number;
+ var height:Number;
+
+ try
+ {
+ width = target["getUnscaledWidth"]() * Math.abs(target.scaleX) * target.root.scaleX;
+ height = target["getUnscaledHeight"]() * Math.abs(target.scaleY) * target.root.scaleY;
+ }
+ catch(e:ReferenceError)
+ {
+ width = target.width * target.root.scaleX;
+ height = target.height * target.root.scaleY;
+ }
+ return new Point(width, height);
+ }
+
+ // Given a displayObject, sets up the screenBits.
+ private function getScreenBits(target:DisplayObject):void{
+ try
+ {
+ if (!stageText) {
+ var targetSize:Point = getTargetSize(target);
+ var stagePt:Point = target.localToGlobal(new Point(0, 0));
+ var altPt:Point = target.localToGlobal(targetSize);
+ stagePt.x = Math.min(stagePt.x, altPt.x);
+ stagePt.y = Math.min(stagePt.y, altPt.y);
+ screenBits = new BitmapData(targetSize.x, targetSize.y);
+ screenBits.draw(target.stage, new Matrix(1, 0, 0, 1, -stagePt.x, -stagePt.y));
+ } else {
+
+ trace ("Using stagetext");
+ try {
+ var tmpbm:BitmapData = target["textDisplay"]["captureBitmapData"]();
+ screenBits = new BitmapData(tmpbm.rect.width, tmpbm.rect.height, true, 0xFFFFFFFF);
+ screenBits.draw (tmpbm, new Matrix());
+
+ } catch (e:Error) {
+ trace ("Tried for StageText bitmap data, but it failed");
+ trace (e.getStackTrace());
+ }
+
+ }
+ }
+ catch (se:SecurityError)
+ {
+ UnitTester.hideSandboxes();
+ try
+ {
+ screenBits.draw(target.stage, new Matrix(1, 0, 0, 1, -stagePt.x, -stagePt.y));
+ }
+ catch (se2:Error)
+ {
+ try
+ {
+ // if we got a security error and ended up here, assume we're in the
+ // genericLoader loads us scenario
+ screenBits.draw(target.root, new Matrix(1, 0, 0, 1, -stagePt.x, -stagePt.y));
+ }
+ catch (se3:Error)
+ {
+ }
+ }
+ UnitTester.showSandboxes();
+ var sb:Array = UnitTester.getSandboxBitmaps();
+ var n:int = sb.length;
+ for (var i:int = 0; i < n; i++)
+ {
+ mergeSandboxBitmap(target, stagePt, screenBits, sb[i]);
+ }
+ }
+ catch (e:Error)
+ {
+ testResult.doFail (e.getStackTrace());
+ }
+ }
+
+ private var MAX_LC:int = 12000;
+ private var screenBits:BitmapData;
+ private var baselineBits:BitmapData;
+ public function comparePNG(target:DisplayObject):Boolean
+ {
+ if (UnitTester.checkEmbeddedFonts)
+ {
+ if (!checkEmbeddedFonts(target))
+ {
+ testResult.doFail ("Target " + target + " is using non-embedded or advanced anti-aliased fonts");
+ return true;
+ }
+ }
+
+ if (!reader.content)
+ {
+ testResult.doFail ("baseline image not available");
+ return true;
+ }
+
+ getScreenBits(target);
+
+ try
+ {
+ baselineBits = new BitmapData(reader.content.width, reader.content.height);
+ baselineBits.draw(reader.content, new Matrix());
+
+ var compareVal:Object = baselineBits.compare (screenBits);
+
+ if (compareVal is BitmapData && numColorVariances) {
+ compareVal = compareWithVariances(compareVal as BitmapData)
+ }
+
+ if (compareVal != 0)
+ {
+ testResult.doFail ("compare returned" + compareVal, absolutePathResult(url) + ".bad.png");
+
+
+ if (useRemoteDiffer)
+ {
+ sendImagesToDiffer();
+ return false;
+ } else if (fileSuffix != "") {
+ writePNG (target);
+ }
+ }
+ }
+ catch (e:Error)
+ {
+ testResult.doFail (e.getStackTrace());
+ }
+ return true;
+ }
+
+ private function mergeSandboxBitmap(target:DisplayObject, pt:Point, bm:BitmapData, obj:Object):void
+ {
+ var targetSize:Point = getTargetSize(target);
+ var sbm:BitmapData = new BitmapData(obj.width, obj.height);
+ var srcRect:Rectangle = new Rectangle(0, 0, obj.width, obj.height);
+ sbm.setPixels(srcRect, obj.bits);
+ var targetRect:Rectangle = new Rectangle(pt.x, pt.y, targetSize.x, targetSize.y);
+ var sbRect:Rectangle = new Rectangle(obj.x, obj.y, obj.width, obj.height);
+ var area:Rectangle = targetRect.intersection(sbRect);
+ if (area)
+ bm.copyPixels(sbm, srcRect, target.globalToLocal(area.topLeft));
+ }
+
+ private function sendImagesToDiffer():void
+ {
+ UnitTester.callback = stringifyScreen;
+ }
+
+ private var ba:ByteArray;
+ private function stringifyScreen():void
+ {
+ ba = screenBits.getPixels(screenBits.rect);
+ ba.position = 0;
+ connection.send("_ImageDiffer", "startScreenData", screenBits.width, screenBits.height, ba.length, UnitTester.currentTestID, UnitTester.currentScript);
+ UnitTester.callback = sendScreen;
+ }
+
+ private function sendScreen():void
+ {
+ if (ba.position + MAX_LC < ba.length)
+ {
+ connection.send("_ImageDiffer", "addScreenData", stringify(ba));
+ UnitTester.callback = sendScreen;
+ }
+ else
+ {
+ connection.send("_ImageDiffer", "addScreenData", stringify(ba));
+ UnitTester.callback = stringifyBase;
+ }
+ }
+
+ private function stringifyBase():void
+ {
+ ba = baselineBits.getPixels(baselineBits.rect);
+ ba.position = 0;
+ connection.send("_ImageDiffer", "startBaseData", baselineBits.width, baselineBits.height, ba.length);
+ UnitTester.callback = sendBase;
+ }
+
+ private function sendBase():void
+ {
+ if (ba.position + MAX_LC < ba.length)
+ {
+ connection.send("_ImageDiffer", "addBaseData", stringify(ba));
+ UnitTester.callback = sendBase;
+ }
+ else
+ {
+ connection.send("_ImageDiffer", "addBaseData", stringify(ba));
+ connection.send("_ImageDiffer", "compareBitmaps");
+ }
+ }
+
+ private function stringify(ba:ByteArray):String
+ {
+ var n:int = Math.min(ba.length - ba.position, MAX_LC);
+ var arr:Array = [];
+ for (var i:int = 0; i < n; i++)
+ {
+ var b:int = ba.readUnsignedByte();
+ arr.push(b.toString(16))
+ }
+ return arr.toString();
+ }
+
+ private function readCompleteHandler(event:Event):void
+ {
+ var actualTarget:DisplayObject = DisplayObject(context.stringToObject(target));
+ if (comparePNG(actualTarget))
+ stepComplete();
+ }
+
+ private function readErrorHandler(event:Event = null):void
+ {
+ var failString:String = "baseline image could not be read.";
+
+ failString += " Creating image file as a .bad.png.";
+ var actualTarget:DisplayObject = DisplayObject(context.stringToObject(target));
+ getScreenBits(actualTarget);
+ writePNG(actualTarget);
+ testResult.doFail ( failString );
+ stepComplete();
+ }
+
+ /**
+ * Read a file and return a ByteArray that we can feed into reader (a Loader).
+ **/
+ public function loadFileBytes( file:File ):ByteArray{
+
+ var fileStream:FileStream = new FileStream();
+ var file:File;
+ var ba:ByteArray = new ByteArray();
+ var bytesRead:int = 0;
+ var bytesAvail:int = 0;
+
+ fileStream.open(file, FileMode.READ);
+ bytesAvail = fileStream.bytesAvailable;
+
+ while( bytesAvail > 0 ){
+ fileStream.readBytes(ba, bytesRead, bytesAvail);
+ bytesAvail = fileStream.bytesAvailable;
+ }
+
+ fileStream.close();
+
+ return ba;
+ }
+
+
+ public function readPNG():void
+ {
+ reader = new Loader();
+ reader.contentLoaderInfo.addEventListener(Event.COMPLETE, readCompleteHandler);
+ reader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, readErrorHandler);
+ reader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, readErrorHandler);
+
+ var req:URLRequest = new URLRequest();
+ var ba:ByteArray = null;
+ var file:File;
+
+ // If iOS and AIR, let's try using file I/O instead of loader stuff. AIR on devices can be a pain with the url stuff.
+ if( UnitTester.isApollo && (UnitTester.cv.os.toLowerCase() == DeviceNames.IOS.toLowerCase()) ){
+ // Trim the leading ../ if we have it.
+ if ( url.indexOf ("../") == 0 ){
+ url = url.substring (3);
+ }
+
+ file = File.documentsDirectory.resolvePath( url );
+
+ if( !file.exists ){
+ readErrorHandler();
+ return;
+ }
+
+ ba = loadFileBytes( file );
+ reader.loadBytes( ba );
+ }else{
+ if (UnitTester.isApollo)
+ {
+ req.url = encodeURI2(CompareBitmap.adjustPath (url));
+ }
+ else
+ {
+ req.url = url;
+ var base:String = normalizeURL(context.application.url);
+ base = base.substring(0, base.lastIndexOf("/"));
+ while (req.url.indexOf("../") == 0)
+ {
+ base = base.substring(0, base.lastIndexOf("/"));
+ req.url = req.url.substring(3);
+ }
+ req.url = encodeURI2(base + "/" + req.url);
+ }
+ // req.url = encodeURI2(url);
+ // }
+
+ trace ("readPNG:requesting url: " + req.url);
+ reader.load (req);
+ }
+ }
+
+
+ public static var adjustPath:Function = function(url:String):String { return url; };
+
+
+
+
+ public function getPngByteArray(target:DisplayObject, bitmapData:BitmapData):ByteArray
+ {
+ // add png headers
+ if (UnitTester.createBitmapReferences)
+ {
+ if (stageText == false)
+ {
+ var targetSize:Point = getTargetSize(target);
+ var stagePt:Point = target.localToGlobal(new Point(0, 0));
+ var altPt:Point = target.localToGlobal(targetSize);
+
+ stagePt.x = Math.min(stagePt.x, altPt.x);
+ stagePt.y = Math.min(stagePt.y, altPt.y);
+ bitmapData = new BitmapData(targetSize.x, targetSize.y);
+ bitmapData.draw(target.stage, new Matrix(1, 0, 0, 1, -stagePt.x, -stagePt.y));
+ } else {
+
+ trace ("stageText value: " + stageText);
+ try {
+ bitmapData = target["textDisplay"]["captureBitmapData"]();
+ trace ("success asking StageText for bitmap data");
+ } catch (e:Error) {
+ trace ("Tried for StageText bitmap data, but it failed");
+ trace (e.getStackTrace());
+ }
+
+ }
+
+ }
+ var png:MustellaPNGEncoder = new MustellaPNGEncoder();
+ var ba:ByteArray = png.encode (bitmapData);
+
+ return ba;
+ }
+
+
+ public function writePNG(target:DisplayObject):void
+ {
+ var ba:ByteArray = getPngByteArray(target, screenBits);
+
+
+ if( UnitTester.createBitmapReferences ){
+ fileSuffix = "";
+ }
+
+ if( UnitTester.writeBaselinesToDisk ){
+ // context.testDir: mobile/components/Button/properties/
+ // url: ../properties/baselines/button_android_test1_CustomName.png
+ var writePath:String = createWritePath( context.testDir, url + fileSuffix );
+ var deviceWritePath:String = UnitTester.mustellaWriteLocation + "/" + writePath;
+// trace("*******deviceWritePath = " + deviceWritePath);
+ var hostWritePath:String = writePath;
+ var file:File = new File ( deviceWritePath );
+ var fileStream:FileStream = new FileStream();
+ var hostCommand:String;
+
+ // open() opens synchronously, so we don't have to (and can't) use listeners.
+ fileStream.open(file, FileMode.WRITE);
+ fileStream.writeBytes(ba);
+ fileStream.close();
+
+ // Tell the host machine to copy the baseline image.
+ // Also, give it a URL with test info. to use when sending it to flexqa01's baseline server.
+ if( UnitTester.cv.os.toLowerCase() == DeviceNames.ANDROID.toLowerCase() ||
+ UnitTester.cv.os.toLowerCase() == DeviceNames.IOS.toLowerCase() ||
+ UnitTester.cv.os.toLowerCase() == DeviceNames.QNX.toLowerCase() ){
+ hostCommand = "CopyDeviceFile: FROM=" + deviceWritePath + " TO=" + hostWritePath;
+
+ // If this is about creating bitmaps, skip the upload, we're done
+ if ( !UnitTester.createBitmapReferences ){
+ hostCommand += " SCREENURL=" + (UnitTester.urlAssemble ("screen", context.testDir, context.scriptName, this.testResult.testID, UnitTester.run_id));
+ hostCommand += " BASELINEURL=" + (UnitTester.urlAssemble ("baseline", context.testDir, context.scriptName, this.testResult.testID, UnitTester.run_id));
+ }
+
+ // Trace statements are parsed by the host.
+ trace( hostCommand );
+ }
+
+ if (UnitTester.createBitmapReferences){
+ stepComplete();
+ }
+
+ return;
+ }else{
+ trace("AIR CompareBitmap is called, but we're not writing to disk. This is wrong.");
+ }
+ }
+
+ private function adjustWriteURI(url:String):String
+ {
+ var base:String = null;
+
+ // For iOS, do something different.
+ if( UnitTester.isApollo && (UnitTester.cv.os != null) && (UnitTester.cv.os.toLowerCase() == DeviceNames.IOS.toLowerCase()) ){
+ base = url;
+
+ // Trim the leading ../ if we have it.
+ if ( base.indexOf ("../") == 0 ){
+ base = base.substring (3);
+ }
+
+ base = File.documentsDirectory.resolvePath(base).nativePath;
+
+ return base;
+ }else{
+ var pos:int = url.indexOf("file:///");
+ if (pos != 0)
+ {
+ return url;
+ }
+ url = url.substring(8);
+ pos = url.indexOf("|");
+
+ if (pos != 1)
+ {
+ return url;
+ }
+
+ var drive:String = url.substring(0, 1);
+ drive = drive.toLowerCase();
+ return drive + ":" + url.substring(2);
+ }
+ }
+
+ /**
+ * Called by writePNG when, for example, we're testing on Android.
+ * firstPart: mobile/components/Button/properties/
+ * secondPart: ../properties/baselines/button_android_test1_CustomName.png
+ **/
+ private function createWritePath( firstPart:String, secondPart:String ):String{
+ var ret:String = "tests/" + firstPart.substring( 0, firstPart.lastIndexOf( "/" ) );
+
+ var removeMe:String = ret.substring( ret.lastIndexOf( "/" ), ret.length ); // "properties"
+ ret += secondPart.substring( secondPart.indexOf( removeMe ) + removeMe.length, secondPart.length );
+
+ trace("createWritePath returning " + ret);
+ return ret;
+ }
+
+ private var screenDone:Boolean = false;
+ private var baselineDone:Boolean = false;
+
+ private function writeCompleteHandler(event:Event):void
+ {
+ trace("baseline write successful " + event);
+ if (UnitTester.createBitmapReferences)
+ stepComplete();
+ }
+
+ private function uploadCompleteHandler(event:Event):void
+ {
+ trace("screen image upload successful " + event);
+ screenDone = true;
+ checkForStepComplete();
+ }
+
+ private function upload2CompleteHandler(event:Event):void
+ {
+ trace("baseline image upload successful " + event);
+ baselineDone = true;
+ checkForStepComplete();
+ }
+
+ private function writeErrorHandler(event:Event):void
+ {
+ testResult.doFail ("error on baseline write: " + event);
+ trace("Image baseline write failed " + event);
+ if (UnitTester.createBitmapReferences)
+ stepComplete();
+ }
+ private function uploadErrorHandler(event:Event):void
+ {
+ testResult.doFail ("error on baseline write: " + event);
+ trace("Image screen upload failed " + event);
+ screenDone = true;
+ checkForStepComplete();
+ }
+
+ private function upload2ErrorHandler(event:Event):void
+ {
+ testResult.doFail ("error on baseline write: " + event);
+ trace("Image baseline upload failed " + event);
+ baselineDone = true;
+ checkForStepComplete();
+ }
+
+ private function checkForStepComplete():void
+ {
+
+ if (baselineDone && screenDone)
+ stepComplete();
+
+
+ }
+
+ /**
+ * customize string representation
+ */
+ override public function toString():String
+ {
+ var s:String = (UnitTester.createBitmapReferences) ? "CreateBitmap: " : "CompareBitmap";
+ if (target)
+ s += ": target = " + target;
+ if (url)
+ s += ", url = " + url;
+ return s;
+ }
+
+ private function absolutePathResult(url:String):String
+ {
+ var base:String = null;
+
+ if( UnitTester.isApollo && (UnitTester.cv.os != null) && (UnitTester.cv.os.toLowerCase() == DeviceNames.IOS.toLowerCase()) ){
+ base = url;
+
+ // Trim the leading ../ if we have it.
+ if ( base.indexOf ("../") == 0 ){
+ base = base.substring (3);
+ }
+
+ base = File.documentsDirectory.resolvePath(base).nativePath;
+
+ } else if( UnitTester.isApollo && (UnitTester.cv.os != null) && (UnitTester.cv.os.toLowerCase() == DeviceNames.ANDROID.toLowerCase()) ){
+
+ /// code doing what it does now:
+
+ var fPath:String = createWritePath( context.testDir, url + fileSuffix );
+
+ /// clean up
+ if (fPath.indexOf ("tests/") == 0)
+ fPath = fPath.substring (5);
+
+ /// clean up
+ /// it probably has the .bad.png suffix
+ if (fPath.indexOf (".bad.png") > 0)
+ fPath = fPath.substring (0, fPath.length-".bad.png".length);
+
+ base = fPath;
+
+ }else{
+ if (UnitTester.isApollo) {
+ base = adjustWriteURI(adjustPath (url));
+ }else{
+ base = context.application.url;
+ }
+
+ base = normalizeURL(base);
+ base = base.substring (base.indexOf ("mustella/tests")+14);
+
+ if (!UnitTester.isApollo) {
+ base = base.substring(0, base.lastIndexOf("/"));
+
+ var tmp:String = url;
+
+ while (tmp.indexOf("../") == 0){
+ base = base.substring(0, base.lastIndexOf("/"));
+ tmp = tmp.substring(3);
+ }
+
+ base += "/" + tmp;
+ }
+ }
+
+ return base;
+ }
+
+
+ private function absolutePath(url:String):String
+ {
+ var swf:String = normalizeURL(root.loaderInfo.url);
+
+ var pos:int = swf.indexOf("file:///");
+ if (pos != 0)
+ {
+ trace("WARNING: unexpected swf url format, no file:/// at offset 0");
+ return url;
+ }
+ swf = swf.substring(8);
+ pos = swf.indexOf("|");
+ if (pos != 1)
+ {
+ trace("WARNING: unexpected swf url format, no | at offset 1 in: " + swf);
+ // assume we're on a mac or other unix box, it will do no harm
+ return "/" + swf.substring(0, swf.lastIndexOf ("/")+1) + url;
+ }
+
+ var drive:String = swf.substring(0, 1);
+ drive = drive.toLowerCase();
+ return drive + ":" + swf.substring(2, swf.lastIndexOf("/") + 1) + url;
+ }
+
+
+ public static function normalizeURL(url:String):String
+ {
+ var results:Array = url.split("/[[DYNAMIC]]/");
+ return results[0];
+ }
+
+
+ public function keepGoing():void
+ {
+ trace("keepgoing", url, hasEventListener("stepComplete"));
+ stepComplete();
+ }
+
+ private 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;
+ }
+
+ private function compareWithVariances(bm:BitmapData):Object
+ {
+
+ var allowed:int = numColorVariances * UnitTester.pixelToleranceMultiplier;
+ var n:int = bm.height;
+ var m:int = bm.width;
+
+ for (var i:int = 0; i < n; i++)
+ {
+ for (var j:int = 0; j < m; j++)
+ {
+ var pix:int = bm.getPixel(j, i);
+ if (pix)
+ {
+ if(!ignoreMaxColorVariance)
+ {
+ var red:int = pix >> 16 & 0xff;
+ var green:int = pix >> 8 & 0xff;
+ var blue:int = pix & 0xff;
+ if (red & 0x80)
+ red = 256 - red;
+ if (blue & 0x80)
+ blue = 256 - blue;
+ if (green & 0x80)
+ green = 256 - green;
+ if (red > maxColorVariance ||
+ blue > maxColorVariance ||
+ green > maxColorVariance)
+ {
+ return bm;
+ }
+ }
+ allowed--;
+ if (allowed < 0)
+ {
+ return bm;
+ }
+ }
+ }
+ }
+ return 0;
+ }
+
+ private function checkEmbeddedFonts(target:Object):Boolean
+ {
+ if ("rawChildren" in target)
+ target = target.rawChildren;
+
+ if (target is TextField)
+ {
+ if (target.embedFonts == false)
+ return false;
+ if (target.antiAliasType == "advanced")
+ return false;
+ return true;
+ }
+ else if ("numChildren" in target)
+ {
+ var n:int = target.numChildren;
+ for (var i:int = 0; i < n; i++)
+ {
+ if (!checkEmbeddedFonts(target.getChildAt(i)))
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ override protected function stepComplete():void
+ {
+
+ if (baselineBits != null)
+ baselineBits.dispose();
+ if (screenBits != null)
+ screenBits.dispose();
+
+
+ reader=null;
+ writer=null;
+
+ super.stepComplete();
+
+
+ }
+}
+
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/AIR/CompareBitmap.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/ApolloFilePath.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/ApolloFilePath.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/ApolloFilePath.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/ApolloFilePath.as Wed May 2 22:44:38 2012
@@ -0,0 +1,129 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package {
+
+import flash.display.DisplayObject;
+import flash.utils.*;
+import flash.net.*;
+import flash.events.*;
+import flash.display.*;
+import flash.desktop.NativeApplication;
+import flash.geom.Matrix;
+import flash.geom.Point;
+import flash.filesystem.File;
+
+[Mixin]
+/**
+ * Apollo doesn't return anything useable from the loaderInfo.url:
+ * it looks like this: app-context://my.swf
+ * The received url in a test, which is looks like "../Properties/baselines/my.png"
+ * won't load. Apparently, the "../" is offensive. To get the fully qualified path,
+ * we need the Apollo File class. That's what this Mixin supplies.
+ * Also, Apollo like soft exits, and won't re-launch after a kill (java's destroy process).
+ * so exit by calling the window's close method.
+ */
+public class ApolloFilePath
+{
+
+ public static var _root:DisplayObject;
+
+ public static function init(root:DisplayObject):void
+ {
+ UnitTester.isApollo = true;
+ CompareBitmap.adjustPath = apolloAdjust;
+
+ /// the exit method has to be gentler for apollo, too
+ UnitTester.exitWhenDone = true;
+ UnitTester.exit = apolloExit;
+ _root=root;
+
+ }
+
+
+ /**
+ * gets the url from CompareBitmap;
+ * creates fully qualified path using flash File class.
+ */
+ public 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;
+
+ if( UnitTester.cv.os == DeviceNames.ANDROID ){
+ // AIR for Android returns empty string for nativePath (on purpose). Use url instead.
+ // See https://zerowing.corp.adobe.com/display/airlinux/Resource+Mapping.
+ path = f.url;
+ }else{
+ path = f.nativePath;
+ path = path.replace (":", "|");
+ }
+
+ path = path.replace (myPattern, "/");
+
+ // 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;
+
+ if( UnitTester.cv.os == DeviceNames.ANDROID ){
+ // AIR for Android needs it to start with app:/, so just return at this point.
+ return path;
+ }else{
+ return "file:///" + path;
+ }
+ }
+
+ /**
+ * call the native window close method
+ */
+ public static function apolloExit(): void
+ {
+ /// hack around an issue that apollo seems to hang when it exits
+ /// with a socket still open. Arbitrary sleep isn't attractive
+ /// but we never received a response from Runner after sending
+ /// ScriptDone
+ setTimeout (real_apolloExit, 1500);
+ }
+
+
+ public static function real_apolloExit(): void
+ {
+
+ // Call the more general exit
+ trace ("Doing an apollo exit");
+ NativeApplication.nativeApplication.exit(1);
+ }
+}
+
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/ApolloFilePath.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/Assert.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/Assert.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/Assert.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/Assert.as Wed May 2 22:44:38 2012
@@ -0,0 +1,170 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package {
+
+import flash.display.DisplayObject;
+import flash.events.Event;
+import flash.events.EventDispatcher;
+import flash.events.IEventDispatcher;
+import flash.utils.getTimer;
+
+import mx.utils.ObjectUtil;
+
+/**
+ * The base class for all Asserts that the test
+ * has succeeded or not.
+ * All asserts should be derived from this class because
+ * the timing of the wait events is different than that for
+ * other TestSteps. See AssertPropertyValue for an example.
+ *
+ * Asserts don't execute their steps until after the
+ * waitEvent has been received (if there is one) whereas
+ * non-Asserts execute their steps and then wait for the
+ * waitEvent.
+ */
+public class Assert extends TestStep
+{
+ // list of properties we don't examine in determining equivalence
+ private static var excludeList:Array = [
+ "stage",
+ "systemManager",
+ "parent",
+ "owner",
+ "target",
+ "currentTarget"
+ ];
+
+ /**
+ * Called by the test case in case you need to set up before execute()
+ */
+ public function preview(root:DisplayObject, context:UnitTester, testCase:TestCase, testResult:TestResult):void
+ {
+ this.root = root;
+ this.context = context;
+ this.testCase = testCase;
+ this.testResult = testResult;
+
+ if (waitEvent)
+ {
+ if (waitTarget == null)
+ waitTarget = target;
+ var actualTarget:Object = context.stringToObject(waitTarget);
+ // it is ok for us to not have an actualTarget during preview
+ // someone may be waiting for the object to be created.
+ if (actualTarget)
+ actualTarget.addEventListener(waitEvent, eventListener);
+ }
+ }
+
+ /**
+ * All subclasses should override this method
+ */
+ override public function execute(root:DisplayObject, context:UnitTester, testCase:TestCase, testResult:TestResult):Boolean
+ {
+ this.root = root;
+ this.context = context;
+ this.testCase = testCase;
+ this.testResult = testResult;
+
+ if (waitEvent)
+ {
+ if (waitTarget == null)
+ waitTarget = target;
+
+ var actualTarget:IEventDispatcher = context.stringToObject(waitTarget) as IEventDispatcher;
+ if (!actualTarget)
+ {
+ testResult.doFail("waitTarget " + waitTarget + " not found");
+ return true;
+ }
+ actualTarget.removeEventListener(waitEvent, eventListener);
+ if (numEvents == 0)
+ {
+ actualTarget.addEventListener(waitEvent, waitEventHandler);
+ testCase.setExpirationTime(getTimer() + timeout);
+ return false;
+ }
+ }
+
+ doStep();
+ return true;
+ }
+
+ /**
+ * Storage for numEvents
+ */
+ private var numEvents:int = 0;
+
+ /**
+ * The name of the object to test.
+ */
+ public var target:String;
+
+ /**
+ * The method that gets called back when the event we're waiting on fires
+ */
+ override protected function waitEventHandler(event:Event):void
+ {
+ doStep();
+ super.waitEventHandler(event);
+ }
+
+ /**
+ * The event listener
+ */
+ private function eventListener(event:Event):void
+ {
+ testCase.setExpirationTime(0);
+
+ numEvents++;
+ }
+
+ /**
+ * Called by the test case in case you need to clean up after execute()
+ */
+ public function cleanup():void
+ {
+ }
+
+ /**
+ * convert everything to strings (like null)
+ */
+ protected function valueToString(value:*):String
+ {
+ if (value == null)
+ return "null";
+ var s:String;
+
+ if (value is Number)
+ {
+ if ((value is int) || (value is uint))
+ s = value.toString();
+ else
+ s = value.toFixed(6);
+ }
+ else
+ s = value.toString();
+
+ if (s == "[object Object]")
+ s = ObjectUtil.toString(value, null, excludeList);
+ return s;
+ }
+}
+
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/Assert.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/AssertError.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/AssertError.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/AssertError.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/AssertError.as Wed May 2 22:44:38 2012
@@ -0,0 +1,86 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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")]
+
+/**
+ * Tests that the value of a property is as expected
+ * MXML attributes:
+ * value
+ * waitTarget (optional)
+ * waitEvent (optional)
+ * timeout (optional)
+ */
+public class AssertError extends Assert
+{
+ /**
+ * See if the property has the correct value
+ */
+ override protected function doStep():void
+ {
+ if (hasEventListener("valueExpression"))
+ {
+ context.resetValue();
+ try
+ {
+ dispatchEvent(new RunCodeEvent("valueExpression", root["document"], context, testCase, testResult));
+ }
+ catch (e1:Error)
+ {
+ TestOutput.logResult("Exception thrown evaluating value expression.");
+ testResult.doFail (e1.getStackTrace());
+ return;
+ }
+ value = context.value;
+ if (!context.valueChanged)
+ TestOutput.logResult("WARNING: value was not set by valueExpression. 'value=' missing from expression?");
+ }
+
+ if (valueToString(testCase.lastError) != valueToString(value))
+ {
+ testResult.doFail ( "Expected Error " + valueToString(value) + ", got " + valueToString(testCase.lastError));
+ }
+ }
+
+ /**
+ * The value the property should have
+ */
+ public var value:Object;
+
+ /**
+ * customize string representation
+ */
+ override public function toString():String
+ {
+ var s:String = "AssertError";
+ return s;
+ }
+}
+
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/AssertError.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/AssertEvent.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/AssertEvent.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/AssertEvent.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/AssertEvent.as Wed May 2 22:44:38 2012
@@ -0,0 +1,219 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package {
+
+import flash.display.DisplayObject;
+import flash.display.IBitmapDrawable;
+import flash.utils.*;
+import flash.net.*;
+import flash.events.*;
+import flash.display.*;
+import flash.geom.Matrix;
+
+/**
+ * Tests that the value of a property is as expected
+ * MXML attributes:
+ * target
+ * eventName
+ * eventType
+ * waitTarget (optional)
+ * waitEvent (optional)
+ * timeout (optional)
+ */
+public class AssertEvent extends Assert
+{
+
+ private var eventListenerListening:Boolean = false;
+
+ /**
+ * Test the value of a property, log result if failure.
+ */
+ override public function preview(root:DisplayObject, context:UnitTester, testCase:TestCase, testResult:TestResult):void
+ {
+ this.root = root;
+ this.context = context;
+ this.testCase = testCase;
+ this.testResult = testResult;
+
+ var actualTarget:Object = context.stringToObject(target);
+ if (actualTarget)
+ {
+ actualTarget.addEventListener(eventName, eventListener);
+ eventListenerListening = true;
+ testCase.cleanupAsserts.push(this);
+ }
+ // we don't fail during preview, we will fail later anyway
+ }
+
+ /**
+ * Test the value of a property, log result if failure.
+ */
+ override public function execute(root:DisplayObject, context:UnitTester, testCase:TestCase, testResult:TestResult):Boolean
+ {
+ this.root = root;
+ this.context = context;
+ this.testCase = testCase;
+ this.testResult = testResult;
+
+ if (numEvents == 1 && (numExpectedEvents == 1 || numExpectedEvents == -1))
+ {
+ doStep();
+ return true;
+ }
+
+ if ((numEvents < numExpectedEvents) || (numEvents == 0 && numExpectedEvents == -1))
+ {
+ var actualTarget:IEventDispatcher = context.stringToObject(target) as IEventDispatcher;
+ if (!actualTarget)
+ {
+ testResult.doFail("target " + target + " not found");
+ return true;
+ }
+ // if eventListener is not hooked up, make sure it is
+ if (!eventListenerListening)
+ {
+ actualTarget.addEventListener(eventName, eventListener);
+ eventListenerListening = true;
+ testCase.cleanupAsserts.push(this);
+ }
+ // don't remove eventListener because we still want to check for extra events
+ // but add this in so we can wait until we get the required number of events
+ actualTarget.addEventListener(eventName, waitEventHandler);
+ testCase.setExpirationTime(getTimer() + timeout);
+ waitEvent = eventName;
+ waitTarget = target;
+ return false;
+ }
+
+ return super.execute(root, context, testCase, testResult);
+ }
+
+ /**
+ * Test the value of a property, log result if failure.
+ */
+ override protected function doStep():void
+ {
+ var actualTarget:Object = context.stringToObject(target);
+ if (!actualTarget)
+ {
+ testResult.doFail("Target " + target + " not found");
+ return;
+ }
+
+ context.lastEvent = lastEvent;
+
+ if (numExpectedEvents != -1 && numEvents != numExpectedEvents)
+ {
+ testResult.doFail("Event " + eventName + " received " + numEvents + " times");
+ return;
+ }
+
+ if (getQualifiedClassName(lastEvent).indexOf(eventClass) == -1)
+ testResult.doFail("Event " + eventName + " of class " + getQualifiedClassName(lastEvent));
+ }
+
+ /**
+ * The name of the event to watch for
+ */
+ public var eventName:String;
+
+ /**
+ * The class of the event, e.g. mx.events.DataGridEvent
+ */
+ public var eventClass:String;
+
+ /**
+ * Storage for numEvents
+ */
+ protected var numEvents:int = 0;
+
+ /**
+ * Number of expected events (must be > 0), use AssertNoEvent for 0.
+ * Set to -1 if you want to see at least one event and don't care if there's more.
+ */
+ public var numExpectedEvents:int = 1;
+
+ /**
+ * The event object
+ */
+ private var lastEvent:Event;
+
+ /**
+ * The event listener
+ */
+ protected function eventListener(event:Event):void
+ {
+ testCase.setExpirationTime(0);
+
+ lastEvent = event;
+ numEvents++;
+
+ if (numExpectedEvents != -1 && numEvents > numExpectedEvents)
+ {
+ testResult.doFail ("Event " + eventName + " received " + numEvents + " times");
+ return;
+ }
+ }
+
+ /**
+ * Test the value of a property, log result if failure.
+ */
+ override public function cleanup():void
+ {
+ var actualTarget:Object = context.stringToObject(target);
+ if (actualTarget) // might be null if object was killed
+ actualTarget.removeEventListener(eventName, eventListener);
+ }
+
+ /**
+ * customize string representation
+ */
+ override public function toString():String
+ {
+ var s:String = "AssertEvent";
+ if (target)
+ s += ": target = " + target;
+ if (eventName)
+ s += ", eventName = " + eventName;
+ return s;
+ }
+
+ /**
+ * The method that gets called back when the event we're waiting on fires
+ */
+ override protected function waitEventHandler(event:Event):void
+ {
+ // we can rely on eventListener to update lastEvent and numEvents
+
+ // keep waiting if there aren't enough events
+ if (numExpectedEvents != -1 && numEvents < numExpectedEvents)
+ {
+ testCase.setExpirationTime(getTimer() + timeout);
+ return;
+ }
+
+ // finish up
+ waitEvent = eventName;
+ waitTarget = target;
+ super.waitEventHandler(event);
+
+ }
+}
+
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/AssertEvent.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/AssertEventPropertyValue.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/AssertEventPropertyValue.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/AssertEventPropertyValue.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/AssertEventPropertyValue.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 {
+
+import flash.display.DisplayObject;
+import flash.utils.*;
+
+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")]
+
+
+/**
+ * Tests that the value of a property is as expected
+ * MXML attributes:
+ * target (ignored)
+ * propertyName
+ * value
+ * waitTarget (optional)
+ * waitEvent (optional)
+ * timeout (optional)
+ */
+public class AssertEventPropertyValue extends Assert
+{
+ /**
+ * See if the property has the correct value
+ */
+ override protected function doStep():void
+ {
+ if (hasEventListener("valueExpression"))
+ {
+ context.resetValue();
+ try
+ {
+ dispatchEvent(new RunCodeEvent("valueExpression", root["document"], context, testCase, testResult));
+ }
+ catch (e1:Error)
+ {
+ TestOutput.logResult("Exception thrown evaluating value expression.");
+ testResult.doFail (e1.getStackTrace());
+ return;
+ }
+ value = context.value;
+ if (!context.valueChanged)
+ TestOutput.logResult("WARNING: value was not set by valueExpression. 'value=' missing from expression?");
+ }
+
+ var val:Object;
+ if (!context.lastEvent)
+ {
+ testResult.doFail ("No event fired prior to this step");
+ return;
+ }
+ if (!(propertyName in context.lastEvent))
+ {
+ testResult.doFail ("Event does not have property " + propertyName);
+ return;
+ }
+ val = context.lastEvent[propertyName];
+
+ if (valueToString(val) != valueToString(value))
+ {
+ testResult.doFail ( getQualifiedClassName(context.lastEvent) + "." + propertyName + " " + valueToString(val) + " != " + valueToString(value));
+ }
+ }
+
+ /**
+ * The name of the property to test
+ */
+ public var propertyName:String;
+
+ /**
+ * The value the property should have
+ */
+ public var value:Object;
+
+ /**
+ * customize string representation
+ */
+ override public function toString():String
+ {
+ var s:String = "AssertEventPropertyValue";
+ if (target)
+ s += ": target = " + target;
+ if (propertyName)
+ s += ", propertyName = " + propertyName;
+ return s;
+ }
+}
+
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/AssertEventPropertyValue.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/AssertMethodValue.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/AssertMethodValue.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/AssertMethodValue.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/AssertMethodValue.as Wed May 2 22:44:38 2012
@@ -0,0 +1,139 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package {
+
+import flash.display.DisplayObject;
+import flash.display.IBitmapDrawable;
+import flash.events.EventDispatcher;
+import flash.utils.*;
+import flash.net.*;
+import flash.events.*;
+import flash.display.*;
+import flash.geom.Matrix;
+
+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="method", type="flash.events.Event")]
+
+/**
+ * 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")]
+
+/**
+* Vector of conditionalValue objects.
+**/
+[DefaultProperty("conditionalValues")]
+
+/**
+ * Tests that the value of a property is as expected
+ * MXML attributes:
+ * target (not used)
+ * method
+ * value
+ * waitTarget (optional)
+ * waitEvent (optional)
+ * timeout (optional)
+ */
+public class AssertMethodValue extends Assert
+{
+ public var conditionalValues:Vector.<ConditionalValue> = null;
+
+ /**
+ * Test the value of a property, log result if failure.
+ */
+ override protected function doStep():void
+ {
+ var cv:ConditionalValue = null;
+ var dispatcher:EventDispatcher = this;
+
+ context.resetValue();
+
+ // Use MultiResult to determine the proper value (or valueExpression, below).
+ if(conditionalValues){
+ cv = new MultiResult().chooseCV(conditionalValues);
+ if(cv){
+ value = cv.value;
+ dispatcher = cv;
+ }
+ }
+
+ // Execute the method.
+ try
+ {
+ dispatchEvent(new RunCodeEvent("method", root["document"], context, testCase, testResult));
+ }
+ catch (e:Error)
+ {
+ TestOutput.logResult("Exception thrown executing method.");
+ testResult.doFail (e.getStackTrace());
+ return;
+ }
+ if (!context.valueChanged)
+ TestOutput.logResult("WARNING: value was not set by method. 'value=' missing from expression?");
+ var methodValue:Object = context.value;
+
+ // Execute the valueExpression.
+ if (dispatcher.hasEventListener("valueExpression"))
+ {
+ context.resetValue();
+ try
+ {
+ dispatcher.dispatchEvent(new RunCodeEvent("valueExpression", root["document"], context, testCase, testResult));
+ }
+ catch (e1:Error)
+ {
+ TestOutput.logResult("Exception thrown evaluating value expression.");
+ testResult.doFail (e1.getStackTrace());
+ return;
+ }
+ value = context.value;
+ if (!context.valueChanged)
+ TestOutput.logResult("WARNING: value was not set by valueExpression. 'value=' missing from expression?");
+ }
+
+ if (valueToString(methodValue) != valueToString(value))
+ {
+ testResult.doFail ( "method returned " + valueToString(methodValue) + ", expected " + valueToString(value));
+ }
+ }
+
+ /**
+ * The value the method should return
+ */
+ public var value:Object;
+
+ /**
+ * customize string representation
+ */
+ override public function toString():String
+ {
+ var s:String = "AssertMethodValue (method cannot be shown) ";
+ return s;
+ }
+
+}
+
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/AssertMethodValue.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/AssertNoEvent.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/AssertNoEvent.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/AssertNoEvent.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/AssertNoEvent.as Wed May 2 22:44:38 2012
@@ -0,0 +1,80 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package {
+
+import flash.display.DisplayObject;
+import flash.display.IBitmapDrawable;
+import flash.utils.*;
+import flash.net.*;
+import flash.events.*;
+import flash.display.*;
+import flash.geom.Matrix;
+
+/**
+ * Tests that the value of a property is as expected
+ * MXML attributes:
+ * target
+ * eventName
+ * eventType
+ * waitTarget (optional)
+ * waitEvent (optional)
+ * timeout (optional)
+ */
+public class AssertNoEvent extends AssertEvent
+{
+ /**
+ * Test the value of a property, log result if failure.
+ */
+ override public function execute(root:DisplayObject, context:UnitTester, testCase:TestCase, testResult:TestResult):Boolean
+ {
+ return true;
+ }
+
+ /**
+ * The event listener
+ */
+ override protected function eventListener(event:Event):void
+ {
+ testCase.setExpirationTime(0);
+
+ numEvents++;
+
+ if (numEvents)
+ {
+ testResult.doFail ("Event " + eventName + " unexpectedly received " + numEvents + " times");
+ return;
+ }
+ }
+
+ /**
+ * customize string representation
+ */
+ override public function toString():String
+ {
+ var s:String = "AssertNoEvent";
+ if (target)
+ s += ": target = " + target;
+ if (eventName)
+ s += ", eventName = " + eventName;
+ return s;
+ }
+
+}
+
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/AssertNoEvent.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/AssertPixelValue.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/AssertPixelValue.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/AssertPixelValue.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/AssertPixelValue.as Wed May 2 22:44:38 2012
@@ -0,0 +1,150 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package {
+
+import flash.display.DisplayObject;
+import flash.display.IBitmapDrawable;
+import flash.events.EventDispatcher;
+import flash.utils.*;
+import flash.net.*;
+import flash.events.*;
+import flash.display.*;
+import flash.geom.Matrix;
+import flash.geom.Point;
+
+import mx.core.mx_internal;
+use namespace mx_internal;
+
+/**
+* Vector of conditionalValue objects.
+**/
+[DefaultProperty("conditionalValues")]
+
+/**
+ * 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")]
+
+/**
+ * Tests that the value of a property is as expected
+ * MXML attributes:
+ * target
+ * value
+ * waitTarget (optional)
+ * waitEvent (optional)
+ * timeout (optional)
+ */
+public class AssertPixelValue extends Assert
+{
+ public var conditionalValues:Vector.<ConditionalValue> = null;
+
+ /**
+ * Test the value of a pixel, log result if failure.
+ */
+ override protected function doStep():void
+ {
+ var cv:ConditionalValue = null;
+ var dispatcher:EventDispatcher = this;
+ var pt:Point = new Point(x, y);
+ var actualTarget:Object = context.stringToObject(target);
+ if (!actualTarget)
+ {
+ testResult.doFail("Target " + target + " not found");
+ return;
+ }
+
+ // Use MultiResult to determine the proper value (or valueExpression, below).
+ if(conditionalValues){
+ cv = new MultiResult().chooseCV(conditionalValues);
+ if(cv){
+ value = uint(cv.value);
+ dispatcher = cv;
+ }
+ }
+
+ var stagePt:Point = actualTarget.localToGlobal(new Point(0, 0));
+ var altPt:Point = actualTarget.localToGlobal(new Point(actualTarget.width, actualTarget.height));
+ stagePt.x = Math.min(stagePt.x, altPt.x);
+ stagePt.y = Math.min(stagePt.y, altPt.y);
+ var screenBits:BitmapData = new BitmapData(actualTarget.width, actualTarget.height);
+ try
+ {
+ screenBits.draw(root.stage, new Matrix(1, 0, 0, 1, -stagePt.x, -stagePt.y));
+ }
+ catch(se2:SecurityError)
+ {
+ screenBits.draw(root, new Matrix(1, 0, 0, 1, -stagePt.x, -stagePt.y));
+ }
+
+ if (dispatcher.hasEventListener("valueExpression"))
+ {
+ context.resetValue();
+ try
+ {
+ dispatcher.dispatchEvent(new RunCodeEvent("valueExpression", root["document"], context, testCase, testResult));
+ }
+ catch (e1:Error)
+ {
+ TestOutput.logResult("Exception thrown evaluating value expression.");
+ testResult.doFail (e1.getStackTrace());
+ return;
+ }
+ value = uint(context.value);
+ if (!context.valueChanged)
+ TestOutput.logResult("WARNING: value was not set by valueExpression. 'value=' missing from expression?");
+ }
+
+ if (screenBits.getPixel(pt.x, pt.y) != value)
+ {
+ testResult.doFail ( target + " pixel at (" + x + "," + y + ") " +
+ screenBits.getPixel(pt.x, pt.y).toString(16).toUpperCase() + " != 0x" + value.toString(16).toUpperCase());
+ }
+ }
+
+ /**
+ * The color value the property should have
+ */
+ public var value:uint;
+
+ /**
+ * The x offset into the component
+ */
+ public var x:Number;
+
+ /**
+ * The y offset into the component
+ */
+ public var y:Number;
+
+ /**
+ * customize string representation
+ */
+ override public function toString():String
+ {
+ var s:String = "AssertPixelValue";
+ if (target)
+ s += ": target = " + target;
+ s += ", x = " + x;
+ s += ", y = " + y;
+ return s;
+ }
+}
+
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/AssertPixelValue.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/AssertPropertyValue.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/AssertPropertyValue.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/AssertPropertyValue.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/AssertPropertyValue.as Wed May 2 22:44:38 2012
@@ -0,0 +1,134 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 mx.core.mx_internal;
+use namespace mx_internal;
+
+/**
+* Vector of conditionalValue objects.
+**/
+[DefaultProperty("conditionalValues")]
+
+/**
+ * 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")]
+
+/**
+ * Tests that the value of a property is as expected
+ * MXML attributes:
+ * target
+ * propertyName
+ * value
+ * waitTarget (optional)
+ * waitEvent (optional)
+ * timeout (optional)
+ */
+public class AssertPropertyValue extends Assert
+{
+ public var conditionalValues:Vector.<ConditionalValue> = null;
+
+ /**
+ * See if the property has the correct value
+ */
+ override protected function doStep():void
+ {
+ var actualTarget:Object = context.stringToObject(target);
+ var multiResultResult:String = "";
+ var cv:ConditionalValue = null;
+ var dispatcher:EventDispatcher = this;
+
+ if (!actualTarget)
+ {
+ testResult.doFail("Target " + target + " not found");
+ return;
+ }
+
+ if (!(propertyName in actualTarget))
+ {
+ testResult.doFail ( target + "." + propertyName + " does not exist");
+ return;
+ }
+
+ // Use MultiResult to determine the proper value (or valueExpression, below).
+ if(conditionalValues){
+ cv = new MultiResult().chooseCV(conditionalValues);
+ if(cv){
+ value = cv.value;
+ dispatcher = cv;
+ }
+ }
+
+ if (dispatcher.hasEventListener("valueExpression"))
+ {
+ context.resetValue();
+ try
+ {
+ dispatcher.dispatchEvent(new RunCodeEvent("valueExpression", root["document"], context, testCase, testResult));
+ }
+ catch (e1:Error)
+ {
+ TestOutput.logResult("Exception thrown evaluating value expression.");
+ testResult.doFail (e1.getStackTrace());
+ return;
+ }
+
+ value = context.value;
+
+ if (!context.valueChanged)
+ TestOutput.logResult("WARNING: value was not set by valueExpression. 'value=' missing from expression?");
+
+ }
+
+ if (valueToString(actualTarget[propertyName]) != valueToString(value))
+ {
+ testResult.doFail ( target + "." + propertyName + " " + valueToString(actualTarget[propertyName]) + " != " + valueToString(value));
+ }
+ }
+
+ /**
+ * The name of the property to test
+ */
+ public var propertyName:String;
+
+ /**
+ * The value the property should have
+ */
+ public var value:Object;
+
+ /**
+ * customize string representation
+ */
+ override public function toString():String
+ {
+ var s:String = "AssertPropertyValue";
+ if (target)
+ s += ": target = " + target;
+ if (propertyName)
+ s += ", propertyName = " + propertyName;
+ return s;
+ }
+}
+
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/AssertPropertyValue.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/AssertStyleValue.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/AssertStyleValue.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/AssertStyleValue.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/AssertStyleValue.as Wed May 2 22:44:38 2012
@@ -0,0 +1,124 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 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")]
+
+/**
+* Vector of conditionalValue objects.
+**/
+[DefaultProperty("conditionalValues")]
+
+/**
+ * Tests that the value of a property is as expected
+ * MXML attributes:
+ * target
+ * styleName
+ * value
+ * waitTarget (optional)
+ * waitEvent (optional)
+ * timeout (optional)
+ */
+public class AssertStyleValue extends Assert
+{
+ public var conditionalValues:Vector.<ConditionalValue> = null;
+
+ /**
+ * Test the value of a property, log result if failure.
+ */
+ override protected function doStep():void
+ {
+ var cv:ConditionalValue = null;
+ var dispatcher:EventDispatcher = this;
+ var actualTarget:Object = context.stringToObject(target);
+
+ if (!actualTarget)
+ {
+ testResult.doFail("Target " + target + " not found");
+ return;
+ }
+
+ // Use MultiResult to determine the proper value (or valueExpression, below).
+ if(conditionalValues){
+ cv = new MultiResult().chooseCV(conditionalValues);
+ if(cv){
+ value = cv.value;
+ dispatcher = cv;
+ }
+ }
+
+ if (dispatcher.hasEventListener("valueExpression"))
+ {
+ context.resetValue();
+ try
+ {
+ dispatcher.dispatchEvent(new RunCodeEvent("valueExpression", root["document"], context, testCase, testResult));
+ }
+ catch (e1:Error)
+ {
+ TestOutput.logResult("Exception thrown evaluating value expression.");
+ testResult.doFail (e1.getStackTrace());
+ return;
+ }
+ value = context.value;
+ if (!context.valueChanged)
+ TestOutput.logResult("WARNING: value was not set by valueExpression. 'value=' missing from expression?");
+ }
+
+ if (valueToString(actualTarget.getStyle(styleName)) != valueToString(value))
+ {
+ testResult.doFail( target + "." + styleName + " " + valueToString(actualTarget.getStyle(styleName)) + " != " + valueToString(value));
+ }
+ }
+
+ /**
+ * The name of the property to test
+ */
+ public var styleName:String;
+
+ /**
+ * The value the property should have
+ */
+ public var value:Object;
+
+ /**
+ * customize string representation
+ */
+ override public function toString():String
+ {
+ var s:String = "AssertStyleValue";
+ if (target)
+ s += ": target = " + target;
+ if (styleName)
+ s += ", styleName = " + styleName;
+ return s;
+ }
+}
+
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/AssertStyleValue.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/AssertTitle.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/AssertTitle.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/AssertTitle.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/AssertTitle.as Wed May 2 22:44:38 2012
@@ -0,0 +1,70 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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")]
+
+/**
+ * Tests that the value of a property is as expected
+ * MXML attributes:
+ * title
+ * waitTarget (optional)
+ * waitEvent (optional)
+ * timeout (optional)
+ */
+public class AssertTitle extends Assert
+{
+ /**
+ * See if the property has the correct value
+ */
+ override protected function doStep():void
+ {
+ var actualTitle:String = ExternalInterface.call("BrowserHistory.getTitle");
+ if (valueToString(actualTitle) != valueToString(title))
+ {
+ testResult.doFail ( "Expected " + valueToString(title) + ", got " + valueToString(actualTitle));
+ }
+ }
+
+ /**
+ * The value the url should have
+ */
+ public var title:String;
+
+ /**
+ * customize string representation
+ */
+ override public function toString():String
+ {
+ var s:String = "AssertTitle";
+ return s;
+ }
+}
+
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/AssertTitle.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/AssertType.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/AssertType.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/AssertType.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/AssertType.as Wed May 2 22:44:38 2012
@@ -0,0 +1,111 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package {
+
+import flash.display.DisplayObject;
+import flash.utils.getQualifiedClassName;
+
+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")]
+
+/**
+ * Tests that the value of a property is as expected
+ * MXML attributes:
+ * target
+ * propertyName
+ * value
+ * waitTarget (optional)
+ * waitEvent (optional)
+ * timeout (optional)
+ */
+public class AssertType extends Assert
+{
+ /**
+ * See if the property has the correct value
+ */
+ override protected function doStep():void
+ {
+ var actualTarget:Object = context.stringToObject(target);
+ if (!actualTarget)
+ {
+ testResult.doFail("Target " + target + " not found");
+ return;
+ }
+
+ if (hasEventListener("valueExpression"))
+ {
+ context.resetValue();
+ try
+ {
+ dispatchEvent(new RunCodeEvent("valueExpression", root["document"], context, testCase, testResult));
+ }
+ catch (e1:Error)
+ {
+ TestOutput.logResult("Exception thrown evaluating value expression.");
+ testResult.doFail (e1.getStackTrace());
+ return;
+ }
+ value = context.value;
+ if (!context.valueChanged)
+ TestOutput.logResult("WARNING: value was not set by valueExpression. 'value=' missing from expression?");
+ }
+
+ if (!(propertyName in actualTarget))
+ {
+ testResult.doFail ( target + "." + propertyName + " does not exist");
+ return;
+ }
+
+ if (getQualifiedClassName(actualTarget[propertyName]) != valueToString(value))
+ {
+ testResult.doFail ( target + "." + propertyName + " " + getQualifiedClassName(actualTarget[propertyName]) + " != " + valueToString(value));
+ }
+ }
+
+ /**
+ * The name of the property to test
+ */
+ public var propertyName:String;
+
+ /**
+ * The value the property should have
+ */
+ public var value:Object;
+
+ /**
+ * customize string representation
+ */
+ override public function toString():String
+ {
+ var s:String = "AssertPropertyValue";
+ if (target)
+ s += ": target = " + target;
+ if (propertyName)
+ s += ", propertyName = " + propertyName;
+ return s;
+ }
+}
+
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/AssertType.as
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/trunk/mustella/as3/src/mustella/AssertURL.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/mustella/as3/src/mustella/AssertURL.as?rev=1333232&view=auto
==============================================================================
--- incubator/flex/trunk/mustella/as3/src/mustella/AssertURL.as (added)
+++ incubator/flex/trunk/mustella/as3/src/mustella/AssertURL.as Wed May 2 22:44:38 2012
@@ -0,0 +1,79 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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")]
+
+/**
+ * Tests that the value of a property is as expected
+ * MXML attributes:
+ * url
+ * waitTarget (optional)
+ * waitEvent (optional)
+ * timeout (optional)
+ */
+public class AssertURL extends Assert
+{
+ /**
+ * See if the property has the correct value
+ */
+ override protected function doStep():void
+ {
+ var actualURL:String = ExternalInterface.call("BrowserHistory.getURL");
+ var pos:int = actualURL.indexOf("#");
+ var actualHash:String = "";
+ if (pos > -1)
+ actualHash = actualURL.substring(pos + 1);
+ var hash:String = "";
+ pos = url.indexOf("#");
+ if (pos > -1)
+ hash = url.substring(pos + 1);
+
+ if (valueToString(actualHash) != valueToString(hash))
+ {
+ testResult.doFail ( "Expected " + valueToString(hash) + ", got " + valueToString(actualHash));
+ }
+ }
+
+ /**
+ * The value the url should have
+ */
+ public var url:String;
+
+ /**
+ * customize string representation
+ */
+ override public function toString():String
+ {
+ var s:String = "AssertURL";
+ return s;
+ }
+}
+
+}
Propchange: incubator/flex/trunk/mustella/as3/src/mustella/AssertURL.as
------------------------------------------------------------------------------
svn:eol-style = native