Screencast: Using Webby to create a static website.
Screencast: Using Webby to create a static website from daniel wanja. Enjoy! Daniel.
Determine Test Coverage on your Flex Projects with Flexcover.
This week I was playing with Flexcover a test coverage tool for Flex…and it’s really cool. If you you to determine how much test coverage you have in your Flex application then check out this screencast…maybe skip to the end where you will see flexcover in action. The first part is how to assemble the Flexcover SDK to use with FlexBuilder. Again this is a non-scripted screencast with several “oops” and a big Swiss-French accent which I hope you will find useful.
The key here is if you do Flex, write unit tests and use this test coverage tool.
Setting up Flexcover as test coverage tool for your Flex applications. from daniel wanja on Vimeo.
Enjoy,
Daniel.
Flex test coverage?
It’s hard to imaging writing a Rails application without using rcov and get that fuzzy feeling you tested most if not all you application. Or at least get a good idea of what’s tested. I heard way back that Alex Uhlmann was working on some test coverage tools, but I didn’t see anything coming out from Adobe. I haven’t used test coverage for my Flex apps, but want to start. Any body has any good hints, stories, frameworks they use for test unit coverage in Flex? A quick google search pointed me to this article describing Flexcover, just what I was looking for. Please share your experience.
Thanks!
Daniel.
UPDATE: I am playing with FlexCover and just saw this “Flexcover is a joint effort with Alex Uhlmann of Adobe Consulting, who has been working on a related set of ideas.”. So I guess this is really Alex’s work that Steven was referring to which is now open source under the MIT license. Cool!
Flash Player 10 Mobile for iPhone?

BlazeDS and open source version of livecycle data services...
That sounds cool. Read all about it here…
Maybe not. Techcrunch released this message on their blog but no text was attached and comments where closed. Maybe somebody clicked the submit button to quickly. Now I am curious…
UPDATE: 10:17pm Denver time…it’s official: http://www.adobe.com/aboutadobe/pressroom/pressreleases/200712/121307BlazeDS.html
Analyzing the Subversion logs from the Rails project with mx:OLAPCube
I started playing with Anthony Eden’s ActiveWarehouse and followed his excellent tutorial on how to analyze the Ruby On Rails Svn Commit Log with the ActiveWarehouse framework. Of course this made me want to try to do the same with the new mx:OLAPCube and mx:OLAPDataGrid provided by Flex 3 as part of the DataVisualization components. Let me just say this…I am not done playing with either the Flex OLAPCube nor the Rails ActiveWarehouse framework as these are pretty complex beasts. Both of these frameworks are overlapping and complementary. There are overlapping as both can digest raw data and perform aggregation of that data. They are complementary in the sense that a server side warehouse needs a good visualization front-end. Maybe the OLAPCube and OLAPDataGrid can be this front-end. In my initial trials I haven’t come up with a compelling way to integrate both, but by using some simple SQL I could extract the data from the ActiveWarehouse and pass it to the OLAPCube.
Before going on you may want to read Anthony’s blog and check his presentation on Data Warehouses with ActiveWarehouse. I didn’t find much information on the Flex OLAPCube besides these: Feature_Introductions:OLAPDataGrid on Adobe’s labs, Flex 3: Feature Introduction Video for OLAP Support, and these beta2.zip">Flex examples.
So I create the following sample application. You can try it out here. Note it’s pretty slow, it takes up to a minute to aggregate 10000 values. The Flex team mentioned they didn’t optimize this component yet. I can confirm this. But I may also have messed something up as these are only my initial steps with that component. The application displays the Author dimension with the Author Name as rows and the Time dimension with the Year and Quarter as columns. The facts is the File Change count during that period. Flex calls the “facts” a measure.

