Index: allurent/coverage/model/application/Recorder.as =================================================================== --- allurent/coverage/model/application/Recorder.as (revision 140) +++ allurent/coverage/model/application/Recorder.as (working copy) @@ -30,8 +30,11 @@ import com.allurent.coverage.model.ICoverageModel; import flash.events.EventDispatcher; + import flash.utils.getQualifiedClassName; import mx.formatters.NumberFormatter; + import mx.logging.ILogger; + import mx.logging.Log; /** Recording of coverage data started. */ [Event(name="recordingStart", @@ -67,6 +70,7 @@ private var coverageElementsMap:Object; private var numCoverageElements:uint = 0; private var timer:IOneTimeInterval; + private var _log:ILogger; public function Recorder(coverageModel:ICoverageModel, timer:IOneTimeInterval) @@ -77,6 +81,7 @@ currentRecording = ""; coverageElementsMap = {}; recordingTimeout = 2000; + _log = Log.getLogger(getQualifiedClassName(this).replace("::",".")); } public function record(keyMap:Object):void @@ -120,12 +125,14 @@ if(hasReceivedDataAndHasNotStartedYet) { startCoverageRecording(); - trace("Recorder.record startCoverageRecording: "); + _log.debug("startCoverageRecording"); + //trace("Recorder.record startCoverageRecording: "); } if(autoUpdate && !isEmpty) { - trace("Recorder.record recordingTimeout: " + recordingTimeout); + _log.debug("recordingTimeout"+ recordingTimeout); + // trace("Recorder.record recordingTimeout: " + recordingTimeout); timer.delay(recordingTimeout, handleRecordingTimeout); } } @@ -142,7 +149,8 @@ } var hasParsed:Boolean = (numCoverageElements > 0); - trace("Recorder.applyCoverageData "); + _log.debug("applyCoverageData"); +// trace("Recorder.applyCoverageData "); coverageElementsMap = {}; numCoverageElements = 0; currentStatusMessage = ""; @@ -166,7 +174,8 @@ currentRecording = ""; timer.clear(); createStatusMessage(); - trace("Recorder.endCoverageRecording recordingTimeout "); + _log.debug("endCoverageRecording recordingTimeout"); + // trace("Recorder.endCoverageRecording recordingTimeout "); dispatchEvent(new CoverageEvent(CoverageEvent.RECORDING_END)); } Index: allurent/coverage/service/CoverageCommunicator.as =================================================================== --- allurent/coverage/service/CoverageCommunicator.as (revision 140) +++ allurent/coverage/service/CoverageCommunicator.as (working copy) @@ -35,8 +35,11 @@ import flash.events.SecurityErrorEvent; import flash.events.StatusEvent; import flash.utils.Dictionary; + import flash.utils.getQualifiedClassName; import mx.controls.Alert; + import mx.logging.ILogger; + import mx.logging.Log; /** This event is dispatched when a coverageEnd even is received from the sender.*/ [Event(name="coverageEnd", @@ -72,8 +75,11 @@ private var recorder:IRecorder; private var isTooBusyToReceiveMore:Boolean; + private var _log:ILogger; + public function CoverageCommunicator(recorder:IRecorder) { + _log = Log.getLogger(getQualifiedClassName(this).replace("::",".")) this.recorder = recorder; this.recorder.addEventListener(CoverageEvent.RECORDING_END, onRecordingEnd); this.recorder.addEventListener(CoverageEvent.PARSING_END, onParsingEnd); @@ -101,7 +107,8 @@ } // Set up our LocalConnection. Note that the Controller handles - trace("attachConnection coverageDataConnection: " + connectionName); + _log.debug("attachConnection coverageDataConnection: " + connectionName); + //trace("attachConnection coverageDataConnection: " + connectionName); coverageDataConnection = createCoverageDataConnection(); coverageDataConnection.allowDomain("*"); coverageDataConnection.client = this; @@ -135,12 +142,14 @@ */ public function coverageData(keyMap:Object, mapNumber:int):void { - trace("Received keyMap ", mapNumber); + _log.debug("coverage Data #"+mapNumber); + //Alert.show("Received keyMap ", mapNumber.toString()); lastMapNumber = mapNumber; if(keyMap == null) { - trace("++++++++++CoverageCommunicator.coverageData "); + _log.debug("++++++++++CoverageCommunicator.coverageData null keymap"); + // trace("++++++++++CoverageCommunicator.coverageData "); sendRegistration(); } else @@ -164,6 +173,8 @@ */ public function coverageDataAndExit(keyMap:Object, mapNumber:int):void { + // Alert.show("coverage data & exit"); + _log.debug("coverage data & exit"); coverageData(keyMap, mapNumber); dispatchEvent(new Event(COVERAGE_END_EVENT)); } @@ -186,8 +197,8 @@ currentAckConnection = 1; } var name:String = getACKConnectionName(currentAckConnection); - - trace("rotateConnection " + name); + _log.debug("rotateConnection"); + //trace("rotateConnection " + name); return name; } @@ -205,12 +216,13 @@ private function sendRegistration():void { var name:String = getACKConnectionName(++ackConnectionCounter); - trace("sendRegistration name " + name); + _log.debug("sendRegistration name " + name); +// trace("sendRegistration name " + name); var ackConnection:ISendingLocalConnection = initializeAckConnection(); registerAckConnection(name, ackConnection); - - trace("sendRegistration ackConnection " + ackConnection); + _log.debug("sendRegistration ackConnection " + ackConnection); +// trace("sendRegistration ackConnection " + ackConnection); sendACK(name, lastMapNumber); } @@ -234,7 +246,8 @@ try { //send ack of received message - trace("Sending ACK of " + mapNumber + " via ", ackConnectionName); +// trace("Sending ACK of " + mapNumber + " via ", ackConnectionName); + _log.debug("Sending ACK of " + mapNumber + " via ", ackConnectionName); var ackConnection:ISendingLocalConnection = ISendingLocalConnection(ackConnections[ackConnectionName]); ackConnection.send(ackConnectionName, ACK_HANDLER, mapNumber); } @@ -263,7 +276,8 @@ private function handleConnectionError(e:ErrorEvent):void { - trace("CoverageCommunicator.handleConnectionError: " + e.text); + _log.error("CoverageCommunicator.handleConnectionError: " + e.text); + // trace("CoverageCommunicator.handleConnectionError: " + e.text); Alert.show(e.type + " " + e.text, "Coverage Recording Acknowledgement Error"); } @@ -271,11 +285,13 @@ { if (e.level == "error") { - trace("CoverageCommunicator.handleConnectionStatus: level error, code " + e.code); + _log.error("CoverageCommunicator.handleConnectionStatus: level error, code " + e.code); + //trace("CoverageCommunicator.handleConnectionStatus: level error, code " + e.code); } else if (e.level == "status") { - trace("CoverageCommunicator.handleConnectionStatus: level status, code " + e.code); + _log.info("CoverageCommunicator.handleConnectionStatus: level status, code " + e.code); + // trace("CoverageCommunicator.handleConnectionStatus: level status, code " + ObjectUtil.toString(e)); } } } Index: allurent/coverage/Controller.as =================================================================== --- allurent/coverage/Controller.as (revision 140) +++ allurent/coverage/Controller.as (working copy) @@ -24,6 +24,7 @@ //TODO: way too many responsiblities. Needs refactoring. package com.allurent.coverage { + import com.allurent.coverage.adapter.ReportAdapter; import com.allurent.coverage.event.CoverageEvent; import com.allurent.coverage.model.ICoverageModel; import com.allurent.coverage.model.application.IRecorder; @@ -43,7 +44,12 @@ import flash.filesystem.File; import flash.filesystem.FileMode; import flash.filesystem.FileStream; + import flash.utils.getQualifiedClassName; + import mx.controls.Alert; + import mx.logging.ILogger; + import mx.logging.Log; + /** This event is dispatched when the coverage model is updated with new metadata. */ [Event(name="coverageModelChange", type="com.allurent.coverage.event.CoverageEvent")] @@ -70,8 +76,10 @@ public var isCoverageDataCleared:Boolean; [Bindable] - public var currentStatusMessage:String; + public var currentStatusMessage:String; + private var _log:ILogger + /** * Flag indicating that application should exit when instrumented app is done. * and all pending data has been written. @@ -82,9 +90,15 @@ * Output file to which coverage data should be written when application is done. */ public var coverageOutputFile:File; + + /** + * Output file to which emma coverage report should be written when application is done. + */ + public var emmaOutputFile:File; public function Controller(project:ProjectModel) { + _log = Log.getLogger(getQualifiedClassName(this).replace("::",".")); currentStatusMessage = ""; isCoverageDataCleared = true; @@ -208,10 +222,11 @@ */ public function close():void { - if (coverageOutputFile != null) + Alert.show("close called"); + if (hasOutputFile) { applyCoverageData(); - writeReport(coverageOutputFile); + writeReports(); } NativeApplication.nativeApplication.exit(); } @@ -228,19 +243,51 @@ out.close(); } + private function writeEmmaReport(f:File):void{ + + var xml:XML = coverageModel.toXML(); + var emmaXML:XML = new ReportAdapter(xml).toEmmaFormat(); + var out:FileStream = new FileStream(); + out.open(f, FileMode.WRITE); + out.writeUTFBytes(emmaXML.toXMLString()); + out.writeUTFBytes("\n"); + out.close(); + } + private function onCoverageEnd(event:Event):void { - if (coverageOutputFile != null) + // Alert.show("coverage end "+autoExit); + _log.debug("on Coverage END"); + if (hasOutputFile) { + _log.debug("has output file"); applyCoverageData(); - writeReport(coverageOutputFile); + writeReports(); } if (autoExit) { + _log.debug("Exiting"); NativeApplication.nativeApplication.exit(); } - } + } + private function writeReports():void{ + var str:String = "writingreports: " + if(coverageOutputFile!=null){ + str += coverageOutputFile.nativePath; + writeReport(coverageOutputFile); + } + if(emmaOutputFile != null){ + str += "\n "+emmaOutputFile.nativePath; + writeEmmaReport(emmaOutputFile); + } + _log.debug(str); + //Alert.show(str); + } + private function get hasOutputFile():Boolean{ + return (coverageOutputFile != null || emmaOutputFile != null); + } + private function handleRecorderEvents(event:CoverageEvent):void { if(event.type == CoverageEvent.PARSING_END && event.hasParsed) Index: allurent/coverage/parse/CommandLineOptionsParser.as =================================================================== --- allurent/coverage/parse/CommandLineOptionsParser.as (revision 140) +++ allurent/coverage/parse/CommandLineOptionsParser.as (working copy) @@ -95,6 +95,12 @@ controller.autoExit = true; controller.recorder.autoUpdate = false; break; + + case "emma-report": + controller.emmaOutputFile = new File(arg); + controller.autoExit = true; + controller.recorder.autoUpdate = false; + break; case "coverage-metadata": controller.loadMetadata(new File(arg));