Skip to content

Instantly share code, notes, and snippets.

@elpete
Last active October 7, 2016 02:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elpete/d981b03abacf7ac5de2c04eaf62c1ed5 to your computer and use it in GitHub Desktop.
Save elpete/d981b03abacf7ac5de2c04eaf62c1ed5 to your computer and use it in GitHub Desktop.
cbmodelfactory
component {
variables.factoryDefinitions = {};
public Factory function init() {
return this;
}
public Factory function define( required string model, required struct defaultAttributes ) {
factoryDefinitions[ model ] = defaultAttributes;
return this;
}
public any function make( required string model, struct attributes = {} ) {
var instance = create( argumentCollection = arguments );
entitySave( instance );
return instance;
}
public any function create( required string model, struct attributes = {} ) {
var instance = createInstance( model );
structAppend( attributes, getDefaultAttributes( model ), false /* do not overwrite */ );
var funcs = getMetadata( instance ).functions ?: [];
var funcNames = arrayMap( funcs, function( func ) {
return lcase( func.name );
} );
var allSetterNames = arrayFilter( funcNames, function( name ) {
return left( lcase( name ), 3 ) == 'set';
} );
var settersWeAreLookingFor = arrayMap( structKeyArray( attributes ), function( attr ) {
return {
attribute = attr,
method = lcase( "set" & attr )
};
} );
var setters = arrayFilter( settersWeAreLookingFor, function( setter ) {
return arrayContains( allSetterNames, setter.method )
} );
for ( var setter in setters ) {
var method = instance[ setter.method ];
method( attributes[ setter.attribute ] );
}
return instance;
}
private struct function getDefaultAttributes( required string model ) {
if ( ! structKeyExists( factoryDefinitions, model) ) {
throw(
type = "FactoryDefinitionNotFound",
message = "No factory definition found for [#model#]"
);
}
return factoryDefinitions[ model ];
}
private any function createInstance( required string model ) {
try {
return entityNew( model );
}
catch ( any e ) {
if ( ! noORMModelExists( e ) ) {
rethrow;
}
}
try {
return application.wirebox.getInstance( model );
}
catch ( any e ) {
if ( ! noWireBoxMappingExists( e ) ) {
rethrow;
}
}
try {
return createObject( "component", model );
}
catch ( any e ) {
if ( ! noComponentDefinitionExists( e ) ) {
rethrow;
}
throw(
type = "FactoryModelNotFound",
message = e.message
);
}
}
private boolean function noORMModelExists( required struct exception ) {
return findNoCase(
"No entity",
exception.message
) > 0;
}
private boolean function noWireBoxMappingExists( required struct exception ) {
return findNoCase(
"Requested instance not found",
exception.message
) > 0;
}
private boolean function noComponentDefinitionExists( required struct exception ) {
return findNoCase(
"Invalid component definition",
exception.message
) > 0;
}
}
component extends="testbox.system.BaseSpec" appMapping="/root" {
function beforeAll() {
variables.factory = new cbmodelfactory.models.Factory();
factory.define( "Lesson", {
// this is where something like `cffaker` would be _super_ useful
id = 2,
title = "Lesson — #createUUID()#",
src = "http://vjs.zencdn.net/v/oceans.mp4"
} );
}
/**
* @aroundEach
*/
function setupLessons( spec ) {
variables.lesson = factory.make( "Lesson" );
spec.body();
structDelete( variables, "lesson", false );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment