FlexUnit and callLater - apache-flex

I'm trying to use callLater with FlexUnit v0.9:
public function testCallLater():void {
Application.application.callLater( addAsync(function():void {
assertTrue(true);
}, 1000));
}
but when it runs I get this error:
ArgumentError: Error #1063: Argument count mismatch on flexunit.framework::AsyncTestHelper/handleEvent(). Expected 1, got 0.
at Function/http://adobe.com/AS3/2006/builtin::apply()
at mx.core::UIComponent/callLaterDispatcher2()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:8628]
at mx.core::UIComponent/callLaterDispatcher()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:8568]
I'm not sure what the problem is. Is callLater incompatible with FlexUnit?

First, you should really consider migrating to FlexUnit 4.0: http://blogs.digitalprimates.net/codeSlinger/index.cfm/2009/5/3/FlexUnit-4-in-360-seconds
Second, callLater is meant to be used to delay processing until the next frame in visual classes. Your test case class is not a visual class extending UIComponent, therefore you should not try to use callLater.
Third, addAsync is use to test the results of an asynchronous operation. This is typically used in testing the results of a network request, of a file read, of a timer event, etc. That is why normally you see an "event" as a parameter in the addAsync test function (because asynchronous requests use events to process results). In your case, you're not responding to an asynchronous operation with your addAsync call, and therefore you shouldn't be looking for an event in your test function. Remove the event:Event parameter and the error will go away.
However, perhaps you can re-phrase this question to state what you're trying to accomplish? The code sample that you've indicated is not really doing anything useful. If you can be a little more specific we can help you write a better test case.
For help with using addAsync with older versions of FlexUnit, see this tutorial: http://life.neophi.com/danielr/2007/03/asynchronous_testing_with_flex.html

It looks like you are expecting an event, but not getting one. I imagine the following code would work.
public function testCallLater():void {
Application.application.callLater( addAsync(function(/*removed event declaration*/):void {
assertTrue(true);
}, 1000));
}

Just in case someone needs it, this works :
private function testCallLater():void {
Application.application.callLater(doCallLater, [ addAsync(funcUnderTest, 1000) ]);
}
private function doCallLater(testFunc:Function):void {
testFunc(null); // Dummy arg necessary because of addAsync expecting one arg
}
private function funcUnderTest(e:Object = null):void {
assertTrue(true);
}

Related

PHPUnit: how to use assertions outside of the "test..." methods?

I have the following code:
private function registerShutdownFunction(): void
{
register_shutdown_function(function () {
$this->dropDatabasesAndUsersIfExist();
});
}
And this code:
private function dropDatabasesAndUsersIfExist(): void
{
// some code for deletion of the databases...
foreach ($connections as $connection) {
$this->assertNotContains($connection, $databases);
}
}
But dropDatabasesAndUsersIfExist is not a "test..." method. And phpunit ignores assertions outside of the test methods.
And seems there are problems may occur, because this shutdown function running directly before the die of the script...
You can use PHPUnit's Assert class outside of test cases if that is really what you want to do:
PHPUnit\Framework\Assert::assertNotContains($connection, $databases);
Edit: After reading your question one more time I'm not really sure if my answer helps you. If I got you right, you are already using the assertion but it did not behave as you'd expect it. My guess is that you want the whole test run to fail if any of the assertions in dropDatabasesAndUsersIfExist was not met.
One solution could be to move the checks you are doing in dropDatabasesAndUsersIfExist to a separate test class that should be executed last. You can achieve this by appending another test suite with the new class right after your test suite(s).

Cancelling a LoadAsync operation after a timeout period and recalling LoadAsync afterwards throws exception

