How to exit an air application from an actionscript library? - apache-flex

I am trying the following but every once in awhile the nativeApp is not defined.
var nativeApp:Object = getDefinitionByName("flash.desktop.NativeApplication");
nativeApp.nativeApplication.exit();
I am confused why sometimes getDefinitionByName("flash.desktop.NativeApplication") resolves and other times it does not.
I am trying to resolve this problem to address the following issue in flexcover - code.google.com/p/flexcover/issues/detail?id=33
Update - here is the class I am attempting to fix: http://code.google.com/p/flexcover/source/browse/trunk/CoverageAgent/src/com/allurent/coverage/runtime/AbstractCoverageAgent.as CoverageAgent.swc is an actionscript library called by the unit tests to exit the flexcover air application used to determine the code coverage of the unit tests. The flexcover air application only exits about the half the time and it is causing problems for our maven builds to execute successfully.

NativeApplication.nativeApplication.exit();

In regards to FlexCover - the reason you are seeing it work sometimes and not others is the CoverageAgent is designed to exit the Unit Tests it does not communicate back to the CoverageViewer. I have created my own FlexCoverListener that sends an exit message over local connection to the CoverageViewer. Below is the code.
package org.flexunit.listeners
{
import flash.events.EventDispatcher;
import org.flexunit.listeners.closer.FlexCoverCloser;
import org.flexunit.runner.IDescription;
import org.flexunit.runner.Result;
import org.flexunit.runner.notification.Failure;
import org.flexunit.runner.notification.IAsyncStartupRunListener;
import org.flexunit.runner.notification.ITemporalRunListener;
public class FlexCoverListener extends EventDispatcher implements IAsyncStartupRunListener,
ITemporalRunListener
{
import com.allurent.coverage.runtime.CoverageManager;
public function FlexCoverListener()
{
}
public function get ready():Boolean
{
return true;
}
public function testTimed( description:IDescription, runTime:Number ):void
{
}
public function testRunFinished( result:Result ):void
{
CoverageManager.agent.recordCoverage("SR_TESTS_COMPLETE");
}
public function testFinished( description:IDescription ):void {}
public function testRunStarted( description:IDescription ):void {}
public function testStarted( description:IDescription ):void{}
public function testFailure( failure:Failure ):void{}
public function testAssumptionFailure( failure:Failure ):void{}
public function testIgnored( description:IDescription ):void{}
}
}
You can add the above listener to your tests by doing the following in your TestRunner:
core.addListener(new FlexCoverListener());
var core : FlexUnitCore = new FlexUnitCore();
Last but most importantly I changed the recordCoverage method in the AbstractCoverageAgent to look like the following:
/**
* Record the execution of a single coverage key; called by
* the global coverage() function.
*/
public function recordCoverage(key:String):void
{
if(key == "SR_TESTS_COMPLETE")
{
exit();
}
else if (isNaN(coverageMap[key]++))
{
// The map must not have contained this key yet, so enter an
// execution count of 1. Subsequent calls will autoincrement without
// returning NaN.
//
coverageMap[key] = 1;
}
}

nativeAppilcation is a static field. It does not need to be called on an object. So you do not have to call getDefinitionByName("flash.desktop.NativeApplication").
Just invoke exit as follows:
NativeApplication.nativeApplication.exit();
Flash Builder or Flash Pro will include the library for you.
If you are not using the IDE, import the library:
import flash.desktop.NativeApplication;

Related

Eclipse Scout Neon mock backend service

