Saturday, 16 July 2011

Preventing browser from closing your Flex Application

At work recently a bug came my way saying that if a user closed the browser mid way through a certain process it would corrupt the database and not allow the user to re-open that task.

Now obviously there are a few issues here:

  • closing the browser did nothing to the database, it just meant that the flex application was not given the opportunity to clean up and the data on the server was left in a state that could not be re-loaded
  • whatever calls a client makes to the server the database should never get corrupted and should always be in a re-loadable state!

Easy then, just pass the bug to the java team!

There has been a long standing nice to have task though that we prompt a user when they try to close the browser when they have unsaved data. This bug made it seem like a good idea to look into this.

I knew the basics behind this (use JavaScript to call a flex function) but have never actually done it. I also knew that there was a way of having the flex app inject the JavaScript into the HTML page. I did a bit of googleing and found these 2 bog posts:

And from what I learnt I came up with this:

The way this works is that when you try to close the browser the onbeforeunload event is fired. This calls the JavaScript function confirmClose which in turn calls the ActionScript function getCloseConfirmMessage. We allow JavaScript to call this function by calling

ExternalInterface.addCallback( "getCloseConfirmMessage", closeConfirmMessage )

within our flex app. This flex function either returns a message to display in the browser dialogue box (the reason why you can’t close the browser for example) or null if you are allowed to close the browser – in which case the browser just closes with no confirm box.

I really like the fact that all this code is inside the swf. I don’t have to make sure that I am deploying the correct html file along side my swf. Any html file will work.

The app I link to above is just an example of how to get it to work. In the real application I have put all of this in a parsley managed class. Parsley is used to dispatch a cancellable event. Any area of the app that has unsaved data for example can cancel the event and provide a message. This message is then returned to JavaScript to be displayed.

I have also added a function call that gets fired when the browser is actually closed. Again this fires a Parsley message and anything that is interested can use this to tidy up – for example close streams that the app is subscribed to.

Thanks to the 2 guys who wrote the 2 blog posts above.

Saturday, 2 July 2011

Spark DataGrid slow?

I am currently in the process of writing a little Air app for myself. I doubt it will be any use to anyone else but I am enjoying writing it and it will be useful for me.

The app collects data (ok, my weight!) and displays it in a graph over time. I can also add targets and plots the target weight against actual – you get the idea.

The app uses charts and a DataGrid for this.

I want to also build the app for mobile so that I use it on my phone and this gives me a bit of a problem. Adobe recommend not to use the spark DataGrid in mobile apps and does the same for the charts.

In the desktop app that I am working on at the moment the line chart is super fast but I have been very disappointed in the performance of the DataGrid. At the moment I have ONE row in the DataGrid with 5 columns.

It takes 300 ms to create this!

What’s even worse is that after it’s created it still takes 150 ms to show the grid again after the view is hidden.

How can the performance be SO bad? Any suggestions about what else I can use? Has anyone else found this?

This is on Flex 4.5.0 build 20967 running in debug mode.

Sunday, 30 January 2011

A Guide to Test Driven Development in Flex – Part 3: Implementing the Class

At the end of part 2 we had completed all of our unit tests and most of them were failing:

We can now go ahead and complete the class implementation and make sure all these tests pass. Lets concentrate on the first test we wrote that is failing – popupOpensOnStartSymbol.
This test asserts that when the user types the startSymbol the PM opens the popup. At the moment this test is failing:

To fix this we add the minimum amount of code to the SUT to make this test pass:

We now run the test again and find that it is still failing:

So we add a bit more code to the SUT:

And now when we run the test it passes:

However one of the tests that was previously passing is now failing – popupRemainsClosedNonStartSymbol:

We are now getting the binding event firing even we don’t type the startSymbol. This is easily fixed:

And we can see that popupOpensOnStartSymbol still passes and now popupRemainsClosedNonStartSymbol passes as well.

It is important to fix the tests in this way. It would certainly be possible to just implement that one method in one go and have both tests pass straight away. Had we done that however we would not know if we had written our tests correctly. Having gone through this process we have now verified that if the SUT does not dispatch a binding event the test fails. We have have also verified that if the model dispatches a binding event when it is not supposed to the popupRemainsClosedNonStartSymbol test fails. Implementing the class in this way tests our tests.

Using this process I will implement the rest of the functionality for the model. When complete you end up with this.

That’s the end of my guide to Test Driven Development. It’s not as strict nor has quite as many steps as some of the other methods I have seen but it works for me. I believe that developing in this way produces much better code that is easily maintainable any much less fragile and can be quicker.