I am working with SerialDevice on C++/winrt and need to listen for data coming over the port. I can successfully work with SerialDevice when data is streaming over the port but if nothing is read the DataReader.LoadAsync() function hangs even though I set timeouts through SerialDevice.ReadTimeout() and SerialDevice.WriteTimeout(). So to cancel the operation I am using IAsyncOperation's wait_for() operation which times out after a provided interval and I call IAsyncOperation's Cancel() and Close(). The problem is I can no longer make another call to DataReader.LoadAsync() without getting a take_ownership_from_abi exception. How can I properly cancel a DataReader.LoadAsync() call to allow subsequent calls to LoadAsync() on the same object?
To work around this, I tried setting the timeouts of SerialDevice but it didn't affect the DataRead.LoadAsync() calls. I also tried using create_task with a cancellation token which also didn't allow for an additional call to LoadAsync(). It took a lot of searching to find this article by Kenny Kerr:
https://kennykerr.ca/2019/06/10/cppwinrt-async-timeouts-made-easy/
where he describes the use of the IAsyncOperation's wait_for function.
Here is the initialization of the SerialDevice and DataReader:
DeviceInformation deviceInfo = devices.GetAt(0);
m_serialDevice = SerialDevice::FromIdAsync(deviceInfo.Id()).get();
m_serialDevice.BaudRate(nBaudRate);
m_serialDevice.DataBits(8);
m_serialDevice.StopBits(SerialStopBitCount::One);
m_serialDevice.Parity(SerialParity::None);
m_serialDevice.ReadTimeout(m_ts);
m_serialDevice.WriteTimeout(m_ts);
m_dataWriter = DataWriter(m_serialDevice.OutputStream());
m_dataReader = DataReader(m_serialDevice.InputStream());
Here is the LoadAsync call:
AsyncStatus iainfo;
auto async = m_dataReader.LoadAsync(STREAM_SIZE);
try {
auto iainfo = async.wait_for(m_ts);
}
catch (...) {};
if (iainfo != AsyncStatus::Completed)
{
async.Cancel();
async.Close();
return 0;
}
else
{
nBytesRead = async.get();
async.Close();
}
So in the case that the AsyncStatus is not Completed, the IAsyncOperation Cancel() and Close() are called which according to the documentation should cancel the Async call but now on subsequent LoadAsync calls I get a take_ownership_from_abi exception.
Anyone have a clue what I'm doing wrong? Why do the SerialDevice timeouts not work in the first place? Is there a better way to cancel the Async call that would allow for further calls without re-initializing DataReader? Generally, it feels like there is very little activity in the C++/winrt space and the documentation is severely lacking (didn't even find the wait_for method until about a day of trying other stuff and randomly searching for clues through different posts) - is there something I'm missing or is this really the case?
Thanks!
Cause: When the wait time is over, the async object is in the AsyncStatus::Started state. It means that the async object is still running.
Solution: When you use close() method, you could use Sleep(m_nTO) let asynchronous operation have enough time to close. Refer the following code.
if (iainfo != AsyncStatus::Completed)
{
m_nReadCount++;
//Sleep(m_nTO);
async.Cancel();
async.Close();
Sleep(m_nTO);
return 0;
}

Mockery false positive in Laravel controller test