In our project I have modules scout.client, scout.server, scout.shared and backend.
Backend has no dependencies to scout.server and scout.shared, but scout.server has dependencies to backend.
Inside backend project I have all business logic and calling all outside services.
My problem is when I try to test scout services that use some service from backend.
Because scout provide some great tool for mocking beans, we defined our service inside backend as beans as :
BEANS.getBeanManager().registerClass(CarService.class);
BEANS.getBeanManager().registerClass(PartnerService.class);
Both, CarService.class and PartnerService.class are in backend.
When I try to write some tests and I add #BeanMock to service in test
#BeanMock
private IPartnerService partnerService;
I get mock, but then every return every function is null, even if I write
doReturn(PartnerBuilder.standardPartnerListWithOneElement()).when(this.partnerService)
.getPartners(any(Set.class));
If I debug in my test, before this test is called with debugger I can get :
partnerService.getPartners(...) -> return a list of person
what is right, but when class that is tested calles this service it return null.
I understand that this could be due to missing annotation on interface #ApplicationScoped. Without this there is no guarantee that only one bean is created, and when statement react on another copy of that bean...?
I could not add annotation on interface because backend has no dependencies to scout modules.
How could I handle this kind of cases?
Tested class is :
public class UtilityPartner {
/**
* Method return service bean for getting partners by ids.
*
* #return
*/
private static IPartnerService getPartnerService() {
return BEANS.get(IPartnerService.class);
}
public static String getPartnerName(final Long partnerId) {
if (partnerId == null) {
return "";
}
final List<Partner> partners =
(List<Partner>) getPartnerService().getPartners(Sets.newHashSet(partnerId));
if (partners == null || partners.isEmpty()) {
return "";
}
final Partner partner = partners.get(0);
return LookupUtil.createLookupDescription(partner.getId(), partner.getName());
}
}
test class is :
#RunWith(ServerTestRunner.class)
#RunWithSubject("anonymous")
#RunWithServerSession(ServerSession.class)
public class TestUtilityPartner {
#BeanMock
private IPartnerService partnerService;
#Before
public void init() {
doReturn(PartnerBuilder.standardPartnerListWithOneElement()).when(this.partnerService).getPartners(any(Set.class));
}
#Test
public void getPartnerName() {
final String name = UtilityPartner.getPartnerName(10L);
Assert.assertEquals("My name", name); // NAME IS ""
}
}
Using #BeanMock does not help here, because you are not using an application scoped service:
In the init method you are changing the local field partnerService. However, in your test you call UtilityPartner.getPartnerService, which is creating a new instance (with BEANS.get(IPartnerService.class)).
#BeanMock is more useful for convenience for mocking application scoped beans.
You can always register your beans manually as shown by Jmini. Please do not forget to unregister the bean again after the test!
We recommend using org.eclipse.scout.rt.testing.shared.TestingUtility.registerBean(BeanMetaData), which is automatically adding a testing order and removing #TunnelToServer annotations.
I think that you should register your mock instance in the Bean manager (See bean registration in the Scout Architecture Document). You should use a small order (-10 000 is recommended for tests), in order for your mock to win over the productive registration. The best approach is to use the TestingUtility class to register/unregister your mock. Do not forget to call the unregisterBean() method (in the method annotated with #After):
import java.util.Collections;
import org.eclipse.scout.rt.platform.BeanMetaData;
import org.eclipse.scout.rt.platform.IBean;
import org.eclipse.scout.rt.testing.shared.TestingUtility;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
public class TestUtilityPartner {
private IBean<?> beanRegistration;
#Before
public void init() {
partnerService = Mockito.mock(IPartnerService.class);
// Register the mock using the Bean meta information:
BeanMetaData beanData = new BeanMetaData(IPartnerService.class)
.withInitialInstance(partnerService)
.withApplicationScoped(true);
this.beanRegistration = TestingUtility.registerBean(beanData);
// Mockito behavior:
Mockito.doReturn(Collections.singletonList(new Partner(34L, "John Smith")))
.when(partnerService).getPartners(Mockito.any(Set.class));
}
#After
public void after() {
// Unregister the mocked services:
TestingUtility.unregisterBean(this.beanRegistration);
}
#Test
public void getPartnerName() {
String name = UtilityPartner.getPartnerName(10L);
Assert.assertEquals("10 - John Smith", name);
}
}
I am not sure what #BeanMock (org.eclipse.scout.rt.testing.platform.mock.BeanMock) is doing, but according to Judith Gull's answer it will not work:
Using #BeanMock does not help here, because you are not using an application scoped service:
In the init method you are changing the local field partnerService. However, in your test you call UtilityPartner.getPartnerService, which is creating a new instance (with BEANS.get(IPartnerService.class)).
#BeanMock is more useful for convenience for mocking application scoped beans.

Glassfish 3.1.2 seems not to run more than one thread in an EJB

I have an EJB to calculate sth. with increasing precision as long as the calculation runs.
So one async function starts the calculation and one async should stop it. But Running on Glassfish 3.1.2 calling stopCalculating() does not create a new Thread but waits until startCalculating() finishes, what obviously never happens.
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.AsyncResult;
import javax.ejb.Asynchronous;
import javax.ejb.Singleton;
#Singleton
public class Calculator {
private boolean calculating = false;
private String result = "Empty";
#Asynchronous
public void startCalculating() {
calculating = true;
Logger.getGlobal().log(Level.INFO, "Starting!");
calculate();
}
private void calculate() {
result = "";
while(calculating) {
/*Calculate and update result*/
Logger.getGlobal().log(Level.INFO, "Calculate...");
}
}
#Asynchronous
public Future<String> stopCalculating() {
Logger.getGlobal().log(Level.INFO, "Stopping!");
calculating = false;
return new AsyncResult<String>(result);
}
}
How can I get Glassfish to run stopCalculating() in an other Thread?
I think it's because by default Singleton EJB has #Lock(WRITE) access.
You're using local calls instead of going through EJB proxy so calculate() invoked from startCalculating(-) is a part of the whole startCalculating(-) invocation (so has #Local(WRITE) as well).
I'd try adding #Lock(READ) to your calculate() method and change the local call to business call or just set #Lock(READ) for your EJB and give it a shot.

How to separate remote object and interface in Flash Builder Flex

The code below shows interface and remote object are coded in the same file How to separate them into two files ?
Current Code :
<s:RemoteObject id="ro"
destination="customerService"
source="customerService"
endpoint="http://localhost/amfphp/gateway.php"
showBusyCursor="true">
<s:method name="getCustomer" result="getCustomer_resultHandler(event)">
<s:arguments>
<CusOpt>{''}</CusOpt>
<option>{''}</option>
<idcompany>{2}</idcompany>
</s:arguments>
</s:method>
<s:method name="genPKID" result="genPKID_resultHandler(event)">
<s:arguments>
<idcompany>{2}</idcompany>
</s:arguments>
</s:method>
</s:RemoteObject>
Wrong way of doing :
import mx.rpc.remoting.RemoteObject;
public class CustomerRO extends RemoteObject
{
public function CustomerRO(destination:String=null)
{
super(destination);
this.destination = "customerService";
this.source = "customerService";
this.endpoint = "http://localhost/amfphp/gateway.php";
this.showBusyCursor = true;
}
}
You want to create a client-side service stub for your remote service. There's a few steps to get this set up properly.
Create the service interface
For brevity we'll create an interface with just one method, but you can add as many as you need.
package be.vmm.user.service {
import mx.rpc.AsyncToken;
public interface ICustomerService{
function getCustomerById(id:int):AsyncToken;
}
}
Create an implementation of the interface
In your example you are extending RemoteObject. I would suggest you encapsulate it: that would be a lot more flexible. Not to mention that in your code the connection information is hardcoded which requires you to recompile your application every time this info changes.
public class CustomerService implements ICustomerService {
private var ro:RemoteObject;
public function CustomerService(ro:RemoteObject) {
this.ro = ro;
}
public function getCustomerById(id:int):AsyncToken {
return ro.getCustomerById(id);
}
}
You also have the option to create another implementation of the interface. The most common use case consists of creating a mock service that doesn't really connect to the server but returns fake data directly. If you want to test your application without server connection you can now just substitute your real service stub with the mock service stub, since they both implement the same interface.
Use the implementation
var ro:RemotObject = new RemoteObject();
ro.destination = "customerService";
ro.source = "customerService";
ro.endpoint = "http://localhost/amfphp/gateway.php";
ro.showBusyCursor = true;
//these properties are best externalized in a configuration file
var service:ICustomerService = new CustomerService(ro);
var token:ASyncToken = service.getCustomerById(1);
token.addResponder(new Responder(handleResult, handleFault));
private function handleResult(event:ResultEvent):void {
//do what you need to do
trace(event.result as Customer);
}
private function handleFault(event:FaultEvent):void {
//show error message
}

flexunit: Parametrized tests

I am trying to run a parametrized tests... Was trying to implement it like it explained here:
http://docs.flexunit.org/index.php?title=Parameterized_Test_Styles
Here is what my test case looking
import org.flexunit.runners.Parameterized;
[RunWith("org.flexunit.runners.Parameterized")]
public class ArrayBasedStackTests
{
[Paremeters]
public static var stackProvider:Array = [new ArrayBasedStack(), new LinkedListBasedStack()] ;
private var _stack:IStack;
public function ArrayBasedStackTests(param:IStack)
{
_stack = param;
}
[Before]
public function setUp():void
{
}
[After]
public function tearDown():void
{
}
[Test ( description = "Checks isEmpty method of the stack. For empty stack", dataProvider="stackProvider" )]
public function isEmptyStackPositiveTest():void
{
var stack:IStack = _stack;
assertEquals( true, stack.isEmpty() );
}
But this code throws following initializing Error:
Error: Custom runner class org.flexunit.runners.Parameterized should
be linked into project and implement IRunner. Further it needs to have
a constructor which either just accepts the class, or the class and a
builder.
Need help to fix it
UPDATE
I've updated the code so it looks like this
[RunWith("org.flexunit.runners.Parameterized")]
public class ArrayBasedStackTests
{
private var foo:Parameterized;
[Parameters]
public static function stacks():Array
{
return [ [new ArrayBasedStack()], [new LinkedListBasedStack()] ] ;
}
[Before]
public function setUp():void
{
}
[After]
public function tearDown():void
{
}
[Test ( description = "Checks isEmpty method of the stack. For empty stack", dataProvider="stacks")]
public function isEmptyStackPositiveTest(stack:IStack):void
{
assertEquals( true, _stack.isEmpty() );
}
It works. But the result is a bit strange. I have 4 test executed instead of 2. (I have 2 items in data provider, so cant get why do I have 4 tests).
Output
http://screencast.com/t/G8DHbcjDUkJ
The [Parameters] meta-data specifies that the parameters are passed to the constructor of the test - so the test class is called for each parameter. You also have the dataProvider set for the specific test method, so the test method is also called once for each parameter. Two calls for the test, and two calls to the method, ends up running four tests.
The solution is to either use [Parameters] meta-tag which specifies the data to use for the whole test class, or use the dataProvider for each test method, but not both with the same data at the same time.
You're missing the static reference to Paramaterized, as shown here:
import org.flexunit.runners.Parameterized;
[RunWith("org.flexunit.runners.Parameterized")]
public class MyTestNGTest
{
private var foo:Parameterized;
...
Basically, that error means that the [Runner] defined isn't available at runtime, which occurs if there is no static reference in the class to cause it to get linked in.
In FlexUnit 4.5.1, this approach changed to using [Rule]'s like so:
public class MyTestNGTest
{
[Rule]
public function paramaterizedRule:ParamaterizedRule = new ParamaterizedRule();
...
}
However, I can't seem to see an actual implementation of IMethodRule for paramaterized tests (that example is fictional).

FlexUnit component testing patterns: use addAsync or manually initialize?

We've been using Flex for about 6 months here at work, and I found that my first batches of FlexUnit tests involving custom components would tend to follow this sort of pattern:
import mx.core.Application;
import mx.events.FlexEvent;
import flexunit.framework.TestCase;
public class CustomComponentTest extends TestCase {
private var component:CustomComponent;
public function testSomeAspect() : void {
component = new CustomComponent();
// set some properties...
component.addEventListener(FlexEvent.CREATION_COMPLETE,
addAsync(verifySomeAspect, 5000));
component.height = 0;
component.width = 0;
Application.application.addChild(component);
}
public function verifySomeAspect(event:FlexEvent) : void {
// Assert some things about component...
}
override public function tearDown() : void {
try {
if (component) {
Application.application.removeChild(component);
component = null;
}
} catch (e:Error) {
// ok to ignore
}
}
Basically, you need to make sure the component has been fully initialized before you can reliably verify anything about it, and in Flex this happens asynchronously after it has been added to the display list. So you need to setup a callback (using FlexUnit's addAsync function) to be notified when that's happened.
Lately i've been just manually calling the methods that the runtime would call for you in the necessary places, so now my tests tend to look more like this:
import flexunit.framework.TestCase;
public class CustomComponentTest extends TestCase {
public function testSomeAspect() : void {
var component:CustomComponent = new CustomComponent();
component.initialize();
// set some properties...
component.validateProperties();
// Assert some things about component...
}
This is much easier to follow, but it kinda feels like I'm cheating a little either way. The first case is slamming it into the current Application (which would be the unit test runner shell app), and the latter isn't a "real" environment.
I was wondering how other people would handle this sort of situation?
I see nothing wrong with using the async version. I can agree that the second version is shorter, but I'm not sure that I think it's easier to follow. The test does a lot of things that you wouldn't normally do, whereas the first example is more true to how you would use the component outside the test environment.
Also, in the second form you have to make sure that you do exactly what the framework would do, miss one step and your test isn't relevant, and each test must repeat this code. Seems to me it's better to test it in a situation that is as close to the real thing as possible.
You could have a look at dpUint's sequences, they made component testing a little more declarative:
public function testLogin():void {
var passThroughData:Object = new Object();
passThroughData.username = "myuser1";
passThroughData.password = "somepsswd";
var sequence:SequenceRunner = new SequenceRunner(this);
sequence.addStep(new SequenceSetter(form.usernameTI, {text:passThroughData.username}));
sequence.addStep(new SequenceWaiter(form.usernameTI, FlexEvent.VALUE_COMMIT, 100));
sequence.addStep(new SequenceSetter(form.passwordTI, {text:passThroughData.password}));
sequence.addStep(new SequenceWaiter(form.passwordTI, FlexEvent.VALUE_COMMIT, 100));
sequence.addStep(new SequenceEventDispatcher(form.loginBtn, new MouseEvent("click", true, false)));
sequence.addStep(new SequenceWaiter(form, "loginRequested", 100));
sequence.addAssertHandler(handleLoginEvent, passThroughData);
sequence.run();
}
(example from the dpUint wiki, see here for more info).

Resources