1  /*
     2   * Copyright the original author or authors.
     3   * 
     4   * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   * 
     8   *      http://www.mozilla.org/MPL/MPL-1.1.html
     9   * 
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  import org.as2lib.app.exec.Process;
    18  import org.as2lib.app.exec.ProcessErrorListener;
    19  import org.as2lib.app.exec.ProcessFinishListener;
    20  import org.as2lib.app.exec.ProcessPauseListener;
    21  import org.as2lib.app.exec.ProcessResumeListener;
    22  import org.as2lib.app.exec.ProcessStartListener;
    23  import org.as2lib.app.exec.ProcessUpdateListener;
    24  import org.as2lib.core.BasicClass;
    25  import org.as2lib.env.log.Logger;
    26  import org.as2lib.env.log.LogManager;
    27  import org.as2lib.test.unit.TestCaseMethodInfo;
    28  import org.as2lib.test.unit.TestResult;
    29  import org.as2lib.test.unit.TestRunner;
    30  import org.as2lib.util.StringUtil;
    31  
    32  /**
    33   * {@code XmlSocketTestListener} writes-out received test execution information with
    34   * the xml socket.
    35   * 
    36   * <p>The written-out information is formatted as follows:
    37   * <ul>
    38   *   <li>&lt;start&gt;Start message.&lt;/start&gt;</li>
    39   *   <li>&lt;update&gt;Update message.&lt;/update&gt;</li>
    40   *   <li>&lt;pause&gt;Pause message.&lt;/pause&gt;</li>
    41   *   <li>&lt;resume&gt;Resume message.&lt;/resume&gt;
    42   *   <li>&lt;error&gt;Error message.&lt;/error&gt;</li>
    43   *   <li>&lt;finish hasErrors="false/true"&gt;Finish message.&lt;/finish&gt;</li>
    44   * </ul>
    45   * 
    46   * <p>This format is also expected by the Unit Test Task of As2ant, so you may easily
    47   * use this test listener and the task in conjunction.
    48   * 
    49   * @author Christophe Herreman
    50   * @author Simon Wacker
    51   */
    52  class org.as2lib.test.unit.XmlSocketTestListener extends BasicClass implements
    53  		ProcessStartListener, ProcessPauseListener, ProcessResumeListener,
    54  		ProcessUpdateListener, ProcessErrorListener, ProcessFinishListener {
    55  	
    56  	private static var logger:Logger = LogManager.getLogger("org.as2lib.test.unit.XmlSocketTestListener");
    57  	
    58  	private var socket:XMLSocket;
    59  	
    60  	/**
    61  	 * Constructs a new {@code XmlSocketTestListener} instance.
    62  	 * 
    63  	 * <p>If {@code host} is not specified, {@code "localhost"} is used. If
    64  	 * {@code port} is not specified, {@code 3212} is used.
    65  	 * 
    66  	 * @param host the host of the connection to open
    67  	 * @param port the port of the connection to open
    68  	 */
    69  	public function XmlSocketTestListener(host:String, port:Number) {
    70  		if (host == null) {
    71  			host = "localhost";
    72  		}
    73  		if (port == null) {
    74  			port = 3212;
    75  		}
    76  		socket = new XMLSocket();
    77  		socket.connect(host, port);
    78  	}
    79  	
    80  	public function onProcessStart(process:Process):Void {
    81  		socket.send(new XML("<start>Started execution of tests.</start>"));
    82  	}
    83  	
    84  	public function onProcessUpdate(process:Process):Void {
    85  		var testRunner:TestRunner = TestRunner(process);
    86  		if (testRunner != null) {
    87  			var methodInfo:TestCaseMethodInfo = testRunner.getCurrentTestCaseMethodInfo();
    88  			if (methodInfo != null) {
    89  				socket.send(new XML("<update>Executing " + testRunner.getCurrentTestCase().getName() +
    90  						"." + methodInfo.getMethodInfo().getName() + ".</update>"));
    91  			}
    92  		}
    93  	}
    94  	
    95  	public function onProcessPause(process:Process):Void {
    96  		var testRunner:TestRunner = TestRunner(process);
    97  		if (testRunner != null) {
    98  			socket.send(new XML("<pause>Paused execution at " +
    99  					testRunner.getCurrentTestCaseMethodInfo().getName() + ".</pause>"));
   100  		}
   101  	}
   102  	
   103  	public function onProcessResume(process:Process):Void {
   104  		var testRunner:TestRunner = TestRunner(process);
   105  		if (testRunner != null) {
   106  			socket.send(new XML("<resume>Resumed execution at " + 
   107  					testRunner.getCurrentTestCaseMethodInfo().getName() + ".</resume>"));
   108  		}
   109  	}
   110  	
   111  	public function onProcessFinish(process:Process):Void {
   112  		if (!(process instanceof TestRunner)) {
   113  			if (logger.isErrorEnabled()) {
   114  				logger.error("The process [" + process + "] this listener was added to " +
   115  						"is not of the expected type 'org.as2lib.test.unit.TestRunner'.");
   116  			}
   117  		}
   118  		var testResult:TestResult = TestRunner(process).getTestResult();
   119  		socket.send(new XML("<finish hasErrors='" + testResult.hasErrors() + "'><![CDATA[" +
   120  				"Finished execution with result:\n" + testResult + "]]></finish>"));
   121  	}
   122  	
   123  	public function onProcessError(process:Process, error):Boolean {
   124  		socket.send(new XML("<error><![CDATA[Error was raised during execution:\n" + error + "]]></error>"));
   125  		return false;
   126  	}
   127  	
   128  }