Run the applicaiton
To extract the data from the ActiveWarehouse I created this SQL to join the facts table with all the dimensions table. I need to find out if the ActiveWarehouse doesn’t just return this data in xml format by using it’s build-in classes.
def report_as_xml
sql = <<-EOSQL
SELECT
date.calendar_year,
date.calendar_quarter,
date.calendar_month_name,
author.name,
file_revision_facts.file_changed AS `file_changed`
FROM
file_revision_facts
JOIN date_dimension as date
ON file_revision_facts.date_id = date.id
JOIN author_dimension as author
ON file_revision_facts.author_id = author.id
WHERE
date.calendar_year > '2005'
EOSQL
@@xml ||= ActiveRecord::Base.connection.select_all(sql).to_xml(:dasherize => false)
render :text => @@xml
endIn Flex the OLAPCube can be loaded with the XML
var data:ICollectionView = new ArrayCollection(result.records.record); // is Array cube.dataProvider = data; cube.addEventListener(CubeEvent.CUBE_COMPLETE, creationCompleteHandler); cube.refresh();
Once the cube is loaded you can slice and dice it in many ways by using an OLAPQuery. I still need to figure out all the possibilities which are offered.
[Bindable]
private var cubeResult:IOLAPResult;
private function creationCompleteHandler(event:CubeEvent):void
{
//Cube was created, let's query it
var query:OLAPQuery = new OLAPQuery;
// TIME DIMENSION
var yearSet:IOLAPSet = new OLAPSet;
yearSet.addElements(cube.findDimension("Time").findAttribute("Year").members);
var quarterSet:IOLAPSet = new OLAPSet;
quarterSet.addElements(cube.findDimension("Time").findAttribute("Quarter").members);
//year-quarter
var newTimeSet:IOLAPSet = yearSet.crossJoin(quarterSet);
// AUTHOR DIMENSION
var authorSet:IOLAPSet = new OLAPSet;
authorSet.addElements(cube.findDimension("Author").findAttribute("Name").members);
// ROW/COLUMNS
var rowAxis:IOLAPQueryAxis = query.getAxis(OLAPQuery.ROW_AXIS);
rowAxis.addSet(authorSet.hierarchize(true));
var colAxis:IOLAPQueryAxis = query.getAxis(OLAPQuery.COLUMN_AXIS);
colAxis.addSet(newTimeSet.hierarchize(true));
// QUERY CUBE
var token:AsyncToken = cube.execute(query);
token.addResponder(new AsyncResponder(displayResult, olapFaultHandler));
}
private function displayResult(result:Object, token:Object=null):void
{
cubeResult = result as IOLAPResult;
}The cube result is the dataProvider of the Cube which in it’s simplests form can be defined as follows:
<mx:OLAPDataGrid id="olapGrid" dataProvider="{cubeResult}" />I’ve then added a change listener for the grid to create the dataProvider for the ColumnChart.
[Bindable]
private var chartData:Array;
private function gridSelectionChanged():void {
if (!(olapGrid.selectedItem is OLAPAxisPosition)) return;
var rowIndex:Number = olapGrid.selectedIndex;
var axis:IOLAPQueryAxis = cubeResult.query.getAxis(OLAPQuery.COLUMN_AXIS);
var columnLength:Number = cubeResult.getAxis(OLAPQuery.COLUMN_AXIS).positions.length;
var newChartData:Array = [];
for (var i:int=0;i<columnLength;i++) {
var tuple:OLAPTuple = axis.tuples[i];
var key:String = tuple.explicitMembers.toArray().join(",");
if (key.indexOf("(All)") > -1) continue; newChartData.push({key:key, value:cubeResult.getCell(rowIndex, i).value});
}
chartData = newChartData;
}This code to extract a time serie for the chart is a little “hairy”. I hope the Flex team has some OLAPCharts on their todo list ;-)
<mx:ColumnChart id="chart" width="100%" height="30%" dataProvider="{chartData}">
<mx:series>
<mx:ColumnSeries yField="value" />
</mx:series>
<mx:horizontalAxis>
<mx:CategoryAxis categoryField="key" />
</mx:horizontalAxis>
</mx:ColumnChart>This are my first tribulations with both frameworks. Over the next few month I will have to dive more deeply into the possibilities which are offered. Thanks to both teams as this is pretty cool.
Enjoy!
Daniel.
flash.utils.ByteArray compressing 4.1MB to 20K
I am currently preparing a demo using an mx:OLAPCube and OLAPDataGrid which analyze the Rails svn commit log. however I don’t want to deploy a specific server side application as the Cube can load data from XML. So I have an report.xml that is 4.1MB. I created the following AIR application (ZlibCompressor.mxml) that use the standard compression provided by the ByteArray class to compress this file down to 20Kb. The application that consumes this file (UnzipTest.mxml) uses the URLLoader to read this file straight into a ByteArray and uncompress the data. It’s fast!
The key code for compression is the ‘compress’ and ‘uncompress’ method provided by the ByteArray. Note the URLLoader dataFormat is set to “binary”.
ZlibCompressor.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
nativeDragDrop="onDrop(event)"
nativeDragEnter="onDragIn(event)" >
<mx:Script>
<![CDATA[
import flash.desktop.ClipboardFormats;
import flash.utils.CompressionAlgorithm;
public function onDragIn(event:NativeDragEvent):void {
var transferable:Clipboard = event.clipboard;
if (transferable.hasFormat(ClipboardFormats.FILE_LIST_FORMAT)) {
DragManager.acceptDragDrop(this);
}
}
public function onDrop(event:NativeDragEvent):void {
var fileList:Array = event.clipboard.dataForFormat(ClipboardFormats.FILE_LIST_FORMAT) as Array;
if (fileList.length==0) return;
var inFile:File = fileList[0];
var fileStream:FileStream = new FileStream();
fileStream.open(inFile, FileMode.READ);
var ba:ByteArray = new ByteArray();
fileStream.readBytes(ba, 0, fileStream.bytesAvailable);
fileStream.close();
var newFileName:String = inFile.nativePath+".zlib";
ba.compress();
var outFile:File = new File(newFileName);
fileStream = new FileStream();
fileStream.open(outFile, FileMode.WRITE);
fileStream.writeBytes(ba, 0, ba.length);
fileStream.close();
}
]]>
</mx:Script>
</mx:WindowedApplication>UnzipTest.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" creationComplete="loadData()">
<mx:Script>
<![CDATA[
import mx.rpc.events.ResultEvent;
import flash.utils.ByteArray;
import flash.events.*;
import flash.net.*;
private function loadData():void {
var loader:URLLoader = new URLLoader();
loader.dataFormat = "binary";
loader.addEventListener(Event.COMPLETE, completeHandler);
var request:URLRequest = new URLRequest("../data/report.xml.zlib");
loader.load(request);
}
private function completeHandler(event:Event):void {
var loader:URLLoader = URLLoader(event.target);
var ba:ByteArray = loader.data;
ba.uncompress();
var s:String = ba.toString();
var xml:XML = new XML(s);
}
]]>
</mx:Script>
</mx:Application>Acts_as_nested_set ActiveRecord rendered with mx:Tree in Flex.
ActiveRecord: app/models/category.rb
app/models/category.rbclass Category < ActiveRecord::Base acts_as_nested_set end
Controller: app/controllers/categories_controller.rb
app/controllers/categories_controller.rbclass CategoriesController < ApplicationController def index Category.result_to_attributes_xml(Category.root.full_set) end end
Flex Application: ActsAsNestedSet.mxml
ActsAsNestedSet.mxml<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" applicationComplete="categories.send()"> <mx:HTTPService id="categories" url="http://localhost:3000/categories" resultFormat="e4x" /> <mx:Tree dataProvider="{categories.lastResult}" labelField="@name" width="100%" height="100%" /> </mx:Application>
Result:

