@@ 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 CreateTestEnv_Command extends CliCommand |
|
64 | { |
|
65 | public function __construct() |
|
66 | { |
|
67 | // define the command |
|
68 | $this->setName('create-test-env'); |
|
69 | $this->setShortDescription('create a new test environment file'); |
|
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 | "namedEnv.php" => "the Env.php file to create" |
|
78 | )); |
|
79 | $this->setSwitches(array( |
|
80 | new CreateTestEnv_BasedOnSwitch, |
|
81 | new CreateTestEnv_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 TEARDOWN |
|
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 |