I'm trying to learn how to use Mockery with Laravel 5. I've based my efforts mostly on Way's book (Laravel Testing Decoded) and other tutorials, which say integration [with PHPUnit] only requires the tearDown() method. So I've included that. The problem is that it doesn't seem to be resetting things between tests. My test class contents look essentially like this:
public function __construct()
{
$this->mock = Mockery::mock('Class\To\Mock');
}
public function tearDown()
{
Mockery::close();
}
public function test_RedirectWithoutAuthentication()
{
// Act
$this->call('GET', '/path/1');
// Assert
$this->assertRedirectedTo('/auth/login');
}
public function test_X()
{
// Arrange
$this->mock->shouldReceive('MockedClassMethod')->once();
// Act
$this->call('GET', '/path/1');
}
The first test works and the Auth middleware kicks the user to the login page. In the interest of TDD, I've written the second test before the MockedClassMethod is actually written. So to my way of thinking, it should fail spectacularly. But it doesn't. It passes!
If I change the order of the tests, it "works" (unwritten fails, auth passes) which leads me to believe that it's not really an order problem, but something to do with one test not getting cleaned up before the next.
Any insights will save my remaining hair from being pulled out. :-)
In accordion with the PHPUnit doc:
The setUp() and tearDown() template methods are run once for each test
method (and on fresh instances) of the test case class.
The constructor is called only the first time so the tearDown is called before the second test executed of the class and the effect is that the mockery instance was closed.
In order to solve your problem you can use the setup method for init the mocked object. So replace the class constructor of the test class with the setup method as follow:
Try to use this:
protected function setUp()
{
$this->mock = Mockery::mock('Class\To\Mock');
}
instead of:
public function __construct()
{
$this->mock = Mockery::mock('Class\To\Mock');
}
Hope this help
I had tried using the setUp() method as described by Matteo, and it caused the tests not to run at all. So I abandoned that course thinking I was way off. But Matteo's suggestion turned me back to it.
A little digging into why it caused the tests to fail showed that the $app object was never getting created. Hmm... So then it dawned on me that the setUp() method was overriding some important stuff. So to fix it, all that was needed was to call the parent method first! Like so:
public function setUp()
{
parent::setUp();
$this->mock = Mockery::mock('Class\To\Mock');
}
From that point, the setUp() and tearDown() worked as expected.
I'm still not sure why all the examples I seem to find show the mock being created in the constructor. Maybe I'm still not getting something, but at least it's working... for now. :-)

Solution for asynchronous notification upon future completion in GridGain needed

