Skip to content

Commit

Permalink
Merge pull request #88 from DoclerLabs/develop
Browse files Browse the repository at this point in the history
prepare 0.34.0
  • Loading branch information
aliokan authored Jan 15, 2018
2 parents c9ece9a + da13dee commit e7d82cf
Show file tree
Hide file tree
Showing 28 changed files with 432 additions and 76 deletions.
100 changes: 52 additions & 48 deletions src/hex/control/trigger/CommandTriggerBuilder.hx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import hex.annotation.AnnotationReplaceBuilder;
import hex.control.payload.ExecutionPayload;
import hex.control.trigger.Command;
import hex.di.IDependencyInjector;
import hex.error.PrivateConstructorException;
import hex.module.IContextModule;
import hex.util.MacroUtil;

Expand All @@ -26,24 +25,16 @@ class CommandTriggerBuilder
{
public static inline var MapAnnotation = "Map";

/** @private */
function new()
{
throw new PrivateConstructorException( "This class can't be instantiated." );
}
/** @private */ function new() throw new hex.error.PrivateConstructorException( "This class can't be instantiated." );

macro static public function build() : Array<Field>
{
var fields = Context.getBuildFields();
var fields = Context.getBuildFields();
if ( Context.getLocalClass().get().isInterface ) return fields;

if ( Context.getLocalClass().get().isInterface )
{
return fields;
}

var CommandClassType = MacroUtil.getClassType( Type.getClassName( Command ) );
var MacroCommandClassType = MacroUtil.getClassType( Type.getClassName( MacroCommand ) );
var IContextModuleClassType = MacroUtil.getClassType( Type.getClassName( IContextModule ) );
var CommandClassType = MacroUtil.getClassType( Type.getClassName( Command ) );
var MacroCommandClassType = MacroUtil.getClassType( Type.getClassName( MacroCommand ) );
var IContextModuleClassType = MacroUtil.getClassType( Type.getClassName( IContextModule ) );
var IDependencyInjectorClassType = MacroUtil.getClassType( Type.getClassName( IDependencyInjector ) );

for ( f in fields )
Expand All @@ -58,7 +49,6 @@ class CommandTriggerBuilder
if ( isMapped )
{
var className = Context.getLocalModule();

if ( m.length > 1 )
{
Context.error( "'" + f.name + "' method defines more than one command mapping (with '@" +
Expand Down Expand Up @@ -107,7 +97,6 @@ class CommandTriggerBuilder
"' annotation) to '" + f.name + "' method in '" + className + "' class", command.pos );
}


var typePath = MacroUtil.getTypePath( command.name, command.pos );

if ( !MacroUtil.isSubClassOf( MacroUtil.getClassType( command.name ), CommandClassType ) )
Expand All @@ -116,7 +105,6 @@ class CommandTriggerBuilder
"' annotation), but it doesn't extend '" + CommandClassType.module + "' class", command.pos );
}


var arguments :Array<Expr> = [];
for ( arg in func.args )
{
Expand All @@ -139,7 +127,6 @@ class CommandTriggerBuilder
];
arguments.push( { expr: EObjectDecl( fields ), pos: Context.currentPos() } );
}

}

var className = MacroUtil.getPack( command.name );
Expand All @@ -158,7 +145,7 @@ class CommandTriggerBuilder
this.injector.mapClassNameToValue( 'Array<hex.control.payload.ExecutionPayload>', payloads );

hex.control.payload.PayloadUtil.mapPayload( payloads, this.injector );
var command = this.injector.getOrCreateNewInstance( $p { className } );
var command = this.injector.instantiateUnmapped( $p { className } );
hex.control.payload.PayloadUtil.unmapPayload( payloads, this.injector );

command.setOwner( this.module );
Expand All @@ -173,22 +160,15 @@ class CommandTriggerBuilder
{
func.expr = macro
{
var injections : Array<{value:Dynamic, className:String, mapName:String}> = $a { arguments };
var payloads = [];
for ( injected in injections )
{
payloads.push( new hex.control.payload.ExecutionPayload( injected.value, null, injected.mapName ).withClassName( injected.className ) );
}

var injections : Array<{value: Dynamic, className: String, mapName: String}> = $a { arguments };
var payloads = [ for ( injected in injections ) new hex.control.payload.ExecutionPayload( injected.value, null, injected.mapName ).withClassName( injected.className ) ];
hex.control.payload.PayloadUtil.mapPayload( payloads, this.injector );
var command = this.injector.getOrCreateNewInstance( $p { className } );
var command = this.injector.instantiateUnmapped( $p { className } );
hex.control.payload.PayloadUtil.unmapPayload( payloads, this.injector );

command.setOwner( this.module );
command.execute();




return command;
};
}
Expand Down Expand Up @@ -220,7 +200,7 @@ class CommandTriggerBuilder
pos: Context.currentPos()
});

return fields;
return hex.di.annotation.AnnotationTransformer.reflect( macro hex.di.IInjectorContainer, fields );
}