XML generated by Category.result_to_attributes_xml(Category.root.full_set):
XML generated by Category.result_to_attributes_xml(Category.root.full_set)<node name="Main Category" id="15" description=""> <node name="Cameras & Photo" id="16" description=""> <node name="Bags" id="17" description=""/> <node name="Accessories" id="18" description=""/> <node name="Analog Cameras" id="19" description=""/> <node name="Digital Cameras" id="20" description=""/> </node> <node name="Cell Phones" id="21" description=""> <node name="Accessories" id="22" description=""/> <node name="Phones" id="23" description=""/> <node name="Prepaid Cards" id="24" description=""/> </node> <node name="Dvds" id="25" description=""> <node name="Blueray" id="26" description=""/> <node name="HD DVD" id="27" description=""/> <node name="DVD" id="28" description=""/> </node> </node>
I used the http://wiki.rubyonrails.org/rails/pages/BetterNestedSet plugin.
Too cool!
UPDATE: The BetterNestedSet plugin doesn’t work out of the box with Rails 2.0 RC1. Thanks Joel for that info. Read more in the comment of this blog entry.
UPDATE2: Thanks Fabien, BetterNestedSet now works with Rails 2.0!
RailsLogVisualizer0.7 for AIR beta 2.
Install RailsLogVisualizer0.7.air
Install Manually
1) Instal Adobe AIR beta 2. (See release notes if previous version was installed)Download AIR for OSX Download AIR for Windows
Learn more on AIR
2) Download and install http://myspyder.net/tools/railslogvisualizer/RailsLogVisualizer0.7.air For time.onrails.org the log file is currently 98Mb and is loaded and process in less than a minute. Here are the loading details:
Loaded 98571986bytes in 28093 milliseconds. Parsing file. Please Wait this may take some time.... Parsing. Split 1639453entries in 1447 milliseconds. found:220767 in 1925 milliseconds. Aggregating data. aggregated:220767 in 13426 milliseconds. Aggregated:89135 aggregated String :4440464(bytes) in 2790 milliseconds.Then you can navigation through time and see how many request where processed and drill down in specific action and specific methods. For example, here we can quickly see that for October 99 people signed up, 869 did login, 22 forgot their password.