We are evaluating Grid Gain 6.5.5 at the moment as a potential solution for distribution of compute jobs over a grid.
The problem we are facing at the moment is a lack of a suitable asynchronous notification mechanism that will notify the sender asynchronously upon job completion (or future completion).
The prototype architecture is relatively simple and the core issue is presented in the pseudo code below (the full code cannot be published due to an NDA). *** Important - the code represents only the "problem", the possible solution in question is described in the text at the bottom together with the question.
//will be used as an entry point to the grid for each client that will submit jobs to the grid
public class GridClient{
//client node for submission that will be reused
private static Grid gNode = GridGain.start("config xml file goes here");
//provides the functionality of submitting multiple jobs to the grid for calculation
public int sendJobs2Grid(GridJob[] jobs){
Collection<GridCallable<GridJobOutput>> calls = new ArrayList<>();
for (final GridJob job : jobs) {
calls.add(new GridCallable<GridJobOutput>() {
#Override public GridJobOutput call() throws Exception {
GridJobOutput result = job.process();
return result;
}
});
}
GridFuture<Collection<GridJobOutput>> fut = this.gNode.compute().call(calls);
fut.listenAsync(new GridInClosure<GridFuture<Collection<GridJobOutput>>>(){
#Override public void apply(GridFuture<Collection<GridJobOutput>> jobsOutputCollection) {
Collection<GridJobOutput> jobsOutput;
try {
jobsOutput = jobsOutputCollection.get();
for(GridJobOutput currResult: jobsOutput){
//do something with the current job output BUT CANNOT call jobFinished(GridJobOutput out) method
//of sendJobs2Grid class here
}
} catch (GridException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
return calls.size();
}
//This function should be invoked asynchronously when the GridFuture is
//will invoke some processing/aggregation of the result for each submitted job
public void jobFinished(GridJobOutput out) {}
}
}
//represents a job type that is to be submitted to the grid
public class GridJob{
public GridJobOutput process(){}
}
Description:
The idea is that a GridClient instance will be used to in order to submit a list/array of jobs to the grid, notify the sender how many jobs were submitted and when the jobs are finished (asynchronously) is will perform some processing of the results. For the results processing part the "GridClient.jobFinished(GridJobOutput out)" method should be invoked.
Now getting to question at hand, we are aware of the GridInClosure interface that can be used with "GridFuture.listenAsync(GridInClosure> lsnr)"
in order to register a future listener.
The problem (if my understanding is correct) is that it is a good and pretty straightforward solution in case the result of the future is to be "processed" by code that is within the scope of the given GridInClosure. In our case we need to use the "GridClient.jobFinished(GridJobOutput out)" which is out of the scope.
Due to the fact that GridInClosure has a single argument R and it has to be of the same type as of GridFuture result it seems impossible to use this approach in a straightforward manner.
If I got it right till now then in order to use "GridFuture.listenAsync(..)" aproach the following has to be done:
GridClient will have to implement an interface granting access to the "jobFinished(..)" method let's name it GridJobFinishedListener.
GridJob will have to be "wrapped" in new class in order to have an additional property of GridJobFinishedListener type.
GridJobOutput will have to be "wrapped" in new class in order to have an addtional property of GridJobFinishedListener type.
When the GridJob will be done in addition to the "standard" result GridJobOutput will contain the corresponding GridJobFinishedListener reference.
Given the above modifications now GridInClosure can be used now and in the apply(GridJobOutput) method it will be possible to call the GridClient.jobFinished(GridJobOutput out) method through the GridJobFinishedListener interface.
So if till now I got it all right it seems a bit clumsy work around so I hope I have missed something and there is a much better way to handle this relatively simple case of asynchronous call back.
Looking forward to any helpful feedback, thanks a lot in advance.
Your code looks correct and I don't see any problems in calling jobFinished method from the future listener closure. You declared it as an anonymous class which always has a reference to the external class (GridClient in your case), therefore you have access to all variables and methods of GridClient instance.

Flex Event Dispatching

I have some questions with a particular structure of a program I'm writing.
I'm using a Remote Object to make a remote call to a Rails method (using WebOrb). The problem arises in the way that I get my data back.
Basically I have a function, getConditions, in which I add an event listener to my remote call and then I make the remote call. However, what I want to do is to get that data back in getConditions so I can return it. This is a problem because I only access the event result data in the event handler. Here's some basic code describing this issue:
public function getConditions():Array
{
remoteObject.getConditions.addEventListener("result", onConditionResult);
remoteObject.getConditions();
//Here is where I want to get my event.result data back
}
public function onConditionResult(event:ResultEvent):void
{
//Here's the data that I want
event.result;
}
How can I achieve this data turn-about?
Remote calls in flex are always asynchronous so you won't be able to call getConditions() and wait there for the result. You have to use a function closure to process the results, either by means of an event handler than you declare elsewhere or a dynamic one created immediately within getConditions(), like so:
remoteObject.getConditions.addEventListener("result", function(event:ResultEvent):void {
// Run the code that you would want to when process the result.
});
remoteObject.getConditions();
The advantage of doing the above is that you would be able to "see" parameters passed to getConditions() or the result of any logic that happened before addEventListener() in the function closure. This however, takes a slight performance hit compared to declaring an explicit function (for that exact reason).
I should also add that doing so requires you to clean up after yourselves to make sure that you are not creating a new listener for every request.
you do it like this
public function getConditions():Array
{
remoteObject.getConditions.addEventListener("result", onConditionResult);
remoteObject.getConditions();
}
public function callMyExtraFunction(data:Object):void
{
//Here is where you want to get your event.result data back
}
public function onConditionResult(event:ResultEvent):void
{
//Here's the data that you want
var data:Object = event.result;
callMyExtraFunction(data);
}
You could make use of Call Responder like so :
<s:CallResponder id="getOperationsResult"/>
then use these lines to get the result from get operations
getOperationResult.token = remoteObject.getOperation();
this creates the call and returns the result stores it in getOpresult
whnever u want to access this u can call that token or getOperationResult.lastResult
Hope that helps
Chris

Resources