If you have any feedback please let me know in the comments.

A Guide to Test Driven Development in Flex – Part 2: Writing The Unit Tests

In part 1 of this series we defined the public properties on the class we’re testing (referred to as the System Under Test or SUT) and wrote some empty unit tests. You can see the code here.
When we run these empty unit tests un-surprisingly they all fail:

And they all give the same failure trace:

It is now time to start implementing these test methods but before we do that we need to do a bit of setup. For example rather than creating a new model to test in each test we can just have a private variable that will always be available for all the tests:


(I use an underscore to signify a private variable)

Now that we have an instance of the model to test we can start defining what each test will check for. The first test – testAutoCompletePM simply tests that the model is in the state that we expect after construction. All we need to do for this test is assert that the showAutoCompletePopup property is false:

The string in quotes is just the message that will displayed in the error. It lets us know what property we are expecting to be false.

The next test popupOpensOnStartSymbol is a bit more involved. We want to check that when the user types the start symbol that the showAutoCompletePopup is set to true and that the binding fires. We’ll probably want to use the same starting symbol in all these tests. So that we don’t have to set it each time we can do this in a setup function:

The static constant means that we are not using magic strings in our tests. We can use the same static when we test the functionality of the class as we do here in the second test – popupOpensOnStartSymbol:

This test is nearly complete but we need to test that the binding event is dispatched as well. As this is a read only property we will use a named bindable and dispatch a custom event type. Event types should always be constants so that we don’t use magic strings. We can define this constant in the SUT but as it is just for binding we don’t want to make it public. Nothing will ever add an event listener for this type. If it is private though the test will not be able to assert that the event is dispatched.
Because of this I use the internal namespace for these binding event constants. This means that most classes can’t see it but that tests that are in the same package will be able to see it:

We can then update our test to make sure that this event is dispatched when the popup is supposed to open:

In the next test – popupRemainsClosedNonStartSymbol we need to make sure that showAutoCompletePopup remains false and that the binding event is not dispatched:

We follow a similar process for the other tests as well. I also added a couple of extra tests for testing selecting an item to test for different labelField values.I also had to create a CloseAutoCompletePopupEvent that we expect to fired when we finish editing. Once finished you’ll end up with something like this.

When we run these tests we get the following:

We can see that most of the tests fail. Only 2 pass, the test verifying the initial start-up state of the class and the test that verifies that nothing happens when we type anything other than the startSymbol.

In the next part we’ll be implementing the class to make these tests pass.

Saturday, 29 January 2011

A Guide to Test Driven Development in Flex – Part 1: Defining What The SUT Does

In the Introduction to this series of tutorial blog posts I described why I use unit testing and why I think that TDD is an especially good way to write both unit tests and the actual classes you’re testing – which I refer to as the SUT or System Under Test.

Before we write any code for either the SUT or the unit tests we need to think about what the class needs to do. For this we need some requirements for the application or component that we are building.

I have decided to write a reusable component that will popup when writing in a text field and allow you to select an entry to insert into your text. An example of where this would be used is in a twitter client. You would provide the component with a list of user names and tell it that the initial symbol is an @ symbol. You would then bind the component to a given text field. When typing in the text field if I typed @ my component would popup and display your list of usernames. As you type the list would filter and when you select an item from the list the username would be added to the text that you were typing.

So now we have a basic and not very well written requirement we can start to define what the component will do and what we need to test. I will be writing the component following the Presentation Model pattern so all of the logic for the view component will reside in the presentation model so that it’s easily testable.

First off we probably need to think of a name for the component. I thank that AutoCompletePopup is a pretty good name that goes some way towards describing what the class does. AutoCompletePopup will probably extend PopupAnchor and will have inside it an AutoCompleteComboBox which will extend ComboBox.
This compositional approach will enable us to re-use the components in other ways in the future more easily. Amongst these view components we’ll also need our presentation model which we’ll call AutoCompletePM. Our test will be called AutoCompletePMTest.

We can create these two classes now. Usually they will both be in the same package but I usually have them in different source folders. Alongside the default src folder I create a test folder:

 

So far we just have 2 empty classes:

We now need to start defining what functions the SUT will perform and then create at least one test for each of these functions.

The SUT will perform the following actions:

  • open the popup when auto-completion is required
  • filter the list of available items based on text input
  • when an item is selected dispatch an event to insert that text into the text field
  • if the Escape button is pressed close the popup without inserting any text

As we can see this is going to be a fairly simple class. From this list we can start to define our tests. Each test should ideally test 1 function call or property update on the class and test that we get the response that we expect. We may well test the same function call multiple times for different situations and each of these calls should be made in a different test.

Lets start with the first function:

  • open the popup when autocompletion is required

This is still a slightly unclear requirement. What it means is that when the user types the startSymbol (for example an @) we want to open the popup.
Let’s add an empty test that will test this situation:

This isn’t quite enough though. We also need to test that if we type anything other than the startSymbol the popup won’t open:

At the moment we’ve assumed that the popup will start off closed but we should make sure by testing the initial state of the PM after construction:

We’ve now got some initial empty tests but we still don’t have anything defined on the SUT. For the SUT to open a popup when a user types a certain symbol the SUT is going to need some properties and functions so that other classes can communicate with it.

To open the popup we can have a bindable Boolean showAutoCompletePopup  property. The class also needs to know what the startSymbol is so we can define that as another property. It needs to know what is being typed in the text field so we can create a textEntryHandler method and it needs to know what is being typed in the popup so we can create another property called filterText:

We then follow these steps for the other requirements as well. When you finish you’ll end up with something like the code here.

By following this process we have now defined a small clean public interface for our class. We have our public properties and methods defined. A developer looking at these properties and methods should find it fairly easy to work out what the class does and how to use it.

The only thing that we have not defined yet is the events that the class will dispatch. You could do this now if you like but I usually do this later.

In the next part we complete the unit tests.

A Guide to Test Driven Development (TDD) in Flex – Introduction

TDD (Test Driven Development) is a method of writing code that starts with creating tests then goes on to writing the classes afterwards.
I am a big fan and use it whenever I can. It is not appropriate for all types of development but if you organise your code using the model view controller pattern or by using presentation models you can make good use of this technique.

Unit testing in general is a very good habit to get into. Not only does it test the code that you have written but it also demonstrates to other developers what the class is supposed to do and how it supposed to be used. If you combine unit tests with a good Continuous Integration set up then you ensure that other developers don’t accidentally break your code.
Unit tests also help when bug fixing. When I get a bug to fix hopefully the code will have unit tests. If it does I add a test that demonstrates the bug and fails. I then modify the class and make sure that my new test and all the existing tests pass.

TDD goes beyond this and encourages us to write better code. By following the steps that I outline it forces you to think about what the class will do before you start to write it. If the class is doing too much or is too complicated then split it up into more than one class and delegate some of the responsibility to other classes.

TDD forces you to think about the public interface that the class presents to other classes. This helps you think about encapsulation. Classes should NOT make things public just so that you can test them.

All of this leads to writing smaller simpler classes with simple public interfaces that are easier to test. If you write the tests first then you are going to write easily testable code. You should also end up with just enough code. When implementing your class you will write just enough code to make the tests pass and no more.

A common reason for not using unit tests or TDD is that the developer doesn’t have time. I disagree with this. Most of the projects I work on are large and compiling the application and running it takes a long time. Doing this every time you want to test every small code change is slow. I find it much quicker to make sure the logic is correct before I have to run the whole application. Compiling and running a test runner is MUCH quicker than running the whole app.
Unit testing also allows you test edge cases or race conditions that would be hard to re-create in a running application.
On top of these savings tests save a lot of time in the long run. They reduced the number of bugs and encourage you to write code that makes maintenance easier and quicker as well.

During this series of tutorials I will use TDD to help me create a fairly simple component. I will step through how I write code using TDD. This doesn’t necessarily follow all the steps that you are supposed to follow if you are strictly following TDD but it works for me.

During these tutorials I will be referring to the SUT – the System Under Test. This is basically the class that you are testing.

The tutorials will be broken up into the following sections:

To get started we need to define what our SUT will do.

Monday, 17 January 2011

Google AuthSub for Actionscript

I was very pleased to find this webpage from Google:

Using AuthSub in Actionscript

For a long time I have though about the apps you could build in flex if you could access Google Docs. This would make it really easy to write flex apps without having to worry about a server side component. You just store everything in Google Docs.

Previously you have been unable to access docs for a number of reasons. The first one was that you could not authenticate from a flex app as there was no crossdomain.xml on the authentication server.
At the moment there is still no crossdomain.xml on the docs server but if we can authenticate we can access the picasa APIs which would work well with my picasa API work.

I followed the instructions above and created an app based on the code samples. I was able to get to the Google log in page and got the first single use token. However trying to get a long lived token never worked. Each time I tried I got a 403 error.

I have posted for help about this on StackOverflow.com and on Google’s API help forum but have so far had no responses.

Has anyone else had issues with this or has anyone else got this working? If you have any tips please let me know in the comments.