1: <?php namespace Laravel\CLI\Tasks\Test;
2:
3: use Laravel\File;
4: use Laravel\Bundle;
5: use Laravel\Request;
6: use Laravel\CLI\Tasks\Task;
7:
8: class Runner extends Task {
9:
10: /**
11: * The base directory where the tests will be executed.
12: *
13: * A phpunit.xml should also be stored in that directory.
14: *
15: * @var string
16: */
17: protected $base_path;
18:
19: /**
20: * Run all of the unit tests for the application.
21: *
22: * @param array $bundles
23: * @return void
24: */
25: public function run($bundles = array())
26: {
27: if (count($bundles) == 0) $bundles = array(DEFAULT_BUNDLE);
28:
29: $this->bundle($bundles);
30: }
31:
32: /**
33: * Run the tests for the Laravel framework.
34: *
35: * @return void
36: */
37: public function core()
38: {
39: $this->base_path = path('sys').'tests'.DS;
40: $this->stub(path('sys').'tests'.DS.'cases');
41:
42: $this->test();
43: }
44:
45: /**
46: * Run the tests for a given bundle.
47: *
48: * @param array $bundles
49: * @return void
50: */
51: public function bundle($bundles = array())
52: {
53: if (count($bundles) == 0)
54: {
55: $bundles = Bundle::names();
56: }
57:
58: $this->base_path = path('sys').'cli'.DS.'tasks'.DS.'test'.DS;
59:
60: foreach ($bundles as $bundle)
61: {
62: // To run PHPUnit for the application, bundles, and the framework
63: // from one task, we'll dynamically stub PHPUnit.xml files via
64: // the task and point the test suite to the correct directory
65: // based on what was requested.
66: if (is_dir($path = Bundle::path($bundle).'tests'))
67: {
68: $this->stub($path);
69:
70: $this->test();
71: }
72: }
73: }
74:
75: /**
76: * Run PHPUnit with the temporary XML configuration.
77: *
78: * @return void
79: */
80: protected function test()
81: {
82: // We'll simply fire off PHPUnit with the configuration switch
83: // pointing to our requested configuration file. This allows
84: // us to flexibly run tests for any setup.
85: $path = 'phpunit.xml';
86:
87: // fix the spaced directories problem when using the command line
88: // strings with spaces inside should be wrapped in quotes.
89: $esc_path = escapeshellarg($path);
90:
91: putenv('LARAVEL_ENV='.Request::env());
92: passthru('phpunit --configuration '.$esc_path, $status);
93:
94: @unlink($path);
95:
96: // Pass through the exit status
97: exit($status);
98: }
99:
100: /**
101: * Write a stub phpunit.xml file to the base directory.
102: *
103: * @param string $directory
104: * @return void
105: */
106: protected function stub($directory)
107: {
108: $path = path('sys').'cli/tasks/test/';
109:
110: $stub = File::get($path.'stub.xml');
111:
112: // The PHPUnit bootstrap file contains several items that are swapped
113: // at test time. This allows us to point PHPUnit at a few different
114: // locations depending on what the developer wants to test.
115: foreach (array('bootstrap', 'directory') as $item)
116: {
117: $stub = $this->{"swap_{$item}"}($stub, $directory);
118: }
119:
120: File::put(path('base').'phpunit.xml', $stub);
121: }
122:
123: /**
124: * Swap the bootstrap file in the stub.
125: *
126: * @param string $stub
127: * @param string $directory
128: * @return string
129: */
130: protected function swap_bootstrap($stub, $directory)
131: {
132: return str_replace('{{bootstrap}}', $this->base_path.'phpunit.php', $stub);
133: }
134:
135: /**
136: * Swap the directory in the stub.
137: *
138: * @param string $stub
139: * @param string $directory
140: * @return string
141: */
142: protected function swap_directory($stub, $directory)
143: {
144: return str_replace('{{directory}}', $directory, $stub);
145: }
146:
147: }