Flex 4

Hello World in Flex 4

  1. Download and install the Flash Builder from Adobe.
  2. Under the Package Explorer, right-click and select New->Flex Project.
  3. Enter a Project name and click on the Finish button.
  4. An mxml file with the same name as your project name should also be created. Open that file and add <s:Label text="hello word"/>. It should look like the following:
    <?xml version="1.0" encoding="utf-8"?>
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
                 xmlns:s="library://ns.adobe.com/flex/spark" 
                 xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
        <fx:Declarations>
            <!-- Place non-visual elements (e.g., services, value objects) here -->
     
        </fx:Declarations>
        <s:Label text="Hello Word"/>
    </s:Application>
     
  5. On the top menu, click on Run->Run test. It will open a browser showing "Hello World".

Run Action Script code in Flash application

Below is an example showing how to run action script code in Flash application. By default, Flash player doesn't know which function to call. In order to let it know, you simply have to set your function name to the creationComplete attribute in the <s:Application> tag. In the example below, it is creationComplete="main()".

<?xml version="1.0" encoding="utf-8"?>
<!--
Description: Show how to run action script in Flash application.
-->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
         creationComplete="main()"
         >
  <fx:Script>
    <![CDATA[
      import mx.controls.Text;
 
      public function main():void
      {
        // Create the "Hello World!" text.
        var oText:Text = new Text();
        oText.text="Hello World!";
 
        // Add the Text element in the screen.
        this.addElement(oText);
      }
    ]]>
  </fx:Script>
</s:Application>

Variables

Example: Declare and using variable

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
 
  <fx:Script>
    <![CDATA[
      // Declare the variable i and set it to 0.
      private var i:int = 0;
 
      /**
       * I don't why the statement below show the 
       *   error "Access of undefined property.".
       */
      //i = 0;
    ]]> 
  </fx:Script>
 
  <s:Button id="myButton" label="Clicked me!" x="100" y="100" height="25" width="100">
    <s:click>
      <![CDATA[
        /**
         * Everytime the button is clicked, 
         *  the color will change(RED, BLUE, RED, BLUE,...).
         */
        if(i%2==0){
          myButton.setStyle("color", "red");
          myButton.label="Red_"+i;
        }
        else{
          myButton.setStyle("color", "blue");
          myButton.label="Blue_"+i;
        }
        i++; // Increment i on every click.
      ]]>
    </s:click>
  </s:Button>
 
</s:Application>

Variables

Data type Default value Usage
Booleanfalse var myVar:Boolean = true;
int0 var myVar:int = 16;
NumberNaN (Not a number) var myVar:Number = 19756465.1654;
Objectnull var myVar:someClass = new someClass();
Stringnull var myVar:String = "Value of my string";
uint0 var myVar:uint = 4294967295;
Not declared (equivalent to type annotation *)undefined  
All other classes, including user-defined classes.null var myVar:yourClass = new yourClass();
Arraynull
var myVar:Array = ["Joe", "Peter", "Denis", "Ken"];
for(var i:int=0; i<myVar.length; i++)
{
  trace(myVar[i]);
}
 

Primitive vs Complex data type

In ActionScript 3.0, primitive values and their wrapper objects are indistinguishable. This means that the following two lines of code are equivalent:

var someInt:int = 3;
var someInt:int = new int(3);

Wait for a certain time before doing something

<?xml version="1.0" encoding="utf-8"?>
<!-- Description: Use setTimeout() to wait for a certain time before doing something.
-->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
         creationComplete="main()"
         >
  <fx:Script>
    <![CDATA[
      import flash.utils.setTimeout;
      import mx.controls.Text;
 
      public function main():void
      {
        var iWaitTime:int = 15000; // Wait time  in milliseconds
 
        // Create the "Hello World!" text.
        var oText:Text = new Text();
        oText.text="The 'Hello World' will be displayed in "+iWaitTime/1000+" seconds.";
 
        // Add the Text element in the screen.
        this.addElement(oText);
 
        // Call doSomething() after waiting for 15 seconds.
        setTimeout(doSomething, iWaitTime);
 
      }
 
      public function doSomething():void
      {
        // Display the following text.
        var oText:Text = new Text();
        oText.text="After waiting for 15 seconds, I'm displaying this. Done!";
        oText.setStyle("color", "red");
        oText.y = 15;
 
        // Add the Text element in the screen.
        this.addElement(oText);               
      }
    ]]>
  </fx:Script>
</s:Application>

Adobe AIR application

Write string to file

