Skip to content
Zwetan Kjukov edited this page Jun 21, 2017 · 1 revision

Contributor Jobs

Common requirements

  • knowing the basic of git and/or svn
    checkout, commits, pull requests, etc.
  • installing/using the Redtamarin SDK
    and associated tools: asc, redbean, etc.
  • installing the Flex SDK
    and using associated tools: mxmlc, compc, asdoc
  • be able to write asdoc or markdown
    or ActionScript 3.0 code

Testing

Redtamarin store integration tests in /src/as3examples/
every test is under its respective package, for example,
if you want to test shell.hasColor() function

  1. in the /src/as3examples/shell/ directory
  2. create a simple actionscript file: hasColor.as
  3. edit the test runner build/run_tests
    add the following line
    "shell/hasColor.as" "" "" ""

the test file /src/as3examples/shell/hasColor.as contains

/**
 * @exampleText Detect if the shell support ANSI colors.
 */
import shell.*;

// use this to force colour output under Cygwin MinTTY
//Program.cygwinCompatibility = true;

var message:String = "hello world";

if( hasColor() )
{
    // display the text in red
    trace( "\x1b[31m" + message + "\x1b[0m" );
}
else
{
    // do not colorize the text
    trace( message );
}

From that point 2 important tasks:

  1. run the tests under one or different platforms
    $ build/run_tests
    and inspect the output
----------------------------------------------------------------
example 0: shell/hasColor.as options:  args: 
----------------------------------------------------------------

hasColor.abc, 242 bytes written
----------------------------------------------------------------
hello world
----------------------------------------------------------------

If under a particular platform the output differs from what is expected, simply report it as a bug.

  1. Update the asdoc for the Redtamarin API
    once a test is verified
    • write/improve the @exampleText asdoc part in the test
    • add the test in the Redtamarin API
      eg. @includeExample hasColor.as

Those integration tests are quite important, they allow to verify that everything is working as it is supposed to, but they are also used as usage examples to get developers started with the Redtamarin API.

Those tests cover the whole breadth of the Redtamarin API: the C API, the AVMGlue API, the Redtamarin Native Library.

The task consist to write snippet of tests where they are missing, or improve tests, or write more complicated tests, or write more useful tests (eg. real life usage).

Just writing a simple test and reporting that something is not working as expected is a huge help to improve the stability and quality of the Redtamarin API.

Documenting

Redtamarin use asdoc to document all the APIs: the C API, the Redtamarin Native Library and the AVMGlue API.

To edit the sources you will work with files in /src/as3/
you will also need to edit /build/targets/documentation.xml
and /build/doc/package.description.xml.

To generate the asdoc HTML you can simply run
$ build/documentation_only

To view the results open
/bin-release/documentation/index.html

You can also consult those wiki pages:

Depending on which part of the API you are documenting (or editing or improving, etc.) you can refer to specific other documentations:

  • for the C API, use The Open Group Base Specifications Issue 7
    on the bottom-left click "headers"
    • if, for example, you are documenting C.stdio
      then click "<stdio.h>".
    • for a specific function you can directly go to:
      http://pubs.opengroup.org/onlinepubs/9699919799/functions/FUNCTION_NAME.html
      replace FUNCTION_NAME with the actual function name you want to document
      for example fopen()
  • for the AVMGlue API, use the AS3LCR
    also known as "ActionScript® 3.0 Reference for the Adobe® Flash® Platform"
    • the goal is not to copy/paste
    • but to check our open source implementation "correctness"
      • do we use the same function signature
      • do we define the correct runtime API versions
      • do we throw the correct error type
      • etc.

Take for example flash.crypto.generateRandomBytes(), from the original doc:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/crypto/package.html#generateRandomBytes()

We can verify:

  • the function signature public function generateRandomBytes(numberRandomBytes:uint):ByteArray
  • the runtime versions
    Flash Player 11, AIR 3

The task would consist to be sure our asdoc contains

    /**
     * @langversion 3.0
     * @playerversion Flash 11
     * @playerversion AIR 3.0
     */

and that we define the correct metadata and function signature

[API(AVMGLUE::SWF_13,AVMGLUE::AIR_3_0)]
public function generateRandomBytes( numberRandomBytes:uint ):ByteArray
{
    // implementation ...
}

Or, maybe add a missing "Related API Elements"

    /**
     * @langversion 3.0
     * @playerversion Flash 11
     * @playerversion AIR 3.0
     * 
     * @see Math#random() Math.random()
     */

Or, if the functionality is not implemented that the function returns

throw new NotImplementedError( "The function 'generateRandomBytes' is not implemented." );

Or, if the functionality requires an example, add one

    /**
     * 
     * @includeExample generateRandomBytes_example.as
     * 
     * @langversion 3.0
     * @playerversion Flash 11
     * @playerversion AIR 3.0
     */

