http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/ErrorArray.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/ErrorArray.as b/mustella/src/main/flex/ErrorArray.as new file mode 100644 index 0000000..b30d234 --- /dev/null +++ b/mustella/src/main/flex/ErrorArray.as @@ -0,0 +1,41 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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 { + public class ErrorArray { + private var _parts:Array; + + public function ErrorArray(parts:Array) { + _parts = parts; + } + + public function get parts():Array { + return _parts; + } + + /** + * customize string representation + */ + public function toString():String { + var s:String; + if (parts && parts.length > 0) + s = '"' + parts.join('"..."') + '"'; + return s; + } + } +}
http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/EventSnifferRemote.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/EventSnifferRemote.as b/mustella/src/main/flex/EventSnifferRemote.as new file mode 100644 index 0000000..f2fe2d2 --- /dev/null +++ b/mustella/src/main/flex/EventSnifferRemote.as @@ -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); + } +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/ExcludeFileLocation.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/ExcludeFileLocation.as b/mustella/src/main/flex/ExcludeFileLocation.as new file mode 100644 index 0000000..ee5ce6f --- /dev/null +++ b/mustella/src/main/flex/ExcludeFileLocation.as @@ -0,0 +1,226 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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.net.URLLoader; +import flash.net.URLRequest; +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 mustellaTestDir: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()); + + _root = root; + + // set up callback to load excludes after + // UnitTester has initialized. + UnitTester.loadExcludeFile = loadExcludeFile; + + } + + public static function loadExcludeFile():void + { + 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"; + } + + url = _root.loaderInfo.url; + + // allow application to override mustella test dir + if (!UnitTester.mustellaTestDir) + mustellaTestDir = url.substring (0, url.indexOf ("mustella/tests")+14); + else + mustellaTestDir = UnitTester.mustellaTestDir; + + 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 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 useFile:String; + + useFile = mustellaTestDir +"/" + 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 "+mustellaTestDir ); + 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 = {}; + 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); + } +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/ExcludeFileLocationApollo.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/ExcludeFileLocationApollo.as b/mustella/src/main/flex/ExcludeFileLocationApollo.as new file mode 100644 index 0000000..56bb0a4 --- /dev/null +++ b/mustella/src/main/flex/ExcludeFileLocationApollo.as @@ -0,0 +1,300 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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 mustellaTestDir: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()); + + _root = root; + + // set up callback to load excludes after + // UnitTester has initialized. + UnitTester.loadExcludeFile = loadExcludeFile; + + } + + + public static function loadExcludeFile():void + { + 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()) ){ + mustellaTestDir = ".."; + excludeFile = UnitTester.excludeFile; + trace("Doing Android style exclude. Checking in " + mustellaTestDir + "/" + excludeFile); + }else if( (UnitTester.cv.os != null) && (UnitTester.cv.os.toLowerCase() == DeviceNames.IOS.toLowerCase()) ){ + mustellaTestDir = File.documentsDirectory.url; + excludeFile = UnitTester.excludeFile; + }else if (os.indexOf ("QNX") > -1) { + mustellaTestDir = ".."; + excludeFile = UnitTester.excludeFile; + trace("Doing QNX style exclude. Checking in " + mustellaTestDir + "/" + excludeFile); + } + else{ + + if (os.indexOf ("Windows") != -1) + { + excludeFile = "ExcludeListWinAIR.txt"; + } else if (os.indexOf ("Mac") != -1) + { + excludeFile = "ExcludeListMacAIR.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"; + } + + 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); + } + + // allow application to override mustella test dir + if (!UnitTester.mustellaTestDir) + mustellaTestDir = url.substring (0, url.indexOf ("mustella/tests")+14); + else + mustellaTestDir = UnitTester.mustellaTestDir; + + 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 = mustellaTestDir +"/" + 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 "+mustellaTestDir ); + 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); + } +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/ExcludeList.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/ExcludeList.as b/mustella/src/main/flex/ExcludeList.as new file mode 100644 index 0000000..bbc24ba --- /dev/null +++ b/mustella/src/main/flex/ExcludeList.as @@ -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 + }; + } + +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/ExcludeList.txt ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/ExcludeList.txt b/mustella/src/main/flex/ExcludeList.txt new file mode 100644 index 0000000..fcf48fb --- /dev/null +++ b/mustella/src/main/flex/ExcludeList.txt @@ -0,0 +1 @@ +CBTester$myButtonTest1 \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/ExcludeListTextFile.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/ExcludeListTextFile.as b/mustella/src/main/flex/ExcludeListTextFile.as new file mode 100644 index 0000000..9ff27ba --- /dev/null +++ b/mustella/src/main/flex/ExcludeListTextFile.as @@ -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; + } + } +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/ExitWhenDone.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/ExitWhenDone.as b/mustella/src/main/flex/ExitWhenDone.as new file mode 100644 index 0000000..1ef9714 --- /dev/null +++ b/mustella/src/main/flex/ExitWhenDone.as @@ -0,0 +1,49 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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 { + +COMPILE::SWF +{ +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 + */ + COMPILE::SWF + public static function init(root:DisplayObject):void + { + UnitTester.exitWhenDone = true; + } + +} +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/FakeSoftKeyboard.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/FakeSoftKeyboard.as b/mustella/src/main/flex/FakeSoftKeyboard.as new file mode 100644 index 0000000..6f7629e --- /dev/null +++ b/mustella/src/main/flex/FakeSoftKeyboard.as @@ -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.display.InteractiveObject; +import flash.display.Sprite; +import flash.events.FocusEvent; +import flash.events.SoftKeyboardEvent; +import flash.events.SoftKeyboardTrigger; +import flash.geom.Rectangle; +import flash.text.TextField; +import flash.utils.getQualifiedClassName; + +import mx.core.mx_internal; + +[Mixin] +/** + * A hash table of tests not to run. + */ +public class FakeSoftKeyboard +{ + + private static var kbdrect:QName = new QName(mx_internal, "_softKeyboardRect"); + + public static var portraitHeight:Number = 200; + public static var landscapeHeight:Number = 150; + + /** + * Mixin callback that checks if we're in the emulator + * and tries to fake what would happen in terms of events + * and sizing if you were on the device. It doesn't actually + * need a useful UI since to type, you should just use + * DispatchKeyEvent + */ + public static function init(root:DisplayObject):void + { + if (DeviceNames.getFromOS() == "") + return; // not mac or win + + FakeSoftKeyboard.root = root; + + root.addEventListener(FocusEvent.FOCUS_IN, focusInHandler); + root.addEventListener(FocusEvent.FOCUS_OUT, focusOutHandler); + } + + public static var kbd:Sprite; + public static var root:DisplayObject; + + public static function focusInHandler(event:FocusEvent):void + { + var comp:Object = event.target; + if (comp is TextField || comp is InteractiveObject) + { + var className: String = getQualifiedClassName(comp); + if (!(comp.needsSoftKeyboard || className.indexOf("StyleableStageText") > 0 || className.indexOf("ScrollableStageText") > 0 )) + return; + + if (!comp.dispatchEvent(new SoftKeyboardEvent(SoftKeyboardEvent.SOFT_KEYBOARD_ACTIVATING, + true, true, event.relatedObject, SoftKeyboardTrigger.USER_TRIGGERED))) + { + root.stage.focus = null; + return; + } + + if (!kbd) + { + kbd = new Sprite(); + kbd.graphics.beginFill(0x808080); + kbd.graphics.drawRect(0, 0, 10, 10); + kbd.graphics.endFill(); + } + + // root is actually a systemManager + if (kbd.parent == null) + root["popUpChildren"].addChild(kbd); + if (root.stage.stageHeight > root.stage.stageWidth) + { + kbd.height = portraitHeight; + kbd.width = root.stage.stageWidth; + kbd.y = root.stage.stageHeight - portraitHeight; + root["document"][kbdrect] = new Rectangle(0, kbd.y, kbd.width, kbd.height); + } + else + { + kbd.height = landscapeHeight; + kbd.width = root.stage.stageWidth; + kbd.y = root.stage.stageHeight - landscapeHeight; + root["document"][kbdrect] = new Rectangle(0, kbd.y, kbd.width, kbd.height); + } + trace("sent softKeyboardActivate from", comp); + comp.dispatchEvent(new SoftKeyboardEvent(SoftKeyboardEvent.SOFT_KEYBOARD_ACTIVATE, + true, false, event.relatedObject, SoftKeyboardTrigger.USER_TRIGGERED)); + } + } + + public static function focusOutHandler(event:FocusEvent):void + { + trace("fakesoftkeyboard focusOut", event.target, event.relatedObject, kbd); + if (kbd && kbd.parent) + { + // root is actually a systemManager + root["popUpChildren"].removeChild(kbd); + root["document"][kbdrect] = new Rectangle(0, 0, 0, 0); + trace("sent softKeyboardDeactivate from", event.target); + event.target.dispatchEvent(new SoftKeyboardEvent(SoftKeyboardEvent.SOFT_KEYBOARD_DEACTIVATE, + true, false, event.relatedObject, SoftKeyboardTrigger.USER_TRIGGERED)); + } + } + +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/IncludeFileLocation.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/IncludeFileLocation.as b/mustella/src/main/flex/IncludeFileLocation.as new file mode 100644 index 0000000..6517c27 --- /dev/null +++ b/mustella/src/main/flex/IncludeFileLocation.as @@ -0,0 +1,100 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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.system.Security; + +[Mixin] +/** + * A hash table of tests not to run, read from IncludeList.txt + * The file is one test per line of the form ScriptName$TestID + * The location of the file is assumed to be c:/tmp on windows, + * or /tmp on Unix + */ +public class IncludeFileLocation +{ + + private static var loader:URLLoader; + + /** + * tell UnitTester it should wait for this load to complete + */ + UnitTester.waitForIncludes = true; + + /** + * Mixin callback that gets everything ready to go. + * Table is of form: ScriptName$TestID: 1, + */ + public static function init(root:DisplayObject):void + { + + + var currentOS:String = Capabilities.os; + + var useFile:String; + + if (currentOS.indexOf ("Windows") != -1) + { + useFile = "c:/tmp/IncludeList.txt"; + } else { + + useFile = "/tmp/IncludeList.txt"; + if (Security.sandboxType == Security.APPLICATION) + useFile = "file:///tmp/IncludeList.txt"; + + } + + + var req:URLRequest = new URLRequest(useFile); + 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.includeList = {}; + 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.includeList[s] = 1; + } + UnitTester.waitForIncludes = false; + UnitTester.pre_startEventHandler(event); + } +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/IncludeList.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/IncludeList.as b/mustella/src/main/flex/IncludeList.as new file mode 100644 index 0000000..1e91b1d --- /dev/null +++ b/mustella/src/main/flex/IncludeList.as @@ -0,0 +1,45 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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 IncludeList +{ + + /** + * Mixin callback that gets everything ready to go. + * Table is of form: ScriptName$TestID: 1, + */ + public static function init(root:DisplayObject):void + { + UnitTester.includeList = { + CBTester: 1, + CBTester$myButtonTest1: 1, + CBTester$myTest2: 1 + }; + } + +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/IncludeList.txt ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/IncludeList.txt b/mustella/src/main/flex/IncludeList.txt new file mode 100644 index 0000000..fcf48fb --- /dev/null +++ b/mustella/src/main/flex/IncludeList.txt @@ -0,0 +1 @@ +CBTester$myButtonTest1 \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/IncludeListTextFile.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/IncludeListTextFile.as b/mustella/src/main/flex/IncludeListTextFile.as new file mode 100644 index 0000000..7be8649 --- /dev/null +++ b/mustella/src/main/flex/IncludeListTextFile.as @@ -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 IncludeList.txt + * The file is one test per line of the form ScriptName$TestID + */ +public class IncludeListTextFile +{ + + 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("IncludeList.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.includeList = {}; + 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.includeList[s] = 1; + } + } +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/Localhost8080.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/Localhost8080.as b/mustella/src/main/flex/Localhost8080.as new file mode 100644 index 0000000..5531550 --- /dev/null +++ b/mustella/src/main/flex/Localhost8080.as @@ -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 Localhost8080 +{ + + /** + * Mixin callback that gets everything ready to go. + * The UnitTester waits for an event before starting + */ + public static function init(root:DisplayObject):void + { + UnitTester.portNumber = 8080; + } + + +} +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/MobileConfig.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/MobileConfig.as b/mustella/src/main/flex/MobileConfig.as new file mode 100644 index 0000000..59764c5 --- /dev/null +++ b/mustella/src/main/flex/MobileConfig.as @@ -0,0 +1,30 @@ +package { +import flash.display.DisplayObject; +import flash.system.Capabilities; +[Mixin] +/** +* By including this mixin via CompileMustellaSwfs, we +* can set up some variables for UnitTester to use for +* an Android run. +*/ +public class MobileConfig +{ + public static function init(root:DisplayObject):void + { + if( UnitTester.cv == null ){ + UnitTester.cv = new ConditionalValue(); + } + UnitTester.cv.device = "mac"; + UnitTester.cv.os = "android"; + UnitTester.cv.targetOS = "android"; + UnitTester.cv.osVersion = "${os_version}"; + UnitTester.cv.deviceDensity = Util.roundDeviceDensity( flash.system.Capabilities.screenDPI ); + UnitTester.cv.screenDPI = flash.system.Capabilities.screenDPI; + //UnitTester.cv.deviceWidth = set by MultiResult; + //UnitTester.cv.deviceHeight = set by MultiResult; + //UnitTester.cv.color = this is not defined yet, but there are rumours it might be. + UnitTester.run_id = "-1"; + UnitTester.excludeFile = "ExcludeList${os}.txt"; + } +} +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/MouseSnifferRemote.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/MouseSnifferRemote.as b/mustella/src/main/flex/MouseSnifferRemote.as new file mode 100644 index 0000000..94f0bf2 --- /dev/null +++ b/mustella/src/main/flex/MouseSnifferRemote.as @@ -0,0 +1,282 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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.geom.Point; +import flash.net.LocalConnection; +import flash.utils.describeType; +import flash.utils.getQualifiedClassName; + +import mx.core.IDeferredInstantiationUIComponent; +import mx.core.IUIComponent; +import mx.managers.SystemManager; + +import mx.core.mx_internal; +use namespace mx_internal; + +[Mixin] +/** + * Tries to show location and target path of mouse + */ +public class MouseSnifferRemote +{ + public function MouseSnifferRemote() + { + } + + public static function init(root:Object):void + { + document = root; + connection = new LocalConnection(); + connection.allowDomain("*"); + connection.addEventListener(StatusEvent.STATUS, statusHandler); + + // Turn on only if the SnifferRemoteClient app's checkbox + // for this item is checked. + connection.send("_MouseSniffer", "toggleSniffersEnabled"); + + mousecommandconnection = new LocalConnection(); + mousecommandconnection.allowDomain("*"); + mousecommandconnection.client = MouseSnifferRemote; + mousecommandconnection.connect("_MouseSnifferCommands"); + } + + 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 mousecommandconnection:LocalConnection; + + public static function enableSniffer():void + { + //trace("MouseSnifferRemote enabled"); + + 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); + } + + public static function disableSniffer():void + { + //trace("MouseSnifferRemote disabled"); + + 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); + } + + public static var propLists:Object = new Object(); + + private static function uberListener(event:MouseEvent):void + { + var target:String = findPath(event.target); + var pt:Point = new Point(event.stageX, event.stageY); + var obj:Object = document.document; + var s:String = target; + var dot:int = s.indexOf("."); + var info:Object = new Object(); + + if (dot != -1) + { + var pieces:Array = s.split("."); + for (var i:int = 0; i < pieces.length; i++) + { + s = pieces[i]; + if (s != null && s.indexOf("getChildAt(") == 0) + { + s = s.substring(11); + s = s.substring(0, s.length - 1); + obj = obj.getChildAt(parseInt(s)); + } + else + { + if (obj!=null && s != null && s in obj) + obj = obj[s]; + else + { + // couldn't find the piece so document chain is broken. + // Containers as item renderers break this + target = ""; + for (var j:int = 0; j < i; j++) + { + target += pieces[j]; + if (j < i - 1) + target += "." + } + break; + } + } + } + } + else if (s.length && s.indexOf(" ") == -1) + obj = obj[s]; + + if (obj != null) + pt = obj.globalToLocal(pt); + + if (target == null || target == ""){ + //connection.send("_MouseSniffer", "appendLog", "Mouse", "stage: " + pt.x + "," + pt.y + " stage: " + event.stageX + "," + event.stageY); + + info.dataSource = "Mouse"; + info.target = "stage: " + pt.x + "," + pt.y + " stage: " + event.stageX + "," + event.stageY; + info.eventName = ""; + info.event = ""; + + connection.send("_MouseSniffer", "appendLog", info); + + }else{ + //connection.send("_MouseSniffer", "appendLog", "Mouse", target + " " + pt.x + "," + pt.y + " stage: " + event.stageX + "," + event.stageY); + info.dataSource = "Mouse"; + info.target = target + " " + pt.x + "," + pt.y + " stage: " + event.stageX + "," + event.stageY; + info.eventName = ""; + info.event = ""; + + connection.send("_MouseSniffer", "appendLog", info); + + } + } + + private static function findPath(target:Object, name:String = ""):String + { + var s:String = target.toString(); + var dot:int = s.indexOf("."); + if (dot == -1) + { + if (target == document.document || target.parent == document.document) + return name; + } + + while (target) + { + if (target is IDeferredInstantiationUIComponent) + { + var targetName:String = target.id; + // id of component in document + if (target.id && target.id in target.document) + { + if (target.document[target.id] is Array) + { + var arr:Array = target.document[target.id]; + for (var i:int = 0; i < arr.length; i++) + { + if (arr[i] == target) + { + targetName += "." + i; + break; + } + } + } + + name = (name == "") ? targetName : targetName + "." + name; + return findPath(target.document, name); + } + // MXML component has id in parent document + if (target.id && target.document == target) + { + name = (name == "") ? target.id : target.id + "." + name; + return findPath(target.parent.document, name); + } + } + if (target.parent == document.document) + break; + + if (target.parent is SystemManager) + { + // must be a popup + if (target is IUIComponent) + { + s = findPropertyInOwner(target) + if (s) + { + name = (name == "") ? s : s + "." + name; + target = target.owner; + continue; + } + } + + var index:int = document.document.systemManager.rawChildren.getChildIndex(target as DisplayObject); + s = "systemManager.rawChildren.getChildAt(" + index + ")"; + name = (name == "") ? s : s + "." + name; + return name; + } + target = target.parent; + } + return "no component with id under mouse"; + + } + + private static function findPropertyInOwner(target:Object):String + { + var owner:Object = target.owner; + var className:String = getQualifiedClassName(owner); + var propList:XMLList = propLists[className]; + if (!propList) + { + var dt:XML = describeType(owner); + propList = dt..accessor.(@type != "Number" && @type != "String" && @type != "int" && @type != "Boolean" + && @type != "Array" && @type != "Object" && @type != "Class" && @access != "writeonly") + + dt..variable.(@type != "Number" && @type != "String" && @type != "int" && @type != "Boolean" + && @type != "Array" && @type != "Object" && @type != "Class"); + propLists[className] = propList; + } + var n:int = propList.length(); + for (var i:int = 0; i < n; i++) + { + var propName:String = propList[i].@name.toString(); + if (owner[propName] == target) + return propName; + } + return null; + } + + +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/MultiResult.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/MultiResult.as b/mustella/src/main/flex/MultiResult.as new file mode 100644 index 0000000..6c92306 --- /dev/null +++ b/mustella/src/main/flex/MultiResult.as @@ -0,0 +1,193 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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 mx.core.FlexGlobals; + import mx.core.mx_internal; + + use namespace mx_internal; + + [DefaultProperty("conditionalValues")] + public class MultiResult + { + private var conditionalValues:Vector.<ConditionalValue>; + + public function MultiResult(){ + } + + /** + * Loop through the conditional values and process the ones which apply to our configuration. + * Functionally, it should work like this: + * 1) Any number of mismatches will case a CV to be ignored. + * 2) Empty CVs will be ignored. + * 3) Among device matches, pick the best. + * 4) If no match yet, among the remaining, pick the one with the most matches. + * 5) If no match yet, the TestStep's is used. + * + * Called by determineResult() and CompareBitmap's execute(). + **/ + public function chooseCV(conditionalValues:Vector.<ConditionalValue>):ConditionalValue{ + var i:int; + var cv:ConditionalValue; + //var cvToUse:ConditionalValue = null; + var cvUT:ConditionalValue = UnitTester.cv; + + var bestDeviceMatch:ConditionalValue = null; + var bestNonDeviceMatch:ConditionalValue = null; + + var bestDeviceMatchCount:int = 0; // # matches for the best match, among device matches + var bestNonDeviceMatchCount:int = 0; // # matches for the best match + var numMatches:int = 0; + + // When running mobile on desktop, set some items in UnitTester's CV later + if( cvUT.deviceWidth == -1 ){ + cvUT.deviceWidth = FlexGlobals.topLevelApplication.width; + } + + if( cvUT.deviceHeight == -1 ){ + cvUT.deviceHeight = FlexGlobals.topLevelApplication.height; + } + + //trace("MultiResult.chooseCV(): Actual test environment is: \n" + cvUT.toString()); + + for(i = 0; i < conditionalValues.length; ++i){ + cv = conditionalValues[ i ]; + + // This is an empty one; ignore it. + if( cv.isDefault() ){ + continue; + } + + numMatches = countMatches( cv, cvUT ); + //trace("numMatches="+numMatches+" with "+cv); + + if( numMatches <= 0 ) // -1 is a mismatch, and 0 is no matches. + continue; + + if( cv.device && cvUT.device && (cv.device == cvUT.device) ){ + + if( numMatches > bestDeviceMatchCount ){ + bestDeviceMatchCount = numMatches; + bestDeviceMatch = cv; + } + }else{ + + if( numMatches > bestNonDeviceMatchCount ){ + bestNonDeviceMatchCount = numMatches; + bestNonDeviceMatch = cv; + } + } + } + + /** + if( bestDeviceMatch != null ) + trace("MultiResult.chooseCV(): bestDeviceMatch:\n" + bestDeviceMatch.toString()); + else + trace("MultiResult.chooseCV(): bestDeviceMatch: null"); + + if( bestNonDeviceMatch != null ) + trace("MultiResult.chooseCV(): bestNonDeviceMatch:\n" + bestNonDeviceMatch.toString()); + else + trace("MultiResult.chooseCV(): bestNonDeviceMatch: null"); + **/ + + if( bestDeviceMatch != null ) + return bestDeviceMatch; + else if( bestNonDeviceMatch != null ) + return bestNonDeviceMatch; + else + return null; + } + + + /** + * Count the matches between two CVs. + * If a value is unset in either, it's not a match or a mismatch. + * Returns 0 if no matches. + * Returns -1 immediately if a mismatch occurs. + **/ + private function countMatches( cv1:ConditionalValue, cv2:ConditionalValue ):int{ + var ret:int = 0; + + // if .targetOS has been set in cv2 (which is the baseline as specified by options) + // use that for comparison otherwise use the normal .os + var os:String = cv2.targetOS != null ? cv2.targetOS : cv2.os; + + if( (cv1.os != null) && (os != null) ){ + if( cv1.os != os ) + return -1; + else + ++ret; + } + + if( (cv1.osVersion != null) && (cv2.osVersion != null) ){ + if( cv1.osVersion != cv2.osVersion ) + return -1; + else + ++ret; + } + + if( (cv1.screenDPI > -1) && (cv2.screenDPI > -1) ){ + if( cv1.screenDPI != cv2.screenDPI ) + return -1; + else + ++ret; + } + + if( (cv1.deviceDensity > -1) && (cv2.deviceDensity > -1) ){ + if( cv1.deviceDensity != cv2.deviceDensity ) + return -1; + else + ++ret; + } + + if( (cv1.deviceWidth > -1) && (cv2.deviceWidth > -1) ){ + if( cv1.deviceWidth != cv2.deviceWidth ) + return -1; + else + ++ret; + } + + if( (cv1.deviceHeight > -1) && (cv2.deviceHeight > -1) ){ + if( cv1.deviceHeight != cv2.deviceHeight ) + return -1; + else + ++ret; + } + + if( (cv1.color > -1) && (cv2.color > -1) ){ + if( cv1.color != cv2.color ) + return -1; + else + ++ret; + } + + if( (cv1.device != null) && (cv2.device != null) ){ + if( cv1.device != cv2.device ) + return -1; + else + ++ret; + } + + return ret; + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/MustellaLogEvent.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/MustellaLogEvent.as b/mustella/src/main/flex/MustellaLogEvent.as new file mode 100644 index 0000000..48bc5c6 --- /dev/null +++ b/mustella/src/main/flex/MustellaLogEvent.as @@ -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.events.Event; + +/** + * The event passed into any code being + * run in a RunCode step. It supplies + * some useful references + */ +public class MustellaLogEvent extends Event +{ + public function MustellaLogEvent (type:String, msg:String) + { + super(type); + this.msg = msg; + } + + /** + * The msg to be logged + */ + public var msg:String; + + +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/MustellaPNGEncoder.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/MustellaPNGEncoder.as b/mustella/src/main/flex/MustellaPNGEncoder.as new file mode 100644 index 0000000..8aaa1ef --- /dev/null +++ b/mustella/src/main/flex/MustellaPNGEncoder.as @@ -0,0 +1,183 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +//////////////////////////////////////////////////////////////////////////////// + +/** + * writes bitmaps into PNG format. + * original author, Ely + */ +package { + + import flash.display.*; + import flash.geom.*; + import flash.utils.*; + import flash.net.*; + +public class MustellaPNGEncoder { + + + private var _png:ByteArray; + + // empty constructor + public function MustellaPNGEncoder () { + } + + public function encode(img:BitmapData):ByteArray + { + var imgWidth:uint = img.width; + var imgHeight:uint = img.height; + + var imgData:ByteArray = img.getPixels(new Rectangle(0,0,imgWidth,imgHeight)); + + _png = new ByteArray(); + + _png.writeByte(137); + _png.writeByte(80); + _png.writeByte(78); + _png.writeByte(71); + _png.writeByte(13); + _png.writeByte(10); + _png.writeByte(26); + _png.writeByte(10); + + var IHDR:ByteArray = new ByteArray(); + IHDR.writeInt(imgWidth); + IHDR.writeInt(imgHeight); + IHDR.writeByte(8); // color depth: 8 bpp + IHDR.writeByte(6); // color type: RGBA + IHDR.writeByte(0); // compression: ZLIB + IHDR.writeByte(0); // filter method + IHDR.writeByte(0); // not interlaced; + + writeChunk([0x49,0x48,0x44,0x52],IHDR); + + var IDAT:ByteArray= new ByteArray(); + for(var i:uint=0;i<imgHeight;i++) { + IDAT.writeByte(0); + for(var j:uint=0;j<imgWidth;j++) { + var p:uint = img.getPixel32(j,i); + IDAT.writeByte((p>>16)&0xFF); + IDAT.writeByte((p>> 8)&0xFF); + IDAT.writeByte((p )&0xFF); + IDAT.writeByte((p>>24)&0xFF); + } + } + + IDAT.compress(); + writeChunk([0x49,0x44,0x41,0x54],IDAT); + + + + writeChunk([0x49,0x45,0x4E,0x44],null); + return _png; + } + + public function dump():String + { + _png.position = 0; + var out:String =""; + for(var i:uint=0;i<_png.length;i++) { + var code:String = "0123456789abcdef"; + var v:uint = _png.readUnsignedByte(); + out += code.charAt((v & 0xF0) >> 4); + out += code.charAt(v & 0xF); + out += " "; + } + return out; + } + private function writeChunk(type:Array,data:ByteArray):void + { + var len:uint = 0; + if(data != null) + len = data.length; // data length + _png.writeUnsignedInt(len); + + var p:uint = _png.position; + + _png.writeByte(type[0]); + _png.writeByte(type[1]); + _png.writeByte(type[2]); + _png.writeByte(type[3]); + if(data != null) + _png.writeBytes(data); + + var endP:uint = _png.position; + _png.position = p; + var c:uint = crc(_png,endP-p); + _png.position = endP; + _png.writeUnsignedInt(c); + } + + /* Table of CRCs of all 8-bit messages. */ + private static var crc_table:Array; + + /* Flag: has the table been computed? Initially false. */ + private static var crc_table_computed:Boolean = false; + + /* Make the table for a fast CRC. */ + private function make_crc_table():void + { + var c:uint; + var n:int; + var k:int; + + crc_table = []; + + for (n = 0; n < 256; n++) { + c = n; + for (k = 0; k < 8; k++) { + if (c & 1) + c = uint(uint(0xedb88320) ^ uint(c >>> 1)); + else + c = uint(c >>> 1); + } + crc_table[n] = c; + } + crc_table_computed = true; + } + + /* Update a running CRC with the bytes buf[0..len-1]--the CRC + should be initialized to all 1's, and the transmitted value + is the 1's complement of the final running CRC (see the + crc() routine below)). */ + + private function update_crc(crc:uint, buf:ByteArray, + len:uint):uint + { + var c:uint = crc; + var n:int; + var v:uint; + + if (!crc_table_computed) + make_crc_table(); + for (n = 0; n < len; n++) { + v = buf.readUnsignedByte(); + c = uint(crc_table[(c ^ v) & uint(0xff)] ^ uint(c >>> 8)); + } + return c; + } + + /* Return the CRC of the bytes buf[0..len-1]. */ + private function crc(buf:ByteArray, len:uint):uint + { + var cc:uint = update_crc(uint(0xffffffff), buf, len); + return uint(cc ^ uint(0xffffffff)); + } + +} +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/MustellaRealTimeLogger.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/MustellaRealTimeLogger.as b/mustella/src/main/flex/MustellaRealTimeLogger.as new file mode 100644 index 0000000..d009de7 --- /dev/null +++ b/mustella/src/main/flex/MustellaRealTimeLogger.as @@ -0,0 +1,68 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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.DataEvent; + import flash.net.XMLSocket; + + public class MustellaRealTimeLogger + { + private static var socketAvailable:Boolean = false; + private static var isInitialized:Boolean = false; + private static var xmlsock:XMLSocket = new XMLSocket(); + + public static function Init():void + { + try + { + xmlsock.connect("127.0.0.1", 13000); + //xmlsock.addEventListener(DataEvent.DATA, onData); + + socketAvailable = true; + isInitialized = true; + } + catch(e:Error) + { + } + } + + public function onData(event:DataEvent):void + { + //indata.text = event.text; + } + + public static function sendData(xmlFormattedData:String):void + { + if(!isInitialized) + { + Init(); + } + + xmlsock.send(xmlFormattedData + "\n"); + } + + public static function Close():void + { + if((socketAvailable) && (isInitialized)) + { + xmlsock.close(); + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/MustellaSandboxEvent.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/MustellaSandboxEvent.as b/mustella/src/main/flex/MustellaSandboxEvent.as new file mode 100644 index 0000000..9ce8b0f --- /dev/null +++ b/mustella/src/main/flex/MustellaSandboxEvent.as @@ -0,0 +1,53 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package { + +import flash.events.Event; + +/** + * An event used as a message passed across security domain boundaries + */ +public class MustellaSandboxEvent extends Event +{ + public static const MUSTELLA_STARTED:String = "mustellaStarted"; + public static const STRING_TO_OBJECT:String = "stringToObject"; + public static const GET_BITMAP:String = "getBitmap"; + public static const GET_EFFECTS:String = "getEffects"; + public static const GET_OBJECTS_UNDER_POINT:String = "getObjectsUnderPoint"; + public static const RESET_COMPONENT:String = "resetComponent"; + public static const MOUSEXY:String = "mouseXY"; + public static const GET_FOCUS:String = "getFocus"; + public static const APP_READY:String = "appReady"; + + /** + * + */ + public function MustellaSandboxEvent(type:String) + { + super(type); + } + + // the string to be parsed and turned into an object + public var string:String; + + // the object returned. + public var obj:Object; +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/NoFail.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/NoFail.as b/mustella/src/main/flex/NoFail.as new file mode 100644 index 0000000..3cf3793 --- /dev/null +++ b/mustella/src/main/flex/NoFail.as @@ -0,0 +1,41 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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] +/** + * Class to report no failures. + * allows tests to continue. Useful for bitmap replacement, etc + */ +public class NoFail +{ + + /** + * Set a flag to ignore all failures (and don't report them) + */ + public static function init(root:DisplayObject):void + { + UnitTester.noFail = true; + } + + +} +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/ObjectSnifferRemote.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/ObjectSnifferRemote.as b/mustella/src/main/flex/ObjectSnifferRemote.as new file mode 100644 index 0000000..272af28 --- /dev/null +++ b/mustella/src/main/flex/ObjectSnifferRemote.as @@ -0,0 +1,333 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package +{ +import flash.display.BitmapData; +import flash.display.DisplayObject; +import flash.events.Event; +import flash.events.MouseEvent; +import flash.events.StatusEvent; +import flash.geom.Matrix; +import flash.geom.Point; +import flash.net.LocalConnection; +import flash.utils.getQualifiedClassName; + +import mx.managers.IFocusManagerComponent; +import mx.managers.SystemManager; +import mx.core.FlexGlobals; +import mx.core.IFlexDisplayObject; +import mx.core.IMXMLObject; +import mx.core.UIComponent; +// import mx.core.Container; +import mx.utils.ObjectUtil; + +import mx.core.mx_internal; +use namespace mx_internal; + +[Mixin] +/** + * Displays object properties and values to SnifferRemoteClient + */ +public class ObjectSnifferRemote +{ + public function ObjectSnifferRemote() + { + } + + public static function init(root:Object):void + { + + _root = 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 = ObjectSnifferRemote; + commandconnection.connect("_ObjectSnifferCommands"); + } + + private static function initHandler(event:Event):void + { + //enableSniffer(); + } + + private static function statusHandler(event:Event):void + { + } + + /** + * @private + * The document containing a reference to this object + */ + private static var document:Object; + private static var _root:Object; + + /** + * @private + * The local connection to the remote client + */ + private static var connection:LocalConnection; + private static var commandconnection:LocalConnection; + + private static var snifferEnabled:Boolean = true; + + public static function enableSniffer():void + { + snifferEnabled = true; + } + + public static function disableSniffer():void + { + snifferEnabled = false; + } + + private static function appendLog(s:String):void + { + //connection.send("_ObjectSniffer", "appendLog", "Object", s); + + var info:Object = new Object(); + + info.dataSource = "Object"; + info.target = s; + info.eventName = ""; + info.event = ""; + + /** + trace("ObjectSniffer is sending: "); + trace (" info.dataSource: " + info.dataSource); + trace (" info.target: " + info.target); + trace (" info.eventName: " + info.eventName); + trace (" info.event: " + info.event); + **/ + + connection.send("_ObjectSniffer", "appendLog", info); + } + + public static function dumpObject(s:String):void + { + if (!snifferEnabled) + return; + + var obj:* = stringToObject(s); + if (obj === null) + { + appendLog(s + " = null"); + } + else if (obj === undefined) + { + appendLog(s + " = undefined"); + } + else if (obj is String) + { + appendLog(s + " = " + obj); + } + else if (obj is Boolean) + { + appendLog(s + " = " + obj.toString()); + } + else if (obj is uint) + { + appendLog(s + " = " + obj.toString(10) + " (0x" + obj.toString(16).toUpperCase() + ")"); + } + else if (obj is Number) + { + appendLog(s + " = " + obj.toString()); + } + else if (obj is XML || obj is XMLList) + { + if (obj is XMLList && obj.length() == 1) + appendLog(s + " = " + obj.toString()); + else if (obj is XMLList && obj.length() == 0) + appendLog(s + " not found"); + else + appendLog(s + " = " + obj.toXMLString()); + } + else if (obj is Array) + { + appendLog(s + " = Array"); + } + else appendLog(s + " = " + getQualifiedClassName(obj)); + } + + public static function listProperties(s:String):void + { + document.document.callLater(listProperties_cb, [s]); + } + + public static function listProperties_cb(s:String):void + { + if (!snifferEnabled) + return; + + var n:int; + var i:int; + + var obj:* = stringToObject(s); + if (obj === null) + { + appendLog(s + " is null, has no properties"); + } + else if (obj === undefined) + { + appendLog(s + " is undefined, has no properties"); + } + else if (obj is String) + { + appendLog(s + " is String, has no properties"); + } + else if (obj is uint) + { + appendLog(s + " is uint, has no properties"); + } + else if (obj is uint) + { + appendLog(s + " is int, has no properties"); + } + else if (obj is Number) + { + appendLog(s + " is Number, has no properties"); + } + else if (obj is XML) + { + appendLog(s); + appendLog(" attributes:"); + var attrs:XMLList = obj.attributes(); + n = attrs.length(); + for (i = 0; i < n; i++) + { + appendLog(" " + attrs[i].name()); + } + var children:XMLList = obj.children(); + n = children.length(); + var namesTable:Object = {}; + for (i = 0; i < n; i++) + { + namesTable[children[i].name()] = 1; + } + appendLog(" children:"); + for (var p:String in namesTable) + appendLog(" " + p); + } + else if (obj is Array) + { + appendLog(s + " is Array of length " + obj.length); + } + else + { + var info:Object = ObjectUtil.getClassInfo(obj, null, { includeReadOnly: true, includeTransient: true, uris: ["", "mx_internal"] } ); + appendLog(s + " = " + info.name); + n = info.properties.length; + for (i = 0; i < n; i++) + appendLog(" " + info.properties[i]); + } + + } + + /** + * direct copy of UnitTester's stringToObject, except that it doesn't handle "script" + * take an expression, find the object. + * handles mx_internal:propName + * a.b.c + * getChildAt() + */ + public static function stringToObject(s:*):* + { + if (s == null || s == "") + return _root["document"]; + + try + { + var propName:* = s; + if (s.indexOf("mx_internal:") == 0) + propName = new QName("mx_internal", s.substring(12)); + if (s.indexOf("getChildAt(") == 0 && s.indexOf(".") == -1) + { + s = s.substring(11); + s = s.substring(0, s.indexOf(")")); + return _root["document"].getChildAt(parseInt(s)); + } + return _root["document"][propName]; + } + catch (e:Error) + { + // maybe it is a class + var dot:int; + var cc:int = s.indexOf("::"); + var className:String = s; + var obj:Object = _root["document"]; + if (cc > 0) + { + dot = s.indexOf(".", cc); + if (dot >= 0) + { + className = s.substring(0, dot); + s = s.substring(dot + 1); + } + else + s = ""; + } + else + dot = s.indexOf("."); + + try + { + obj = _root["info"]().currentDomain.getDefinition(className); + } + catch (e:Error) + { + if (dot == -1) + return undefined; + } + if (dot == -1) + return obj; + + var list:Array = s.split("."); + while (list.length) + { + try + { + s = list.shift(); + if (s.indexOf("mx_internal:") == 0) + s = new QName(mx_internal, s.substring(12)); + if (s is String && s.indexOf("getChildAt(") == 0) + { + s = s.substring(11); + s = s.substring(0, s.indexOf(")")); + obj = obj.getChildAt(parseInt(s)); + } + else + obj = obj[s]; + } + catch (e:Error) + { + return undefined; + } + } + return obj; + } + return null; + } + +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/Pause.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/Pause.as b/mustella/src/main/flex/Pause.as new file mode 100644 index 0000000..13349d3 --- /dev/null +++ b/mustella/src/main/flex/Pause.as @@ -0,0 +1,66 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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.setTimeout; + +import mx.core.mx_internal; +use namespace mx_internal; + +/** + * The test step that sets a property to some value + * MXML attributes: + * + * waitTarget (optional) + * waitEvent (optional) + * timeout + */ +public class Pause extends TestStep +{ + public var reason:String; + + 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; + + setTimeout(stepComplete, timeout); + TestOutput.logResult(this.toString()); + + return false; + } + + /** + * customize string representation + */ + override public function toString():String + { + var s:String = "Paused for " + timeout + "ms."; + + if(this.reason != null) + s = s + " Reason: " + this.reason; + + return s; + } +} + +}