<?xml version="1.0" encoding="utf-8"?>
<!--
Description: Show how to write string to a file.
Note: This example can only be run as Adobe AIR application.
-->
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
             xmlns:s="library://ns.adobe.com/flex/spark" 
             xmlns:mx="library://ns.adobe.com/flex/mx"
             creationComplete="main()"
             >
  <fx:Script>
    <![CDATA[
      import flash.filesystem.File;
      import flash.filesystem.FileStream;
      import flash.filesystem.FileMode;
 
      public function main():void
      {
        // Point a File object to a file path.
        var oFile:File = new File();
        var sFilePath:String = "c:/myfile.txt";
        oFile.nativePath = sFilePath;
 
        // Open the file.
        var oWrite:FileStream = new FileStream();
        oWrite.open(oFile, FileMode.WRITE);
 
        // Here  is the tricky part. In order to write
        //  a string to a file, you have to first convert the string
        //  into a ByteArray and then write the ByteArray into the file.
        var sText:String = "Write this message to a file."
        var oByteArray:ByteArray = new ByteArray();
        oByteArray.writeUTFBytes(sText);
        oWrite.writeBytes(oByteArray, 0, oByteArray.length);
 
        // Close the file.
        oWrite.close();
 
      }
    ]]>
  </fx:Script>
</s:WindowedApplication>

Reference: http://livedocs.adobe.com/flex/3/html/help.html?content=Filesystem_08.html http://livedocs.adobe.com/flex/3/html/help.html?content=Filesystem_03.html#1028332

Read text of the whole file

<?xml version="1.0" encoding="utf-8"?>
<!--
Description: Show how to read text of the whole file.
-->
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
             xmlns:s="library://ns.adobe.com/flex/spark" 
             xmlns:mx="library://ns.adobe.com/flex/mx"
             creationComplete="main()"
             >
  <fx:Script>
    <![CDATA[
      import flash.filesystem.File;
      import flash.filesystem.FileMode;
      import flash.filesystem.FileStream;
 
      import mx.controls.Text;
 
      public function main():void
      {
        // Point a File object to a file path.
        var oFile:File = new File();
        var sFilePath:String = "c:/myfile.txt";
        oFile.nativePath = sFilePath;
 
        // Open the file.
        var oRead:FileStream = new FileStream();
        oRead.open(oFile, FileMode.READ);
 
        // Read the whole file.
        var sText:String = oRead.readUTFBytes(oRead.bytesAvailable);
 
        // Display text read on the screen.
        var oText:Text = new Text();
        oText.text = sText;
        this.addElement(oText);
 
        // Close the file.
        oRead.close();
      }
    ]]>
  </fx:Script>
</s:WindowedApplication>

FlexUnit

FlexUnit is a unit test framework for Flex.

Mismatch version of the CIListener library causing "command not understood"

If you are running FlexUnit through Ant and getting the following error:

java.util.concurrent.ExecutionException: 
  command [<testcase classname='MyTestCase' name='MyMethod' time='0.000'  status='success'/>] not understood

This is due to the mismatch in version of the CIListener library. For my case, I was using Flex 4.1 to compile my codes and using FlexUnit 4.0 to run my compiled code. To remedy this, I went to flexunit.org to get the latest version of FlexUnit(flexunit-flex-4.1.0-RC1-77-sdk4.0.0.14159.zip).

java.util.concurrent.ExecutionException: command [<testcase classname='MyTestCase' name='MyMethod' time='0.000'  status='success'/>] not understood
        at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222)
        at java.util.concurrent.FutureTask.get(FutureTask.java:83)
        at org.flexunit.ant.tasks.TestRun.run(Unknown Source)
        at org.flexunit.ant.tasks.FlexUnitTask.execute(Unknown Source)
        at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
        at org.apache.tools.ant.Task.perform(Task.java:348)
        at org.apache.tools.ant.Target.execute(Target.java:390)
        at org.apache.tools.ant.Target.performTasks(Target.java:411)
        at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1397)
        at org.apache.tools.ant.Project.executeTarget(Project.java:1366)
        at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
        at org.apache.tools.ant.Project.executeTargets(Project.java:1249)
        at org.apache.tools.ant.Main.runBuild(Main.java:801)
        at org.apache.tools.ant.Main.startAnt(Main.java:218)
        at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
        at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)
Caused by: command [<testcase classname='MyTestCase' name='MyMethod' time='0.000'  status='success'/>] not understood
        at org.flexunit.ant.FlexUnitSocketThread.parseInboundMessages(Unknown Source)
        at org.flexunit.ant.FlexUnitSocketThread.call(Unknown Source)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
        at java.util.concurrent.FutureTask.run(FutureTask.java:138)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:619)

Run your first unit test with FlexUnit