and either report that an example is missing in
/src/as3examples/flash/crypto/generateRandomBytes_example.as
or simply write that code example (which can also be added to the integration tests).

And many other tasks that do not look glorious "like that" but are tremendously important as this documentation is the first thing developers refer to.

Writing ActionScript 3.0 Code

It can be as simple as creating a missing class in the AVMGlue API,
for example: flash.display.CapsStyle and provide its implementation in reference to the AS3LCR CapsStyle

package flash.display
{
    public final class CapsStyle
    {
        public static const NONE:String = "none";
        public static const ROUND:String = "round";
        public static const SQUARE:String = "square";
    }
}

with or without the asdoc (but "with" is strongly advised), with or without the code example: CapsStyleExample.as (at least create an empty file in /src/as3examples/flash/display/CapsStyleExample.as).

Or more complicated implementations and/or tests.

here a full implementation of flash.crypto.generateRandomBytes()

/* -*- c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package flash.crypto
{
    import C.errno.errno;
    import C.errno.CError;

    import C.fcntl.open;
    import C.fcntl.O_RDONLY;

    import C.stdlib.rand_s;

    import C.unistd.read;
    import C.unistd.close;

    import shell.Runtime;
    
    import flash.utils.ByteArray;

    /**
     * Generates a sequence of random bytes.
     *
     * <p>
     * Use <code>generateRandomBytes()</code> to generate cryptographic keys, strong identifiers, session ids, and so on.
     * The random sequence is generated using cryptographically strong functions provided by the operating system.
     * If the appropriate function is not available on an individual client computer or device, then an error is thrown.
     * </p>
     *
     * @param numberRandomBytes the number random bytes to generate, between 1 and 1024.
     * @return                  a ByteArray containing the generated bytes.
     * 
     * @langversion 3.0
     * @playerversion Flash 11
     * @playerversion AIR 3.0
     *
     * @throws Error when the random bytes could not be generated.
     * 
     * @see Math#random() Math.random()
     */
    [API(AVMGLUE::SWF_13,AVMGLUE::AIR_3_0)]
    public function generateRandomBytes( numberRandomBytes:uint ):ByteArray
    {
        if( numberRandomBytes < 1 )
        {
            numberRandomBytes = 1;
        }
        
        if( numberRandomBytes > 1024 )
        {
            numberRandomBytes = 1024;
        }
        
        var bytes:ByteArray = new ByteArray();

        if( Runtime.platform == "windows" )
        {
            /* Note:
               rand_s() returns a uint (32bit = 4 bytes)
            */
            var total:uint = Math.ceil( numberRandomBytes / 4);
            var byte:uint;

            while( total > 0 )
            {
                byte = rand_s();

                // we detected an error
                if( (errno > 0) && (byte == 0) )
                {
                    throw new CError( "", errno );
                }

                bytes.writeUnsignedInt( byte );
                total--;
            }

            if( bytes.length > numberRandomBytes )
            {
                // cut off the tail
                bytes.length = numberRandomBytes;
            }
        }
        else
        {
            /* Note:
               even if we have an implementation of rand_s() for POSIX
               it is more optimised to open/read "/dev/urandom"
               as it allows to read more than 1 byte
               and store directly the data into a ByteArray
            */
            var fd:int = open( "/dev/urandom", O_RDONLY, 0 );
            if( fd < 0 )
            {
                throw new CError( "", errno );
            }

            var read_total:int = read( fd, bytes, numberRandomBytes);
            if( read_total < 0 )
            {
                close( fd );
                throw new CError( "", errno );
            }

            close( fd );
        }

        /* TODO:
           do we reset the ByteArray position ?
           eg. bytes.position = 0

           check vs Flash/AIR runtime behavior
        */

        return bytes;
    }

}

Here few things to notice

  • all implementations starts with the MPL 2.0 banner
  • the asdoc is complete
    • versioning is here
    • granted we copy pasted the description from the AS3LCR but we think/hope Adobe will not sue us for that
    • copying the @param, @return is fair play
  • the order of imports
    • first any C package
    • then any shell package
    • then any flash package
  • we use the full path of imports, no *
  • the implementation take into account the different platforms
    here you can see if( Runtime.platform == "windows" )
    because we had to do things differently for Windows
  • we took some liberties with the errors
    instead of throwing a simple Error
    we throw CError which can provide more details
  • it's one implementation, it could be improved/changed etc.
    for example:
    • Cygwin could be detected and use the open("/dev/urandom") under Windows
    • under POSIX, if for some reasons "/dev/urandom" were not accessible
      we could fallback on using rand_s()
    • etc.
Clone this wiki locally