Conditions | 12 |
Paths | 42 |
Total Lines | 257 |
Code Lines | 40 |
Lines | 257 |
Ratio | 100 % |
Changes | 4 | ||
Bugs | 1 | Features | 1 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
1 | <?php |
||
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 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.