The steps below show you step-by-step how to run your first unit test with FlexUnit. Don't worry if you don't understand the code. They will be explained in later tutorial.

  1. Create a Flex project using Adobe Flash Builder.
  2. Download FlexUnit from Adobe.
  3. Decompress FlexUnit into the lib folder of your project. Be careful, the zip file is compress twice. At the end, you should see lib/*.swc files. Make sure that you refresh your project after you added the files. Otherwise, Adobe Flash Builder will not see them.
  4. Suppose that you want to unit test the following ActionScript class:
    // Calculator.as
    package 
    {
      public class Calculator
      {
        // The constructor
        public function Calculator()
        {}
     
        // The implementation of the Add function.
        public function add(a:int, b:int): int
        {
          return a+b;
        }
      }
    }
     
  5. You create an ActionScript test class to test the add() function like the following:
     
    // CalculatorTestCase.as
    package
    {
      import org.flexunit.Assert;
     
      public class CalculatorTestCase
      {   
        [Test( description = "Test add()." )]
        public function AddSimpleTest():void 
        {
          var iA:int = 5;
          var iB:int = 6;
          var iExpected:int = 11;
     
          var oCalc:Calculator = new Calculator();
     
          Assert.assertEquals( iExpected, oCalc.add(iA, iB ) );
        }
     
        [Test( description = "This test is intended to fail." )]
        public function AddFailTest():void 
        {
          var iA:int = 5;
          var iB:int = 6;
          var iExpected:int = 12;
     
          var oCalc:Calculator = new Calculator();
     
          Assert.assertEquals( iExpected, oCalc.add(iA, iB ) );
        }   
      }
    }
     
  6. You have to add your test class to the Test Suite class like the following:
    // CalculatorTestSuite.as
    package
    {
      [Suite]
      [RunWith("org.flexunit.runners.Suite")]
      public class CalculatorTestSuite
      {
        // Make sure that your test cases object are declared as public. 
        //  Otherwise, FlexUnit will not be able to run it.
        public var oCalculatorTestCase:CalculatorTestCase = new CalculatorTestCase();
      }
    }  
     
  7. In your *.mxml file, to run your Test Suite, you have to add it as follow:
    <?xml version="1.0" encoding="utf-8"?>
    <!-- FlexUnitSample.mxml -->
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
             xmlns:s="library://ns.adobe.com/flex/spark" 
             xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
     
             xmlns:flexUnitUIRunner="http://www.adobe.com/2009/flexUnitUIRunner"
             creationComplete="runMe()"><!-- Add this namespace. -->
     
      <fx:Script>
        <![CDATA[
          import org.flexunit.listeners.UIListener;
          import org.flexunit.runner.FlexUnitCore;
     
          private var core:FlexUnitCore;
     
          public function runMe():void
          {
            core = new FlexUnitCore();
            core.addListener(new UIListener(uiListener));
            core.run(CalculatorTestSuite); // Add all your Test Suite classes here.
          }
        ]]>
      </fx:Script>
     
      <flexUnitUIRunner:TestRunnerBase id="uiListener" width="100%" height="100%" />
     
    </s:Application>
     
  8. Run your MXML application. You should see the FlexUnit Runner graphical interface. 2 tests are run: 1 success, 1 failed.
AttachmentSize
Package icon FlexUnitSample.zip1.55 KB

Parameterized test in Flex

  1. Import package import org.flexunit.runners.Parameterized;.
  2. Add the meta data [RunWith("org.flexunit.runners.Parameterized")] at the top of the parameterized test class.
  3. Declare a static data set(i.e. myTestData).
  4. Add the meta data [Test(dataProvider="myTestData")] at the top of the test function. Make sure that the order of the function parameters(i.e. iA:int, iB:int, iExpected:int) match the order your data set.

package org.tutorial.calculator.unittest
{
  import org.flexunit.runners.Parameterized;
  import org.flexunit.asserts.assertEquals;
 
  [RunWith("org.flexunit.runners.Parameterized")]
  public class FlexParameterizedTest
  {
    public static var myTestData:Array = [
                                          // iA, iB, iExpected
                                          [2, 4, 6],
                                          [-2,4, 2],
                                          [5, 6, 14], // Will fail.
                                          [0, 1, 1],
                                         ];
 
    [Test(dataProvider="myTestData")]
    public function getSumTest(iA:int, iB:int, iExpected:int): void
    {
      assertEquals("getSum() doesn't give expected result.", iExpected, this.getSum(iA, iB));
    }
 
    /**
     * Function to be tested. It adds 2 integers.
     * Note: For convenient and completeness, I put this function 
     *  in this same test class. In practice, you shouldn't. 
     */
    public function getSum(iA:int, iB:int): int
    {
      return iA+iB;
    }
  }
}