FLEX-34809 Flex Code Coverage Tool This is a tool designed to be run from the command line as part of a build to create code coverage reports.
The tool has three pieces: 1. A Flex client that listens to the executed lines in the running SWF and sends them over a socket to a Java server. 2. A Java server that reads the executed lines and writes them to disk. 3. A reporting tool that analyzes the executed lines and creates a report. In addition to the source, this commit contains command line scripts, a Flash Builder project file for the Flex code and an Eclipse project file for the Java code. Project: http://git-wip-us.apache.org/repos/asf/flex-utilities/repo Commit: http://git-wip-us.apache.org/repos/asf/flex-utilities/commit/5077c457 Tree: http://git-wip-us.apache.org/repos/asf/flex-utilities/tree/5077c457 Diff: http://git-wip-us.apache.org/repos/asf/flex-utilities/diff/5077c457 Branch: refs/heads/develop Commit: 5077c457aa7473b4d889b015b98c8beaedbc8ce9 Parents: 257a7b7 Author: dloverin <darrell.love...@gmail.com> Authored: Sat Mar 21 21:01:21 2015 -0400 Committer: dloverin <darrell.love...@gmail.com> Committed: Sat Mar 21 21:01:21 2015 -0400 ---------------------------------------------------------------------- .../AIRServer/CodeCoveragePreloadSWF.as | 81 +++ .../AIRServer/CodeCoverageServer-app.xml | 265 +++++++++ CodeCoverage/AIRServer/CodeCoverageServer.mxml | 295 ++++++++++ CodeCoverage/CodeCoveragePreloadSWF.as | 81 --- CodeCoverage/CodeCoverageServer-app.xml | 265 --------- CodeCoverage/CodeCoverageServer.mxml | 295 ---------- CodeCoverage/JavaServer/README | 131 +++++ CodeCoverage/JavaServer/build.xml | 39 ++ CodeCoverage/JavaServer/flex/build.xml | 68 +++ .../flex/src/CodeCoverageClientSocket.as | 145 +++++ .../flex/src/CodeCoveragePreloadSWF.as | 190 +++++++ CodeCoverage/JavaServer/java/build.xml | 157 ++++++ .../JavaServer/java/ccserver.properties | 8 + .../reporter/CodeCoverageReporter.java | 549 ++++++++++++++++++ .../codecoverage/reporter/CoverageData.java | 113 ++++ .../codecoverage/reporter/CoverageSummary.java | 423 ++++++++++++++ .../tools/codecoverage/reporter/LineInfo.java | 107 ++++ .../reporter/PackageSummaryInfo.java | 77 +++ .../codecoverage/reporter/SummaryInfo.java | 187 +++++++ .../codecoverage/reporter/SummaryType.java | 29 + .../reporter/reports/IReportFactory.java | 37 ++ .../reporter/reports/IReportWriter.java | 40 ++ .../reporter/reports/ReportOptions.java | 204 +++++++ .../reporter/reports/XMLReportFactory.java | 36 ++ .../reporter/reports/XMLReportWriter.java | 371 +++++++++++++ .../reporter/swf/DebugLineVisitor.java | 239 ++++++++ .../reporter/swf/SWFLineReporter.java | 143 +++++ .../codecoverage/server/CodeCoverageServer.java | 552 +++++++++++++++++++ .../codecoverage/server/DataSocketAccepter.java | 174 ++++++ .../codecoverage/server/DataSocketReader.java | 88 +++ .../codecoverage/server/PolicyFileServer.java | 167 ++++++ 31 files changed, 4915 insertions(+), 641 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/5077c457/CodeCoverage/AIRServer/CodeCoveragePreloadSWF.as ---------------------------------------------------------------------- diff --git a/CodeCoverage/AIRServer/CodeCoveragePreloadSWF.as b/CodeCoverage/AIRServer/CodeCoveragePreloadSWF.as new file mode 100644 index 0000000..a8200d1 --- /dev/null +++ b/CodeCoverage/AIRServer/CodeCoveragePreloadSWF.as @@ -0,0 +1,81 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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.Sprite; + import flash.events.StatusEvent; + import flash.net.LocalConnection; + import flash.trace.Trace; + import flash.utils.getTimer; + + public class CodeCoveragePreloadSWF extends Sprite + { + public function CodeCoveragePreloadSWF() + { + Trace.setLevel(Trace.METHODS_AND_LINES, Trace.LISTENER); + Trace.setListener(callback); + lc = new LocalConnection(); + lc.addEventListener(StatusEvent.STATUS, onStatus); + lc.send("_CodeCoverageLC", "reset"); + } + + private var lc:LocalConnection; + + private var stringMap:Object = {}; + private var stringIndex:int = 0; + + private function onStatus(event:StatusEvent):void + { + } + + private var ids:String = ""; + private var lines:String = ""; + private var lastTime:Number = 0; + + public function callback(file_name:String, linenum:int, method_name:String, method_args:String):void + { + if (linenum > 0) + { + // trace(file_name, linenum); + if (!stringMap.hasOwnProperty(file_name)) + { + lc.send("_CodeCoverageLC", "newString", file_name); + stringMap[file_name] = stringIndex.toString(); + stringIndex++; + } + var id:String = stringMap[file_name]; + var line:String = linenum.toString(); + if (ids.length > 0) + { + ids += " "; + lines += " "; + } + ids += id; + lines += line; + if (ids.length > 20000 || lines.length > 20000 || (lastTime > 0 && getTimer() - lastTime > 500)) + { + lc.send("_CodeCoverageLC", "debugline", ids, lines); + ids = ""; + lines = ""; + } + lastTime = getTimer(); + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/5077c457/CodeCoverage/AIRServer/CodeCoverageServer-app.xml ---------------------------------------------------------------------- diff --git a/CodeCoverage/AIRServer/CodeCoverageServer-app.xml b/CodeCoverage/AIRServer/CodeCoverageServer-app.xml new file mode 100644 index 0000000..2c7d9b2 --- /dev/null +++ b/CodeCoverage/AIRServer/CodeCoverageServer-app.xml @@ -0,0 +1,265 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!-- + +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +--> +<application xmlns="http://ns.adobe.com/air/application/3.4"> + +<!-- Adobe AIR Application Descriptor File Template. + + Specifies parameters for identifying, installing, and launching AIR applications. + + xmlns - The Adobe AIR namespace: http://ns.adobe.com/air/application/3.4 + The last segment of the namespace specifies the version + of the AIR runtime required for this application to run. + + minimumPatchLevel - The minimum patch level of the AIR runtime required to run + the application. Optional. +--> + + <!-- A universally unique application identifier. Must be unique across all AIR applications. + Using a reverse DNS-style name as the id is recommended. (Eg. com.example.ExampleApplication.) Required. --> + <id>CodeCoverageServer</id> + + <!-- Used as the filename for the application. Required. --> + <filename>CodeCoverageServer</filename> + + <!-- The name that is displayed in the AIR application installer. + May have multiple values for each language. See samples or xsd schema file. Optional. --> + <name>CodeCoverageServer</name> + + <!-- A string value of the format <0-999>.<0-999>.<0-999> that represents application version which can be used to check for application upgrade. + Values can also be 1-part or 2-part. It is not necessary to have a 3-part value. + An updated version of application must have a versionNumber value higher than the previous version. Required for namespace >= 2.5 . --> + <versionNumber>0.0.0</versionNumber> + + <!-- A string value (such as "v1", "2.5", or "Alpha 1") that represents the version of the application, as it should be shown to users. Optional. --> + <!-- <versionLabel></versionLabel> --> + + <!-- Description, displayed in the AIR application installer. + May have multiple values for each language. See samples or xsd schema file. Optional. --> + <!-- <description></description> --> + + <!-- Copyright information. Optional --> + <!-- <copyright></copyright> --> + + <!-- Publisher ID. Used if you're updating an application created prior to 1.5.3 --> + <!-- <publisherID></publisherID> --> + + <!-- Settings for the application's initial window. Required. --> + <initialWindow> + <!-- The main SWF or HTML file of the application. Required. --> + <!-- Note: In Flash Builder, the SWF reference is set automatically. --> + <content>[This value will be overwritten by Flash Builder in the output app.xml]</content> + + <!-- The title of the main window. Optional. --> + <!-- <title></title> --> + + <!-- The type of system chrome to use (either "standard" or "none"). Optional. Default standard. --> + <!-- <systemChrome></systemChrome> --> + + <!-- Whether the window is transparent. Only applicable when systemChrome is none. Optional. Default false. --> + <!-- <transparent></transparent> --> + + <!-- Whether the window is initially visible. Optional. Default false. --> + <!-- <visible></visible> --> + + <!-- Whether the user can minimize the window. Optional. Default true. --> + <!-- <minimizable></minimizable> --> + + <!-- Whether the user can maximize the window. Optional. Default true. --> + <!-- <maximizable></maximizable> --> + + <!-- Whether the user can resize the window. Optional. Default true. --> + <!-- <resizable></resizable> --> + + <!-- The window's initial width in pixels. Optional. --> + <!-- <width></width> --> + + <!-- The window's initial height in pixels. Optional. --> + <!-- <height></height> --> + + <!-- The window's initial x position. Optional. --> + <!-- <x></x> --> + + <!-- The window's initial y position. Optional. --> + <!-- <y></y> --> + + <!-- The window's minimum size, specified as a width/height pair in pixels, such as "400 200". Optional. --> + <!-- <minSize></minSize> --> + + <!-- The window's initial maximum size, specified as a width/height pair in pixels, such as "1600 1200". Optional. --> + <!-- <maxSize></maxSize> --> + + <!-- The aspect ratio of the app ("portrait" or "landscape" or "any"). Optional. Mobile only. Default is the natural orientation of the device --> + + <!-- <aspectRatio></aspectRatio> --> + + <!-- Whether the app will begin auto-orienting on launch. Optional. Mobile only. Default false --> + + <!-- <autoOrients></autoOrients> --> + + <!-- Whether the app launches in full screen. Optional. Mobile only. Default false --> + + <!-- <fullScreen></fullScreen> --> + + <!-- The render mode for the app (either auto, cpu, gpu, or direct). Optional. Default auto --> + + <!-- <renderMode></renderMode> --> + + <!-- Whether the default direct mode rendering context allocates storage for depth and stencil buffers. Optional. Default false. --> + <!-- <depthAndStencil></depthAndStencil> --> + + <!-- Whether or not to pan when a soft keyboard is raised or lowered (either "pan" or "none"). Optional. Defaults "pan." --> + <!-- <softKeyboardBehavior></softKeyboardBehavior> --> + + <autoOrients>false</autoOrients> + <fullScreen>false</fullScreen> + <visible>false</visible> + </initialWindow> + + <!-- We recommend omitting the supportedProfiles element, --> + <!-- which in turn permits your application to be deployed to all --> + <!-- devices supported by AIR. If you wish to restrict deployment --> + <!-- (i.e., to only mobile devices) then add this element and list --> + <!-- only the profiles which your application does support. --> + <!-- <supportedProfiles>desktop extendedDesktop mobileDevice extendedMobileDevice</supportedProfiles> --> + + <!-- Languages supported by application --> + <!-- Only these languages can be specified --> + <!-- <supportedLanguages>en de cs es fr it ja ko nl pl pt ru sv tr zh</supportedLanguages> --> + + <!-- The subpath of the standard default installation location to use. Optional. --> + <!-- <installFolder></installFolder> --> + + <!-- The subpath of the Programs menu to use. (Ignored on operating systems without a Programs menu.) Optional. --> + <!-- <programMenuFolder></programMenuFolder> --> + + <!-- The icon the system uses for the application. For at least one resolution, + specify the path to a PNG file included in the AIR package. Optional. --> + <!-- <icon> + <image16x16></image16x16> + <image29x29></image29x29> + <image32x32></image32x32> + <image36x36></image36x36> + <image48x48></image48x48> + <image50x50></image50x50> + <image57x57></image57x57> + <image58x58></image58x58> + <image72x72></image72x72> + <image100x100></image100x100> + <image114x114></image114x114> + <image128x128></image128x128> + <image144x144></image144x144> + <image512x512></image512x512> + <image1024x1024></image1024x1024> + </icon> --> + + <!-- Whether the application handles the update when a user double-clicks an update version + of the AIR file (true), or the default AIR application installer handles the update (false). + Optional. Default false. --> + <!-- <customUpdateUI></customUpdateUI> --> + + <!-- Whether the application can be launched when the user clicks a link in a web browser. + Optional. Default false. --> + <!-- <allowBrowserInvocation></allowBrowserInvocation> --> + + <!-- Listing of file types for which the application can register. Optional. --> + <!-- <fileTypes> --> + + <!-- Defines one file type. Optional. --> + <!-- <fileType> --> + + <!-- The name that the system displays for the registered file type. Required. --> + <!-- <name></name> --> + + <!-- The extension to register. Required. --> + <!-- <extension></extension> --> + + <!-- The description of the file type. Optional. --> + <!-- <description></description> --> + + <!-- The MIME content type. --> + <!-- <contentType></contentType> --> + + <!-- The icon to display for the file type. Optional. --> + <!-- <icon> + <image16x16></image16x16> + <image32x32></image32x32> + <image48x48></image48x48> + <image128x128></image128x128> + </icon> --> + + <!-- </fileType> --> + <!-- </fileTypes> --> + + <!-- iOS specific capabilities --> + <!-- <iPhone> --> + <!-- A list of plist key/value pairs to be added to the application Info.plist --> + <!-- <InfoAdditions> + <![CDATA[ + <key>UIDeviceFamily</key> + <array> + <string>1</string> + <string>2</string> + </array> + <key>UIStatusBarStyle</key> + <string>UIStatusBarStyleBlackOpaque</string> + <key>UIRequiresPersistentWiFi</key> + <string>YES</string> + ]]> + </InfoAdditions> --> + <!-- A list of plist key/value pairs to be added to the application Entitlements.plist --> + <!-- <Entitlements> + <![CDATA[ + <key>keychain-access-groups</key> + <array> + <string></string> + <string></string> + </array> + ]]> + </Entitlements> --> + <!-- Display Resolution for the app (either "standard" or "high"). Optional. Default "standard" --> + <!-- <requestedDisplayResolution></requestedDisplayResolution> --> + <!-- </iPhone> --> + + <!-- Specify Android specific tags that get passed to AndroidManifest.xml file. --> + <!--<android> --> + <!-- <manifestAdditions> + <![CDATA[ + <manifest android:installLocation="auto"> + <uses-permission android:name="android.permission.INTERNET"/> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> + <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> + <uses-feature android:required="true" android:name="android.hardware.touchscreen.multitouch"/> + <application android:enabled="true"> + <activity android:excludeFromRecents="false"> + <intent-filter> + <action android:name="android.intent.action.MAIN"/> + <category android:name="android.intent.category.LAUNCHER"/> + </intent-filter> + </activity> + </application> + </manifest> + ]]> + </manifestAdditions> --> + <!-- Color depth for the app (either "32bit" or "16bit"). Optional. Default 16bit before namespace 3.0, 32bit after --> + <!-- <colorDepth></colorDepth> --> + <!-- </android> --> + <!-- End of the schema for adding the android specific tags in AndroidManifest.xml file --> + +</application> http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/5077c457/CodeCoverage/AIRServer/CodeCoverageServer.mxml ---------------------------------------------------------------------- diff --git a/CodeCoverage/AIRServer/CodeCoverageServer.mxml b/CodeCoverage/AIRServer/CodeCoverageServer.mxml new file mode 100644 index 0000000..54d903c --- /dev/null +++ b/CodeCoverage/AIRServer/CodeCoverageServer.mxml @@ -0,0 +1,295 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +--> +<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" + xmlns:s="library://ns.adobe.com/flex/spark" + xmlns:mx="library://ns.adobe.com/flex/mx" + applicationComplete="setupLC()" + enterFrame="updateStuff()" close="closeHandler(event)" + > + <fx:Declarations> + <!-- Place non-visual elements (e.g., services, value objects) here --> + </fx:Declarations> + <!-- preloadSWF=/Users/aharui/CodeCoveragePreloadSWF.swf --> + <fx:Script> + <![CDATA[ + import mx.controls.Alert; + + private var lc:LocalConnection; + private var file:File; + private var fs:FileStream; + + private var stringMap:Array = []; + private var lineMap:Array = []; + + private var so:SharedObject; + + private function setupLC():void + { + lc = new LocalConnection(); + lc.client = this; + lc.allowDomain('*'); + lc.connect("_CodeCoverageLC"); + + file = File.userDirectory; + file = file.resolvePath("codecoverage.txt"); + fs = new FileStream(); + fs.open(file, FileMode.APPEND); + + so = SharedObject.getLocal("CodeCoverageServer"); + if (so.data.mmcfg) + mmPath.text = so.data.mmcfg; + else + mmPath.text = File.userDirectory.nativePath + File.separator + "mm.cfg"; + + if (so.data.swfpath) + swfPath.text = so.data.swfpath; + else + swfPath.text = File.userDirectory.nativePath + File.separator + "CodeCoveragePreloadSWF.swf"; + + applyConfig(); + } + + private var mmFile:File; + + private function search():void + { + mmFile = new File(File.userDirectory.nativePath); + mmFile.browseForOpen("Path to mm.cfg"); + mmFile.addEventListener(Event.SELECT, selectHandler); + } + + private function selectHandler(event:Event):void + { + mmPath.text = mmFile.nativePath; + } + + private var swfFile:File; + + private function searchSWF():void + { + swfFile = new File(File.userDirectory.nativePath); + swfFile.browseForOpen("Path to CodeCoveragePreloadSWF.swf"); + swfFile.addEventListener(Event.SELECT, selectSWFHandler); + } + + private function selectSWFHandler(event:Event):void + { + swfPath.text = swfFile.nativePath; + } + + private function saveConfig():void + { + so.data.mmcfg = mmPath.text; + so.data.swfpath = swfPath.text; + + applyConfig(); + } + + private const PRELOAD_SWF:String = "preloadSWF="; + private function applyConfig():void + { + if (mmPath.text.length == 0) + return; + if (!mmFile) + mmFile = new File(); + + mmFile.nativePath = mmPath.text; + if (!mmFile.exists) + { + Alert.show("mm.cfg not found", "Error"); + return; + } + + if (!swfFile) + swfFile = new File(); + + swfFile.nativePath = swfPath.text; + if (!swfFile.exists) + { + Alert.show("CodeCoveragePreloadSWF.swf not found", "Error"); + return; + } + + var fs:FileStream = new FileStream(); + fs.open(mmFile, FileMode.UPDATE); + var text:String = fs.readUTFBytes(fs.bytesAvailable); + var lineSep:String = "\r\n"; + if (text.indexOf(lineSep) == -1) + { + lineSep = "\r"; + if (text.indexOf(lineSep) == -1) + { + lineSep = "\n"; + } + } + var lines:Array = text.split(lineSep); + var n:int = lines.length; + for (var i:int = 0; i < n; i++) + { + if (lines[i].indexOf(PRELOAD_SWF) != -1) + { + lines.splice(i, 1); + i--; + n-- + } + } + if (lines[n - 1].length == 0) + lines.pop(); + lines.push(PRELOAD_SWF + swfFile.nativePath); + lines.push(""); + text = lines.join(lineSep); + fs.position = 0; + fs.truncate(); + fs.writeUTFBytes(text); + fs.close(); + } + + private var count:int = 0; + + public function reset():void + { + if (stringMap.length > 0) + { + // codecoverpreloadswf is first one + var s:String = stringMap[0]; + stringMap = [s]; + lineMap = [{}]; + } + else + { + stringMap = []; + lineMap = [{}]; + } + } + + public function newString(file_name:String):void + { + stringMap.push(file_name); + lineMap.push({}); + //trace(file_name); + } + + private var s:String = ""; + + public function debugline(string_ids:String, linenums:String):void + { + var ids:Array = string_ids.split(" "); + var lines:Array = linenums.split(" "); + var n:int = ids.length; + for (var i:int = 0; i < n; i++) + { + ++count; + if (stringMap[ids[i]] == undefined) + s += ids[i] + ':' + rightJustify(lines[i]) + "\n"; + else if (lineMap[ids[i]][lines[i]] == undefined) + { + lineMap[ids[i]][lines[i]] = 1; + s += '"' + stringMap[ids[i]] + '":' + rightJustify(lines[i]) + "\n"; + } + } + } + + private var padding:String = " "; + + private function rightJustify(num:String):String + { + var i:int = 8 - num.length; + var pad:String = padding.substr(0, i); + return pad + num; + } + + private function updateStuff():void + { + if (count > 0) + { + fs.writeUTFBytes(s); + s = ""; + numlines.text = count.toString(); + } + } + + protected function closeHandler(event:Event):void + { + mmFile.nativePath = mmPath.text; + if (!mmFile.exists) + { + Alert.show("mm.cfg not found", "Error"); + return; + } + swfFile.nativePath = swfPath.text; + if (!swfFile.exists) + { + Alert.show("CodeCoveragePreloadSWF.swf not found", "Error"); + return; + } + + var fs:FileStream = new FileStream(); + fs.open(mmFile, FileMode.UPDATE); + var text:String = fs.readUTFBytes(fs.bytesAvailable); + var lineSep:String = "\r\n"; + if (text.indexOf(lineSep) == -1) + { + lineSep = "\r"; + if (text.indexOf(lineSep) == -1) + { + lineSep = "\n"; + } + } + var lines:Array = text.split(lineSep); + var n:int = lines.length; + for (var i:int = 0; i < n; i++) + { + if (lines[i].indexOf(PRELOAD_SWF) != -1) + { + lines.splice(i, 1); + i--; + n--; + } + } + if (lines[n - 1].length > 0) + lines.push(""); + text = lines.join(lineSep); + fs.position = 0; + fs.truncate(); + fs.writeUTFBytes(text); + fs.close(); + } + + ]]> + </fx:Script> + <s:layout> + <s:VerticalLayout /> + </s:layout> + <s:HGroup width="100%"> + <s:Label text="Path to mm.cfg: " /> + <s:TextInput id="mmPath" width="100%" /> + <s:Button label="Search..." click="search()" /> + </s:HGroup> + <s:HGroup width="100%"> + <s:Label text="Path to CodeCoveragePreloadSWF.swf: " /> + <s:TextInput id="swfPath" width="100%" /> + <s:Button label="Search..." click="searchSWF()" /> + </s:HGroup> + <s:Button label="Save Configuration" click="saveConfig()" /> + <s:HGroup> + <s:Label text="Num Lines:" /> + <s:Label id="numlines" /> + </s:HGroup> +</s:WindowedApplication> http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/5077c457/CodeCoverage/CodeCoveragePreloadSWF.as ---------------------------------------------------------------------- diff --git a/CodeCoverage/CodeCoveragePreloadSWF.as b/CodeCoverage/CodeCoveragePreloadSWF.as deleted file mode 100644 index a8200d1..0000000 --- a/CodeCoverage/CodeCoveragePreloadSWF.as +++ /dev/null @@ -1,81 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// 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.Sprite; - import flash.events.StatusEvent; - import flash.net.LocalConnection; - import flash.trace.Trace; - import flash.utils.getTimer; - - public class CodeCoveragePreloadSWF extends Sprite - { - public function CodeCoveragePreloadSWF() - { - Trace.setLevel(Trace.METHODS_AND_LINES, Trace.LISTENER); - Trace.setListener(callback); - lc = new LocalConnection(); - lc.addEventListener(StatusEvent.STATUS, onStatus); - lc.send("_CodeCoverageLC", "reset"); - } - - private var lc:LocalConnection; - - private var stringMap:Object = {}; - private var stringIndex:int = 0; - - private function onStatus(event:StatusEvent):void - { - } - - private var ids:String = ""; - private var lines:String = ""; - private var lastTime:Number = 0; - - public function callback(file_name:String, linenum:int, method_name:String, method_args:String):void - { - if (linenum > 0) - { - // trace(file_name, linenum); - if (!stringMap.hasOwnProperty(file_name)) - { - lc.send("_CodeCoverageLC", "newString", file_name); - stringMap[file_name] = stringIndex.toString(); - stringIndex++; - } - var id:String = stringMap[file_name]; - var line:String = linenum.toString(); - if (ids.length > 0) - { - ids += " "; - lines += " "; - } - ids += id; - lines += line; - if (ids.length > 20000 || lines.length > 20000 || (lastTime > 0 && getTimer() - lastTime > 500)) - { - lc.send("_CodeCoverageLC", "debugline", ids, lines); - ids = ""; - lines = ""; - } - lastTime = getTimer(); - } - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/5077c457/CodeCoverage/CodeCoverageServer-app.xml ---------------------------------------------------------------------- diff --git a/CodeCoverage/CodeCoverageServer-app.xml b/CodeCoverage/CodeCoverageServer-app.xml deleted file mode 100644 index 2c7d9b2..0000000 --- a/CodeCoverage/CodeCoverageServer-app.xml +++ /dev/null @@ -1,265 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="no"?> -<!-- - -Licensed to the Apache Software Foundation (ASF) under one or more -contributor license agreements. See the NOTICE file distributed with -this work for additional information regarding copyright ownership. -The ASF licenses this file to You under the Apache License, Version 2.0 -(the "License"); you may not use this file except in compliance with -the License. You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - ---> -<application xmlns="http://ns.adobe.com/air/application/3.4"> - -<!-- Adobe AIR Application Descriptor File Template. - - Specifies parameters for identifying, installing, and launching AIR applications. - - xmlns - The Adobe AIR namespace: http://ns.adobe.com/air/application/3.4 - The last segment of the namespace specifies the version - of the AIR runtime required for this application to run. - - minimumPatchLevel - The minimum patch level of the AIR runtime required to run - the application. Optional. ---> - - <!-- A universally unique application identifier. Must be unique across all AIR applications. - Using a reverse DNS-style name as the id is recommended. (Eg. com.example.ExampleApplication.) Required. --> - <id>CodeCoverageServer</id> - - <!-- Used as the filename for the application. Required. --> - <filename>CodeCoverageServer</filename> - - <!-- The name that is displayed in the AIR application installer. - May have multiple values for each language. See samples or xsd schema file. Optional. --> - <name>CodeCoverageServer</name> - - <!-- A string value of the format <0-999>.<0-999>.<0-999> that represents application version which can be used to check for application upgrade. - Values can also be 1-part or 2-part. It is not necessary to have a 3-part value. - An updated version of application must have a versionNumber value higher than the previous version. Required for namespace >= 2.5 . --> - <versionNumber>0.0.0</versionNumber> - - <!-- A string value (such as "v1", "2.5", or "Alpha 1") that represents the version of the application, as it should be shown to users. Optional. --> - <!-- <versionLabel></versionLabel> --> - - <!-- Description, displayed in the AIR application installer. - May have multiple values for each language. See samples or xsd schema file. Optional. --> - <!-- <description></description> --> - - <!-- Copyright information. Optional --> - <!-- <copyright></copyright> --> - - <!-- Publisher ID. Used if you're updating an application created prior to 1.5.3 --> - <!-- <publisherID></publisherID> --> - - <!-- Settings for the application's initial window. Required. --> - <initialWindow> - <!-- The main SWF or HTML file of the application. Required. --> - <!-- Note: In Flash Builder, the SWF reference is set automatically. --> - <content>[This value will be overwritten by Flash Builder in the output app.xml]</content> - - <!-- The title of the main window. Optional. --> - <!-- <title></title> --> - - <!-- The type of system chrome to use (either "standard" or "none"). Optional. Default standard. --> - <!-- <systemChrome></systemChrome> --> - - <!-- Whether the window is transparent. Only applicable when systemChrome is none. Optional. Default false. --> - <!-- <transparent></transparent> --> - - <!-- Whether the window is initially visible. Optional. Default false. --> - <!-- <visible></visible> --> - - <!-- Whether the user can minimize the window. Optional. Default true. --> - <!-- <minimizable></minimizable> --> - - <!-- Whether the user can maximize the window. Optional. Default true. --> - <!-- <maximizable></maximizable> --> - - <!-- Whether the user can resize the window. Optional. Default true. --> - <!-- <resizable></resizable> --> - - <!-- The window's initial width in pixels. Optional. --> - <!-- <width></width> --> - - <!-- The window's initial height in pixels. Optional. --> - <!-- <height></height> --> - - <!-- The window's initial x position. Optional. --> - <!-- <x></x> --> - - <!-- The window's initial y position. Optional. --> - <!-- <y></y> --> - - <!-- The window's minimum size, specified as a width/height pair in pixels, such as "400 200". Optional. --> - <!-- <minSize></minSize> --> - - <!-- The window's initial maximum size, specified as a width/height pair in pixels, such as "1600 1200". Optional. --> - <!-- <maxSize></maxSize> --> - - <!-- The aspect ratio of the app ("portrait" or "landscape" or "any"). Optional. Mobile only. Default is the natural orientation of the device --> - - <!-- <aspectRatio></aspectRatio> --> - - <!-- Whether the app will begin auto-orienting on launch. Optional. Mobile only. Default false --> - - <!-- <autoOrients></autoOrients> --> - - <!-- Whether the app launches in full screen. Optional. Mobile only. Default false --> - - <!-- <fullScreen></fullScreen> --> - - <!-- The render mode for the app (either auto, cpu, gpu, or direct). Optional. Default auto --> - - <!-- <renderMode></renderMode> --> - - <!-- Whether the default direct mode rendering context allocates storage for depth and stencil buffers. Optional. Default false. --> - <!-- <depthAndStencil></depthAndStencil> --> - - <!-- Whether or not to pan when a soft keyboard is raised or lowered (either "pan" or "none"). Optional. Defaults "pan." --> - <!-- <softKeyboardBehavior></softKeyboardBehavior> --> - - <autoOrients>false</autoOrients> - <fullScreen>false</fullScreen> - <visible>false</visible> - </initialWindow> - - <!-- We recommend omitting the supportedProfiles element, --> - <!-- which in turn permits your application to be deployed to all --> - <!-- devices supported by AIR. If you wish to restrict deployment --> - <!-- (i.e., to only mobile devices) then add this element and list --> - <!-- only the profiles which your application does support. --> - <!-- <supportedProfiles>desktop extendedDesktop mobileDevice extendedMobileDevice</supportedProfiles> --> - - <!-- Languages supported by application --> - <!-- Only these languages can be specified --> - <!-- <supportedLanguages>en de cs es fr it ja ko nl pl pt ru sv tr zh</supportedLanguages> --> - - <!-- The subpath of the standard default installation location to use. Optional. --> - <!-- <installFolder></installFolder> --> - - <!-- The subpath of the Programs menu to use. (Ignored on operating systems without a Programs menu.) Optional. --> - <!-- <programMenuFolder></programMenuFolder> --> - - <!-- The icon the system uses for the application. For at least one resolution, - specify the path to a PNG file included in the AIR package. Optional. --> - <!-- <icon> - <image16x16></image16x16> - <image29x29></image29x29> - <image32x32></image32x32> - <image36x36></image36x36> - <image48x48></image48x48> - <image50x50></image50x50> - <image57x57></image57x57> - <image58x58></image58x58> - <image72x72></image72x72> - <image100x100></image100x100> - <image114x114></image114x114> - <image128x128></image128x128> - <image144x144></image144x144> - <image512x512></image512x512> - <image1024x1024></image1024x1024> - </icon> --> - - <!-- Whether the application handles the update when a user double-clicks an update version - of the AIR file (true), or the default AIR application installer handles the update (false). - Optional. Default false. --> - <!-- <customUpdateUI></customUpdateUI> --> - - <!-- Whether the application can be launched when the user clicks a link in a web browser. - Optional. Default false. --> - <!-- <allowBrowserInvocation></allowBrowserInvocation> --> - - <!-- Listing of file types for which the application can register. Optional. --> - <!-- <fileTypes> --> - - <!-- Defines one file type. Optional. --> - <!-- <fileType> --> - - <!-- The name that the system displays for the registered file type. Required. --> - <!-- <name></name> --> - - <!-- The extension to register. Required. --> - <!-- <extension></extension> --> - - <!-- The description of the file type. Optional. --> - <!-- <description></description> --> - - <!-- The MIME content type. --> - <!-- <contentType></contentType> --> - - <!-- The icon to display for the file type. Optional. --> - <!-- <icon> - <image16x16></image16x16> - <image32x32></image32x32> - <image48x48></image48x48> - <image128x128></image128x128> - </icon> --> - - <!-- </fileType> --> - <!-- </fileTypes> --> - - <!-- iOS specific capabilities --> - <!-- <iPhone> --> - <!-- A list of plist key/value pairs to be added to the application Info.plist --> - <!-- <InfoAdditions> - <![CDATA[ - <key>UIDeviceFamily</key> - <array> - <string>1</string> - <string>2</string> - </array> - <key>UIStatusBarStyle</key> - <string>UIStatusBarStyleBlackOpaque</string> - <key>UIRequiresPersistentWiFi</key> - <string>YES</string> - ]]> - </InfoAdditions> --> - <!-- A list of plist key/value pairs to be added to the application Entitlements.plist --> - <!-- <Entitlements> - <![CDATA[ - <key>keychain-access-groups</key> - <array> - <string></string> - <string></string> - </array> - ]]> - </Entitlements> --> - <!-- Display Resolution for the app (either "standard" or "high"). Optional. Default "standard" --> - <!-- <requestedDisplayResolution></requestedDisplayResolution> --> - <!-- </iPhone> --> - - <!-- Specify Android specific tags that get passed to AndroidManifest.xml file. --> - <!--<android> --> - <!-- <manifestAdditions> - <![CDATA[ - <manifest android:installLocation="auto"> - <uses-permission android:name="android.permission.INTERNET"/> - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> - <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> - <uses-feature android:required="true" android:name="android.hardware.touchscreen.multitouch"/> - <application android:enabled="true"> - <activity android:excludeFromRecents="false"> - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - </activity> - </application> - </manifest> - ]]> - </manifestAdditions> --> - <!-- Color depth for the app (either "32bit" or "16bit"). Optional. Default 16bit before namespace 3.0, 32bit after --> - <!-- <colorDepth></colorDepth> --> - <!-- </android> --> - <!-- End of the schema for adding the android specific tags in AndroidManifest.xml file --> - -</application> http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/5077c457/CodeCoverage/CodeCoverageServer.mxml ---------------------------------------------------------------------- diff --git a/CodeCoverage/CodeCoverageServer.mxml b/CodeCoverage/CodeCoverageServer.mxml deleted file mode 100644 index 54d903c..0000000 --- a/CodeCoverage/CodeCoverageServer.mxml +++ /dev/null @@ -1,295 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - -Licensed to the Apache Software Foundation (ASF) under one or more -contributor license agreements. See the NOTICE file distributed with -this work for additional information regarding copyright ownership. -The ASF licenses this file to You under the Apache License, Version 2.0 -(the "License"); you may not use this file except in compliance with -the License. You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - ---> -<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" - xmlns:s="library://ns.adobe.com/flex/spark" - xmlns:mx="library://ns.adobe.com/flex/mx" - applicationComplete="setupLC()" - enterFrame="updateStuff()" close="closeHandler(event)" - > - <fx:Declarations> - <!-- Place non-visual elements (e.g., services, value objects) here --> - </fx:Declarations> - <!-- preloadSWF=/Users/aharui/CodeCoveragePreloadSWF.swf --> - <fx:Script> - <![CDATA[ - import mx.controls.Alert; - - private var lc:LocalConnection; - private var file:File; - private var fs:FileStream; - - private var stringMap:Array = []; - private var lineMap:Array = []; - - private var so:SharedObject; - - private function setupLC():void - { - lc = new LocalConnection(); - lc.client = this; - lc.allowDomain('*'); - lc.connect("_CodeCoverageLC"); - - file = File.userDirectory; - file = file.resolvePath("codecoverage.txt"); - fs = new FileStream(); - fs.open(file, FileMode.APPEND); - - so = SharedObject.getLocal("CodeCoverageServer"); - if (so.data.mmcfg) - mmPath.text = so.data.mmcfg; - else - mmPath.text = File.userDirectory.nativePath + File.separator + "mm.cfg"; - - if (so.data.swfpath) - swfPath.text = so.data.swfpath; - else - swfPath.text = File.userDirectory.nativePath + File.separator + "CodeCoveragePreloadSWF.swf"; - - applyConfig(); - } - - private var mmFile:File; - - private function search():void - { - mmFile = new File(File.userDirectory.nativePath); - mmFile.browseForOpen("Path to mm.cfg"); - mmFile.addEventListener(Event.SELECT, selectHandler); - } - - private function selectHandler(event:Event):void - { - mmPath.text = mmFile.nativePath; - } - - private var swfFile:File; - - private function searchSWF():void - { - swfFile = new File(File.userDirectory.nativePath); - swfFile.browseForOpen("Path to CodeCoveragePreloadSWF.swf"); - swfFile.addEventListener(Event.SELECT, selectSWFHandler); - } - - private function selectSWFHandler(event:Event):void - { - swfPath.text = swfFile.nativePath; - } - - private function saveConfig():void - { - so.data.mmcfg = mmPath.text; - so.data.swfpath = swfPath.text; - - applyConfig(); - } - - private const PRELOAD_SWF:String = "preloadSWF="; - private function applyConfig():void - { - if (mmPath.text.length == 0) - return; - if (!mmFile) - mmFile = new File(); - - mmFile.nativePath = mmPath.text; - if (!mmFile.exists) - { - Alert.show("mm.cfg not found", "Error"); - return; - } - - if (!swfFile) - swfFile = new File(); - - swfFile.nativePath = swfPath.text; - if (!swfFile.exists) - { - Alert.show("CodeCoveragePreloadSWF.swf not found", "Error"); - return; - } - - var fs:FileStream = new FileStream(); - fs.open(mmFile, FileMode.UPDATE); - var text:String = fs.readUTFBytes(fs.bytesAvailable); - var lineSep:String = "\r\n"; - if (text.indexOf(lineSep) == -1) - { - lineSep = "\r"; - if (text.indexOf(lineSep) == -1) - { - lineSep = "\n"; - } - } - var lines:Array = text.split(lineSep); - var n:int = lines.length; - for (var i:int = 0; i < n; i++) - { - if (lines[i].indexOf(PRELOAD_SWF) != -1) - { - lines.splice(i, 1); - i--; - n-- - } - } - if (lines[n - 1].length == 0) - lines.pop(); - lines.push(PRELOAD_SWF + swfFile.nativePath); - lines.push(""); - text = lines.join(lineSep); - fs.position = 0; - fs.truncate(); - fs.writeUTFBytes(text); - fs.close(); - } - - private var count:int = 0; - - public function reset():void - { - if (stringMap.length > 0) - { - // codecoverpreloadswf is first one - var s:String = stringMap[0]; - stringMap = [s]; - lineMap = [{}]; - } - else - { - stringMap = []; - lineMap = [{}]; - } - } - - public function newString(file_name:String):void - { - stringMap.push(file_name); - lineMap.push({}); - //trace(file_name); - } - - private var s:String = ""; - - public function debugline(string_ids:String, linenums:String):void - { - var ids:Array = string_ids.split(" "); - var lines:Array = linenums.split(" "); - var n:int = ids.length; - for (var i:int = 0; i < n; i++) - { - ++count; - if (stringMap[ids[i]] == undefined) - s += ids[i] + ':' + rightJustify(lines[i]) + "\n"; - else if (lineMap[ids[i]][lines[i]] == undefined) - { - lineMap[ids[i]][lines[i]] = 1; - s += '"' + stringMap[ids[i]] + '":' + rightJustify(lines[i]) + "\n"; - } - } - } - - private var padding:String = " "; - - private function rightJustify(num:String):String - { - var i:int = 8 - num.length; - var pad:String = padding.substr(0, i); - return pad + num; - } - - private function updateStuff():void - { - if (count > 0) - { - fs.writeUTFBytes(s); - s = ""; - numlines.text = count.toString(); - } - } - - protected function closeHandler(event:Event):void - { - mmFile.nativePath = mmPath.text; - if (!mmFile.exists) - { - Alert.show("mm.cfg not found", "Error"); - return; - } - swfFile.nativePath = swfPath.text; - if (!swfFile.exists) - { - Alert.show("CodeCoveragePreloadSWF.swf not found", "Error"); - return; - } - - var fs:FileStream = new FileStream(); - fs.open(mmFile, FileMode.UPDATE); - var text:String = fs.readUTFBytes(fs.bytesAvailable); - var lineSep:String = "\r\n"; - if (text.indexOf(lineSep) == -1) - { - lineSep = "\r"; - if (text.indexOf(lineSep) == -1) - { - lineSep = "\n"; - } - } - var lines:Array = text.split(lineSep); - var n:int = lines.length; - for (var i:int = 0; i < n; i++) - { - if (lines[i].indexOf(PRELOAD_SWF) != -1) - { - lines.splice(i, 1); - i--; - n--; - } - } - if (lines[n - 1].length > 0) - lines.push(""); - text = lines.join(lineSep); - fs.position = 0; - fs.truncate(); - fs.writeUTFBytes(text); - fs.close(); - } - - ]]> - </fx:Script> - <s:layout> - <s:VerticalLayout /> - </s:layout> - <s:HGroup width="100%"> - <s:Label text="Path to mm.cfg: " /> - <s:TextInput id="mmPath" width="100%" /> - <s:Button label="Search..." click="search()" /> - </s:HGroup> - <s:HGroup width="100%"> - <s:Label text="Path to CodeCoveragePreloadSWF.swf: " /> - <s:TextInput id="swfPath" width="100%" /> - <s:Button label="Search..." click="searchSWF()" /> - </s:HGroup> - <s:Button label="Save Configuration" click="saveConfig()" /> - <s:HGroup> - <s:Label text="Num Lines:" /> - <s:Label id="numlines" /> - </s:HGroup> -</s:WindowedApplication> http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/5077c457/CodeCoverage/JavaServer/README ---------------------------------------------------------------------- diff --git a/CodeCoverage/JavaServer/README b/CodeCoverage/JavaServer/README new file mode 100755 index 0000000..ec7e608 --- /dev/null +++ b/CodeCoverage/JavaServer/README @@ -0,0 +1,131 @@ +Apache Flex Code Coverage Tool - Java Server +============================================== + + This code coverage tool is designed to be used at the command line + to provide code coverage for nightly builds. + + For detailed information about the Apache Flex Code Coverage Tool please visit + https://cwiki.apache.org/confluence/display/FLEX/Code+Coverage+Tool + + For detailed information about Apache Flex please visit + http://flex.apache.org/ + +Getting the latest sources via Git +================================== + + Getting the source code is the recommended way to get the Apache Flex Code Coverage Tool. + + You can always checkout the latest source from Apache's source control repository + using the following commands: + + git clone https://git-wip-us.apache.org/repos/asf/flex-utilities.git flex-utilities + cd flex-utilities + git checkout develop + cd CodeCoverage/JavaServer + +Building Apache Flex Code Coverage Tool +======================================= + + The Apache Flex Code Coverage Tool requires some build tools + which must be installed prior to building it. + Some of these have different licenses. See the Software Dependencies section + for more information on the external software dependencies. + +Install Prerequisites +--------------------- + + Before building this tool you must install the following software + and set the corresponding environment variables using absolute file paths. + Relative file paths will result in build errors. + + ================================================================================== + SOFTWARE ENVIRONMENT VARIABLE (absolute paths) + ================================================================================== + + Java SDK 1.7 or greater (*1)(*2) JAVA_HOME + + Ant 1.7.1 or greater (*1) ANT_HOME + (for Java 1.7 see note at (*2)) + + Apache Flex 'Falcon' Compiler (*2) FALCON_HOME + + Apache Flex SDK or repository FLEX_HOME + + ================================================================================== + + *1) The bin directories for ANT_HOME and JAVA_HOME should be added to your + PATH. + + On Windows, set PATH to + + PATH=%PATH%;%ANT_HOME%\bin;%JAVA_HOME%\bin + + On the Mac (bash), set PATH to + + export PATH="$PATH:$ANT_HOME/bin:$JAVA_HOME/bin" + + On Linux make sure you path include ANT_HOME and JAVA_HOME. + + *2) If you are using Java SDK 1.7 or greater on a Mac you must use Ant 1.8 + or greater. If you use Java 1.7 with Ant 1.7, ant reports the java + version as 1.6 so the JVM args for the data model (-d32/-d64) will not + be set correctly and you will get compile errors. + + *3) Set FALCON_HOME to the root of its SDK. When using the flex-falcon + repository, set + FALCON_HOME=<repo-path>/compiler/generated/dist/sdk + +Software Dependencies +--------------------- + + The Apache Flex Code Coverage Tool requires compiler.jar from the + Apache Flex Falcon Compiler. The external dependences for compiler.jar are + (relative to compiler.jar): + + * external/antlr.jar + * external/commons-cli.jar + * external/commons-io.jar + * external/flex-tool-api.jar + * external/guava.jar + * external/jburg.jar + * external/lzma-sdk.jar + + The external jar have various licenses. + + When the Code Coverage Tool is built the Falcon jars are copied from + FALCON_HOME to the Code Coverage Tool's lib directory. This step makes the tool ready to run. + + +Building the Source in the Source Distribution +---------------------------------------------- + + When you have all the prerequisites in place and the environment variables set, + (see Install Prerequisites above), to build the Apache Flex Code Coverage + Tool use: + + cd CodeCoverage/JavaServer + ant + + To clean the build use: + + ant clean + +Building the Source in the Eclispe and Flash Builder +---------------------------------------------------- + + The Java source comes with an Eclipse project in the JavaServer/java + directory. Before importing the Eclipse project first define a Java + Classpath variable. Under Eclipse Preferences, + + * Go to Java - Build Path - Classpath Varables. + * Click on "New...". + * Enter "FALCON_HOME" in "Name" field. + * Enter the directory containing "lib/compiler.jar" in the "Path" field. + + The Flex code comes with a Flash Builder project in the JavaServer/flex + directory. This project can be imported without any additional setup. + +Thanks for using Apache Flex. Enjoy! + + The Apache Flex Project + <http://flex.apache.org> http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/5077c457/CodeCoverage/JavaServer/build.xml ---------------------------------------------------------------------- diff --git a/CodeCoverage/JavaServer/build.xml b/CodeCoverage/JavaServer/build.xml new file mode 100755 index 0000000..88b2b29 --- /dev/null +++ b/CodeCoverage/JavaServer/build.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" ?> +<!-- + + 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. + +--> +<project default="main" basedir="."> + + <property file="${basedir}/env.properties"/> + <property environment="env"/> + <condition property="FLEX_HOME" value="${env.FLEX_HOME}"> + <isset property="env.FLEX_HOME" /> + </condition> + + <target name="main"> + <mkdir dir="${basedir}/lib"/> + <ant dir="${basedir}/flex"/> + <ant dir="${basedir}/java"/> + </target> + + <target name="clean" description="clean up"> + <ant dir="${basedir}/flex" target="clean"/> + <ant dir="${basedir}/java" target="clean"/> + <delete dir="${basedir}/lib"/> + </target> +</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/5077c457/CodeCoverage/JavaServer/flex/build.xml ---------------------------------------------------------------------- diff --git a/CodeCoverage/JavaServer/flex/build.xml b/CodeCoverage/JavaServer/flex/build.xml new file mode 100755 index 0000000..44d33d5 --- /dev/null +++ b/CodeCoverage/JavaServer/flex/build.xml @@ -0,0 +1,68 @@ +<?xml version="1.0" ?> +<!-- + + 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. + +--> +<project default="main" basedir="."> + + <property file="${basedir}/env.properties"/> + <property environment="env"/> + <condition property="FLEX_HOME" value="${env.FLEX_HOME}"> + <isset property="env.FLEX_HOME" /> + </condition> + <property name="lib.dir" value="${basedir}/../lib"/> + + <!-- additional tasks - mxmlc tag --> + <path id="flexTasks.path"> + <fileset dir="${FLEX_HOME}"> + <include name="lib/flexTasks.jar" /> + <include name="ant/lib/flexTasks.jar" /> + </fileset> + </path> + <taskdef resource="flexTasks.tasks" classpathref="flexTasks.path"/> + + <target name="check-flex-home" unless="FLEX_HOME.set" + description="Check that FLEX_HOME is a directory"> + + <echo message="FLEX_HOME is ${env.FLEX_HOME}"/> + + <condition property="FLEX_HOME.set"> + <and> + <length string="${env.FLEX_HOME}" when="greater" length="0" /> + <available file="${env.FLEX_HOME}" type="dir"/> + </and> + </condition> + + <fail message="The environment variable FLEX_HOME must be set to the Flex SDK directory" + unless="FLEX_HOME.set"/> + </target> + + <target name="compile"> + <mxmlc file="${basedir}/src/CodeCoveragePreloadSWF.as" static-link-runtime-shared-libraries="true" + output="${lib.dir}/CodeCoveragePreloadSWF.swf" fork="true" failonerror="true"> + <load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/> + <source-path path-element="${basedir}/src"/> + </mxmlc> + </target> + + <target name="main" depends="check-flex-home,clean,compile"> + </target> + + <target name="clean" description="clean up"> + <delete file="${lib.dir}/CodeCoveragePreloadSWF.swf"/> + </target> +</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/5077c457/CodeCoverage/JavaServer/flex/src/CodeCoverageClientSocket.as ---------------------------------------------------------------------- diff --git a/CodeCoverage/JavaServer/flex/src/CodeCoverageClientSocket.as b/CodeCoverage/JavaServer/flex/src/CodeCoverageClientSocket.as new file mode 100755 index 0000000..7d9e016 --- /dev/null +++ b/CodeCoverage/JavaServer/flex/src/CodeCoverageClientSocket.as @@ -0,0 +1,145 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// + +package +{ +import flash.events.Event; +import flash.events.IOErrorEvent; +import flash.events.SecurityErrorEvent; +import flash.net.Socket; +import flash.system.Security; + +/** + * Wrapper around a Flash Player Socket. + */ +public class CodeCoverageClientSocket extends Socket +{ + //-------------------------------------------------------------------------- + // + // Constructor + // + //-------------------------------------------------------------------------- + + /** + * Constructor + * + * @param host The host to connect to. + * @param port The port to send trace data to. + * @param policyFilePort The port used to load the policy file. + */ + public function CodeCoverageClientSocket(host:String, port:int, policyFilePort:int) + { + super(); + addListeners(); + + var policyFile:String = "xmlsocket://" + host + ":" + policyFilePort; + Security.loadPolicyFile(policyFile); + connect(host, port); + } + + //-------------------------------------------------------------------------- + // + // Variables + // + //-------------------------------------------------------------------------- + + /** + * Buffer output from trace data received before a connect is avaiable from + * the server. + */ + private var preConnectBuffer:Array = []; + private var connectionAvailable:Boolean; + + //-------------------------------------------------------------------------- + // + // Methods + // + //-------------------------------------------------------------------------- + + /** + * Send data to the sever. + * + * If the socket is not connected the data will be buffered until the + * connection is made. + * + * @param data The data to send. + */ + public function sendData(data:String):void + { + if (connectionAvailable) + { + writeUTFBytes(data); + flush(); + } + else + { + preConnectBuffer.push(data); + } + } + + private function addListeners():void + { + addEventListener(Event.CLOSE, closeHandler); + addEventListener(Event.CONNECT, connectHandler); + addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler); + addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler); + } + + //-------------------------------------------------------------------------- + // + // Event handler + // + //-------------------------------------------------------------------------- + + private function closeHandler(event:Event):void + { + connectionAvailable = false; + } + + /** + * Call when the socket connection is established. + */ + private function connectHandler(event:Event):void + { + removeEventListener(Event.CONNECT, connectHandler); + + // Write out buffered data. + if (preConnectBuffer.length > 0) + { + var data:String = preConnectBuffer.join(""); + writeUTFBytes(data); + flush(); + } + + connectionAvailable = true; + preConnectBuffer = []; + } + + private function ioErrorHandler(event:IOErrorEvent):void + { + trace("CodeCoveragePreloadSWF ioErrorHandler: " + event.errorID); + } + + private function securityErrorHandler(event:SecurityErrorEvent):void + { + trace("CodeCoveragePreloadSWF securityErrorHandler: " + event.errorID); + } + +} +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/5077c457/CodeCoverage/JavaServer/flex/src/CodeCoveragePreloadSWF.as ---------------------------------------------------------------------- diff --git a/CodeCoverage/JavaServer/flex/src/CodeCoveragePreloadSWF.as b/CodeCoverage/JavaServer/flex/src/CodeCoveragePreloadSWF.as new file mode 100755 index 0000000..858f1e5 --- /dev/null +++ b/CodeCoverage/JavaServer/flex/src/CodeCoveragePreloadSWF.as @@ -0,0 +1,190 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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.LoaderInfo; +import flash.display.Sprite; +import flash.events.Event; +import flash.trace.Trace; +import flash.utils.getTimer; + +/** + * Main of preload SWF. This SWF listens to the trace of the primary application + * and sends the data to a server using a web socket. + */ +public class CodeCoveragePreloadSWF extends Sprite +{ + //-------------------------------------------------------------------------- + // + // Class constants + // + //-------------------------------------------------------------------------- + + private static const DEFAULT_HOST:String = "localhost"; + private static const DEFAULT_DATA_PORT:int = 9097; + private static const DEFAULT_POLICY_FILE_PORT:int = 9843; + + //-------------------------------------------------------------------------- + // + // Constructor + // + //-------------------------------------------------------------------------- + + /** + * Constructor + */ + public function CodeCoveragePreloadSWF() + { + createClientSocket(); + addEventListener("allComplete", allCompleteHandler); + + Trace.setLevel(Trace.METHODS_AND_LINES, Trace.LISTENER); + Trace.setListener(methodsAndLinesCallback); + } + + //-------------------------------------------------------------------------- + // + // Variables + // + //-------------------------------------------------------------------------- + + /** + * Map the debug file info to an index number to reduce the amount + * of data sent over the port and stored. + * + * Key debug_file string + * Index: unique index representing the key. + */ + private var stringMap:Object = {}; + + /** + * incremented to provide a unique index for every string. + */ + private var stringIndex:int = 0; + + /** + * Collection of lines that have been sent to server. + * For the purposes of code coverage there is no need to send a debug line + * more than once. + */ + private var lineMap:Object = {}; + + /** + * socket to send trace data to the server. + */ + private var socket:CodeCoverageClientSocket; + + /** + * If true ignore the trace data. Used to prevent this code from being part of code + * coverage. Is this needed if the application is run w/o debug instructions. + */ + private var ignoreTrace:Boolean; + + //-------------------------------------------------------------------------- + // + // Methods + // + //-------------------------------------------------------------------------- + + /** + * Create a socket to handle sending trace data to the server. + */ + private function createClientSocket():void + { + var key:String; + var value:String; + var paramObj:Object = LoaderInfo(this.root.loaderInfo).parameters; + var host:String = DEFAULT_HOST; + var port:int = DEFAULT_DATA_PORT; + var policyFilePort:int = DEFAULT_POLICY_FILE_PORT; + + for (key in paramObj) + { + value = String(paramObj[key]); + if (key == "host") + host = value; + else if (key == "dataPort") + port = int(value); + else if (key == "policyFilePort") + policyFilePort = int(value); + } + + socket = new CodeCoverageClientSocket(host, port, policyFilePort); + } + + //-------------------------------------------------------------------------- + // + // Event handlers + // + //-------------------------------------------------------------------------- + + /** + * Callback for methods and lines trace data. + */ + public function methodsAndLinesCallback(filename:String, lineNumber:int, methodName:String, methodArgs:String):void + { + if (lineNumber <= 0 || ignoreTrace) + return; + + try + { + // Map file name to and index + if (!stringMap.hasOwnProperty(filename)) + { + socket.sendData("#" + stringIndex + "," + filename + "\n"); + stringMap[filename] = stringIndex.toString(); + stringIndex++; + } + + var id:String = stringMap[filename]; + var line:String = lineNumber.toString(); + var data:String = id + "," + line + "\n"; + + // Only send a debug line once. + if (!lineMap.hasOwnProperty(data)) + lineMap[data] = 1; + else + return; + + socket.sendData(data); + } + catch (e:Error) + { + trace("CodeCoveragePreloadSWF Error: " + e.message); + } + + } + + /** + * Called when the main application finishing loading. + * This provides us with the name of the SWF. + */ + private function allCompleteHandler(event:Event):void + { + ignoreTrace = true; + removeEventListener("allComplete", allCompleteHandler); + + var loaderInfo:LoaderInfo = event.target as LoaderInfo; + socket.sendData("@" + loaderInfo.loaderURL + "\n"); + ignoreTrace = false; + } + +} +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/5077c457/CodeCoverage/JavaServer/java/build.xml ---------------------------------------------------------------------- diff --git a/CodeCoverage/JavaServer/java/build.xml b/CodeCoverage/JavaServer/java/build.xml new file mode 100755 index 0000000..a631529 --- /dev/null +++ b/CodeCoverage/JavaServer/java/build.xml @@ -0,0 +1,157 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- + + 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. + +--> +<project default="main" basedir="." name="Code Coverage Server and Code Coverge Reporter"> + + <property file="${basedir}/env.properties"/> + <property environment="env"/> + <property name="lib.dir" value="${basedir}/../lib"/> + + <!-- Options for <javac> tasks --> + <property name="javac.debug" value="true"/> + <property name="javac.deprecation" value="false"/> + <property name="javac.src" value="1.7"/> + + <!-- JAR manifest entries --> + <property name="manifest.Implementation-Version" value="0.9.0"/> + <property name="manifest.Implementation-Vendor" value="Apache Software Foundation"/> + + <target name="main" depends="check-falcon-home,clean,compile-ccserver,create-ccserver.jar,compile-ccreporter,create-ccreporter.jar,copy-bin-lib"> + </target> + + <target name="check-falcon-home" unless="FALCON_HOME" + description="Check FALCON_HOME is a directory."> + + <echo message="FALCON_HOME is ${env.FALCON_HOME}"/> + + <available file="${env.FALCON_HOME}/lib/compiler.jar" + type="file" + property="FALCON_HOME" + value="${env.FALCON_HOME}"/> + + <fail message="FALCON_HOME must be set to a folder with a lib sub-folder containing compiler.jar such as the compiler/generated/dist/sdk folder in flex-falcon repo." + unless="FALCON_HOME"/> + </target> + + <target name="clean"> + <delete dir="${basedir}/generated"/> + <delete file="${lib.dir}/ccreporter.jar" quiet="true" failonerror="false"/> + <delete file="${lib.dir}/ccserver.jar" quiet="true" failonerror="false"/> + <delete quiet="true" failonerror="false"> + <fileset dir="${lib.dir}"> + <include name="compiler.jar"/> + <include name="ccreporter.jar"/> + <include name="ccserver.jar"/> + <include name="ccserver.properties"/> + </fileset> + </delete> + <delete dir="${lib.dir}/external" quiet="true" failonerror="false"/> + </target> + + <path id="classpath"> + <fileset dir="${env.FALCON_HOME}/lib" includes="**/*.jar" excludes="ccserver.jar,ccreporter.jar"/> + </path> + + <target name="create-ccserver.jar" depends="set.ccserver.jar.uptodate" unless="ccserver.jar.uptodate"> + <jar file="${lib.dir}/ccserver.jar" basedir="${basedir}/generated/classes" includes="**/server/*" whenmanifestonly="fail"> + <manifest> + <attribute name="Implementation-Title" value="Apache Flex Code Coverage Server"/> + <attribute name="Implementation-Version" value="${manifest.Implementation-Version}"/> + <attribute name="Implementation-Vendor" value="${manifest.Implementation-Vendor}"/> + <attribute name="Main-Class" value="org.apache.flex.tools.codecoverage.server.CodeCoverageServer"/> + <attribute name="Class-Path" value="."/> + </manifest> + </jar> + </target> + + <target name="set.ccserver.jar.uptodate"> + <uptodate property="ccserver.jar.uptodate" + targetfile="${lib.dir}/ccserver.jar"> + <srcfiles dir="${basedir}/generated/classes"> + <include name="**/server/*.class"/> + <include name="**/*.properties"/> + </srcfiles> + </uptodate> + </target> + + <target name="compile-ccserver" description="compile"> + <mkdir dir="${basedir}/generated/classes"/> + <javac debug="${javac.debug}" deprecation="${javac.deprecation}" + includes="**/server/*.java" destdir="${basedir}/generated/classes" + classpathref="classpath" includeAntRuntime="false" + source="${javac.src}" target="${javac.src}"> + <src path="${basedir}/src"/> + <compilerarg value="-Xlint:all,-path,-fallthrough,-cast"/> + </javac> + <copy todir="${basedir}/generated/classes"> + <fileset dir="${basedir}/src" includes="**/*.properties"/> + </copy> + </target> + + <target name="create-ccreporter.jar" depends="set.ccreporter.jar.uptodate" unless="ccreporter.jar.uptodate"> + <jar file="${lib.dir}/ccreporter.jar" basedir="${basedir}/generated/classes" includes="**/reporter/**/*" whenmanifestonly="fail"> + <manifest> + <attribute name="Implementation-Title" value="Apache Flex Code Coverage Reporter"/> + <attribute name="Implementation-Version" value="${manifest.Implementation-Version}"/> + <attribute name="Implementation-Vendor" value="${manifest.Implementation-Vendor}"/> + <attribute name="Main-Class" value="org.apache.flex.tools.codecoverage.reporter.CodeCoverageReporter"/> + <attribute name="Class-Path" value="compiler.jar ."/> + </manifest> + </jar> + </target> + + <target name="set.ccreporter.jar.uptodate"> + <uptodate property="ccreporter.jar.uptodate" + targetfile="${lib.dir}/ccreporter.jar"> + <srcfiles dir="${basedir}/generated/classes"> + <include name="**/*.class"/> + <include name="**/*.properties"/> + </srcfiles> + </uptodate> + </target> + + <target name="compile-ccreporter" description="compile"> + <javac debug="${javac.debug}" deprecation="${javac.deprecation}" + includes="**/reporter/**/*.java" destdir="${basedir}/generated/classes" + classpathref="classpath" includeAntRuntime="false" + source="${javac.src}" target="${javac.src}"> + <src path="${basedir}/src"/> + <compilerarg value="-Xlint:all,-path,-fallthrough,-cast"/> + </javac> + <copy todir="${basedir}/generated/classes"> + <fileset dir="${basedir}/src" includes="**/*.properties"/> + </copy> + </target> + + <target name="copy-bin-lib" description="copy lib dependencies"> + <copy todir="${lib.dir}"> + <fileset dir="${FALCON_HOME}/lib/"> + <include name="compiler.jar"/> + <include name="external/antlr*.*"/> + <include name="external/commons-cli*.*"/> + <include name="external/commons-io*.*"/> + <include name="external/flex-tool-api*.*"/> + <include name="external/guava*.*"/> + <include name="external/lzma-sdk*.*"/> + </fileset> + <fileset dir="${basedir}" includes="ccserver.properties"/> + </copy> + </target> + +</project> http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/5077c457/CodeCoverage/JavaServer/java/ccserver.properties ---------------------------------------------------------------------- diff --git a/CodeCoverage/JavaServer/java/ccserver.properties b/CodeCoverage/JavaServer/java/ccserver.properties new file mode 100755 index 0000000..18f5e98 --- /dev/null +++ b/CodeCoverage/JavaServer/java/ccserver.properties @@ -0,0 +1,8 @@ +#host=localhost +#dataPort=9097 +#commandPort=9098 +#policyFilePort=9843 +#preloadSWF=CodeCoveragePreloadSWF.swf +#mmCfgPath= +#dataDirectory= +