Thursday, March 10, 2011

Generating fake data

Fake data? Why would you ever need fake data?

Well the backend isn't ready? You're doing a POC? You're offline (airplane) while trying to develop.

I've found myself creating collections of vo's just to fill a list or combo box to test my interactions and events. I use to write for loops to do this and found that I could simplify the process somewhat.

So I created a little generator script, that you input the class (VO), the number that you want, and optionally any properties that you don't want to generate and it will return an Array of sequentially described VOs.

Basically what this means is that all of your vo string properties will be A,B,C,etc. Your vo number properties will be the index that it is, ie first vo = 0, 2nd vo = 1, etc. boolean vo properties will be random t/f. Date properties will be new Date().

This is not set up for complex nested datatypes


package com.squaredi.core.data.generators
{
 /**
  *
  * Context:
  *  During development (unit testing, POC's, and deployment before the backend)
  *  We may want to quickly create a series of temporary objects to fill a grid or to play with
  * 
  * Therefore:
  *   We can generate a series of objects where string properties will be "A,B,C..."  
  *   Number properties will be the number of the item that is generated
  *   Boolean properties will be random. 
  * 
  * Forces:
  *   The intent is to create a filled VO quickly... the data is not ment to be accurate
  * 
  * But:
  *   This doesn't include any additional datatypes then the intrinsic ones listed
  */
 
 import flash.utils.describeType;
 
 import mx.utils.ObjectUtil;

 public class MockGenerator
 {
  private static function createStub(cls:Class,index:int = 0, ignoreProperties:Array /*String*/ = null):Object // NO PMD
  {
   if (ignoreProperties == null) {ignoreProperties = [];}
   
   // First grab all of our writeable getter/setters and variables
   var info:XML =  describeType(cls);
   var setters:XMLList = info..accessor.(@access == "readwrite");
   var vars:XMLList = info..variable;
   var merge:XMLList = setters + vars;
   
   //Figure out what letter in the sequence this is going to be
   //If we go above 26, then start repeating letters (AA, BB) (AAA,BBB)
   var lettersInAlphabet:Number = 26; //0 based
   var repeatCount:int = Math.max(1,Math.ceil(index / lettersInAlphabet));
   if (index % lettersInAlphabet ==0 && index >0) {repeatCount++;}
   var asciiNum:Number = 65 + (index % lettersInAlphabet)
   var asciiChar:String = String.fromCharCode(asciiNum);
   var stringVal:String = ""
   for (var i:int = 0 ; i < repeatCount; i++)
   {
    stringVal += asciiChar
   }
   
   //Figure out what Numbers and Booleans are going to be
   var numVal:Number = index;
   var boolVal:Boolean = Boolean(Math.round(Math.random()));
   
   //Create the new Object, loop over each property and apply value
   var obj:Object = new cls();
   var prop:String;
   var type:String;
   for each (var propXml:XML in merge)
   {
    prop = propXml.@name;
    type= propXml.@type;
    
    //skip over namespaced properties (internal managed data for example)
    if (propXml.attribute("uri").length() >0)
    {
     break;
    }
    
    //Skip over uid
    if (prop == "uid")
    {
     continue;
    }
    
    //Allow for the developer to ignore setting some of the properties (as that might be the thing that they are testing)
    if (ignoreProperties.indexOf(prop) == -1)
    {
     switch(type)
     {
      case "String": obj[prop] = stringVal;break;
      case "Number":
      case "int":
       obj[prop] = numVal;
       break;
      case "Boolean":
       obj[prop] = boolVal;
       break;
      case "Date":
       obj[prop] = new Date();
       break;
     }
    }
   }
   
   return obj;
  }
  
  /**
   * Generate a given number of mock objects with some unique data
   * */
  public static function createStubs(cls:Class, total:int, ignoreProperties:Array /*String*/ = null ):Array /*Objects of type Class*/
  {
   var rtn:Array = new Array();
   for (var i:int = 0; i < total; i++)
   {
    rtn.push(createStub(cls,i,ignoreProperties));
   }
   return rtn;
  }
  
 }
}

No comments:

Post a Comment