static function _searchForInjection( expr : Expr ) : Void
Expand All @@ -233,20 +213,14 @@ class CommandTriggerBuilder
{
switch( arg.expr )
{
case EMeta( meta1, _.expr => EMeta( meta2, _.expr => EVars( vars ) ) ) if ( meta1.name == "Inject" && meta2.name == "Optional" ):
_generateInjectionCode( meta1, arg, vars, _shouldThrowAnError( meta2 ) );

case EMeta( meta1, _.expr => EMeta( meta2, _.expr => EVars( vars ) ) ) if ( meta1.name == "Optional" && meta2.name == "Inject" ):
_generateInjectionCode( meta2, arg, vars, _shouldThrowAnError( meta1 ) );

case EMeta( s, _.expr => EVars( vars ) ) if ( s.name == "Inject" ):
var mapName = if ( s.params.length > 0 )
{
var transformed = AnnotationReplaceBuilder.processParam(s.params[ 0 ]);
switch(transformed.expr)
{
case EConst(CString(name)): name;
case _: "";
}
} else "";

var varName = vars[0].name;
var varType = vars[0].type;
arg.expr = (macro var $varName : $varType = this.injector.getInstanceWithClassName( $v{ MacroUtil.getFQCNFromComplexType( varType ) }, $v{mapName} )).expr;
_generateInjectionCode( s, arg, vars );

case _:
CommandTriggerBuilder._searchForInjection( arg );
Expand All @@ -257,12 +231,42 @@ class CommandTriggerBuilder
}
}

static function hasMetaValue( meta, metaName : String )
static function _shouldThrowAnError( s : MetadataEntry ) : Bool
{
if ( s.params.length > 0 )
{
var transformed = AnnotationReplaceBuilder.processParam( s.params[ 0 ] );
return switch( transformed.expr )
{
case EConst(CIdent( "true" )): false;
case EConst(CIdent("false")): true;
case _: false;
}
}

return false;
}

static function _generateInjectionCode( s : MetadataEntry, arg : Expr, vars : Array<Var>, shouldThrowAnError = true )
{
var meta = Lambda.find( meta, function(m) return m.name == metaName );
return ( meta != null );
var mapName = if ( s.params.length > 0 )
{
var transformed = AnnotationReplaceBuilder.processParam( s.params[ 0 ] );
switch( transformed.expr )
{
case EConst(CString(name)): name;
case _: "";
}
} else "";

var varName = vars[0].name;
var varType = vars[0].type;
arg.expr = (macro var $varName : $varType = this.injector.getInstanceWithClassName( $v{ MacroUtil.getFQCNFromComplexType( varType ) }, $v{mapName}, null, $v{shouldThrowAnError} )).expr;
}

static function hasMetaValue( meta, metaName : String )
return Lambda.find( meta, function(m) return m.name == metaName ) != null;

static function getMetaValue( meta : Null<Metadata>, metaName : String )
{
var meta : MetadataEntry = Lambda.find( meta, function(m) return m.name == metaName );
Expand Down
129 changes: 125 additions & 4 deletions test/hex/control/trigger/CommandTriggerTest.hx
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ package hex.control.trigger;
import hex.collection.Locator;
import hex.control.trigger.MockCommandClassWithParameters;
import hex.control.trigger.MockCommandClassWithoutParameters;
import hex.control.trigger.mock.MockController;
import hex.control.trigger.mock.AnotherMockCommand;
import hex.control.trigger.mock.MockCommand;
import hex.control.trigger.mock.MockController;
import hex.control.trigger.mock.MockMacroCommand;
import hex.control.trigger.mock.MockMacroController;
import hex.control.trigger.mock.MockModule;
import hex.di.IDependencyInjector;
import hex.di.Injector;
import hex.log.ILogger;
import hex.di.error.MissingMappingException;
import hex.module.IContextModule;
import hex.module.IModule;
import hex.unittest.assertion.Assert;
import hex.unittest.runner.MethodRunner;
Expand Down Expand Up @@ -118,10 +119,11 @@ class CommandTriggerTest
vos[ 6 ] = [ 'hello', 'world' ];
vos[ 7 ] = [ 'hello' => 'world' ];
vos[ 8 ] = Date.now();
vos[ 9 ] = MockEnum.TEST;

var result = '';
controller.doSomething( vos[ 0 ], vos[ 1 ], vos[ 2 ], vos[ 3 ], vos[ 4 ], vos[ 5 ], vos[ 6 ], vos[ 7 ], [3, 4], vos[ 8 ] )
.onComplete( function(r) result = r );
controller.doSomething( vos[ 0 ], vos[ 1 ], vos[ 2 ], vos[ 3 ], vos[ 4 ], vos[ 5 ], vos[ 6 ], vos[ 7 ], [3, 4], vos[ 8 ], vos[ 9 ] )
.onComplete( function(r) { result = r; } );

Assert.equals( 'string2', result );

Expand All @@ -135,6 +137,7 @@ class CommandTriggerTest
Assert.equals( vos[ 6 ], mo.pArray );
Assert.equals( vos[ 7 ], mo.pStringMap );
Assert.equals( vos[ 8 ], mo.pDate );
Assert.equals( vos[ 9 ], mo.pEnum );

//
var cmd = MockCommand.command;
Expand All @@ -147,6 +150,7 @@ class CommandTriggerTest
Assert.equals( vos[ 6 ], cmd.pArray );
Assert.equals( vos[ 7 ], cmd.pStringMap );
Assert.equals( vos[ 8 ], cmd.pDate );
Assert.equals( vos[ 9 ], cmd.pEnum );

//
var acmd = AnotherMockCommand.command;
Expand All @@ -159,5 +163,122 @@ class CommandTriggerTest
Assert.equals( vos[ 6 ], acmd.pArray );
Assert.equals( vos[ 7 ], acmd.pStringMap );
Assert.equals( vos[ 8 ], acmd.pDate );
Assert.equals( vos[ 9 ], acmd.pEnum );
}