Sweet way to write Flex Unit tests for Rails
Using ActiveResources from Flex? Using FlexUnit? Here is a nice way to write your tests.
Example Test Casepackage tests { import flexunit.framework.*; import mx.rpc.AsyncToken; import mx.rpc.events.ResultEvent; import resources.Rafflespackage tests
public class TestRaffles extends BaseTestCase { private var raffles:Raffles; public function TestRaffles(name : String = null) { super(name); fixtures(["raffles"]); raffles = new Raffles(); } public function testRemoteFindRaffle():void { assertRemote(raffles.show(1)); } public function assertRemote_testRemoteFindRaffle(data:Object):void { Assert.assertTrue("Raffle show successfully called", data is ResultEvent); assertEquals("MyString", data.result.name); } }
{
import flexunit.framework.*;
import mx.rpc.AsyncToken;
import mx.rpc.events.ResultEvent;
import resources.Raffles;}
Note this code is not yet a plugin and is using code you can find here: http://code.google.com/p/flexonrails/source. I was starting to use it on multiple projects so I thought it was to time find a home for it. Also it is using the org.onrails.rails.ActiveResourceClient Flex class. I would recommend that you use Alex MacCaw’s ActvieResrouce for Actionscript. I still need to talk with Alex and integrate this fixture loading code with his code.
The BaseTestCase Flex class is an extended TestCase that provides support for fixtures. Now in your constructor you can define which fixtures you want to reload between each test. Only tests methods starting with “testRemote” will trigger refreshing the fixtures. As you know, when using AMF or HttpService remote invocations are asynchronous and you cannot test the result of a remote call in the same method than where the call is made from. That’s why I added the assertRemote method which takes an AsyncToken as parameters. This will automatically invoke a method whos name starts with assertRemote_ followed by the test method name. This simplifies greatly writing asynchronous tests. FlexUnit provides the addAsync method, we just add the convenience assertRemote function to setup all the callbacks.
To make this work for you Flex with Rails project. You need to fixtures_controller.rb to your controllers and setup the following routes:
if RAILS_ENV == "test"
map.resources :fixtures, :new => { :test_results => :post }
map.crossdomain '/crossdomain.xml', :controller => 'fixtures', :action => 'crossdomain'
endYou need to extend your Flex TestCase from tests.BaseTestCase.
Enjoy,
Daniel.