| @@ 62-348 (lines=287) @@ | ||
| 59 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License |
|
| 60 | * @link http://datasift.github.io/storyplayer |
|
| 61 | */ |
|
| 62 | class CreateStory_Command extends CliCommand |
|
| 63 | { |
|
| 64 | public function __construct() |
|
| 65 | { |
|
| 66 | // define the command |
|
| 67 | $this->setName('create-story'); |
|
| 68 | $this->setShortDescription('create a new story'); |
|
| 69 | $this->setLongDescription( |
|
| 70 | "Use this command to create a new Story.php file, complete with " |
|
| 71 | ."the necessary PHP 'use' statement and comments to help guide you " |
|
| 72 | ."as you bring your story to life." |
|
| 73 | .PHP_EOL |
|
| 74 | ); |
|
| 75 | $this->setArgsList(array( |
|
| 76 | "namedStory.php" => "the story.php file to create" |
|
| 77 | )); |
|
| 78 | $this->setSwitches(array( |
|
| 79 | new CreateStory_BasedOnSwitch, |
|
| 80 | new CreateStory_ForceSwitch |
|
| 81 | )); |
|
| 82 | } |
|
| 83 | ||
| 84 | /** |
|
| 85 | * |
|
| 86 | * @param CliEngine $engine |
|
| 87 | * @param array $params |
|
| 88 | * @param mixed $additionalContext |
|
| 89 | * @return int |
|
| 90 | */ |
|
| 91 | public function processCommand(CliEngine $engine, $params = array(), $additionalContext = null) |
|
| 92 | { |
|
| 93 | // do we have the name of the file to create? |
|
| 94 | if (!isset($params[0])) { |
|
| 95 | echo "*** error: you must specify which story to create\n"; |
|
| 96 | exit(1); |
|
| 97 | } |
|
| 98 | ||
| 99 | // we're going to be dealing with some prehistoric parts of PHP |
|
| 100 | $legacyHandler = new Legacy_ErrorHandler(); |
|
| 101 | ||
| 102 | // create the path to the story |
|
| 103 | $storyFolder = dirname($params[0]); |
|
| 104 | if (!file_exists($storyFolder)) { |
|
| 105 | try { |
|
| 106 | $legacyHandler->run(function() use ($storyFolder) { |
|
| 107 | mkdir($storyFolder, 0755, true); |
|
| 108 | }); |
|
| 109 | } |
|
| 110 | catch (Exception $e) { |
|
| 111 | echo "*** error: unable to create folder '{$storyFolder}'\n"; |
|
| 112 | exit(1); |
|
| 113 | } |
|
| 114 | } |
|
| 115 | ||
| 116 | // create the story inside the folder |
|
| 117 | $story = <<<EOS |
|
| 118 | <?php |
|
| 119 | ||
| 120 | use Storyplayer\SPv2\Modules\Asserts; |
|
| 121 | use Storyplayer\SPv2\Modules\Checkpoint; |
|
| 122 | use Storyplayer\SPv2\Modules\Log; |
|
| 123 | use Storyplayer\SPv2\Stories\BuildStory; |
|
| 124 | ||
| 125 | EOS; |
|
| 126 | ||
| 127 | if (isset($engine->options->basedOn)) { |
|
| 128 | foreach ($engine->options->basedOn as $templateClass) { |
|
| 129 | $story .= "use {$templateClass};\n"; |
|
| 130 | } |
|
| 131 | } |
|
| 132 | $story .= <<<EOS |
|
| 133 | ||
| 134 | // ======================================================================== |
|
| 135 | // |
|
| 136 | // STORY DETAILS |
|
| 137 | // |
|
| 138 | // ------------------------------------------------------------------------ |
|
| 139 | ||
| 140 | \$story = BuildStory::newStory(); |
|
| 141 | EOS; |
|
| 142 | ||
| 143 | if (isset($engine->options->basedOn)) { |
|
| 144 | foreach ($engine->options->basedOn as $templateClass) { |
|
| 145 | $story .= "\n\$story->basedOn(new " . basename(str_replace('\\', '/', $templateClass)) . ");"; |
|
| 146 | } |
|
| 147 | } |
|
| 148 | ||
| 149 | $story .= <<<EOS |
|
| 150 | ||
| 151 | ||
| 152 | /** |
|
| 153 | * the scenario uses Ubquitous Language to describe what you are testing |
|
| 154 | * |
|
| 155 | * unlike other test tools, Storyplayer does not parse your scenario in any way |
|
| 156 | * it is only used for display purposes, to make your test self-documenting |
|
| 157 | * |
|
| 158 | * INSTRUCTIONS: |
|
| 159 | * |
|
| 160 | * pick one of the formats below that best fits your test, |
|
| 161 | * edit to suit, |
|
| 162 | * and delete the other scenario format(s) |
|
| 163 | */ |
|
| 164 | ||
| 165 | // this format suits a functional test |
|
| 166 | \$story->setScenario([ |
|
| 167 | // what are the pre-conditions? |
|
| 168 | "given:", |
|
| 169 | "- first pre-condition", |
|
| 170 | "- second pre-condition", |
|
| 171 | // how will the actions be performed? |
|
| 172 | // e.g. using a browser, or an API, |
|
| 173 | "using ...", |
|
| 174 | // who or what is performing the actions? |
|
| 175 | "as ...", |
|
| 176 | // what functionality is being tested? |
|
| 177 | "I can ...", |
|
| 178 | "even if:", |
|
| 179 | "- pre-condition", |
|
| 180 | // has anything changed as a result of the actions? |
|
| 181 | // if so, list each expected change here |
|
| 182 | "afterwards:", |
|
| 183 | "- XXX will exist in the database" |
|
| 184 | ]); |
|
| 185 | ||
| 186 | // this format suits a test that focuses on checking for a specific consequence |
|
| 187 | // of an action (e.g. testing robustness or correctness) |
|
| 188 | \$story->setScenario([ |
|
| 189 | // what are the pre-conditions? |
|
| 190 | "given:", |
|
| 191 | "- first pre-condition", |
|
| 192 | "- second pre-condition", |
|
| 193 | // how will the actions be performed? |
|
| 194 | // e.g. using a browser, or an API, |
|
| 195 | "using ...", |
|
| 196 | // who or what is performing the actions? |
|
| 197 | "as ...", |
|
| 198 | // what output do I expect? |
|
| 199 | "if I ...", |
|
| 200 | "- I get XXX", // e.g. HTTP 404 |
|
| 201 | "even if:", |
|
| 202 | "- first pre-condition", |
|
| 203 | // has anything changed as a result of the actions? |
|
| 204 | // if so, list each expected change here |
|
| 205 | "afterwards:", |
|
| 206 | "- XXX will exist in the database" |
|
| 207 | ]); |
|
| 208 | ||
| 209 | // ======================================================================== |
|
| 210 | // |
|
| 211 | // TEST SETUP / TEAR-DOWN |
|
| 212 | // |
|
| 213 | // ------------------------------------------------------------------------ |
|
| 214 | ||
| 215 | /* |
|
| 216 | \$story->addTestSetup(function() { |
|
| 217 | // what are we doing? |
|
| 218 | \$log = Log::usingLog()->startAction("describe what we are doing"); |
|
| 219 | ||
| 220 | // setup the conditions for this specific test |
|
| 221 | \$checkpoint = Checkpoint::getCheckpoint(); |
|
| 222 | ||
| 223 | // all done |
|
| 224 | \$log->endAction(); |
|
| 225 | }); |
|
| 226 | */ |
|
| 227 | ||
| 228 | /* |
|
| 229 | \$story->addTestTeardown(function() { |
|
| 230 | // what are we doing? |
|
| 231 | \$log = Log::usingLog()->startAction("describe what we are doing"); |
|
| 232 | ||
| 233 | // undo anything that you did in addTestSetup() |
|
| 234 | ||
| 235 | // all done |
|
| 236 | \$log->endAction(); |
|
| 237 | }); |
|
| 238 | */ |
|
| 239 | ||
| 240 | // ======================================================================== |
|
| 241 | // |
|
| 242 | // PRE-TEST PREDICTION |
|
| 243 | // |
|
| 244 | // ------------------------------------------------------------------------ |
|
| 245 | ||
| 246 | /* |
|
| 247 | \$story->addPreTestPrediction(function() { |
|
| 248 | // what are we doing? |
|
| 249 | \$log = Log::usingLog()->startAction("describe what we are doing"); |
|
| 250 | ||
| 251 | // if it is okay for your story to fail, detect that here |
|
| 252 | ||
| 253 | // all done |
|
| 254 | \$log->endAction(); |
|
| 255 | }); |
|
| 256 | */ |
|
| 257 | ||
| 258 | // ======================================================================== |
|
| 259 | // |
|
| 260 | // PRE-TEST INSPECTION |
|
| 261 | // |
|
| 262 | // ------------------------------------------------------------------------ |
|
| 263 | ||
| 264 | /* |
|
| 265 | \$story->addPreTestInspection(function() { |
|
| 266 | // what are we doing? |
|
| 267 | \$log = Log::usingLog()->startAction("describe what we are doing"); |
|
| 268 | ||
| 269 | // get the checkpoint - we're going to store data in here |
|
| 270 | \$checkpoint = Checkpoint::getCheckpoint(); |
|
| 271 | ||
| 272 | // store any data that your story is about to change, so that you |
|
| 273 | // can do a before and after comparison |
|
| 274 | ||
| 275 | // all done |
|
| 276 | \$log->endAction(); |
|
| 277 | }); |
|
| 278 | */ |
|
| 279 | ||
| 280 | // ======================================================================== |
|
| 281 | // |
|
| 282 | // ACTIONS |
|
| 283 | // |
|
| 284 | // ------------------------------------------------------------------------ |
|
| 285 | ||
| 286 | /* |
|
| 287 | \$story->addAction(function() { |
|
| 288 | // what are we doing? |
|
| 289 | \$log = Log::usingLog()->startAction("describe what we are doing"); |
|
| 290 | ||
| 291 | // use the checkpoint to store any data collected during the action |
|
| 292 | // this data will be examined in the postTestInspection phase |
|
| 293 | \$checkpoint = Checkpoint::getCheckpoint(); |
|
| 294 | ||
| 295 | // this is where you perform the steps of your user story |
|
| 296 | ||
| 297 | // all done |
|
| 298 | \$log->endAction(); |
|
| 299 | }); |
|
| 300 | */ |
|
| 301 | ||
| 302 | // ======================================================================== |
|
| 303 | // |
|
| 304 | // POST-TEST INSPECTION |
|
| 305 | // |
|
| 306 | // ------------------------------------------------------------------------ |
|
| 307 | ||
| 308 | \$story->addPostTestInspection(function() { |
|
| 309 | // what are we doing? |
|
| 310 | \$log = Log::usingLog()->startAction("describe what we are doing"); |
|
| 311 | ||
| 312 | // the information to guide our checks is in the checkpoint |
|
| 313 | \$checkpoint = Checkpoint::getCheckpoint(); |
|
| 314 | ||
| 315 | // gather new data, and make sure that your action actually changed |
|
| 316 | // something. never assume that the action worked just because it |
|
| 317 | // completed to the end with no errors or exceptions! |
|
| 318 | ||
| 319 | // all done |
|
| 320 | \$log->endAction(); |
|
| 321 | }); |
|
| 322 | ||
| 323 | EOS; |
|
| 324 | ||
| 325 | // does the file already exist? |
|
| 326 | if (file_exists($params[0])) { |
|
| 327 | // has the user used --force? |
|
| 328 | if (!isset($engine->options->force) || !$engine->options->force) { |
|
| 329 | echo "*** error: file '{$params[0]}' already exists\n"; |
|
| 330 | echo "use --force to replace this file with the new story file\n"; |
|
| 331 | exit(1); |
|
| 332 | } |
|
| 333 | } |
|
| 334 | ||
| 335 | try { |
|
| 336 | $legacyHandler->run(function() use($params, $story) { |
|
| 337 | file_put_contents($params[0], $story); |
|
| 338 | }); |
|
| 339 | } |
|
| 340 | catch (Exception $e) { |
|
| 341 | echo "*** error: " . $e->getMessage() . "\n"; |
|
| 342 | exit(1); |
|
| 343 | } |
|
| 344 | ||
| 345 | // all done |
|
| 346 | return 0; |
|
| 347 | } |
|
| 348 | } |
|
| 349 | ||
| @@ 63-227 (lines=165) @@ | ||
| 60 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License |
|
| 61 | * @link http://datasift.github.io/storyplayer |
|
| 62 | */ |
|
| 63 | class CreateTestEnvironment_Command extends CliCommand |
|
| 64 | { |
|
| 65 | public function __construct() |
|
| 66 | { |
|
| 67 | // define the command |
|
| 68 | $this->setName('create-test-environment'); |
|
| 69 | $this->setShortDescription('create a new test environment'); |
|
| 70 | $this->setLongDescription( |
|
| 71 | "Use this command to create a new Env.php file, complete with " |
|
| 72 | ."the necessary PHP 'use' statement and comments to help guide you " |
|
| 73 | ."as you bring your story to life." |
|
| 74 | .PHP_EOL |
|
| 75 | ); |
|
| 76 | $this->setArgsList(array( |
|
| 77 | "namedEnvironment.php" => "the Env.php file to create" |
|
| 78 | )); |
|
| 79 | $this->setSwitches(array( |
|
| 80 | new CreateTestEnvironment_BasedOnSwitch, |
|
| 81 | new CreateTestEnvironment_ForceSwitch |
|
| 82 | )); |
|
| 83 | } |
|
| 84 | ||
| 85 | /** |
|
| 86 | * |
|
| 87 | * @param CliEngine $engine |
|
| 88 | * @param array $params |
|
| 89 | * @param mixed $additionalContext |
|
| 90 | * @return int |
|
| 91 | */ |
|
| 92 | public function processCommand(CliEngine $engine, $params = array(), $additionalContext = null) |
|
| 93 | { |
|
| 94 | // do we have the name of the file to create? |
|
| 95 | if (!isset($params[0])) { |
|
| 96 | echo "*** error: you must specify which Env.php file to create\n"; |
|
| 97 | exit(1); |
|
| 98 | } |
|
| 99 | ||
| 100 | // we're going to be dealing with some prehistoric parts of PHP |
|
| 101 | $legacyHandler = new Legacy_ErrorHandler(); |
|
| 102 | ||
| 103 | // create the path to the environment |
|
| 104 | $storyFolder = dirname($params[0]); |
|
| 105 | if (!file_exists($storyFolder)) { |
|
| 106 | try { |
|
| 107 | $legacyHandler->run(function() use ($storyFolder) { |
|
| 108 | mkdir($storyFolder, 0755, true); |
|
| 109 | }); |
|
| 110 | } |
|
| 111 | catch (Exception $e) { |
|
| 112 | echo "*** error: unable to create folder '{$storyFolder}'\n"; |
|
| 113 | exit(1); |
|
| 114 | } |
|
| 115 | } |
|
| 116 | ||
| 117 | // create the environment inside the folder |
|
| 118 | $env = <<<EOS |
|
| 119 | <?php |
|
| 120 | ||
| 121 | use Storyplayer\SPv3\Modules\Asserts; |
|
| 122 | use Storyplayer\SPv3\Modules\Checkpoint; |
|
| 123 | use Storyplayer\SPv3\Modules\Log; |
|
| 124 | use Storyplayer\SPv3\Stories\BuildTestEnvironment; |
|
| 125 | ||
| 126 | EOS; |
|
| 127 | ||
| 128 | if (isset($engine->options->basedOn)) { |
|
| 129 | foreach ($engine->options->basedOn as $templateClass) { |
|
| 130 | $story .= "use {$templateClass};\n"; |
|
| 131 | } |
|
| 132 | } |
|
| 133 | $env .= <<<EOS |
|
| 134 | ||
| 135 | // ======================================================================== |
|
| 136 | // |
|
| 137 | // TEST ENVIRONMENT DETAILS |
|
| 138 | // |
|
| 139 | // ------------------------------------------------------------------------ |
|
| 140 | ||
| 141 | \$env = BuildTestEnvironment::newTestEnvironment(); |
|
| 142 | EOS; |
|
| 143 | ||
| 144 | if (isset($engine->options->basedOn)) { |
|
| 145 | foreach ($engine->options->basedOn as $templateClass) { |
|
| 146 | $story .= "\n\$env->basedOn(new " . basename(str_replace('\\', '/', $templateClass)) . ");"; |
|
| 147 | } |
|
| 148 | } |
|
| 149 | ||
| 150 | $env .= <<<EOS |
|
| 151 | ||
| 152 | ||
| 153 | // ======================================================================== |
|
| 154 | // |
|
| 155 | // TEST ENVIRONMENT SETUP |
|
| 156 | // |
|
| 157 | // Add one function per step. This makes it easier to debug and maintain |
|
| 158 | // your test environment construction. |
|
| 159 | // |
|
| 160 | // ------------------------------------------------------------------------ |
|
| 161 | ||
| 162 | \$env->addTestEnvironmentSetup(function() { |
|
| 163 | // what are we doing? |
|
| 164 | \$log = Log::usingLog()->startAction("describe what we are doing"); |
|
| 165 | ||
| 166 | // add the instructions required to build the environment |
|
| 167 | ||
| 168 | // all done |
|
| 169 | \$log->endAction(); |
|
| 170 | }); |
|
| 171 | ||
| 172 | // ======================================================================== |
|
| 173 | // |
|
| 174 | // TEST ENVIRONMENT SETUP |
|
| 175 | // |
|
| 176 | // Add one function per step. This makes it easier to debug and maintain |
|
| 177 | // your test environment cleanup. |
|
| 178 | // |
|
| 179 | // ------------------------------------------------------------------------ |
|
| 180 | ||
| 181 | \$env->addTestEnvironmentTeardown(function() { |
|
| 182 | // what are we doing? |
|
| 183 | \$log = Log::usingLog()->startAction("describe what we are doing"); |
|
| 184 | ||
| 185 | // undo anything that you did in addTestEnvironmentSetup() |
|
| 186 | ||
| 187 | // all done |
|
| 188 | \$log->endAction(); |
|
| 189 | }); |
|
| 190 | ||
| 191 | // ======================================================================== |
|
| 192 | // |
|
| 193 | // ALL DONE |
|
| 194 | // |
|
| 195 | // Return your constructed test environment object, for Storyplayer |
|
| 196 | // to execute. |
|
| 197 | // |
|
| 198 | // ------------------------------------------------------------------------ |
|
| 199 | ||
| 200 | return $env; |
|
| 201 | ||
| 202 | EOS; |
|
| 203 | ||
| 204 | // does the file already exist? |
|
| 205 | if (file_exists($params[0])) { |
|
| 206 | // has the user used --force? |
|
| 207 | if (!isset($engine->options->force) || !$engine->options->force) { |
|
| 208 | echo "*** error: file '{$params[0]}' already exists\n"; |
|
| 209 | echo "use --force to replace this file with the new Env.php file\n"; |
|
| 210 | exit(1); |
|
| 211 | } |
|
| 212 | } |
|
| 213 | ||
| 214 | try { |
|
| 215 | $legacyHandler->run(function() use($params, $env) { |
|
| 216 | file_put_contents($params[0], $env); |
|
| 217 | }); |
|
| 218 | } |
|
| 219 | catch (Exception $e) { |
|
| 220 | echo "*** error: " . $e->getMessage() . "\n"; |
|
| 221 | exit(1); |
|
| 222 | } |
|
| 223 | ||
| 224 | // all done |
|
| 225 | return 0; |
|
| 226 | } |
|
| 227 | } |
|
| 228 | ||