├── .gitignore ├── LICENSE └── src ├── org └── robotlegs │ └── utilities │ └── macrobot │ ├── AsyncCommand.as │ ├── MacroCommandMap.as │ ├── ParallelCommand.as │ ├── SequenceCommand.as │ └── core │ ├── IAsyncCommand.as │ ├── IMacroCommandMap.as │ └── MacroBase.as └── test └── org └── robotlegs └── utilities └── macrobot ├── AsyncCommandTest.as ├── MacroBaseTest.as ├── MacroCommandMapTest.as ├── ParallelCommandTest.as ├── SequenceCommandTest.as ├── base └── MacroTestBase.as └── support ├── CompletionDirective.as ├── MacroCommandEvent.as ├── SubcommandConfigEvent.as ├── SubcommandStatusEvent.as ├── TestAsyncCommand.as ├── TestCommandMap.as ├── TestMacroBase.as ├── TestMacroCommandMap.as ├── TestParallelCommand.as ├── TestSequenceCommand.as └── TestSyncCommand.as /.gitignore: -------------------------------------------------------------------------------- 1 | .actionScriptProperties 2 | .flexLibProperties 3 | .settings 4 | .project 5 | bin-debug 6 | bin 7 | bin-release 8 | libs 9 | 10 | /.FlexUnitSettings/FlexUnitApplicationLastRun.xml 11 | /.FlexUnitSettings/FlexUnitApplicationLastSelection.xml 12 | /src/FlexUnitApplication.mxml -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 the original author or authors 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /src/org/robotlegs/utilities/macrobot/AsyncCommand.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 the original author or authors 3 | * 4 | * Permission is hereby granted to use, modify, and distribute this file 5 | * in accordance with the terms of the license agreement accompanying it. 6 | */ 7 | package org.robotlegs.utilities.macrobot 8 | { 9 | import org.robotlegs.mvcs.Command; 10 | import org.robotlegs.utilities.macrobot.core.IAsyncCommand; 11 | 12 | /** 13 | * Provides functionality for holding an asynchronous command in memory and dispatching 14 | * when the command is complete. 15 | */ 16 | public class AsyncCommand extends Command implements IAsyncCommand 17 | { 18 | /** 19 | * Registered listeners. 20 | */ 21 | protected var listeners:Array; 22 | 23 | /** 24 | * @inheritDoc 25 | */ 26 | public function addCompletionListener(listener:Function):void 27 | { 28 | listeners ||= []; 29 | listeners.push(listener); 30 | } 31 | 32 | /** 33 | * @inheritDoc 34 | */ 35 | override public function execute():void 36 | { 37 | super.execute(); 38 | 39 | // Maintain a reference to this command while it executes so it doesn't get 40 | // garbage collected. 41 | commandMap.detain(this); 42 | } 43 | 44 | /** 45 | * Notifies any registered listeners of the completion of this command along with 46 | * whether or not it was successful. 47 | */ 48 | protected function dispatchComplete(success:Boolean):void 49 | { 50 | commandMap.release(this); 51 | for each (var listener:Function in listeners) 52 | { 53 | listener(success); 54 | } 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /src/org/robotlegs/utilities/macrobot/MacroCommandMap.as: -------------------------------------------------------------------------------- 1 | package org.robotlegs.utilities.macrobot 2 | { 3 | import flash.events.IEventDispatcher; 4 | 5 | import org.robotlegs.base.CommandMap; 6 | import org.robotlegs.core.IInjector; 7 | import org.robotlegs.core.IReflector; 8 | import org.robotlegs.utilities.macrobot.core.IMacroCommandMap; 9 | 10 | /** 11 | * A IMacroCommandMap implementation 12 | */ 13 | public class MacroCommandMap extends CommandMap implements IMacroCommandMap 14 | { 15 | public function MacroCommandMap(eventDispatcher:IEventDispatcher, injector:IInjector, 16 | reflector:IReflector) 17 | { 18 | super(eventDispatcher, injector, reflector); 19 | } 20 | 21 | /** 22 | * @inheritDoc 23 | */ 24 | override public function execute(commandClass:Class, payload:Object=null, 25 | payloadClass:Class=null, named:String=""):void 26 | { 27 | var command:Object = prepare(commandClass, payload, payloadClass, named); 28 | executePrepared(command); 29 | } 30 | 31 | /** 32 | * @inheritDoc 33 | */ 34 | public function prepare(commandClass:Class, payload:Object = null, 35 | payloadClass:Class = null, named:String = ''):Object 36 | { 37 | verifyCommandClass(commandClass); 38 | 39 | if (payload != null || payloadClass != null) 40 | { 41 | payloadClass ||= reflector.getClass(payload); 42 | injector.mapValue(payloadClass, payload, named); 43 | } 44 | 45 | var command:Object = injector.instantiate(commandClass); 46 | 47 | if (payload !== null || payloadClass != null) 48 | injector.unmap(payloadClass, named); 49 | 50 | return command; 51 | } 52 | 53 | /** 54 | * @inheritDoc 55 | */ 56 | public function executePrepared(command:Object):void 57 | { 58 | command.execute(); 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /src/org/robotlegs/utilities/macrobot/ParallelCommand.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 the original author or authors 3 | * 4 | * Permission is hereby granted to use, modify, and distribute this file 5 | * in accordance with the terms of the license agreement accompanying it. 6 | */ 7 | package org.robotlegs.utilities.macrobot 8 | { 9 | import org.robotlegs.utilities.macrobot.core.MacroBase; 10 | 11 | /** 12 | * A command for executing multiple other commands in parallel. All commands will start 13 | * execution as simultaneously as possible in the order they were added. This command will 14 | * not be marked complete until all commands have completed. It can be nested inside other 15 | * parallel or sequence commands. 16 | */ 17 | public class ParallelCommand extends MacroBase 18 | { 19 | /** 20 | * The number of commands currently executing. 21 | */ 22 | protected var numCommandsExecuting:uint = 0; 23 | 24 | /** 25 | * @inheritDoc 26 | */ 27 | override public function execute():void 28 | { 29 | super.execute(); 30 | if (commands && commands.length > 0) 31 | { 32 | numCommandsExecuting = commands.length; 33 | for each (var command:Object in commands) 34 | { 35 | success ? executeCommand(command) : dispatchComplete(false); 36 | } 37 | } 38 | else 39 | { 40 | dispatchComplete(true); 41 | } 42 | } 43 | 44 | /** 45 | * @inheritDoc 46 | */ 47 | override protected function commandCompleteHandler(success:Boolean):void 48 | { 49 | super.commandCompleteHandler(success); 50 | this.success &&= success; 51 | numCommandsExecuting--; 52 | 53 | if (numCommandsExecuting == 0) 54 | { 55 | dispatchComplete(this.success); 56 | } 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /src/org/robotlegs/utilities/macrobot/SequenceCommand.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 the original author or authors 3 | * 4 | * Permission is hereby granted to use, modify, and distribute this file 5 | * in accordance with the terms of the license agreement accompanying it. 6 | */ 7 | package org.robotlegs.utilities.macrobot 8 | { 9 | import org.robotlegs.utilities.macrobot.core.MacroBase; 10 | 11 | /** 12 | * A command for executing multiple other commands in sequence in the order they were added. 13 | * In other words, the second command will not begin execution until the first command has 14 | * completed. This command will not be marked complete until all commands have completed. It 15 | * can be nested inside other parallel or sequence commands. 16 | */ 17 | public class SequenceCommand extends MacroBase 18 | { 19 | /** 20 | * Whether the sequence command should execute subsequent commands when a command fails. 21 | * If atomic is true, the sequence command will continue executing commands. 22 | */ 23 | public var atomic:Boolean = true; 24 | 25 | /** 26 | * The index of the command in execution. 27 | */ 28 | protected var executionIndex:uint; 29 | 30 | /** 31 | * @inheritDoc 32 | */ 33 | override public function execute():void 34 | { 35 | super.execute(); 36 | executionIndex = 0; // undo/redo compatibility 37 | executeNext(); 38 | } 39 | 40 | /** 41 | * Executes the next subcommand. 42 | */ 43 | protected function executeNext():void 44 | { 45 | commands && executionIndex < commands.length ? 46 | executeCommand(commands[executionIndex]) : 47 | dispatchComplete(success); 48 | } 49 | 50 | /** 51 | * @inheritDoc 52 | */ 53 | override protected function commandCompleteHandler(success:Boolean):void 54 | { 55 | super.commandCompleteHandler(success); 56 | this.success &&= success; 57 | executionIndex++; 58 | (atomic || this.success) ? executeNext() : dispatchComplete(false); 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /src/org/robotlegs/utilities/macrobot/core/IAsyncCommand.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 the original author or authors 3 | * 4 | * Permission is hereby granted to use, modify, and distribute this file 5 | * in accordance with the terms of the license agreement accompanying it. 6 | */ 7 | package org.robotlegs.utilities.macrobot.core 8 | { 9 | public interface IAsyncCommand 10 | { 11 | /** 12 | * Registers a function to be executed when this command completes. The function must 13 | * accept a single boolean parameter which will indicate whether this command completed 14 | * successfully. 15 | */ 16 | function addCompletionListener(listener:Function):void; 17 | } 18 | } -------------------------------------------------------------------------------- /src/org/robotlegs/utilities/macrobot/core/IMacroCommandMap.as: -------------------------------------------------------------------------------- 1 | package org.robotlegs.utilities.macrobot.core 2 | { 3 | import org.robotlegs.core.ICommandMap; 4 | 5 | /** 6 | * Provides an interface for preparing and executing a command in a manner that allows for 7 | * both macro management and a single point of execution. 8 | * 9 | * It provides macro management by preparing an instance of a command and returning it before 10 | * execution. This allows macro commands to attach required listeners to subcommands before 11 | * execution. 12 | * 13 | * It provides a single point of execution because an instance of an IMacroCommandMap can 14 | * replace a context's default command map. Without this replacement, a macro command 15 | * is itself responsible for executing its subcommands because the default command map is 16 | * insufficient for macro requirements. Having a single point of command execution 17 | * (the context's command map) is helpful when, for example, implementing a logging mechanism 18 | * to track when any command is executed within a context. 19 | * 20 | * It is not required to use an IMacroCommandMap for executing macro commands. If one is not 21 | * used, there will not be a single point of command execution within the context as previously 22 | * explained which is fine for most needs. To understand how to replace the default command map 23 | * within a context, please visit the Robotlegs forums. 24 | */ 25 | public interface IMacroCommandMap extends ICommandMap 26 | { 27 | /** 28 | * Instantiates and prepares a command with everything it needs to be executed but does 29 | * not execute it. 30 | * 31 | * @param commandClass The Class to instantiate - must have an execute() method 32 | * @param payload An optional payload 33 | * @param payloadClass An optional class to inject the payload as 34 | * @param named An optional name for the payload injection 35 | * 36 | * @return The instantiated command. 37 | * 38 | * @throws org.robotlegs.base::ContextError 39 | */ 40 | function prepare(commandClass:Class, payload:Object = null, payloadClass:Class = null, 41 | named:String = ''):Object 42 | 43 | /** 44 | * Executes and command that has already been prepared for execution. 45 | */ 46 | function executePrepared(command:Object):void 47 | } 48 | } -------------------------------------------------------------------------------- /src/org/robotlegs/utilities/macrobot/core/MacroBase.as: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 the original author or authors 3 | * 4 | * Permission is hereby granted to use, modify, and distribute this file 5 | * in accordance with the terms of the license agreement accompanying it. 6 | */ 7 | package org.robotlegs.utilities.macrobot.core 8 | { 9 | import flash.events.Event; 10 | 11 | import org.robotlegs.core.IReflector; 12 | import org.robotlegs.mvcs.Command; 13 | import org.robotlegs.utilities.macrobot.AsyncCommand; 14 | import org.swiftsuspenders.Reflector; 15 | 16 | /** 17 | * Base functionality for ParallelCommand and SequenceCommand. This 18 | * provides the main API for adding and executing commands. 19 | */ 20 | public class MacroBase extends AsyncCommand 21 | { 22 | /** 23 | * Whether all commands have completed successfully. 24 | */ 25 | protected var success:Boolean = true; 26 | 27 | /** 28 | * A collection of command or CommandDescriptor instances. 29 | */ 30 | protected var commands:Array; 31 | 32 | /** 33 | * Add a command to the macro using metadata that will be used to instantiate, inject 34 | * into, and execute the command at the appropriate time. 35 | * 36 | * @param commandClass The command class to instantiate - must have an execute() method 37 | * @param payload An optional payload 38 | * @param payloadClass An optional class to inject the payload as 39 | * @param named An optional name for the payload injection 40 | */ 41 | public function addCommand(commandClass:Class, payload:Object=null, payloadClass:Class=null, 42 | named:String=''):void 43 | { 44 | commands ||= []; 45 | commands.push(new CommandDescriptor(commandClass, payload, payloadClass, named)); 46 | } 47 | 48 | /** 49 | * Add a command instance to the macro. Injections will occur before execution. 50 | * 51 | * @param command The command instance to add to the macro - must have an execute() method. 52 | */ 53 | public function addCommandInstance(command:Object):void 54 | { 55 | commands ||= []; 56 | commands.push(command); 57 | } 58 | 59 | /** 60 | * @inheritDoc 61 | */ 62 | override public function execute():void 63 | { 64 | super.execute(); 65 | success = true; // undo/redo compatibility 66 | } 67 | 68 | /** 69 | * Executes a command. 70 | * 71 | * @param commandOrDescriptor A command or CommandDescriptor instance. 72 | */ 73 | protected function executeCommand(commandOrDescriptor:Object):void 74 | { 75 | var command:Object = prepareCommand(commandOrDescriptor); 76 | var isAsync:Boolean = command is IAsyncCommand; 77 | 78 | if (isAsync) 79 | { 80 | IAsyncCommand(command).addCompletionListener(commandCompleteHandler); 81 | } 82 | 83 | // If the command map is IMacroCommandMap, use it. This is allows us to maintain 84 | // a single point of execution within the application. This can be very useful when 85 | // it comes to debugging or having a custom command map with logging support, etc. 86 | if (commandMap is IMacroCommandMap) 87 | { 88 | IMacroCommandMap(commandMap).executePrepared(command); 89 | } 90 | else 91 | { 92 | command.execute(); 93 | } 94 | 95 | if (!isAsync) 96 | { 97 | commandCompleteHandler(true); 98 | } 99 | } 100 | 101 | /** 102 | * Prepares a command by instantiation if necessary and fulfilling injections. 103 | * 104 | * @param commandOrDescriptor An instantiated command object or a command descriptor. 105 | * 106 | * @return A command instance with fulfilled injections. 107 | */ 108 | protected function prepareCommand(commandOrDescriptor:Object):Object 109 | { 110 | if (commandOrDescriptor is CommandDescriptor) 111 | { 112 | return prepareCommandFromDescriptor(CommandDescriptor(commandOrDescriptor)); 113 | } 114 | else 115 | { 116 | injector.injectInto(commandOrDescriptor); 117 | return commandOrDescriptor; 118 | } 119 | } 120 | 121 | /** 122 | * Instantiates and injects a command based on a command descriptor. 123 | * 124 | * @param descriptor A command descriptor. 125 | * 126 | * @return A command instance with fulfilled injections. 127 | */ 128 | protected function prepareCommandFromDescriptor(descriptor:CommandDescriptor):Object 129 | { 130 | var command:Object; 131 | 132 | // If we have an IMacroCommandMap, use it to prepare the command object. 133 | if (commandMap is IMacroCommandMap) 134 | { 135 | command = IMacroCommandMap(commandMap).prepare(descriptor.commandClass, 136 | descriptor.payload, descriptor.payloadClass, descriptor.named); 137 | } 138 | // Otherwise, we'll do our best to prepare it ourselves. 139 | else 140 | { 141 | // Perform injections. 142 | // Note: if RL's CommandMap ever implements an interface like IMacroCommandMap 143 | // we could use it instead and wouldn't need IMacroCommandMap or the code 144 | // below at all. 145 | if (descriptor.payload != null) 146 | { 147 | var payloadClass:Class; 148 | if (descriptor.payloadClass) 149 | { 150 | payloadClass = descriptor.payloadClass; 151 | } 152 | else 153 | { 154 | var reflector:IReflector = injector.getInstance(IReflector); 155 | 156 | if (reflector) 157 | { 158 | payloadClass = reflector.getClass(descriptor.payload); 159 | } 160 | else 161 | { 162 | payloadClass = Event; 163 | } 164 | } 165 | injector.mapValue(payloadClass, descriptor.payload, descriptor.named); 166 | command = injector.instantiate(descriptor.commandClass); 167 | injector.unmap(payloadClass, descriptor.named); 168 | } 169 | else 170 | { 171 | command = injector.instantiate(descriptor.commandClass); 172 | } 173 | } 174 | 175 | return command; 176 | } 177 | 178 | /** 179 | * Handles completion of a command. 180 | */ 181 | protected function commandCompleteHandler(success:Boolean):void 182 | { 183 | // Override. 184 | } 185 | } 186 | } 187 | 188 | /** 189 | * Holds "meta" information regarding a command so when it becomes time to execute, the command can 190 | * be instantiated, injected into, and then executed. 191 | */ 192 | class CommandDescriptor 193 | { 194 | public function CommandDescriptor(commandClass:Class, payload:Object=null, 195 | payloadClass:Class=null, named:String='') 196 | { 197 | this.commandClass = commandClass; 198 | this.payload = payload; 199 | this.payloadClass = payloadClass; 200 | this.named = named; 201 | } 202 | 203 | public var commandClass:Class; 204 | public var payload:Object; 205 | public var payloadClass:Class; 206 | public var named:String; 207 | } -------------------------------------------------------------------------------- /src/test/org/robotlegs/utilities/macrobot/AsyncCommandTest.as: -------------------------------------------------------------------------------- 1 | package test.org.robotlegs.utilities.macrobot 2 | { 3 | import flash.display.DisplayObjectContainer; 4 | import flash.display.Sprite; 5 | import flash.events.EventDispatcher; 6 | import flash.events.IEventDispatcher; 7 | 8 | import flexunit.framework.Assert; 9 | 10 | import org.robotlegs.adapters.SwiftSuspendersInjector; 11 | import org.robotlegs.adapters.SwiftSuspendersReflector; 12 | import org.robotlegs.base.MediatorMap; 13 | import org.robotlegs.core.ICommandMap; 14 | import org.robotlegs.core.IInjector; 15 | import org.robotlegs.core.IMediatorMap; 16 | import org.robotlegs.core.IReflector; 17 | 18 | import test.org.robotlegs.utilities.macrobot.support.CompletionDirective; 19 | import test.org.robotlegs.utilities.macrobot.support.SubcommandConfigEvent; 20 | import test.org.robotlegs.utilities.macrobot.support.TestAsyncCommand; 21 | import test.org.robotlegs.utilities.macrobot.support.TestCommandMap; 22 | 23 | public class AsyncCommandTest 24 | { 25 | protected var command:TestAsyncCommand; 26 | 27 | protected var commandComplete:Boolean; 28 | protected var commandSuccess:Boolean; 29 | 30 | protected var injector:IInjector; 31 | protected var commandMap:TestCommandMap; 32 | 33 | [Before] 34 | public function setUp():void 35 | { 36 | var contextView:Sprite = new Sprite(); 37 | var reflector:IReflector = new SwiftSuspendersReflector(); 38 | var eventDispatcher:IEventDispatcher = new EventDispatcher(); 39 | injector = new SwiftSuspendersInjector(); 40 | injector.mapValue(IInjector, injector); 41 | injector.mapValue(IReflector, reflector); 42 | injector.mapValue(DisplayObjectContainer, contextView); 43 | commandMap = new TestCommandMap(eventDispatcher, injector, reflector); 44 | injector.mapValue(ICommandMap, commandMap); 45 | injector.mapValue(IEventDispatcher, eventDispatcher); 46 | injector.mapValue(IMediatorMap, new MediatorMap(contextView, injector, reflector)); 47 | } 48 | 49 | [After] 50 | public function tearDown():void 51 | { 52 | injector = null; 53 | commandMap = null; 54 | commandComplete = false; 55 | commandSuccess = false; 56 | } 57 | 58 | [Test] 59 | public function testExecutionSuccess():void 60 | { 61 | command = new TestAsyncCommand(new SubcommandConfigEvent(SubcommandConfigEvent.CONFIG, 0, 0, CompletionDirective.SUCCESS)); 62 | injector.injectInto(command); 63 | command.addCompletionListener(completeHandler); 64 | command.execute(); 65 | Assert.assertTrue("Command should have dispatched complete.", commandComplete); 66 | Assert.assertTrue("Command should have dispatched completion success.", commandSuccess); 67 | } 68 | 69 | [Test] 70 | public function testExecutionFailure():void 71 | { 72 | command = new TestAsyncCommand(new SubcommandConfigEvent(SubcommandConfigEvent.CONFIG, 0, 0, CompletionDirective.FAILURE)); 73 | injector.injectInto(command); 74 | command.addCompletionListener(completeHandler); 75 | command.execute(); 76 | Assert.assertTrue("Command should have dispatched complete.", commandComplete); 77 | Assert.assertFalse("Command should have dispatched completion failure.", commandSuccess); 78 | } 79 | 80 | [Test] 81 | public function testCommandDetained():void 82 | { 83 | command = new TestAsyncCommand(new SubcommandConfigEvent(SubcommandConfigEvent.CONFIG, 0, 0, CompletionDirective.PREVENT_COMPLETION)); 84 | injector.injectInto(command); 85 | command.execute(); 86 | Assert.assertTrue("Command should have been detained.", commandMap.isCommandDetained); 87 | commandMap.release(command); 88 | } 89 | 90 | [Test] 91 | public function testCommandReleased():void 92 | { 93 | command = new TestAsyncCommand(new SubcommandConfigEvent(SubcommandConfigEvent.CONFIG, 0, 0, CompletionDirective.SUCCESS)); 94 | injector.injectInto(command); 95 | command.addCompletionListener(completeHandler); 96 | command.execute(); 97 | Assert.assertFalse("Command should have been released.", commandMap.isCommandDetained); 98 | } 99 | 100 | protected function completeHandler(success:Boolean):void 101 | { 102 | commandComplete = true; 103 | commandSuccess = success; 104 | } 105 | } 106 | } -------------------------------------------------------------------------------- /src/test/org/robotlegs/utilities/macrobot/MacroBaseTest.as: -------------------------------------------------------------------------------- 1 | package test.org.robotlegs.utilities.macrobot 2 | { 3 | import flexunit.framework.Assert; 4 | 5 | import org.robotlegs.mvcs.Command; 6 | 7 | import test.org.robotlegs.utilities.macrobot.support.TestMacroBase; 8 | 9 | public class MacroBaseTest 10 | { 11 | [Test] 12 | public function testAddCommand():void 13 | { 14 | var command:TestMacroBase = new TestMacroBase(); 15 | var subcommands:Array = command.getSubcommands() || []; 16 | Assert.assertEquals('No commands should have been added yet.', subcommands.length, 0); 17 | command.addCommandInstance(new Command()); 18 | subcommands = command.getSubcommands(); 19 | Assert.assertEquals('A single command should have been added.', subcommands.length, 1); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/test/org/robotlegs/utilities/macrobot/MacroCommandMapTest.as: -------------------------------------------------------------------------------- 1 | package test.org.robotlegs.utilities.macrobot 2 | { 3 | import flash.display.DisplayObjectContainer; 4 | import flash.display.Sprite; 5 | import flash.events.EventDispatcher; 6 | import flash.events.IEventDispatcher; 7 | 8 | import flexunit.framework.Assert; 9 | 10 | import org.robotlegs.adapters.SwiftSuspendersInjector; 11 | import org.robotlegs.adapters.SwiftSuspendersReflector; 12 | import org.robotlegs.base.MediatorMap; 13 | import org.robotlegs.core.ICommandMap; 14 | import org.robotlegs.core.IInjector; 15 | import org.robotlegs.core.IMediatorMap; 16 | import org.robotlegs.core.IReflector; 17 | import org.robotlegs.utilities.macrobot.MacroCommandMap; 18 | import org.robotlegs.utilities.macrobot.core.IMacroCommandMap; 19 | 20 | import test.org.robotlegs.utilities.macrobot.support.SubcommandConfigEvent; 21 | import test.org.robotlegs.utilities.macrobot.support.SubcommandStatusEvent; 22 | import test.org.robotlegs.utilities.macrobot.support.TestAsyncCommand; 23 | import test.org.robotlegs.utilities.macrobot.support.TestSyncCommand; 24 | 25 | 26 | public class MacroCommandMapTest 27 | { 28 | protected var reflector:IReflector; 29 | protected var injector:IInjector; 30 | protected var commandMap:IMacroCommandMap; 31 | protected var eventDispatcher:IEventDispatcher; 32 | 33 | protected var commandExecuted:Boolean; 34 | 35 | [Before] 36 | public function setUp():void 37 | { 38 | var contextView:Sprite = new Sprite(); 39 | reflector = new SwiftSuspendersReflector(); 40 | eventDispatcher = new EventDispatcher(); 41 | injector = new SwiftSuspendersInjector(); 42 | injector.mapValue(IInjector, injector); 43 | injector.mapValue(IReflector, reflector); 44 | injector.mapValue(DisplayObjectContainer, contextView); 45 | commandMap = new MacroCommandMap(eventDispatcher, injector, reflector); 46 | injector.mapValue(ICommandMap, commandMap); 47 | injector.mapValue(IEventDispatcher, eventDispatcher); 48 | injector.mapValue(IMediatorMap, new MediatorMap(contextView, injector, reflector)); 49 | } 50 | 51 | [After] 52 | public function tearDown():void 53 | { 54 | reflector = null; 55 | injector = null; 56 | commandMap = null; 57 | eventDispatcher = null; 58 | commandExecuted = false; 59 | } 60 | 61 | [Test] 62 | public function testPrepare():void 63 | { 64 | var command:Object = commandMap.prepare( 65 | TestAsyncCommand, new SubcommandConfigEvent(SubcommandConfigEvent.CONFIG)); 66 | Assert.assertTrue("Prepared command isn't of expected type.", command is TestAsyncCommand); 67 | Assert.assertNotNull("Injection didn't occur for command.", TestAsyncCommand(command).event); 68 | } 69 | 70 | [Test] 71 | public function testExecutePrepared():void 72 | { 73 | eventDispatcher.addEventListener(SubcommandStatusEvent.COMPLETE, completeHandler, false, 0, true); 74 | var command:Object = new TestSyncCommand(new SubcommandConfigEvent(SubcommandConfigEvent.CONFIG)); 75 | injector.injectInto(command); 76 | commandMap.executePrepared(command); 77 | Assert.assertTrue("Command never executed.", commandExecuted); 78 | } 79 | 80 | [Test] 81 | public function testExecute():void 82 | { 83 | eventDispatcher.addEventListener(SubcommandStatusEvent.COMPLETE, completeHandler, false, 0, true); 84 | commandMap.execute(TestSyncCommand, new SubcommandConfigEvent(SubcommandConfigEvent.CONFIG)); 85 | Assert.assertTrue("Command never executed.", commandExecuted); 86 | } 87 | 88 | protected function completeHandler(event:SubcommandStatusEvent):void 89 | { 90 | commandExecuted = true; 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /src/test/org/robotlegs/utilities/macrobot/ParallelCommandTest.as: -------------------------------------------------------------------------------- 1 | package test.org.robotlegs.utilities.macrobot 2 | { 3 | import test.org.robotlegs.utilities.macrobot.base.MacroTestBase; 4 | import test.org.robotlegs.utilities.macrobot.support.SubcommandStatusEvent; 5 | import test.org.robotlegs.utilities.macrobot.support.TestParallelCommand; 6 | 7 | public class ParallelCommandTest extends MacroTestBase 8 | { 9 | public function ParallelCommandTest() 10 | { 11 | super(); 12 | commandClass = TestParallelCommand; 13 | } 14 | 15 | [Before] 16 | override public function setUp():void 17 | { 18 | super.setUp(); 19 | } 20 | 21 | [After] 22 | override public function tearDown():void 23 | { 24 | super.tearDown(); 25 | } 26 | 27 | [Test(async)] 28 | override public function testSyncCommandInstanceExecution():void 29 | { 30 | super.testSyncCommandInstanceExecution(); 31 | } 32 | 33 | [Test(async)] 34 | override public function testAsyncCommandInstanceExecution():void 35 | { 36 | super.testAsyncCommandInstanceExecution(); 37 | } 38 | 39 | [Test(async)] 40 | override public function testAsyncAndSyncCommandInstanceExecution():void 41 | { 42 | super.testAsyncAndSyncCommandInstanceExecution(); 43 | } 44 | 45 | [Test(async)] 46 | override public function testSyncCommandDescriptorExecution():void 47 | { 48 | super.testSyncCommandDescriptorExecution(); 49 | } 50 | 51 | [Test(async)] 52 | override public function testAsyncCommandDescriptorExecution():void 53 | { 54 | super.testAsyncCommandDescriptorExecution(); 55 | } 56 | 57 | [Test(async)] 58 | override public function testAsyncAndSyncCommandDescriptorExecution():void 59 | { 60 | super.testAsyncAndSyncCommandDescriptorExecution(); 61 | } 62 | 63 | [Test(async)] 64 | override public function testNoCommandExecution():void 65 | { 66 | super.testNoCommandExecution(); 67 | } 68 | 69 | [Test(async)] 70 | override public function testFailedExecution():void 71 | { 72 | super.testFailedExecution(); 73 | } 74 | 75 | [Test(async)] 76 | override public function testExecutionWithMacroCommandMap():void 77 | { 78 | super.testExecutionWithMacroCommandMap(); 79 | } 80 | 81 | override protected function wereSubcommandsExecutedAsExpected(ids:Vector.):Boolean 82 | { 83 | ids = ids.slice(); // Dereference for good measure. 84 | for each (var event:SubcommandStatusEvent in statusEvents) 85 | { 86 | if (event.type != SubcommandStatusEvent.COMPLETE) 87 | { 88 | continue; 89 | } 90 | 91 | var index:int = ids.indexOf(event.id); 92 | if (index > -1) 93 | { 94 | ids.splice(index, 1); 95 | } 96 | else 97 | { 98 | // A command was executed that wasn't expected to execute. 99 | return false; 100 | } 101 | } 102 | 103 | // Not all commands expected to execute were executed. 104 | return ids.length == 0; 105 | } 106 | } 107 | } -------------------------------------------------------------------------------- /src/test/org/robotlegs/utilities/macrobot/SequenceCommandTest.as: -------------------------------------------------------------------------------- 1 | package test.org.robotlegs.utilities.macrobot 2 | { 3 | import org.flexunit.async.Async; 4 | import org.robotlegs.utilities.macrobot.SequenceCommand; 5 | 6 | import test.org.robotlegs.utilities.macrobot.base.MacroTestBase; 7 | import test.org.robotlegs.utilities.macrobot.support.CompletionDirective; 8 | import test.org.robotlegs.utilities.macrobot.support.MacroCommandEvent; 9 | import test.org.robotlegs.utilities.macrobot.support.SubcommandConfigEvent; 10 | import test.org.robotlegs.utilities.macrobot.support.SubcommandStatusEvent; 11 | import test.org.robotlegs.utilities.macrobot.support.TestAsyncCommand; 12 | import test.org.robotlegs.utilities.macrobot.support.TestSequenceCommand; 13 | 14 | public class SequenceCommandTest extends MacroTestBase 15 | { 16 | public function SequenceCommandTest() 17 | { 18 | super(); 19 | commandClass = TestSequenceCommand; 20 | } 21 | 22 | [Before] 23 | override public function setUp():void 24 | { 25 | super.setUp(); 26 | } 27 | 28 | [After] 29 | override public function tearDown():void 30 | { 31 | super.tearDown(); 32 | } 33 | 34 | [Test(async)] 35 | override public function testSyncCommandInstanceExecution():void 36 | { 37 | super.testSyncCommandInstanceExecution(); 38 | } 39 | 40 | [Test(async)] 41 | override public function testAsyncCommandInstanceExecution():void 42 | { 43 | super.testAsyncCommandInstanceExecution(); 44 | } 45 | 46 | [Test(async)] 47 | override public function testAsyncAndSyncCommandInstanceExecution():void 48 | { 49 | super.testAsyncAndSyncCommandInstanceExecution(); 50 | } 51 | 52 | [Test(async)] 53 | override public function testSyncCommandDescriptorExecution():void 54 | { 55 | super.testSyncCommandDescriptorExecution(); 56 | } 57 | 58 | [Test(async)] 59 | override public function testAsyncCommandDescriptorExecution():void 60 | { 61 | super.testAsyncCommandDescriptorExecution(); 62 | } 63 | 64 | [Test(async)] 65 | override public function testAsyncAndSyncCommandDescriptorExecution():void 66 | { 67 | super.testAsyncAndSyncCommandDescriptorExecution(); 68 | } 69 | 70 | [Test(async)] 71 | override public function testNoCommandExecution():void 72 | { 73 | super.testNoCommandExecution(); 74 | } 75 | 76 | [Test(async)] 77 | override public function testFailedExecution():void 78 | { 79 | super.testFailedExecution(); 80 | } 81 | 82 | [Test(async)] 83 | override public function testExecutionWithMacroCommandMap():void 84 | { 85 | super.testExecutionWithMacroCommandMap(); 86 | } 87 | 88 | [Test(async)] 89 | public function testFailExecutionWithAtomicFalse():void 90 | { 91 | var command:SequenceCommand = new commandClass(); 92 | command.atomic = false; 93 | 94 | for (var i:uint = 1; i < 11; i++) 95 | { 96 | var completionDirective:String = i == 2 ? 97 | CompletionDirective.FAILURE : 98 | CompletionDirective.SUCCESS; 99 | command.addCommand(TestAsyncCommand, 100 | new SubcommandConfigEvent(SubcommandConfigEvent.CONFIG, i, 1, completionDirective)); 101 | } 102 | 103 | injector.injectInto(command); 104 | eventDispatcher.addEventListener(SubcommandStatusEvent.EXECUTED, subcommand_statusHandler, false, 0, true); 105 | eventDispatcher.addEventListener(SubcommandStatusEvent.COMPLETE, subcommand_statusHandler, false, 0, true); 106 | 107 | var ids:Vector. = new Vector.(); 108 | ids.push(1); 109 | ids.push(2); // Only the first two commands should execute. 110 | var asyncHandler:Function = Async.asyncHandler(this, 111 | macro_completeHandler, 5000, 112 | {ids: ids}, 113 | macro_timeoutHandler) 114 | eventDispatcher.addEventListener(MacroCommandEvent.COMPLETE, asyncHandler, false, 0, true); 115 | 116 | command.execute(); 117 | } 118 | 119 | override protected function wereSubcommandsExecutedAsExpected(ids:Vector.):Boolean 120 | { 121 | for (var i:uint = 0; i < ids.length; i++) 122 | { 123 | var id:uint = ids[i]; 124 | 125 | var executeEvent:SubcommandStatusEvent = statusEvents[i * 2]; 126 | 127 | if (executeEvent.id != id || executeEvent.type != SubcommandStatusEvent.EXECUTED) 128 | { 129 | return false; 130 | } 131 | 132 | var completeEvent:SubcommandStatusEvent = statusEvents[i * 2 + 1]; 133 | 134 | if (completeEvent.id != id || completeEvent.type != SubcommandStatusEvent.COMPLETE) 135 | { 136 | return false; 137 | } 138 | } 139 | 140 | return true; 141 | } 142 | 143 | } 144 | } -------------------------------------------------------------------------------- /src/test/org/robotlegs/utilities/macrobot/base/MacroTestBase.as: -------------------------------------------------------------------------------- 1 | package test.org.robotlegs.utilities.macrobot.base 2 | { 3 | import flash.display.DisplayObjectContainer; 4 | import flash.display.Sprite; 5 | import flash.events.EventDispatcher; 6 | import flash.events.IEventDispatcher; 7 | 8 | import flexunit.framework.Assert; 9 | 10 | import org.flexunit.async.Async; 11 | import org.robotlegs.adapters.SwiftSuspendersInjector; 12 | import org.robotlegs.adapters.SwiftSuspendersReflector; 13 | import org.robotlegs.base.CommandMap; 14 | import org.robotlegs.base.MediatorMap; 15 | import org.robotlegs.core.ICommandMap; 16 | import org.robotlegs.core.IInjector; 17 | import org.robotlegs.core.IMediatorMap; 18 | import org.robotlegs.core.IReflector; 19 | import org.robotlegs.utilities.macrobot.MacroCommandMap; 20 | import org.robotlegs.utilities.macrobot.core.MacroBase; 21 | 22 | import test.org.robotlegs.utilities.macrobot.support.CompletionDirective; 23 | import test.org.robotlegs.utilities.macrobot.support.MacroCommandEvent; 24 | import test.org.robotlegs.utilities.macrobot.support.SubcommandConfigEvent; 25 | import test.org.robotlegs.utilities.macrobot.support.SubcommandStatusEvent; 26 | import test.org.robotlegs.utilities.macrobot.support.TestAsyncCommand; 27 | import test.org.robotlegs.utilities.macrobot.support.TestMacroCommandMap; 28 | import test.org.robotlegs.utilities.macrobot.support.TestSyncCommand; 29 | 30 | public class MacroTestBase 31 | { 32 | protected var commandClass:Class; 33 | 34 | protected var reflector:IReflector; 35 | protected var injector:IInjector; 36 | protected var commandMap:CommandMap; 37 | protected var eventDispatcher:IEventDispatcher; 38 | protected var statusEvents:Vector.; 39 | 40 | public function setUp():void 41 | { 42 | var contextView:Sprite = new Sprite(); 43 | reflector = new SwiftSuspendersReflector(); 44 | eventDispatcher = new EventDispatcher(); 45 | injector = new SwiftSuspendersInjector(); 46 | injector.mapValue(IInjector, injector); 47 | injector.mapValue(IReflector, reflector); 48 | injector.mapValue(DisplayObjectContainer, contextView); 49 | commandMap = new CommandMap(eventDispatcher, injector, reflector); 50 | injector.mapValue(ICommandMap, commandMap); 51 | injector.mapValue(IEventDispatcher, eventDispatcher); 52 | injector.mapValue(IMediatorMap, new MediatorMap(contextView, injector, reflector)); 53 | 54 | statusEvents = new Vector.() 55 | } 56 | 57 | public function tearDown():void 58 | { 59 | reflector = null; 60 | injector = null; 61 | commandMap = null; 62 | eventDispatcher = null; 63 | statusEvents = null; 64 | } 65 | 66 | public function testSyncCommandInstanceExecution():void 67 | { 68 | var subcommandFactory:Function = function(command:MacroBase, id:uint):void 69 | { 70 | var subcommand:Object = new TestSyncCommand( 71 | new SubcommandConfigEvent(SubcommandConfigEvent.CONFIG, id)); 72 | command.addCommandInstance(subcommand); 73 | } 74 | 75 | testUsingFactory(subcommandFactory); 76 | } 77 | 78 | public function testAsyncCommandInstanceExecution():void 79 | { 80 | var subcommandFactory:Function = function(command:MacroBase, id:uint):void 81 | { 82 | var subcommand:Object = new TestAsyncCommand( 83 | new SubcommandConfigEvent(SubcommandConfigEvent.CONFIG, id)); 84 | command.addCommandInstance(subcommand); 85 | } 86 | 87 | testUsingFactory(subcommandFactory); 88 | } 89 | 90 | public function testAsyncAndSyncCommandInstanceExecution():void 91 | { 92 | var subcommandFactory:Function = function(command:MacroBase, id:uint):void 93 | { 94 | var config:SubcommandConfigEvent = new SubcommandConfigEvent(SubcommandConfigEvent.CONFIG, id); 95 | var subcommand:Object = id % 2 == 0 ? new TestAsyncCommand(config) : new TestSyncCommand(config); 96 | command.addCommandInstance(subcommand); 97 | } 98 | 99 | testUsingFactory(subcommandFactory); 100 | } 101 | 102 | public function testSyncCommandDescriptorExecution():void 103 | { 104 | var subcommandFactory:Function = function(command:MacroBase, id:uint):void 105 | { 106 | command.addCommand(TestSyncCommand, new SubcommandConfigEvent(SubcommandConfigEvent.CONFIG, id)); 107 | } 108 | 109 | testUsingFactory(subcommandFactory); 110 | } 111 | 112 | public function testAsyncCommandDescriptorExecution():void 113 | { 114 | var subcommandFactory:Function = function(command:MacroBase, id:uint):void 115 | { 116 | command.addCommand(TestAsyncCommand, new SubcommandConfigEvent(SubcommandConfigEvent.CONFIG, id)); 117 | } 118 | 119 | testUsingFactory(subcommandFactory); 120 | } 121 | 122 | public function testAsyncAndSyncCommandDescriptorExecution():void 123 | { 124 | var subcommandFactory:Function = function(command:MacroBase, id:uint):void 125 | { 126 | var config:SubcommandConfigEvent = new SubcommandConfigEvent(SubcommandConfigEvent.CONFIG, id); 127 | var subcommandClass:Class = id % 2 == 0 ? TestAsyncCommand : TestSyncCommand; 128 | command.addCommand(subcommandClass, config); 129 | } 130 | 131 | testUsingFactory(subcommandFactory); 132 | } 133 | 134 | public function testNoCommandExecution():void 135 | { 136 | testUsingFactory(null, 0); 137 | } 138 | 139 | public function testFailedExecution():void 140 | { 141 | var command:MacroBase = new commandClass(); 142 | 143 | for (var i:uint = 1; i < 11; i++) 144 | { 145 | var completionDirective:String = i == 2 ? 146 | CompletionDirective.FAILURE : 147 | CompletionDirective.SUCCESS; 148 | command.addCommand(TestAsyncCommand, 149 | new SubcommandConfigEvent(SubcommandConfigEvent.CONFIG, i, 1, completionDirective)); 150 | } 151 | 152 | injector.injectInto(command); 153 | 154 | var asyncHandler:Function = Async.asyncHandler(this, 155 | testFailedExecution_completeHandler, 5000, 156 | null, 157 | macro_timeoutHandler) 158 | eventDispatcher.addEventListener(MacroCommandEvent.COMPLETE, asyncHandler, false, 0, true); 159 | 160 | command.execute(); 161 | } 162 | 163 | public function testExecutionWithMacroCommandMap():void 164 | { 165 | commandMap = new TestMacroCommandMap(eventDispatcher, injector, reflector); 166 | injector.mapValue(ICommandMap, commandMap); 167 | 168 | var subcommandFactory:Function = function(command:MacroBase, id:uint):void 169 | { 170 | var config:SubcommandConfigEvent = new SubcommandConfigEvent(SubcommandConfigEvent.CONFIG, id); 171 | var subcommandClass:Class = id % 2 == 0 ? TestAsyncCommand : TestSyncCommand; 172 | command.addCommand(subcommandClass, config); 173 | } 174 | 175 | testUsingFactory(subcommandFactory, 10, testExecutionWithMacroCommandMap_completeHandler); 176 | } 177 | 178 | protected function testExecutionWithMacroCommandMap_completeHandler(event:MacroCommandEvent, passThru:Object):void 179 | { 180 | macro_completeHandler(event, passThru); 181 | Assert.assertEquals('execute() should not have been called when using MacroCommandMap.', 182 | TestMacroCommandMap(commandMap).executeCallCount, 0); 183 | Assert.assertEquals('prepare() should have been called once for each subcommand.', 184 | TestMacroCommandMap(commandMap).prepareCallCount, 10); 185 | Assert.assertEquals('executePrepared() should have been called once for each subcommand.', 186 | TestMacroCommandMap(commandMap).executePreparedCallCount, 10); 187 | } 188 | 189 | protected function testFailedExecution_completeHandler(event:MacroCommandEvent, passThru:Object):void 190 | { 191 | Assert.assertFalse('The macro command should have failed since a subcommand failed.', event.success); 192 | } 193 | 194 | protected function testUsingFactory(subcommandFactory:Function, numSubcommands:uint = 10, completeHandler:Function = null):void 195 | { 196 | var command:MacroBase = new commandClass(); 197 | var ids:Vector. = new Vector.(); 198 | 199 | for (var i:uint = 1; i < numSubcommands + 1; i++) 200 | { 201 | subcommandFactory(command, i); 202 | ids.push(i); 203 | } 204 | 205 | injector.injectInto(command); 206 | eventDispatcher.addEventListener(SubcommandStatusEvent.EXECUTED, subcommand_statusHandler, false, 0, true); 207 | eventDispatcher.addEventListener(SubcommandStatusEvent.COMPLETE, subcommand_statusHandler, false, 0, true); 208 | 209 | completeHandler ||= macro_completeHandler; 210 | 211 | var asyncHandler:Function = Async.asyncHandler(this, 212 | completeHandler, 5000, 213 | {ids: ids}, 214 | macro_timeoutHandler) 215 | eventDispatcher.addEventListener(MacroCommandEvent.COMPLETE, asyncHandler, false, 0, true); 216 | 217 | command.execute(); 218 | } 219 | 220 | protected function macro_completeHandler(event:MacroCommandEvent, passThru:Object):void 221 | { 222 | Assert.assertEquals('The incorrect number of commands completed.', passThru.ids.length * 2, statusEvents.length); 223 | Assert.assertTrue('Subcommands were not completed as expected.', wereSubcommandsExecutedAsExpected(passThru.ids)); 224 | } 225 | 226 | protected function macro_timeoutHandler(passThru:Object):void 227 | { 228 | Assert.fail('Macro command did not complete.'); 229 | } 230 | 231 | protected function wereSubcommandsExecutedAsExpected(ids:Vector.):Boolean 232 | { 233 | // to be overridden 234 | return true; 235 | } 236 | 237 | protected function subcommand_statusHandler(event:SubcommandStatusEvent):void 238 | { 239 | if (statusEvents) 240 | { 241 | statusEvents.push(event); 242 | } 243 | } 244 | } 245 | } -------------------------------------------------------------------------------- /src/test/org/robotlegs/utilities/macrobot/support/CompletionDirective.as: -------------------------------------------------------------------------------- 1 | package test.org.robotlegs.utilities.macrobot.support 2 | { 3 | public class CompletionDirective 4 | { 5 | public static const SUCCESS:String = 'success'; 6 | public static const FAILURE:String = 'failure'; 7 | public static const PREVENT_COMPLETION:String = 'preventCompletion'; 8 | } 9 | } -------------------------------------------------------------------------------- /src/test/org/robotlegs/utilities/macrobot/support/MacroCommandEvent.as: -------------------------------------------------------------------------------- 1 | package test.org.robotlegs.utilities.macrobot.support 2 | { 3 | import flash.events.Event; 4 | 5 | public class MacroCommandEvent extends Event 6 | { 7 | public static const COMPLETE:String = 'macroCommandComplete'; 8 | 9 | public var success:Boolean; 10 | 11 | public function MacroCommandEvent(type:String, success:Boolean, bubbles:Boolean=false, cancelable:Boolean=false) 12 | { 13 | super(type, bubbles, cancelable); 14 | this.success = success; 15 | } 16 | 17 | override public function clone():Event 18 | { 19 | return new MacroCommandEvent(type, success, bubbles, cancelable); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/test/org/robotlegs/utilities/macrobot/support/SubcommandConfigEvent.as: -------------------------------------------------------------------------------- 1 | package test.org.robotlegs.utilities.macrobot.support 2 | { 3 | import flash.events.Event; 4 | 5 | public class SubcommandConfigEvent extends Event 6 | { 7 | public static const CONFIG:String = 'config'; 8 | 9 | public var id:uint; 10 | public var asyncDelay:uint; 11 | public var completionDirective:String; 12 | 13 | public function SubcommandConfigEvent(type:String, id:uint = 0, asyncDelay:uint = 1, 14 | completionDirective:String = 'success', 15 | bubbles:Boolean=false, cancelable:Boolean=false) 16 | { 17 | super(type, bubbles, cancelable); 18 | this.id = id; 19 | this.asyncDelay = asyncDelay; 20 | this.completionDirective = completionDirective; 21 | } 22 | 23 | override public function clone():Event 24 | { 25 | return new SubcommandConfigEvent(type, id, asyncDelay, completionDirective, bubbles, cancelable); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/test/org/robotlegs/utilities/macrobot/support/SubcommandStatusEvent.as: -------------------------------------------------------------------------------- 1 | package test.org.robotlegs.utilities.macrobot.support 2 | { 3 | import flash.events.Event; 4 | 5 | public class SubcommandStatusEvent extends Event 6 | { 7 | public static const EXECUTED:String = 'subcommandExecuted'; 8 | public static const COMPLETE:String = 'subcommandComplete'; 9 | 10 | public var id:uint; 11 | 12 | public function SubcommandStatusEvent(type:String, id:uint, bubbles:Boolean=false, cancelable:Boolean=false) 13 | { 14 | super(type, bubbles, cancelable); 15 | this.id = id; 16 | } 17 | 18 | override public function clone():Event 19 | { 20 | return new SubcommandStatusEvent(type, id, bubbles, cancelable); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/test/org/robotlegs/utilities/macrobot/support/TestAsyncCommand.as: -------------------------------------------------------------------------------- 1 | package test.org.robotlegs.utilities.macrobot.support 2 | { 3 | import flash.events.Event; 4 | import flash.events.TimerEvent; 5 | import flash.utils.Timer; 6 | 7 | import org.robotlegs.utilities.macrobot.AsyncCommand; 8 | 9 | public class TestAsyncCommand extends AsyncCommand 10 | { 11 | public var event:SubcommandConfigEvent; 12 | protected var timer:Timer; 13 | 14 | public function TestAsyncCommand(event:SubcommandConfigEvent) 15 | { 16 | super(); 17 | this.event = event; 18 | } 19 | 20 | override public function execute():void 21 | { 22 | dispatch(new SubcommandStatusEvent(SubcommandStatusEvent.EXECUTED, event.id)); 23 | 24 | super.execute(); 25 | 26 | if (event.asyncDelay == 0) 27 | { 28 | handleCompletion(); 29 | } 30 | else 31 | { 32 | timer = new Timer(event.asyncDelay, 1); 33 | timer.addEventListener(TimerEvent.TIMER_COMPLETE, timer_completeHandler); 34 | timer.start(); 35 | } 36 | } 37 | 38 | protected function timer_completeHandler(e:TimerEvent):void 39 | { 40 | timer.removeEventListener(TimerEvent.TIMER_COMPLETE, timer_completeHandler); 41 | timer = null; 42 | handleCompletion(); 43 | } 44 | 45 | protected function handleCompletion():void 46 | { 47 | if (event.completionDirective != CompletionDirective.PREVENT_COMPLETION) 48 | { 49 | dispatchComplete(event.completionDirective == CompletionDirective.SUCCESS); 50 | } 51 | } 52 | 53 | override protected function dispatchComplete(success:Boolean):void 54 | { 55 | dispatch(new SubcommandStatusEvent(SubcommandStatusEvent.COMPLETE, event.id)); 56 | super.dispatchComplete(success); 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /src/test/org/robotlegs/utilities/macrobot/support/TestCommandMap.as: -------------------------------------------------------------------------------- 1 | package test.org.robotlegs.utilities.macrobot.support 2 | { 3 | import flash.events.IEventDispatcher; 4 | 5 | import org.robotlegs.base.CommandMap; 6 | import org.robotlegs.core.IInjector; 7 | import org.robotlegs.core.IReflector; 8 | 9 | public class TestCommandMap extends CommandMap 10 | { 11 | public function TestCommandMap(eventDispatcher:IEventDispatcher, injector:IInjector, reflector:IReflector) 12 | { 13 | super(eventDispatcher, injector, reflector); 14 | } 15 | 16 | public function get isCommandDetained():Boolean 17 | { 18 | for (var command:* in detainedCommands) 19 | { 20 | return true; 21 | } 22 | return false; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/test/org/robotlegs/utilities/macrobot/support/TestMacroBase.as: -------------------------------------------------------------------------------- 1 | package test.org.robotlegs.utilities.macrobot.support 2 | { 3 | import org.robotlegs.utilities.macrobot.core.MacroBase; 4 | 5 | public class TestMacroBase extends MacroBase 6 | { 7 | override public function execute():void 8 | { 9 | super.execute(); 10 | for each (var commandOrDescriptor:Object in commands) 11 | { 12 | executeCommand(commandOrDescriptor); 13 | } 14 | } 15 | 16 | public function getSubcommands():Array 17 | { 18 | return commands; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/test/org/robotlegs/utilities/macrobot/support/TestMacroCommandMap.as: -------------------------------------------------------------------------------- 1 | package test.org.robotlegs.utilities.macrobot.support 2 | { 3 | import flash.events.IEventDispatcher; 4 | 5 | import org.robotlegs.core.IInjector; 6 | import org.robotlegs.core.IReflector; 7 | import org.robotlegs.utilities.macrobot.MacroCommandMap; 8 | 9 | public class TestMacroCommandMap extends MacroCommandMap 10 | { 11 | public var executeCallCount:uint; 12 | public var executePreparedCallCount:uint; 13 | public var prepareCallCount:uint; 14 | 15 | public function TestMacroCommandMap(eventDispatcher:IEventDispatcher, injector:IInjector, reflector:IReflector) 16 | { 17 | super(eventDispatcher, injector, reflector); 18 | } 19 | 20 | override public function execute(commandClass:Class, payload:Object=null, payloadClass:Class=null, named:String=""):void 21 | { 22 | executeCallCount++; 23 | super.execute(commandClass, payload, payloadClass, named); 24 | } 25 | 26 | override public function executePrepared(command:Object):void 27 | { 28 | executePreparedCallCount++; 29 | super.executePrepared(command); 30 | } 31 | 32 | override public function prepare(commandClass:Class, payload:Object=null, payloadClass:Class=null, named:String=''):Object 33 | { 34 | prepareCallCount++; 35 | return super.prepare(commandClass, payload, payloadClass, named); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/test/org/robotlegs/utilities/macrobot/support/TestParallelCommand.as: -------------------------------------------------------------------------------- 1 | package test.org.robotlegs.utilities.macrobot.support 2 | { 3 | import org.robotlegs.utilities.macrobot.ParallelCommand; 4 | 5 | public class TestParallelCommand extends ParallelCommand 6 | { 7 | override protected function dispatchComplete(success:Boolean):void 8 | { 9 | super.dispatchComplete(success); 10 | dispatch(new MacroCommandEvent(MacroCommandEvent.COMPLETE, success)); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/test/org/robotlegs/utilities/macrobot/support/TestSequenceCommand.as: -------------------------------------------------------------------------------- 1 | package test.org.robotlegs.utilities.macrobot.support 2 | { 3 | import org.robotlegs.utilities.macrobot.SequenceCommand; 4 | 5 | public class TestSequenceCommand extends SequenceCommand 6 | { 7 | override protected function dispatchComplete(success:Boolean):void 8 | { 9 | super.dispatchComplete(success); 10 | dispatch(new MacroCommandEvent(MacroCommandEvent.COMPLETE, success)); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/test/org/robotlegs/utilities/macrobot/support/TestSyncCommand.as: -------------------------------------------------------------------------------- 1 | package test.org.robotlegs.utilities.macrobot.support 2 | { 3 | import org.robotlegs.mvcs.Command; 4 | 5 | public class TestSyncCommand extends Command 6 | { 7 | protected var event:SubcommandConfigEvent; 8 | 9 | public function TestSyncCommand(event:SubcommandConfigEvent) 10 | { 11 | super(); 12 | this.event = event; 13 | } 14 | 15 | override public function execute():void 16 | { 17 | dispatch(new SubcommandStatusEvent(SubcommandStatusEvent.EXECUTED, event.id)); 18 | dispatch(new SubcommandStatusEvent(SubcommandStatusEvent.COMPLETE, event.id)); 19 | super.execute(); 20 | } 21 | } 22 | } --------------------------------------------------------------------------------