@Test( "test local var injection" )
public function testLocalVarInjection() : Void
{
//Settings
var injector = new Injector();
injector.mapToValue( IDependencyInjector, injector );
injector.mapToValue( IContextModule, new MockModule() );

this._controller = injector.instantiateUnmapped( MockController );
injector.mapToValue( String, 'test' );

//testing
var result = this._controller.testLocalVarInjection();
Assert.equals( 'test', result );
}

@Test( "test local var injection with name" )
public function testLocalVarInjectionWithName() : Void
{
//Settings
var injector = new Injector();
injector.mapToValue( IDependencyInjector, injector );
injector.mapToValue( IContextModule, new MockModule() );

this._controller = injector.instantiateUnmapped( MockController );
injector.mapToValue( String, 'test', 'test' );

//testing
var result = this._controller.testLocalVarInjectionWithName();
Assert.equals( 'test', result );
}

@Test( "test local var with missing optional injection" )
public function testLocalVarWithMissingOptionalInjection() : Void
{
//Settings
var injector = new Injector();
injector.mapToValue( IDependencyInjector, injector );
injector.mapToValue( IContextModule, new MockModule() );

this._controller = injector.instantiateUnmapped( MockController );

//testing
Assert.methodCallThrows( MissingMappingException, this._controller, this._controller.testLocalVarOptionalInjection, [] );

injector.mapToValue( String, 'test3', 'test3' );
var result = this._controller.testLocalVarOptionalInjection();
Assert.deepEquals( [ null, null, 'test3' ], result );
}

@Test( "test local var optional injection" )
public function testLocalVarOptionalInjection() : Void
{
//Settings
var injector = new Injector();
injector.mapToValue( IDependencyInjector, injector );
injector.mapToValue( IContextModule, new MockModule() );

this._controller = injector.instantiateUnmapped( MockController );
injector.mapToValue( String, 'test1', 'test1' );
injector.mapToValue( String, 'test2', 'test2' );

//testing
Assert.methodCallThrows( MissingMappingException, this._controller, this._controller.testLocalVarOptionalInjection, [] );

injector.mapToValue( String, 'test3', 'test3' );
var result = this._controller.testLocalVarOptionalInjection();
Assert.deepEquals( [ 'test1', 'test2', 'test3' ], result );
}

@Test( "test local var with parameterized optional injection" )
public function testLocalVarWithParameterizedOptionalInjection() : Void
{
//Settings
var injector = new Injector();
injector.mapToValue( IDependencyInjector, injector );
injector.mapToValue( IContextModule, new MockModule() );

this._controller = injector.instantiateUnmapped( MockController );
injector.mapToValue( String, 'test1', 'test1' );
injector.mapToValue( String, 'test2', 'test2' );

//testing
Assert.methodCallThrows( MissingMappingException, this._controller, this._controller.testLocalVarParamOptionalInjection, [] );

injector.mapToValue( String, 'test3', 'test3' );
Assert.methodCallThrows( MissingMappingException, this._controller, this._controller.testLocalVarParamOptionalInjection, [] );

injector.mapToValue( String, 'test4', 'test4' );
var result = this._controller.testLocalVarParamOptionalInjection();
Assert.deepEquals( [ 'test1', 'test2', 'test3', 'test4' ], result );
}

@Test( "test local var with replaced parameterized optional injection" )
public function testLocalVarWithReplacedParameterizedOptionalInjection() : Void
{
//Settings
var injector = new Injector();
injector.mapToValue( IDependencyInjector, injector );
injector.mapToValue( IContextModule, new MockModule() );

this._controller = injector.instantiateUnmapped( MockController );
injector.mapToValue( String, 'test1', 'test1' );
injector.mapToValue( String, 'test2', 'test2' );

//testing
Assert.methodCallThrows( MissingMappingException, this._controller, this._controller.testLocalVarReplacedParamOptionalInjection, [] );

injector.mapToValue( String, 'test3', 'test3' );
Assert.methodCallThrows( MissingMappingException, this._controller, this._controller.testLocalVarReplacedParamOptionalInjection, [] );

injector.mapToValue( String, 'test4', 'test4' );
var result = this._controller.testLocalVarReplacedParamOptionalInjection();
Assert.deepEquals( [ 'test1', 'test2', 'test3', 'test4' ], result );
}
}
Loading

0 comments on commit e7d82cf

Please sign in to comment.