comparison cake/tests/cases/console/libs/tasks/test.test.php @ 0:261e66bd5a0c

hg init
author Shoshi TAMAKI <shoshi@cr.ie.u-ryukyu.ac.jp>
date Sun, 24 Jul 2011 21:08:31 +0900
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:261e66bd5a0c
1 <?php
2 /**
3 * TestTaskTest file
4 *
5 * Test Case for test generation shell task
6 *
7 * PHP versions 4 and 5
8 *
9 * CakePHP : Rapid Development Framework (http://cakephp.org)
10 * Copyright 2006-2010, Cake Software Foundation, Inc.
11 *
12 * Licensed under The MIT License
13 * Redistributions of files must retain the above copyright notice.
14 *
15 * @copyright Copyright 2006-2010, Cake Software Foundation, Inc.
16 * @link http://cakephp.org CakePHP Project
17 * @package cake
18 * @subpackage cake.tests.cases.console.libs.tasks
19 * @since CakePHP v 1.2.0.7726
20 * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
21 */
22 App::import('Shell', 'Shell', false);
23 App::import('Controller', 'Controller', false);
24 App::import('Model', 'Model', false);
25
26 if (!defined('DISABLE_AUTO_DISPATCH')) {
27 define('DISABLE_AUTO_DISPATCH', true);
28 }
29
30 if (!class_exists('ShellDispatcher')) {
31 ob_start();
32 $argv = false;
33 require CAKE . 'console' . DS . 'cake.php';
34 ob_end_clean();
35 }
36
37 require_once CAKE . 'console' . DS . 'libs' . DS . 'tasks' . DS . 'test.php';
38 require_once CAKE . 'console' . DS . 'libs' . DS . 'tasks' . DS . 'template.php';
39
40
41 Mock::generatePartial(
42 'ShellDispatcher', 'TestTestTaskMockShellDispatcher',
43 array('getInput', 'stdout', 'stderr', '_stop', '_initEnvironment')
44 );
45 Mock::generatePartial(
46 'TestTask', 'MockTestTask',
47 array('in', '_stop', 'err', 'out', 'hr', 'createFile', 'isLoadableClass')
48 );
49
50 /**
51 * Test Article model
52 *
53 * @package cake
54 * @subpackage cake.tests.cases.console.libs.tasks
55 */
56 class TestTaskArticle extends Model {
57
58 /**
59 * Model name
60 *
61 * @var string
62 * @access public
63 */
64 var $name = 'TestTaskArticle';
65
66 /**
67 * Table name to use
68 *
69 * @var string
70 * @access public
71 */
72 var $useTable = 'articles';
73
74 /**
75 * HasMany Associations
76 *
77 * @var array
78 * @access public
79 */
80 var $hasMany = array(
81 'Comment' => array(
82 'className' => 'TestTask.TestTaskComment',
83 'foreignKey' => 'article_id',
84 )
85 );
86
87 /**
88 * Has and Belongs To Many Associations
89 *
90 * @var array
91 * @access public
92 */
93 var $hasAndBelongsToMany = array(
94 'Tag' => array(
95 'className' => 'TestTaskTag',
96 'joinTable' => 'articles_tags',
97 'foreignKey' => 'article_id',
98 'associationForeignKey' => 'tag_id'
99 )
100 );
101
102 /**
103 * Example public method
104 *
105 * @return void
106 * @access public
107 */
108 function doSomething() {
109 }
110
111 /**
112 * Example Secondary public method
113 *
114 * @return void
115 * @access public
116 */
117 function doSomethingElse() {
118 }
119
120 /**
121 * Example protected method
122 *
123 * @return void
124 * @access protected
125 */
126 function _innerMethod() {
127 }
128 }
129
130 /**
131 * Tag Testing Model
132 *
133 * @package cake
134 * @subpackage cake.tests.cases.console.libs.tasks
135 */
136 class TestTaskTag extends Model {
137
138 /**
139 * Model name
140 *
141 * @var string
142 * @access public
143 */
144 var $name = 'TestTaskTag';
145
146 /**
147 * Table name
148 *
149 * @var string
150 * @access public
151 */
152 var $useTable = 'tags';
153
154 /**
155 * Has and Belongs To Many Associations
156 *
157 * @var array
158 * @access public
159 */
160 var $hasAndBelongsToMany = array(
161 'Article' => array(
162 'className' => 'TestTaskArticle',
163 'joinTable' => 'articles_tags',
164 'foreignKey' => 'tag_id',
165 'associationForeignKey' => 'article_id'
166 )
167 );
168 }
169
170 /**
171 * Simulated plugin
172 *
173 * @package cake
174 * @subpackage cake.tests.cases.console.libs.tasks
175 */
176 class TestTaskAppModel extends Model {
177 }
178
179 /**
180 * Testing AppMode (TaskComment)
181 *
182 * @package cake
183 * @subpackage cake.tests.cases.console.libs.tasks
184 */
185 class TestTaskComment extends TestTaskAppModel {
186
187 /**
188 * Model name
189 *
190 * @var string
191 * @access public
192 */
193 var $name = 'TestTaskComment';
194
195 /**
196 * Table name
197 *
198 * @var string
199 * @access public
200 */
201 var $useTable = 'comments';
202
203 /**
204 * Belongs To Associations
205 *
206 * @var array
207 * @access public
208 */
209 var $belongsTo = array(
210 'Article' => array(
211 'className' => 'TestTaskArticle',
212 'foreignKey' => 'article_id',
213 )
214 );
215 }
216
217 /**
218 * Test Task Comments Controller
219 *
220 * @package cake
221 * @subpackage cake.tests.cases.console.libs.tasks
222 */
223 class TestTaskCommentsController extends Controller {
224
225 /**
226 * Controller Name
227 *
228 * @var string
229 * @access public
230 */
231 var $name = 'TestTaskComments';
232
233 /**
234 * Models to use
235 *
236 * @var array
237 * @access public
238 */
239 var $uses = array('TestTaskComment', 'TestTaskTag');
240 }
241
242 /**
243 * TestTaskTest class
244 *
245 * @package cake
246 * @subpackage cake.tests.cases.console.libs.tasks
247 */
248 class TestTaskTest extends CakeTestCase {
249
250 /**
251 * Fixtures
252 *
253 * @var string
254 * @access public
255 */
256 var $fixtures = array('core.article', 'core.comment', 'core.articles_tag', 'core.tag');
257
258 /**
259 * startTest method
260 *
261 * @return void
262 * @access public
263 */
264 function startTest() {
265 $this->Dispatcher =& new TestTestTaskMockShellDispatcher();
266 $this->Dispatcher->shellPaths = App::path('shells');
267 $this->Task =& new MockTestTask($this->Dispatcher);
268 $this->Task->name = 'TestTask';
269 $this->Task->Dispatch =& $this->Dispatcher;
270 $this->Task->Template =& new TemplateTask($this->Dispatcher);
271 }
272
273 /**
274 * endTest method
275 *
276 * @return void
277 * @access public
278 */
279 function endTest() {
280 ClassRegistry::flush();
281 App::build();
282 }
283
284 /**
285 * Test that file path generation doesn't continuously append paths.
286 *
287 * @return void
288 * @access public
289 */
290 function testFilePathGeneration() {
291 $file = TESTS . 'cases' . DS . 'models' . DS . 'my_class.test.php';
292
293 $this->Task->Dispatch->expectNever('stderr');
294 $this->Task->Dispatch->expectNever('_stop');
295
296 $this->Task->setReturnValue('in', 'y');
297 $this->Task->expectAt(0, 'createFile', array($file, '*'));
298 $this->Task->bake('Model', 'MyClass');
299
300 $this->Task->expectAt(1, 'createFile', array($file, '*'));
301 $this->Task->bake('Model', 'MyClass');
302
303 $file = TESTS . 'cases' . DS . 'controllers' . DS . 'comments_controller.test.php';
304 $this->Task->expectAt(2, 'createFile', array($file, '*'));
305 $this->Task->bake('Controller', 'Comments');
306 }
307
308 /**
309 * Test that method introspection pulls all relevant non parent class
310 * methods into the test case.
311 *
312 * @return void
313 */
314 function testMethodIntrospection() {
315 $result = $this->Task->getTestableMethods('TestTaskArticle');
316 $expected = array('dosomething', 'dosomethingelse');
317 $this->assertEqual(array_map('strtolower', $result), $expected);
318 }
319
320 /**
321 * test that the generation of fixtures works correctly.
322 *
323 * @return void
324 * @access public
325 */
326 function testFixtureArrayGenerationFromModel() {
327 $subject = ClassRegistry::init('TestTaskArticle');
328 $result = $this->Task->generateFixtureList($subject);
329 $expected = array('plugin.test_task.test_task_comment', 'app.articles_tags',
330 'app.test_task_article', 'app.test_task_tag');
331
332 $this->assertEqual(sort($result), sort($expected));
333 }
334
335 /**
336 * test that the generation of fixtures works correctly.
337 *
338 * @return void
339 * @access public
340 */
341 function testFixtureArrayGenerationFromController() {
342 $subject = new TestTaskCommentsController();
343 $result = $this->Task->generateFixtureList($subject);
344 $expected = array('plugin.test_task.test_task_comment', 'app.articles_tags',
345 'app.test_task_article', 'app.test_task_tag');
346
347 $this->assertEqual(sort($result), sort($expected));
348 }
349
350 /**
351 * test user interaction to get object type
352 *
353 * @return void
354 * @access public
355 */
356 function testGetObjectType() {
357 $this->Task->expectOnce('_stop');
358 $this->Task->setReturnValueAt(0, 'in', 'q');
359 $this->Task->getObjectType();
360
361 $this->Task->setReturnValueAt(1, 'in', 2);
362 $result = $this->Task->getObjectType();
363 $this->assertEqual($result, $this->Task->classTypes[1]);
364 }
365
366 /**
367 * creating test subjects should clear the registry so the registry is always fresh
368 *
369 * @return void
370 * @access public
371 */
372 function testRegistryClearWhenBuildingTestObjects() {
373 ClassRegistry::flush();
374 $model = ClassRegistry::init('TestTaskComment');
375 $model->bindModel(array(
376 'belongsTo' => array(
377 'Random' => array(
378 'className' => 'TestTaskArticle',
379 'foreignKey' => 'article_id',
380 )
381 )
382 ));
383 $keys = ClassRegistry::keys();
384 $this->assertTrue(in_array('random', $keys));
385 $object =& $this->Task->buildTestSubject('Model', 'TestTaskComment');
386
387 $keys = ClassRegistry::keys();
388 $this->assertFalse(in_array('random', $keys));
389 }
390
391 /**
392 * test that getClassName returns the user choice as a classname.
393 *
394 * @return void
395 * @access public
396 */
397 function testGetClassName() {
398 $objects = App::objects('model');
399 $skip = $this->skipIf(empty($objects), 'No models in app, this test will fail. %s');
400 if ($skip) {
401 return;
402 }
403 $this->Task->setReturnValueAt(0, 'in', 'MyCustomClass');
404 $result = $this->Task->getClassName('Model');
405 $this->assertEqual($result, 'MyCustomClass');
406
407 $this->Task->setReturnValueAt(1, 'in', 1);
408 $result = $this->Task->getClassName('Model');
409 $options = App::objects('model');
410 $this->assertEqual($result, $options[0]);
411 }
412
413 /**
414 * Test the user interaction for defining additional fixtures.
415 *
416 * @return void
417 * @access public
418 */
419 function testGetUserFixtures() {
420 $this->Task->setReturnValueAt(0, 'in', 'y');
421 $this->Task->setReturnValueAt(1, 'in', 'app.pizza, app.topping, app.side_dish');
422 $result = $this->Task->getUserFixtures();
423 $expected = array('app.pizza', 'app.topping', 'app.side_dish');
424 $this->assertEqual($result, $expected);
425 }
426
427 /**
428 * test that resolving classnames works
429 *
430 * @return void
431 * @access public
432 */
433 function testGetRealClassname() {
434 $result = $this->Task->getRealClassname('Model', 'Post');
435 $this->assertEqual($result, 'Post');
436
437 $result = $this->Task->getRealClassname('Controller', 'Posts');
438 $this->assertEqual($result, 'PostsController');
439
440 $result = $this->Task->getRealClassname('Helper', 'Form');
441 $this->assertEqual($result, 'FormHelper');
442
443 $result = $this->Task->getRealClassname('Behavior', 'Containable');
444 $this->assertEqual($result, 'ContainableBehavior');
445
446 $result = $this->Task->getRealClassname('Component', 'Auth');
447 $this->assertEqual($result, 'AuthComponent');
448 }
449
450 /**
451 * test baking files. The conditionally run tests are known to fail in PHP4
452 * as PHP4 classnames are all lower case, breaking the plugin path inflection.
453 *
454 * @return void
455 * @access public
456 */
457 function testBakeModelTest() {
458 $this->Task->setReturnValue('createFile', true);
459 $this->Task->setReturnValue('isLoadableClass', true);
460
461 $result = $this->Task->bake('Model', 'TestTaskArticle');
462
463 $this->assertPattern('/App::import\(\'Model\', \'TestTaskArticle\'\)/', $result);
464 $this->assertPattern('/class TestTaskArticleTestCase extends CakeTestCase/', $result);
465
466 $this->assertPattern('/function startTest\(\)/', $result);
467 $this->assertPattern("/\\\$this->TestTaskArticle \=\& ClassRegistry::init\('TestTaskArticle'\)/", $result);
468
469 $this->assertPattern('/function endTest\(\)/', $result);
470 $this->assertPattern('/unset\(\$this->TestTaskArticle\)/', $result);
471
472 $this->assertPattern('/function testDoSomething\(\)/i', $result);
473 $this->assertPattern('/function testDoSomethingElse\(\)/i', $result);
474
475 $this->assertPattern("/'app\.test_task_article'/", $result);
476 if (PHP5) {
477 $this->assertPattern("/'plugin\.test_task\.test_task_comment'/", $result);
478 }
479 $this->assertPattern("/'app\.test_task_tag'/", $result);
480 $this->assertPattern("/'app\.articles_tag'/", $result);
481 }
482
483 /**
484 * test baking controller test files, ensure that the stub class is generated.
485 * Conditional assertion is known to fail on PHP4 as classnames are all lower case
486 * causing issues with inflection of path name from classname.
487 *
488 * @return void
489 * @access public
490 */
491 function testBakeControllerTest() {
492 $this->Task->setReturnValue('createFile', true);
493 $this->Task->setReturnValue('isLoadableClass', true);
494
495 $result = $this->Task->bake('Controller', 'TestTaskComments');
496
497 $this->assertPattern('/App::import\(\'Controller\', \'TestTaskComments\'\)/', $result);
498 $this->assertPattern('/class TestTaskCommentsControllerTestCase extends CakeTestCase/', $result);
499
500 $this->assertPattern('/class TestTestTaskCommentsController extends TestTaskCommentsController/', $result);
501 $this->assertPattern('/var \$autoRender = false/', $result);
502 $this->assertPattern('/function redirect\(\$url, \$status = null, \$exit = true\)/', $result);
503
504 $this->assertPattern('/function startTest\(\)/', $result);
505 $this->assertPattern("/\\\$this->TestTaskComments \=\& new TestTestTaskCommentsController\(\)/", $result);
506 $this->assertPattern("/\\\$this->TestTaskComments->constructClasses\(\)/", $result);
507
508 $this->assertPattern('/function endTest\(\)/', $result);
509 $this->assertPattern('/unset\(\$this->TestTaskComments\)/', $result);
510
511 $this->assertPattern("/'app\.test_task_article'/", $result);
512 if (PHP5) {
513 $this->assertPattern("/'plugin\.test_task\.test_task_comment'/", $result);
514 }
515 $this->assertPattern("/'app\.test_task_tag'/", $result);
516 $this->assertPattern("/'app\.articles_tag'/", $result);
517 }
518
519 /**
520 * test Constructor generation ensure that constructClasses is called for controllers
521 *
522 * @return void
523 * @access public
524 */
525 function testGenerateConstructor() {
526 $result = $this->Task->generateConstructor('controller', 'PostsController');
527 $expected = "new TestPostsController();\n\t\t\$this->Posts->constructClasses();\n";
528 $this->assertEqual($result, $expected);
529
530 $result = $this->Task->generateConstructor('model', 'Post');
531 $expected = "ClassRegistry::init('Post');\n";
532 $this->assertEqual($result, $expected);
533
534 $result = $this->Task->generateConstructor('helper', 'FormHelper');
535 $expected = "new FormHelper();\n";
536 $this->assertEqual($result, $expected);
537 }
538
539 /**
540 * Test that mock class generation works for the appropriate classes
541 *
542 * @return void
543 * @access public
544 */
545 function testMockClassGeneration() {
546 $result = $this->Task->hasMockClass('controller');
547 $this->assertTrue($result);
548 }
549
550 /**
551 * test bake() with a -plugin param
552 *
553 * @return void
554 * @access public
555 */
556 function testBakeWithPlugin() {
557 $this->Task->plugin = 'TestTest';
558
559 $path = APP . 'plugins' . DS . 'test_test' . DS . 'tests' . DS . 'cases' . DS . 'helpers' . DS . 'form.test.php';
560 $this->Task->expectAt(0, 'createFile', array($path, '*'));
561 $this->Task->bake('Helper', 'Form');
562 }
563
564 /**
565 * test interactive with plugins lists from the plugin
566 *
567 * @return void
568 */
569 function testInteractiveWithPlugin() {
570 $testApp = TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS;
571 App::build(array(
572 'plugins' => array($testApp)
573 ), true);
574
575 $this->Task->plugin = 'TestPlugin';
576 $path = $testApp . 'test_plugin' . DS . 'tests' . DS . 'cases' . DS . 'helpers' . DS . 'other_helper.test.php';
577 $this->Task->setReturnValueAt(0, 'in', 5); //helper
578 $this->Task->setReturnValueAt(1, 'in', 1); //OtherHelper
579 $this->Task->expectAt(0, 'createFile', array($path, '*'));
580 $this->Task->expectAt(9, 'out', array('1. OtherHelper'));
581 $this->Task->execute();
582 }
583
584 /**
585 * Test filename generation for each type + plugins
586 *
587 * @return void
588 * @access public
589 */
590 function testTestCaseFileName() {
591 $this->Task->path = '/my/path/tests/';
592
593 $result = $this->Task->testCaseFileName('Model', 'Post');
594 $expected = $this->Task->path . 'cases' . DS . 'models' . DS . 'post.test.php';
595 $this->assertEqual($result, $expected);
596
597 $result = $this->Task->testCaseFileName('Helper', 'Form');
598 $expected = $this->Task->path . 'cases' . DS . 'helpers' . DS . 'form.test.php';
599 $this->assertEqual($result, $expected);
600
601 $result = $this->Task->testCaseFileName('Controller', 'Posts');
602 $expected = $this->Task->path . 'cases' . DS . 'controllers' . DS . 'posts_controller.test.php';
603 $this->assertEqual($result, $expected);
604
605 $result = $this->Task->testCaseFileName('Behavior', 'Containable');
606 $expected = $this->Task->path . 'cases' . DS . 'behaviors' . DS . 'containable.test.php';
607 $this->assertEqual($result, $expected);
608
609 $result = $this->Task->testCaseFileName('Component', 'Auth');
610 $expected = $this->Task->path . 'cases' . DS . 'components' . DS . 'auth.test.php';
611 $this->assertEqual($result, $expected);
612
613 $this->Task->plugin = 'TestTest';
614 $result = $this->Task->testCaseFileName('Model', 'Post');
615 $expected = APP . 'plugins' . DS . 'test_test' . DS . 'tests' . DS . 'cases' . DS . 'models' . DS . 'post.test.php';
616 $this->assertEqual($result, $expected);
617 }
618
619 /**
620 * test execute with a type defined
621 *
622 * @return void
623 * @access public
624 */
625 function testExecuteWithOneArg() {
626 $this->Task->args[0] = 'Model';
627 $this->Task->setReturnValueAt(0, 'in', 'TestTaskTag');
628 $this->Task->setReturnValue('isLoadableClass', true);
629 $this->Task->expectAt(0, 'createFile', array('*', new PatternExpectation('/class TestTaskTagTestCase extends CakeTestCase/')));
630 $this->Task->execute();
631 }
632
633 /**
634 * test execute with type and class name defined
635 *
636 * @return void
637 * @access public
638 */
639 function testExecuteWithTwoArgs() {
640 $this->Task->args = array('Model', 'TestTaskTag');
641 $this->Task->setReturnValueAt(0, 'in', 'TestTaskTag');
642 $this->Task->setReturnValue('isLoadableClass', true);
643 $this->Task->expectAt(0, 'createFile', array('*', new PatternExpectation('/class TestTaskTagTestCase extends CakeTestCase/')));
644 $this->Task->execute();
645 }
646 }