Ectypes is a DSL for building persistable data types and describing how they should be filled with data. If you've ever used factory_girl or machinist (Ruby testing libraries) the concept will be familiar to you.

Ectypes uses a strategy to identify how to talk to whichever persistence layer you've chosen to use (mongodb, relational db, redis, whatever).

var ectypes = require('ectypes')

, ctx = ectypes.createContext()

, SimpleStrategy = require('./simple-strategy');

ctx.load(new SimpleStrategy());

Ectype contexts take blueprints of data types, and make them available.

In the above the array of functions in befores will be processed in order. The first function takes a callback, the second and subsequent functions take an object to pass on their generated values down the line of functions and a callback - function(vals, cb) in the above. This means that associated data or preconditions can be fulfilled asynchronously before the ectype is constructed.

Outside of the befores array properties that map to functions are treated synchronously (typically mapped to helper libraries that produce test data).

Blueprints can also be added as arrays.

var multiBlueprint = [

{Person: {

title: function(){ return Faker.Name.findName() }

}}

, {Ancestor: {

title: function(){ return Faker.Name.findName() }

}}

];

ctx.load(multiBlueprint);

Every function on the strategy (except for what is listed in an ignores array) is then mapped to the type, as a producer.

ctx.Project.build(function(err, project){

console.log(project.title); //gives 'Elaina Orn', a value produced by the Faker library.

});

In the above example, the simpleStrategy has defined a function named 'build' accepting the arguments '(modelName, values, callback)'. Ectypes builds a producer function mapping to the strategy's function and passing it the appropriate data.

If you wanted to override the value of some test data in some circumstances (to set up relations to other objects, etc.):

ctx.Project.build({title: 'Someone else'}, function(err, project){

console.log(project.title); //gives 'Someone else'

});

In the above, if the first argument to a strategy call is an object, any values it contains will be used to override the generated ones. If it's a function then it's assumed to be the conventional Node.js callback function(err, result).

It is up to you, when writing the strategy, which behaviours you want to support.