Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 255 lines (232 sloc) 6.935 kb
fe822aa GWoo initial work on test controller and reporters
gwoo authored
1 <?php
2 /**
3 * Lithium: the most rad php framework
4 *
14de7bf GWoo Happy 2012!
gwoo authored
5 * @copyright Copyright 2012, Union of RAD (http://union-of-rad.org)
fe822aa GWoo initial work on test controller and reporters
gwoo authored
6 * @license http://opensource.org/licenses/bsd-license.php The BSD License
7 */
8
9 namespace lithium\test;
10
00ce46c Nate Abele Implemented core exceptions. Implemented `\core\Libraries::instance()` t...
nateabele authored
11 use lithium\core\Libraries;
12 use lithium\util\Inflector;
13 use lithium\core\ClassNotFoundException;
7cdd71a GWoo more refactoring of test suite
gwoo authored
14
15 /**
8dd7503 Joel Perras Adding class doc blocks to `test\Report`.
jperras authored
16 * This `Report` object aggregates tests in a group and allows you to run said tests to
17 * obtain the results and stats (passes, fails, exceptions, skips) of the test run.
18 *
19 * While Lithium already comes with a text-based as well as web-based test interface, you
20 * may use or extend the `Report` class to create your own test reporter functionality. In
21 * addition, you can also create your own custom templates for displaying results in a different
22 * format, such as json.
23 *
24 * Example usage, for built-in HTML format/reporter:
25 *
26 * {{{
27 * $report = new Report(array(
28 * 'title' => 'Test Report Title',
d7ba3e0 Nate Abele Cleaning up class references.
nateabele authored
29 * 'group' => new Group(array('data' => array('lithium\tests\cases\net\http\MediaTest'))),
8dd7503 Joel Perras Adding class doc blocks to `test\Report`.
jperras authored
30 * 'format' => 'html',
31 * 'reporter' => 'html'
32 * ));
33 *
34 * $report->run();
35 *
36 * //Get the test stats:
37 * $report->stats();
38 *
39 * //Get test results:
40 * $report->results
41 * }}}
42 *
43 * You may also choose to filter the results of the test runs to obtain additional information.
44 * For example, say you wish to calculate the cyclomatic complexity of the classes you are testing:
45 *
46 * {{{
47 * $report = new Report(array(
48 * 'title' => 'Test Report Title',
d7ba3e0 Nate Abele Cleaning up class references.
nateabele authored
49 * 'group' => new Group(array('data' => array('lithium\tests\cases\net\http\MediaTest'))),
8dd7503 Joel Perras Adding class doc blocks to `test\Report`.
jperras authored
50 * 'filters' => array('Complexity')
51 * ));
52 *
53 * $report->run();
54 *
55 * //Get test results, including filter results:
56 * $report->results
57 * }}}
58 *
59 * @see lithium\test\Group
60 * @see lithium\test\filter
61 * @see lithium\test\templates
7cdd71a GWoo more refactoring of test suite
gwoo authored
62 */
fe822aa GWoo initial work on test controller and reporters
gwoo authored
63 class Report extends \lithium\core\Object {
64
65 /**
66 * Contains an instance of `lithium\test\Group`, which contains all unit tests to be executed
67 * this test run.
68 *
69 * @var object
70 */
71 public $group = null;
72
73 /**
7cdd71a GWoo more refactoring of test suite
gwoo authored
74 * Title of the group being run
75 *
76 * @var string
77 */
78 public $title = null;
79
80 /**
81 * group and filter results
82 *
83 * @var array
84 */
85 public $results = array('group' => array(), 'filters' => array());
86
87 /**
88 * start and end timers
89 *
90 * @var array
91 */
92 public $timer = array('start' => null, 'end' => null);
81d6725 GWoo test suite refactor is "working" still needs more cleanup and organizati...
gwoo authored
93
7cdd71a GWoo more refactoring of test suite
gwoo authored
94 /**
8ac8a36 GWoo refactoring how filters are handled
gwoo authored
95 * An array key on fully-namespaced class names of the filter with options to be
96 * applied for the filter as the value
97 *
98 * @var array
99 */
100 protected $_filters = array();
101
102 /**
7cdd71a GWoo more refactoring of test suite
gwoo authored
103 * Construct Report Object
104 *
105 * @param array $config Options array for the test run. Valid options are:
eb53e19 GWoo adding some coverage for \test\Report
gwoo authored
106 * - 'group': The test group with items to be run.
7cdd71a GWoo more refactoring of test suite
gwoo authored
107 * - 'filters': An array of filters that the test output should be run through.
108 */
f80098d Nate Abele Adding type hinting to constructor `$config` arrays and all applicable `...
nateabele authored
109 public function __construct(array $config = array()) {
7cdd71a GWoo more refactoring of test suite
gwoo authored
110 $defaults = array(
eb53e19 GWoo adding some coverage for \test\Report
gwoo authored
111 'title' => null,
7cdd71a GWoo more refactoring of test suite
gwoo authored
112 'group' => null,
113 'filters' => array(),
97199ea GWoo adding some filters for `\test\Dispatcher` and `\test\Report`
gwoo authored
114 'format' => 'txt',
26c2192 David Persson QA: Removing trailing comma in arrays, lowercasing some keywords.
davidpersson authored
115 'reporter' => 'console'
7cdd71a GWoo more refactoring of test suite
gwoo authored
116 );
126affc Nate Abele Type fixes to handle test suite warnings.
nateabele authored
117 parent::__construct($config + $defaults);
7cdd71a GWoo more refactoring of test suite
gwoo authored
118 }
fe822aa GWoo initial work on test controller and reporters
gwoo authored
119
7cdd71a GWoo more refactoring of test suite
gwoo authored
120 /**
121 * undocumented function
122 *
123 * @return void
124 */
fe822aa GWoo initial work on test controller and reporters
gwoo authored
125 protected function _init() {
7cdd71a GWoo more refactoring of test suite
gwoo authored
126 $this->group = $this->_config['group'];
127 $this->title = $this->_config['title'] ?: $this->_config['title'];
fe822aa GWoo initial work on test controller and reporters
gwoo authored
128 }
1e23d77 GWoo hacking on Report
gwoo authored
129
7cdd71a GWoo more refactoring of test suite
gwoo authored
130 /**
131 * undocumented function
132 *
133 * @return void
134 */
135 public function run() {
136 $tests = $this->group->tests();
e6cd7c1 David Persson Adding `Base` test filter.
davidpersson authored
137
8ac8a36 GWoo refactoring how filters are handled
gwoo authored
138 foreach ($this->filters() as $filter => $options) {
139 $this->results['filters'][$filter] = array();
140 $tests = $filter::apply($this, $tests, $options['apply']) ?: $tests;
1e23d77 GWoo hacking on Report
gwoo authored
141 }
7cdd71a GWoo more refactoring of test suite
gwoo authored
142 $this->results['group'] = $tests->run();
1e23d77 GWoo hacking on Report
gwoo authored
143
8ac8a36 GWoo refactoring how filters are handled
gwoo authored
144 foreach ($this->filters() as $filter => $options) {
145 $this->results['filters'][$filter] = $filter::analyze($this, $options['analyze']);
1e23d77 GWoo hacking on Report
gwoo authored
146 }
7cdd71a GWoo more refactoring of test suite
gwoo authored
147 }
148
149 /**
f0f623e Marke Hallowell Updated Report to use new Test Filter interface
indiefan authored
150 * Collects Results from the test filters and aggregates them.
151 *
0fddf6c Marke Hallowell Refactored test filter interface to better handle raw filter results pri...
indiefan authored
152 * @param string $class Classname of the filter for which to aggregate results.
153 * @param array $results Array of the filter results for
f0f623e Marke Hallowell Updated Report to use new Test Filter interface
indiefan authored
154 * later analysis by the filter itself.
155 * @return void
156 */
c552f97 Marke Hallowell Renamed Report collectFilterResults to just be collect
indiefan authored
157 public function collect($class, $results) {
0fddf6c Marke Hallowell Refactored test filter interface to better handle raw filter results pri...
indiefan authored
158 $this->results['filters'][$class][] = $results;
f0f623e Marke Hallowell Updated Report to use new Test Filter interface
indiefan authored
159 }
160
161 /**
7cdd71a GWoo more refactoring of test suite
gwoo authored
162 * undocumented function
163 *
164 * @return void
165 */
166 public function stats() {
81d6725 GWoo test suite refactor is "working" still needs more cleanup and organizati...
gwoo authored
167 $results = (array) $this->results['group'];
36f1b2c GWoo updating `\test\Unit` handling of array comparisons and exception report...
gwoo authored
168 $defaults = array(
169 'asserts' => 0,
170 'passes' => array(),
171 'fails' => array(),
172 'exceptions' => array(),
173 'errors' => array(),
174 'skips' => array()
175 );
176 $stats = array_reduce($results, function($stats, $result) use ($defaults) {
5616836 GWoo `\core\Object::instance()` will return false or null `$name` is null
gwoo authored
177 $stats = (array) $stats + $defaults;
7cdd71a GWoo more refactoring of test suite
gwoo authored
178 $result = empty($result[0]) ? array($result) : $result;
179 foreach ($result as $response) {
180 if (empty($response['result'])) {
181 continue;
182 }
183 $result = $response['result'];
184
185 if (in_array($result, array('fail', 'exception'))) {
a00543d Marke Hallowell Moved test stat reporting into template and completely removed Html Repo...
indiefan authored
186 $response = array_merge(
187 array('class' => 'unknown', 'method' => 'unknown'), $response
188 );
7cdd71a GWoo more refactoring of test suite
gwoo authored
189 $stats['errors'][] = $response;
190 }
191 unset($response['file'], $response['result']);
192
193 if (in_array($result, array('pass', 'fail'))) {
194 $stats['asserts']++;
195 }
b3601fc GWoo adding skip rendering to \test
gwoo authored
196 if (in_array($result, array('pass', 'fail', 'exception', 'skip'))) {
7cdd71a GWoo more refactoring of test suite
gwoo authored
197 $stats[Inflector::pluralize($result)][] = $response;
198 }
199 }
200 return $stats;
a00543d Marke Hallowell Moved test stat reporting into template and completely removed Html Repo...
indiefan authored
201 });
126affc Nate Abele Type fixes to handle test suite warnings.
nateabele authored
202 $stats = (array) $stats + $defaults;
a00543d Marke Hallowell Moved test stat reporting into template and completely removed Html Repo...
indiefan authored
203 $count = array_map(
126affc Nate Abele Type fixes to handle test suite warnings.
nateabele authored
204 function($value) { return is_array($value) ? count($value) : $value; }, $stats
a00543d Marke Hallowell Moved test stat reporting into template and completely removed Html Repo...
indiefan authored
205 );
b3d0a5e Marke Hallowell Fixed empty test run reporting color. Added 'Run All Tests' Button. Styl...
indiefan authored
206 $success = $count['passes'] == $count['asserts'] && $count['errors'] === 0;
a00543d Marke Hallowell Moved test stat reporting into template and completely removed Html Repo...
indiefan authored
207 return compact("stats", "count", "success");
7cdd71a GWoo more refactoring of test suite
gwoo authored
208 }
81d6725 GWoo test suite refactor is "working" still needs more cleanup and organizati...
gwoo authored
209
7cdd71a GWoo more refactoring of test suite
gwoo authored
210 /**
dca5abf Marke Hallowell Refactored Test execution to filter in test bootstrap and removed Test C...
indiefan authored
211 * Renders the test output (e.g. layouts and filter templates)
212 *
213 * @param string $template name of the template (eg: layout)
97c5e7c Howard Lince III Doing a general QA and Docblock
Howard3 authored
214 * @param string|array $data array from `_data()` method
dca5abf Marke Hallowell Refactored Test execution to filter in test bootstrap and removed Test C...
indiefan authored
215 * @return string
59cb735 Nate Abele Ensuring `@filter` tags are present in docblocks that support filtering....
nateabele authored
216 * @filter
dca5abf Marke Hallowell Refactored Test execution to filter in test bootstrap and removed Test C...
indiefan authored
217 */
97199ea GWoo adding some filters for `\test\Dispatcher` and `\test\Report`
gwoo authored
218 public function render($template, $data = array()) {
219 $config = $this->_config;
ea0abeb Nate Abele Refactoring the `Test` command to use typed output handlers, and consoli...
nateabele authored
220
221 if ($template == "stats" && !$data) {
d4a14da Marke Hallowell Added test coverage for Report.
indiefan authored
222 $data = $this->stats();
223 }
97199ea GWoo adding some filters for `\test\Dispatcher` and `\test\Report`
gwoo authored
224 $template = Libraries::locate("test.templates.{$config['reporter']}", $template, array(
26c2192 David Persson QA: Removing trailing comma in arrays, lowercasing some keywords.
davidpersson authored
225 'filter' => false, 'type' => 'file', 'suffix' => ".{$config['format']}.php"
dca5abf Marke Hallowell Refactored Test execution to filter in test bootstrap and removed Test C...
indiefan authored
226 ));
97199ea GWoo adding some filters for `\test\Dispatcher` and `\test\Report`
gwoo authored
227 $params = compact('template', 'data', 'config');
228
229 return $this->_filter(__METHOD__, $params, function($self, $params, $chain) {
230 extract($params['data']);
231 ob_start();
232 include $params['template'];
233 return ob_get_clean();
234 });
dca5abf Marke Hallowell Refactored Test execution to filter in test bootstrap and removed Test C...
indiefan authored
235 }
944fd8f Marke Hallowell Added filters method to Report to render all filters and updated html an...
indiefan authored
236
8ac8a36 GWoo refactoring how filters are handled
gwoo authored
237 public function filters(array $filters = array()) {
ea0abeb Nate Abele Refactoring the `Test` command to use typed output handlers, and consoli...
nateabele authored
238 if ($this->_filters && !$filters) {
8ac8a36 GWoo refactoring how filters are handled
gwoo authored
239 return $this->_filters;
944fd8f Marke Hallowell Added filters method to Report to render all filters and updated html an...
indiefan authored
240 }
8ac8a36 GWoo refactoring how filters are handled
gwoo authored
241 $filters += (array) $this->_config['filters'];
242 $results = array();
ea0abeb Nate Abele Refactoring the `Test` command to use typed output handlers, and consoli...
nateabele authored
243
8ac8a36 GWoo refactoring how filters are handled
gwoo authored
244 foreach ($filters as $filter => $options) {
245 if (!$class = Libraries::locate('test.filter', $filter)) {
583059b David Persson Adding and replacing ticks/quotes with backticks in error and exception ...
davidpersson authored
246 throw new ClassNotFoundException("`{$class}` is not a valid test filter.");
8ac8a36 GWoo refactoring how filters are handled
gwoo authored
247 }
248 $options['name'] = strtolower(join('', array_slice(explode("\\", $class), -1)));
249 $results[$class] = $options + array('apply' => array(), 'analyze' => array());
250 }
251 return $this->_filters = $results;
944fd8f Marke Hallowell Added filters method to Report to render all filters and updated html an...
indiefan authored
252 }
fe822aa GWoo initial work on test controller and reporters
gwoo authored
253 }
254
255 ?>
Something went wrong with that request. Please try again.