Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 995 lines (911 sloc) 30.305 kB
e7f3c31 @gwoo going lithium
gwoo authored
1 <?php
2 /**
3 * Lithium: the most rad php framework
4 *
4f1a9c0 @nateabele Updating copyright year.
nateabele authored
5 * @copyright Copyright 2011, Union of RAD (http://union-of-rad.org)
e7f3c31 @gwoo going lithium
gwoo authored
6 * @license http://opensource.org/licenses/bsd-license.php The BSD License
7 */
8
9 namespace lithium\test;
10
b7c93e9 @davidpersson QA: Removing leading backslash from classes in use statements.
davidpersson authored
11 use Exception;
6fb3f64 @daschl change _use lithium_ commands and remove the prefixed slash
daschl authored
12 use lithium\util\String;
13 use lithium\core\Libraries;
14 use lithium\util\Validator;
15 use lithium\analysis\Debugger;
16 use lithium\analysis\Inspector;
b7c93e9 @davidpersson QA: Removing leading backslash from classes in use statements.
davidpersson authored
17 use RecursiveDirectoryIterator;
18 use RecursiveIteratorIterator;
e7f3c31 @gwoo going lithium
gwoo authored
19
efbf1d8 @niel Adding some documentation for Unit class
niel authored
20 /**
21 * This is the base class for all test cases. Test are performed using an assertion method. If the
8c98a6f @niel Adding/fixing dock blocks for class and methods assertTags(), _array(…
niel authored
22 * assertion is correct, the test passes, otherwise it fails. Most assertions take an expected
23 * result, a received result, and a message (to describe the failure) as parameters.
efbf1d8 @niel Adding some documentation for Unit class
niel authored
24 *
e0cb56a @alkemann hooks fixes for lithium/test
alkemann authored
25 * Available assertions are (see `assert<assertion-name>` methods for details): Equal, False,
26 * Identical, NoPattern, NotEqual, Null, Pattern, Tags, True.
efbf1d8 @niel Adding some documentation for Unit class
niel authored
27 *
28 * If an assertion is expected to produce an exception, the `expectException` method should be
29 * called before it.
30 *
8c98a6f @niel Adding/fixing dock blocks for class and methods assertTags(), _array(…
niel authored
31 * Both _case_ (unit) and _integration_ tests extend this class. These two test types can loosely
32 * be defined as follows:
33 * - Case: These tests are used to check a small unit of functionality, such as if a method
34 * returns an expected result for a known input, or whether an adapter can successfully open a
35 * connection.
36 * - Integration: These are tests for determining that different parts of the framework will work
37 * together (integrate) as expected. For example, a model has CRUD functionality with its
38 * underlying data source.
39 *
efbf1d8 @niel Adding some documentation for Unit class
niel authored
40 */
e7f3c31 @gwoo going lithium
gwoo authored
41 class Unit extends \lithium\core\Object {
42
1b37b2f @gwoo adding Unit::_cleanUp to assist in clearing stuff in temp
gwoo authored
43 /**
1ccd9da @davidpersson Refactoring `Reporter` into reporter `Base` class.
davidpersson authored
44 * The Reference to a test reporter class.
1b37b2f @gwoo adding Unit::_cleanUp to assist in clearing stuff in temp
gwoo authored
45 *
46 * @var string
47 */
e7f3c31 @gwoo going lithium
gwoo authored
48 protected $_reporter = null;
49
1b37b2f @gwoo adding Unit::_cleanUp to assist in clearing stuff in temp
gwoo authored
50 /**
51 * The list of test results.
52 *
53 * @var string
54 */
55 protected $_results = array();
56
57 /**
58 * The list of expected exceptions.
59 *
60 * @var string
61 */
e7f3c31 @gwoo going lithium
gwoo authored
62 protected $_expected = array();
63
64 /**
596ddbf @nateabele Moving `\test\filter\Affected::_testCaseForClass()` to `\test\Unit::g…
nateabele authored
65 * Finds the test case for the corresponding class name.
66 *
67 * @param string $class A fully-namespaced class reference for which to find a test case.
68 * @return string Returns the class name of a test case for `$class`, or `null` if none exists.
69 */
70 public static function get($class) {
71 $parts = explode('\\', $class);
72
73 $library = array_shift($parts);
74 $name = array_pop($parts);
75 $type = "tests.cases." . implode('.', $parts);
76
77 return Libraries::locate($type, $name, compact('library'));
78 }
79
80 /**
45956a0 @gwoo updating `\test\Unit::subject()` so coverage works for plugin and app…
gwoo authored
81 * Setup method run before every test method. override in subclasses
82 *
83 * @return void
84 */
85 public function setUp() {}
f247ae2 @gwoo adding filters to console\Dispatcher, refactoring \console\Request to…
gwoo authored
86
45956a0 @gwoo updating `\test\Unit::subject()` so coverage works for plugin and app…
gwoo authored
87 /**
88 * Teardown method run after every test method. override in subclasses
89 *
90 * @return void
91 */
92 public function tearDown() {}
e7f3c31 @gwoo going lithium
gwoo authored
93
efbf1d8 @niel Adding some documentation for Unit class
niel authored
94 /**
95 * Subclasses should use this method to set conditions that, if failed, terminate further
96 * testing.
97 *
98 * For example:
99 * {{{
100 * public function skip() {
101 * $this->_dbConfig = Connections::get('default', array('config' => true));
102 * $hasDb = (isset($this->_dbConfig['adapter']) && $this->_dbConfig['adapter'] == 'MySql');
103 * $message = 'Test database is either unavailable, or not using a MySQL adapter';
104 * $this->skipIf(!$hasDb, $message);
105 * }
106 * }}}
107 *
108 * @return void
109 */
2421efa @davidpersson Syntax.
davidpersson authored
110 public function skip() {}
e7f3c31 @gwoo going lithium
gwoo authored
111
efbf1d8 @niel Adding some documentation for Unit class
niel authored
112 /**
113 * Skips test(s) if the condition is met.
114 *
115 * When used within a subclass' `skip` method, all tests are ignored if the condition is met,
116 * otherwise processing continues as normal.
117 * For other methods, only the remainder of the method is skipped, when the condition is met.
118 *
97c5e7c @Howard3 Doing a general QA and Docblock
Howard3 authored
119 * @throws Exception
efbf1d8 @niel Adding some documentation for Unit class
niel authored
120 * @param boolean $condition
97c5e7c @Howard3 Doing a general QA and Docblock
Howard3 authored
121 * @param string|boolean $message Message to pass if the condition is met.
efbf1d8 @niel Adding some documentation for Unit class
niel authored
122 * @return mixed
123 */
3989785 @davidpersson Making skipIf message handling similar to the one of assert.
davidpersson authored
124 public function skipIf($condition, $message = false) {
125 if ($condition) {
126 throw new Exception(is_string($message) ? $message : null);
e7f3c31 @gwoo going lithium
gwoo authored
127 }
128 }
129
f247ae2 @gwoo adding filters to console\Dispatcher, refactoring \console\Request to…
gwoo authored
130 /**
94759a2 @gwoo adding test coverage and fixes to `\test\Unit`
gwoo authored
131 * Returns the class name that is the subject under test for this test case.
f247ae2 @gwoo adding filters to console\Dispatcher, refactoring \console\Request to…
gwoo authored
132 *
94759a2 @gwoo adding test coverage and fixes to `\test\Unit`
gwoo authored
133 * @return string
134 */
135 public function subject() {
136 return preg_replace('/Test$/', '', str_replace('tests\\cases\\', '', get_class($this)));
137 }
138
139 /**
140 * Return test methods to run
141 *
142 * @return array
143 */
144 public function methods() {
145 static $methods;
146 return $methods ?: $methods = array_values(preg_grep('/^test/', get_class_methods($this)));
147 }
148
149 /**
150 * Runs the test methods in this test case, with the given options.
151 *
152 * @param array $options The options to use when running the test. Available options are:
153 * - 'methods': An arbitrary array of method names to execute. If
154 * unspecified, all methods starting with 'test' are run.
155 * - 'reporter': A closure which gets called after each test result,
156 * which may modify the results presented.
157 * @return array
158 */
159 public function run(array $options = array()) {
160 $defaults = array('methods' => array(), 'reporter' => null, 'handler' => null);
161 $options += $defaults;
162 $this->_results = array();
163 $self = $this;
164
36f1b2c @gwoo updating `\test\Unit` handling of array comparisons and exception rep…
gwoo authored
165 try {
166 $this->skip();
167 } catch (Exception $e) {
168 $this->_handleException($e);
169 return $this->_results;
170 }
171
94759a2 @gwoo adding test coverage and fixes to `\test\Unit`
gwoo authored
172 $h = function($code, $message, $file, $line = 0, $context = array()) use ($self) {
173 $trace = debug_backtrace();
174 $trace = array_slice($trace, 1, count($trace));
36f1b2c @gwoo updating `\test\Unit` handling of array comparisons and exception rep…
gwoo authored
175 $self->invokeMethod('_reportException', array(
94759a2 @gwoo adding test coverage and fixes to `\test\Unit`
gwoo authored
176 compact('code', 'message', 'file', 'line', 'trace', 'context')
177 ));
178 };
179 $options['handler'] = $options['handler'] ?: $h;
36f1b2c @gwoo updating `\test\Unit` handling of array comparisons and exception rep…
gwoo authored
180 set_error_handler($options['handler']);
181
94759a2 @gwoo adding test coverage and fixes to `\test\Unit`
gwoo authored
182 $methods = $options['methods'] ?: $this->methods();
183 $this->_reporter = $options['reporter'] ?: $this->_reporter;
184
185 foreach ($methods as $method) {
186 if ($this->_runTestMethod($method, $options) === false) {
187 break;
188 }
189 }
190 restore_error_handler();
191 return $this->_results;
192 }
193
194 /**
195 * General assert method used by others for common output.
196 *
197 * @param boolean $expression
97c5e7c @Howard3 Doing a general QA and Docblock
Howard3 authored
198 * @param string|boolean $message The message to output. If the message is not a string,
199 * then it will be converted to '{:message}'. Use '{:message}' in the string and it
200 * will use the `$data` to format the message with `String::insert()`.
94759a2 @gwoo adding test coverage and fixes to `\test\Unit`
gwoo authored
201 * @param array $data
f247ae2 @gwoo adding filters to console\Dispatcher, refactoring \console\Request to…
gwoo authored
202 * @return void
203 */
94759a2 @gwoo adding test coverage and fixes to `\test\Unit`
gwoo authored
204 public function assert($expression, $message = false, $data = array()) {
f247ae2 @gwoo adding filters to console\Dispatcher, refactoring \console\Request to…
gwoo authored
205 if (!is_string($message)) {
206 $message = '{:message}';
207 }
94759a2 @gwoo adding test coverage and fixes to `\test\Unit`
gwoo authored
208 if (strpos($message, "{:message}") !== false) {
209 $params = $data;
210 $params['message'] = $this->_message($params);
211 $message = String::insert($message, $params);
212 }
eda1da3 @nateabele Optimizing stack traces produced by unit tests.
nateabele authored
213 $trace = Debugger::trace(array(
214 'start' => 1, 'depth' => 4, 'format' => 'array', 'closures' => !$expression
215 ));
e7f3c31 @gwoo going lithium
gwoo authored
216 $methods = $this->methods();
217 $i = 1;
218
219 while ($i < count($trace)) {
220 if (in_array($trace[$i]['function'], $methods) && $trace[$i - 1]['object'] == $this) {
221 break;
222 }
223 $i++;
224 }
eb64d5a @nateabele Adding handling for exceptions thrown in `setUp()` and `tearDown()` o…
nateabele authored
225 $class = isset($trace[$i - 1]['object']) ? get_class($trace[$i - 1]['object']) : null;
4eab6b4 @nateabele Fixing issue where assertions run from outside test methods would att…
nateabele authored
226 $method = isset($trace[$i]) ? $trace[$i]['function'] : $trace[$i - 1]['function'];
eb64d5a @nateabele Adding handling for exceptions thrown in `setUp()` and `tearDown()` o…
nateabele authored
227
4eab6b4 @nateabele Fixing issue where assertions run from outside test methods would att…
nateabele authored
228 $result = compact('class', 'method', 'message', 'data') + array(
e7f3c31 @gwoo going lithium
gwoo authored
229 'file' => $trace[$i - 1]['file'],
230 'line' => $trace[$i - 1]['line'],
26c2192 @davidpersson QA: Removing trailing comma in arrays, lowercasing some keywords.
davidpersson authored
231 'assertion' => $trace[$i - 1]['function']
e7f3c31 @gwoo going lithium
gwoo authored
232 );
eda1da3 @nateabele Optimizing stack traces produced by unit tests.
nateabele authored
233 $this->_result($expression ? 'pass' : 'fail', $result);
e7f3c31 @gwoo going lithium
gwoo authored
234 return $expression;
235 }
236
efbf1d8 @niel Adding some documentation for Unit class
niel authored
237 /**
238 * Checks that the actual result is equal, but not neccessarily identical, to the expected
239 * result.
240 *
241 * @param mixed $expected
242 * @param mixed $result
97c5e7c @Howard3 Doing a general QA and Docblock
Howard3 authored
243 * @param string|boolean $message
efbf1d8 @niel Adding some documentation for Unit class
niel authored
244 */
94759a2 @gwoo adding test coverage and fixes to `\test\Unit`
gwoo authored
245 public function assertEqual($expected, $result, $message = false) {
246 $data = ($expected != $result) ? $this->_compare('equal', $expected, $result) : null;
e7f3c31 @gwoo going lithium
gwoo authored
247 $this->assert($expected == $result, $message, $data);
248 }
249
efbf1d8 @niel Adding some documentation for Unit class
niel authored
250 /**
251 * Checks that the actual result and the expected result are not equal to each other.
252 *
253 * @param mixed $expected
254 * @param mixed $result
97c5e7c @Howard3 Doing a general QA and Docblock
Howard3 authored
255 * @param string|boolean $message
efbf1d8 @niel Adding some documentation for Unit class
niel authored
256 */
94759a2 @gwoo adding test coverage and fixes to `\test\Unit`
gwoo authored
257 public function assertNotEqual($expected, $result, $message = false) {
e7f3c31 @gwoo going lithium
gwoo authored
258 $this->assert($result != $expected, $message, compact('expected', 'result'));
259 }
260
efbf1d8 @niel Adding some documentation for Unit class
niel authored
261 /**
262 * Checks that the actual result and the expected result are identical.
263 *
264 * @param mixed $expected
265 * @param mixed $result
97c5e7c @Howard3 Doing a general QA and Docblock
Howard3 authored
266 * @param string|boolean $message
efbf1d8 @niel Adding some documentation for Unit class
niel authored
267 */
94759a2 @gwoo adding test coverage and fixes to `\test\Unit`
gwoo authored
268 public function assertIdentical($expected, $result, $message = false) {
269 $data = ($expected !== $result) ? $this->_compare('identical', $expected, $result) : null;
4ebff72 @gwoo fixing assertIdentical
gwoo authored
270 $this->assert($expected === $result, $message, $data);
e7f3c31 @gwoo going lithium
gwoo authored
271 }
272
efbf1d8 @niel Adding some documentation for Unit class
niel authored
273 /**
274 * Checks that the result evalutes to true.
275 *
276 * For example:
277 * {{{
278 * $this->assertTrue('false', 'String has content');
279 * }}}
280 * {{{
281 * $this->assertTrue(10, 'Non-Zero value');
282 * }}}
283 * {{{
284 * $this->assertTrue(true, 'Boolean true');
285 * }}}
286 * all evaluate to true.
287 *
288 * @param mixed $result
289 * @param string $message
290 */
e7f3c31 @gwoo going lithium
gwoo authored
291 public function assertTrue($result, $message = '{:message}') {
292 $expected = true;
293 $this->assert(!empty($result), $message, compact('expected', 'result'));
294 }
295
efbf1d8 @niel Adding some documentation for Unit class
niel authored
296 /**
297 * Checks that the result evalutes to false.
298 *
299 * For example:
300 * {{{
301 * $this->assertFalse('', 'String is empty');
302 * }}}
303 *
304 * {{{
305 * $this->assertFalse(0, 'Zero value');
306 * }}}
307 *
308 * {{{
2e45b12 @niel Fixing some ommisions.
niel authored
309 * $this->assertFalse(false, 'Boolean false');
efbf1d8 @niel Adding some documentation for Unit class
niel authored
310 * }}}
311 * all evaluate to false.
312 *
313 * @param mixed $result
314 * @param string $message
315 */
e7f3c31 @gwoo going lithium
gwoo authored
316 public function assertFalse($result, $message = '{:message}') {
317 $expected = false;
318 $this->assert(empty($result), $message, compact('expected', 'result'));
319 }
320
efbf1d8 @niel Adding some documentation for Unit class
niel authored
321 /**
322 * Checks if the result is null.
323 *
324 * @param mixed $result
325 * @param string $message
326 */
e7f3c31 @gwoo going lithium
gwoo authored
327 public function assertNull($result, $message = '{:message}') {
328 $expected = null;
329 $this->assert($result === null, $message, compact('expected', 'result'));
330 }
331
efbf1d8 @niel Adding some documentation for Unit class
niel authored
332 /**
b255f40 @niel Reverting my changes, that occured at the same time as coder document…
niel authored
333 * Checks that the regular expression `$expected` is not matched in the result.
efbf1d8 @niel Adding some documentation for Unit class
niel authored
334 *
335 * @param mixed $expected
336 * @param mixed $result
337 * @param string $message
338 */
e7f3c31 @gwoo going lithium
gwoo authored
339 public function assertNoPattern($expected, $result, $message = '{:message}') {
340 $this->assert(!preg_match($expected, $result), $message, compact('expected', 'result'));
341 }
342
efbf1d8 @niel Adding some documentation for Unit class
niel authored
343 /**
b255f40 @niel Reverting my changes, that occured at the same time as coder document…
niel authored
344 * Checks that the regular expression `$expected` is matched in the result.
efbf1d8 @niel Adding some documentation for Unit class
niel authored
345 *
346 * @param mixed $expected
347 * @param mixed $result
348 * @param string $message
349 */
e7f3c31 @gwoo going lithium
gwoo authored
350 public function assertPattern($expected, $result, $message = '{:message}') {
351 $this->assert(!!preg_match($expected, $result), $message, compact('expected', 'result'));
352 }
353
354 /**
355 * Takes an array $expected and generates a regex from it to match the provided $string.
356 * Samples for $expected:
357 *
358 * Checks for an input tag with a name attribute (contains any non-empty value) and an id
359 * attribute that contains 'my-input':
2c6d422 @pointlessjon refactored `assertCookie()` to not require passing headers_list() exp…
pointlessjon authored
360 * {{{
e7f3c31 @gwoo going lithium
gwoo authored
361 * array('input' => array('name', 'id' => 'my-input'))
2c6d422 @pointlessjon refactored `assertCookie()` to not require passing headers_list() exp…
pointlessjon authored
362 * }}}
e7f3c31 @gwoo going lithium
gwoo authored
363 *
364 * Checks for two p elements with some text in them:
2c6d422 @pointlessjon refactored `assertCookie()` to not require passing headers_list() exp…
pointlessjon authored
365 * {{{
e7f3c31 @gwoo going lithium
gwoo authored
366 * array(
367 * array('p' => true),
368 * 'textA',
369 * '/p',
370 * array('p' => true),
371 * 'textB',
372 * '/p'
373 * )
2c6d422 @pointlessjon refactored `assertCookie()` to not require passing headers_list() exp…
pointlessjon authored
374 * }}}
e7f3c31 @gwoo going lithium
gwoo authored
375 *
376 * You can also specify a pattern expression as part of the attribute values, or the tag
377 * being defined, if you prepend the value with preg: and enclose it with slashes, like so:
2c6d422 @pointlessjon refactored `assertCookie()` to not require passing headers_list() exp…
pointlessjon authored
378 * {{{
e7f3c31 @gwoo going lithium
gwoo authored
379 * array(
380 * array('input' => array('name', 'id' => 'preg:/FieldName\d+/')),
381 * 'preg:/My\s+field/'
382 * )
2c6d422 @pointlessjon refactored `assertCookie()` to not require passing headers_list() exp…
pointlessjon authored
383 * }}}
e7f3c31 @gwoo going lithium
gwoo authored
384 *
385 * Important: This function is very forgiving about whitespace and also accepts any
386 * permutation of attribute order. It will also allow whitespaces between specified tags.
387 *
388 * @param string $string An HTML/XHTML/XML string
389 * @param array $expected An array, see above
c25e039 @Howard3 Cleaning up PHPDoc @return tags with multiple return types defined.
Howard3 authored
390 * @return boolean
e7f3c31 @gwoo going lithium
gwoo authored
391 */
010bf9b @nateabele Removing unused parameter from `\test\Unit::assertTags()`.
nateabele authored
392 function assertTags($string, $expected) {
e7f3c31 @gwoo going lithium
gwoo authored
393 $regex = array();
394 $normalized = array();
395
9decac0 @alkemann insert space after type casting parenthesis
alkemann authored
396 foreach ((array) $expected as $key => $val) {
e7f3c31 @gwoo going lithium
gwoo authored
397 if (!is_numeric($key)) {
398 $normalized[] = array($key => $val);
399 } else {
400 $normalized[] = $val;
401 }
402 }
403 $i = 0;
404
405 foreach ($normalized as $tags) {
406 $i++;
407 if (is_string($tags) && $tags{0} == '<') {
408 $tags = array(substr($tags, 1) => array());
409 } elseif (is_string($tags)) {
410 $tagsTrimmed = preg_replace('/\s+/m', '', $tags);
411
412 if (preg_match('/^\*?\//', $tags, $match) && $tagsTrimmed !== '//') {
413 $prefix = array(null, null);
414
415 if ($match[0] == '*/') {
416 $prefix = array('Anything, ', '.*?');
417 }
418 $regex[] = array(
419 sprintf('%sClose %s tag', $prefix[0], substr($tags, strlen($match[0]))),
420 sprintf('%s<[\s]*\/[\s]*%s[\s]*>[\n\r]*', $prefix[1], substr(
421 $tags, strlen($match[0])
422 )),
423 $i
424 );
425 continue;
426 }
427
4611a8a @gwoo changing keyword preg to regex in \test\Unit::assertTags
gwoo authored
428 if (!empty($tags) && preg_match('/^regex\:\/(.+)\/$/i', $tags, $matches)) {
e7f3c31 @gwoo going lithium
gwoo authored
429 $tags = $matches[1];
430 $type = 'Regex matches';
431 } else {
432 $tags = preg_quote($tags, '/');
433 $type = 'Text equals';
434 }
435 $regex[] = array(sprintf('%s "%s"', $type, $tags), $tags, $i);
436 continue;
437 }
438 foreach ($tags as $tag => $attributes) {
439 $regex[] = array(
440 sprintf('Open %s tag', $tag),
441 sprintf('[\s]*<%s', preg_quote($tag, '/')),
442 $i
443 );
444 if ($attributes === true) {
445 $attributes = array();
446 }
447 $attrs = array();
448 $explanations = array();
449
450 foreach ($attributes as $attr => $val) {
4611a8a @gwoo changing keyword preg to regex in \test\Unit::assertTags
gwoo authored
451 if (is_numeric($attr) && preg_match('/^regex\:\/(.+)\/$/i', $val, $matches)) {
e7f3c31 @gwoo going lithium
gwoo authored
452 $attrs[] = $matches[1];
453 $explanations[] = sprintf('Regex "%s" matches', $matches[1]);
454 continue;
455 } else {
456 $quotes = '"';
457
458 if (is_numeric($attr)) {
459 $attr = $val;
460 $val = '.+?';
461 $explanations[] = sprintf('Attribute "%s" present', $attr);
25e5f82 @indiefan Updated Unit class to potentially break on fail (for Integration tests)
indiefan authored
462 } elseif (
463 !empty($val) && preg_match('/^regex\:\/(.+)\/$/i', $val, $matches)
464 ) {
e7f3c31 @gwoo going lithium
gwoo authored
465 $quotes = '"?';
466 $val = $matches[1];
467 $explanations[] = sprintf('Attribute "%s" matches "%s"', $attr, $val);
468 } else {
469 $explanations[] = sprintf('Attribute "%s" == "%s"', $attr, $val);
470 $val = preg_quote($val, '/');
471 }
472 $attrs[] = '[\s]+' . preg_quote($attr, '/') . "={$quotes}{$val}{$quotes}";
473 }
474 }
475 if ($attrs) {
476 $permutations = $this->_arrayPermute($attrs);
477 $permutationTokens = array();
478 foreach ($permutations as $permutation) {
479 $permutationTokens[] = join('', $permutation);
480 }
481 $regex[] = array(
482 sprintf('%s', join(', ', $explanations)),
483 $permutationTokens,
484 $i
485 );
486 }
487 $regex[] = array(sprintf('End %s tag', $tag), '[\s]*\/?[\s]*>[\n\r]*', $i);
488 }
489 }
490
491 foreach ($regex as $i => $assertation) {
492 list($description, $expressions, $itemNum) = $assertation;
493 $matches = false;
494
9decac0 @alkemann insert space after type casting parenthesis
alkemann authored
495 foreach ((array) $expressions as $expression) {
e7f3c31 @gwoo going lithium
gwoo authored
496 if (preg_match(sprintf('/^%s/s', $expression), $string, $match)) {
497 $matches = true;
498 $string = substr($string, strlen($match[0]));
499 break;
500 }
501 }
502
503 if (!$matches) {
504 $this->assert(false, sprintf(
94759a2 @gwoo adding test coverage and fixes to `\test\Unit`
gwoo authored
505 '- Item #%d / regex #%d failed: %s', $itemNum, $i, $description
e7f3c31 @gwoo going lithium
gwoo authored
506 ));
507 return false;
508 }
509 }
94759a2 @gwoo adding test coverage and fixes to `\test\Unit`
gwoo authored
510 return $this->assert(true);
e7f3c31 @gwoo going lithium
gwoo authored
511 }
512
513 /**
2c6d422 @pointlessjon refactored `assertCookie()` to not require passing headers_list() exp…
pointlessjon authored
514 * Assert Cookie data is properly set in headers.
515 *
516 * The value passed to `exepected` is an array of the cookie data, with at least the key and
517 * value expected, but can support any of the following keys:
518 * - `key`: the expected key
519 * - `value`: the expected value
520 * - `path`: optionally specifiy a path
521 * - `name`: optionally specify the cookie name
522 * - `expires`: optionally assert a specific expire time
523 *
524 * @param array $expected
525 * @param array $headers When empty, value of `headers_list()` is used.
c25e039 @Howard3 Cleaning up PHPDoc @return tags with multiple return types defined.
Howard3 authored
526 * @return boolean
2c6d422 @pointlessjon refactored `assertCookie()` to not require passing headers_list() exp…
pointlessjon authored
527 */
528 public function assertCookie($expected, $headers = null) {
50bf3e0 @jperras Adding new `assertNoCookie` method to `test\Unit`.
jperras authored
529 $matched = $this->_cookieMatch($expected, $headers);
530 if (!$matched['match']) {
531 $message = sprintf('%s - Cookie not found in headers.', $matched['pattern']);
532 $this->assert(false, $message, compact('expected', 'result'));
533 return false;
534 }
535 return $this->assert(true, '%s');
536 }
537
538 /**
539 * Assert Cookie data is *not* set in headers.
540 *
a0930f4 @phishy fixed spelling errors
phishy authored
541 * The value passed to `expected` is an array of the cookie data, with at least the key and
50bf3e0 @jperras Adding new `assertNoCookie` method to `test\Unit`.
jperras authored
542 * value expected, but can support any of the following keys:
543 * - `key`: the expected key
544 * - `value`: the expected value
a0930f4 @phishy fixed spelling errors
phishy authored
545 * - `path`: optionally specify a path
50bf3e0 @jperras Adding new `assertNoCookie` method to `test\Unit`.
jperras authored
546 * - `name`: optionally specify the cookie name
547 * - `expires`: optionally assert a specific expire time
548 *
549 * @param array $expected
550 * @param array $headers When empty, value of `headers_list()` is used.
c25e039 @Howard3 Cleaning up PHPDoc @return tags with multiple return types defined.
Howard3 authored
551 * @return boolean
50bf3e0 @jperras Adding new `assertNoCookie` method to `test\Unit`.
jperras authored
552 */
553 public function assertNoCookie($expected, $headers = null) {
554 $matched = $this->_cookieMatch($expected, $headers);
555 if ($matched['match']) {
3590379 @daschl fixing typo in Unit class
daschl authored
556 $message = sprintf('%s - Cookie found in headers.', $matched['pattern']);
50bf3e0 @jperras Adding new `assertNoCookie` method to `test\Unit`.
jperras authored
557 $this->assert(false, $message, compact('expected', 'result'));
558 return false;
559 }
560 return $this->assert(true, '%s');
561 }
562
563 /**
564 * Match an `$expected` cookie with the given headers. If no headers are provided, then
565 * the value of `headers_list()` will be used.
566 *
567 * @param array $expected
568 * @param array $headers When empty, value of `headers_list()` will be used.
569 * @return boolean True if cookie is found, false otherwise.
570 */
571 protected function _cookieMatch($expected, $headers) {
2fd813c @nateabele Fixing `\test\Unit::assertCookie()` for better spec conformance, addr…
nateabele authored
572 $defaults = array('path' => '/', 'name' => '[\w.-]+');
2c6d422 @pointlessjon refactored `assertCookie()` to not require passing headers_list() exp…
pointlessjon authored
573 $expected += $defaults;
574
b80f3b1 @jperras Small simplification to `test\Unit::assertCookie()`.
jperras authored
575 $headers = ($headers) ?: headers_list();
2c6d422 @pointlessjon refactored `assertCookie()` to not require passing headers_list() exp…
pointlessjon authored
576 $value = preg_quote(urlencode($expected['value']), '/');
577
578 $key = explode('.', $expected['key']);
579 $key = (count($key) == 1) ? '[' . current($key) . ']' : ('[' . join('][', $key) . ']');
580 $key = preg_quote($key, '/');
581
582 if (isset($expected['expires'])) {
583 $date = gmdate('D, d-M-Y H:i:s \G\M\T', strtotime($expected['expires']));
584 $expires = preg_quote($date, '/');
585 } else {
586 $expires = '(?:.+?)';
587 }
588 $path = preg_quote($expected['path'], '/');
589 $pattern = "/^Set\-Cookie:\s{$expected['name']}$key=$value;";
590 $pattern .= "\sexpires=$expires;\spath=$path/";
591 $match = false;
592
b96b63c @gwoo fixing up test cases that were failing.
gwoo authored
593 foreach ($headers as $header) {
2c6d422 @pointlessjon refactored `assertCookie()` to not require passing headers_list() exp…
pointlessjon authored
594 if (preg_match($pattern, $header)) {
595 $match = true;
596 continue;
597 }
598 }
50bf3e0 @jperras Adding new `assertNoCookie` method to `test\Unit`.
jperras authored
599 return compact('match', 'pattern');
2c6d422 @pointlessjon refactored `assertCookie()` to not require passing headers_list() exp…
pointlessjon authored
600 }
601
602 /**
e7f3c31 @gwoo going lithium
gwoo authored
603 * Used before a call to `assert*()` if you expect the test assertion to generate an exception
604 * or PHP error. If no error or exception is thrown, a test failure will be reported. Can
605 * be called multiple times per assertion, if more than one error is expected.
606 *
607 * @param mixed $message A string indicating what the error text is expected to be. This can
608 * be an exact string, a /-delimited regular expression, or true, indicating that
609 * any error text is acceptable.
610 * @return void
611 */
612 public function expectException($message = true) {
613 $this->_expected[] = $message;
614 }
615
616 /**
617 * Reports test result messages.
618 *
619 * @param string $type The type of result being reported. Can be `'pass'`, `'fail'`, `'skip'`
620 * or `'exception'`.
621 * @param array $info An array of information about the test result. At a minimum, this should
622 * contain a `'message'` key. Other possible keys are `'file'`, `'line'`,
623 * `'class'`, `'method'`, `'assertion'` and `'data'`.
624 * @param array $options Currently unimplemented.
625 * @return void
626 */
f80098d @nateabele Adding type hinting to constructor `$config` arrays and all applicabl…
nateabele authored
627 protected function _result($type, $info, array $options = array()) {
e7f3c31 @gwoo going lithium
gwoo authored
628 $info = (array('result' => $type) + $info);
629 $defaults = array();
630 $options += $defaults;
631 if ($this->_reporter) {
632 $filtered = $this->_reporter->__invoke($info);
633 $info = is_array($filtered) ? $filtered : $info;
634 }
635 $this->_results[] = $info;
636 }
637
638 /**
639 * Runs an individual test method, collecting results and catching exceptions along the way.
640 *
641 * @param string $method The name of the test method to run.
642 * @param array $options
c25e039 @Howard3 Cleaning up PHPDoc @return tags with multiple return types defined.
Howard3 authored
643 * @return mixed
59cb735 @nateabele Ensuring `@filter` tags are present in docblocks that support filteri…
nateabele authored
644 * @filter
e7f3c31 @gwoo going lithium
gwoo authored
645 */
646 protected function _runTestMethod($method, $options) {
a098506 @nateabele Catching setup exceptions in `test\Unit`, correcting total number of …
nateabele authored
647 try {
648 $this->setUp();
649 } catch (Exception $e) {
650 $this->_handleException($e, __LINE__ - 2);
b3601fc @gwoo adding skip rendering to \test
gwoo authored
651 return $this->_results;
a098506 @nateabele Catching setup exceptions in `test\Unit`, correcting total number of …
nateabele authored
652 }
e7f3c31 @gwoo going lithium
gwoo authored
653 $params = compact('options', 'method');
654
0fe57ca @indiefan Added Base Integration test class and unit testing of said class.
indiefan authored
655 $passed = $this->_filter(__CLASS__ . '::run', $params, function($self, $params, $chain) {
e7f3c31 @gwoo going lithium
gwoo authored
656 try {
657 $method = $params['method'];
658 $lineFlag = __LINE__ + 1;
659 $self->$method();
660 } catch (Exception $e) {
b3601fc @gwoo adding skip rendering to \test
gwoo authored
661 $self->invokeMethod('_handleException', array($e));
e7f3c31 @gwoo going lithium
gwoo authored
662 }
663 });
664 $this->tearDown();
0fe57ca @indiefan Added Base Integration test class and unit testing of said class.
indiefan authored
665
666 return $passed;
e7f3c31 @gwoo going lithium
gwoo authored
667 }
668
669 /**
670 * Normalizes `Exception` objects and PHP error data into a single array format, and checks
671 * each error against the list of expected errors (set using `expectException()`). If a match
672 * is found, the expectation is removed from the stack and the error is ignored. If no match
673 * is found, then the error data is logged to the test results.
674 *
25e5f82 @indiefan Updated Unit class to potentially break on fail (for Integration tests)
indiefan authored
675 * @see lithium\test\Unit::expectException()
676 * @see lithium\test\Unit::_reportException()
e7f3c31 @gwoo going lithium
gwoo authored
677 * @param mixed $exception An `Exception` object instance, or an array containing the following
678 * keys: `'message'`, `'file'`, `'line'`, `'trace'` (in `debug_backtrace()`
679 * format) and optionally `'code'` (error code number) and `'context'` (an array
680 * of variables relevant to the scope of where the error occurred).
681 * @param integer $lineFlag A flag used for determining the relevant scope of the call stack.
682 * Set to the line number where test methods are called.
683 * @return void
684 */
685 protected function _handleException($exception, $lineFlag = null) {
36f1b2c @gwoo updating `\test\Unit` handling of array comparisons and exception rep…
gwoo authored
686 $data = $exception;
687
e7f3c31 @gwoo going lithium
gwoo authored
688 if (is_object($exception)) {
689 $data = array();
690
691 foreach (array('message', 'file', 'line', 'trace') as $key) {
692 $method = 'get' . ucfirst($key);
693 $data[$key] = $exception->{$method}();
694 }
695 $ref = $exception->getTrace();
696 $ref = $ref[0] + array('class' => null);
697
698 if ($ref['class'] == __CLASS__ && $ref['function'] == 'skipIf') {
699 return $this->_result('skip', $data);
700 }
701 }
36f1b2c @gwoo updating `\test\Unit` handling of array comparisons and exception rep…
gwoo authored
702 return $this->_reportException($data, $lineFlag);
e7f3c31 @gwoo going lithium
gwoo authored
703 }
704
705 /**
706 * Convert an exception object to an exception result array for test reporting.
707 *
36f1b2c @gwoo updating `\test\Unit` handling of array comparisons and exception rep…
gwoo authored
708 * @param array $exception The exception data to report on. Statistics are gathered and
e7f3c31 @gwoo going lithium
gwoo authored
709 * added to the reporting stack contained in `Unit::$_results`.
e0cb56a @alkemann hooks fixes for lithium/test
alkemann authored
710 * @param string $lineFlag
e7f3c31 @gwoo going lithium
gwoo authored
711 * @return void
712 * @todo Refactor so that reporters handle trace formatting.
713 */
714 protected function _reportException($exception, $lineFlag = null) {
36f1b2c @gwoo updating `\test\Unit` handling of array comparisons and exception rep…
gwoo authored
715 $message = $exception['message'];
716
717 $isExpected = (($exp = end($this->_expected)) && ($exp === true || $exp == $message || (
718 Validator::isRegex($exp) && preg_match($exp, $message)
719 )));
720 if ($isExpected) {
721 return array_pop($this->_expected);
722 }
e7f3c31 @gwoo going lithium
gwoo authored
723 $initFrame = current($exception['trace']) + array('class' => '-', 'function' => '-');
36f1b2c @gwoo updating `\test\Unit` handling of array comparisons and exception rep…
gwoo authored
724
e7f3c31 @gwoo going lithium
gwoo authored
725 foreach ($exception['trace'] as $frame) {
726 if (isset($scopedFrame)) {
727 break;
728 }
d9cd028 @nateabele Moving all classes from `util\reflection` to `analysis` package.
nateabele authored
729 if (!class_exists('lithium\analysis\Inspector')) {
e292c8f @nateabele Fixing issue in `Unit::_reportException()` where errors are reported …
nateabele authored
730 continue;
731 }
e7f3c31 @gwoo going lithium
gwoo authored
732 if (isset($frame['class']) && in_array($frame['class'], Inspector::parents($this))) {
733 $scopedFrame = $frame;
734 }
735 }
36f1b2c @gwoo updating `\test\Unit` handling of array comparisons and exception rep…
gwoo authored
736 if (class_exists('lithium\analysis\Debugger')) {
737 $exception['trace'] = Debugger::trace(array(
738 'trace' => $exception['trace'],
e7f3c31 @gwoo going lithium
gwoo authored
739 'format' => '{:functionRef}, line {:line}',
740 'includeScope' => false,
741 'scope' => array_filter(array(
742 'functionRef' => __NAMESPACE__ . '\{closure}',
743 'line' => $lineFlag
26c2192 @davidpersson QA: Removing trailing comma in arrays, lowercasing some keywords.
davidpersson authored
744 ))
36f1b2c @gwoo updating `\test\Unit` handling of array comparisons and exception rep…
gwoo authored
745 ));
746 }
747 $this->_result('exception', $exception + array(
748 'class' => $initFrame['class'],
749 'method' => $initFrame['function']
e7f3c31 @gwoo going lithium
gwoo authored
750 ));
751 }
752
753 /**
754 * Compare the expected with the result. If `$result` is null `$expected` equals `$type`
755 * and `$result` equals `$expected`.
756 *
757 * @param string $type The type of comparison either `'identical'` or `'equal'` (default).
758 * @param mixed $expected The expected value.
759 * @param mixed $result An optional result value, defaults to `null`
760 * @param string $trace An optional trace used internally to track arrays and objects,
761 * defaults to `null`.
762 * @return array Data with the keys `trace'`, `'expected'` and `'result'`.
763 */
764 protected function _compare($type, $expected, $result = null, $trace = null) {
947ed22 @gwoo fixing issue in \test\Unit when comparing empty arrays would cause in…
gwoo authored
765 $compareTypes = function($expected, $result, $trace) {
766 $types = array('expected' => gettype($expected), 'result' => gettype($result));
36f1b2c @gwoo updating `\test\Unit` handling of array comparisons and exception rep…
gwoo authored
767
947ed22 @gwoo fixing issue in \test\Unit when comparing empty arrays would cause in…
gwoo authored
768 if ($types['expected'] !== $types['result']) {
ba43dfb @gwoo made some code easier to read in \test\Unit
gwoo authored
769 $expected = trim("({$types['expected']}) " . print_r($expected, true));
770 $result = trim("({$types['result']}) " . print_r($result, true));
771 return compact('trace', 'expected', 'result');
947ed22 @gwoo fixing issue in \test\Unit when comparing empty arrays would cause in…
gwoo authored
772 }
773 };
774 if ($types = $compareTypes($expected, $result, $trace)) {
775 return $types;
e7f3c31 @gwoo going lithium
gwoo authored
776 }
777 $data = array();
778
7528ad9 @gwoo cleaning up \test\* to run all tests.
gwoo authored
779 if (!is_scalar($expected)) {
e7f3c31 @gwoo going lithium
gwoo authored
780 foreach ($expected as $key => $value) {
947ed22 @gwoo fixing issue in \test\Unit when comparing empty arrays would cause in…
gwoo authored
781 $newTrace = "{$trace}[{$key}]";
7528ad9 @gwoo cleaning up \test\* to run all tests.
gwoo authored
782 $isObject = false;
783
784 if (is_object($expected)) {
785 $isObject = true;
786 $expected = (array) $expected;
787 $result = (array) $result;
788 }
947ed22 @gwoo fixing issue in \test\Unit when comparing empty arrays would cause in…
gwoo authored
789 if (!array_key_exists($key, $result)) {
790 $trace = (!$key) ? null : $newTrace;
791 $expected = (!$key) ? $expected : $value;
792 $result = ($key) ? null : $result;
793 return compact('trace', 'expected', 'result');
794 }
795 $check = $result[$key];
7528ad9 @gwoo cleaning up \test\* to run all tests.
gwoo authored
796
b49ef92 @gwoo 91% coverage for `\test\Unit`
gwoo authored
797 if ($isObject) {
798 $newTrace = ($trace) ? "{$trace}->{$key}" : $key;
799 $expected = (object) $expected;
800 $result = (object) $result;
801 }
e7f3c31 @gwoo going lithium
gwoo authored
802 if ($type === 'identical') {
803 if ($value === $check) {
947ed22 @gwoo fixing issue in \test\Unit when comparing empty arrays would cause in…
gwoo authored
804 if ($types = $compareTypes($value, $check, $trace)) {
805 return $types;
806 }
e7f3c31 @gwoo going lithium
gwoo authored
807 continue;
808 }
36f1b2c @gwoo updating `\test\Unit` handling of array comparisons and exception rep…
gwoo authored
809 if ($check === array()) {
e7f3c31 @gwoo going lithium
gwoo authored
810 $trace = $newTrace;
811 return compact('trace', 'expected', 'result');
812 }
b49ef92 @gwoo 91% coverage for `\test\Unit`
gwoo authored
813 if (is_string($check)) {
814 $trace = $newTrace;
815 $expected = $value;
816 $result = $check;
817 return compact('trace', 'expected', 'result');
818 }
e7f3c31 @gwoo going lithium
gwoo authored
819 } else {
820 if ($value == $check) {
947ed22 @gwoo fixing issue in \test\Unit when comparing empty arrays would cause in…
gwoo authored
821 if ($types = $compareTypes($value, $check, $trace)) {
822 return $types;
823 }
e7f3c31 @gwoo going lithium
gwoo authored
824 continue;
825 }
826 if (!is_array($value)) {
827 $trace = $newTrace;
828 return compact('trace', 'expected', 'result');
829 }
830 }
831 $compare = $this->_compare($type, $value, $check, $newTrace);
832
833 if ($compare !== true) {
834 $data[] = $compare;
835 }
836 }
3b36487 @gwoo adding more comparison data to \test\Unit
gwoo authored
837 if (!empty($data)) {
838 return $data;
839 }
840 }
841 if (!is_scalar($result)) {
842 $data = $this->_compare($type, $result, $expected);
843
844 if (!empty($data)) {
845 return array(
846 'trace' => $data['trace'],
847 'expected' => $data['result'],
848 'result' => $data['expected']
849 );
850 }
e7f3c31 @gwoo going lithium
gwoo authored
851 }
947ed22 @gwoo fixing issue in \test\Unit when comparing empty arrays would cause in…
gwoo authored
852 if ((($type === 'identical') ? $expected === $result : $expected == $result)) {
853 if ($types = $compareTypes($expected, $result, $trace)) {
854 return $types;
e7f3c31 @gwoo going lithium
gwoo authored
855 }
7528ad9 @gwoo cleaning up \test\* to run all tests.
gwoo authored
856 return true;
e7f3c31 @gwoo going lithium
gwoo authored
857 }
94759a2 @gwoo adding test coverage and fixes to `\test\Unit`
gwoo authored
858 return compact('trace', 'expected', 'result');
e7f3c31 @gwoo going lithium
gwoo authored
859 }
860
861 /**
862 * Returns a basic message for the data returned from `_result()`.
863 *
864 * @see lithium\test\Unit::assert()
865 * @see lithium\test\Unit::_result()
25e5f82 @indiefan Updated Unit class to potentially break on fail (for Integration tests)
indiefan authored
866 * @param array $data The data to use for creating the message.
94759a2 @gwoo adding test coverage and fixes to `\test\Unit`
gwoo authored
867 * @param string $message The string prepended to the generate message in the current scope.
25e5f82 @indiefan Updated Unit class to potentially break on fail (for Integration tests)
indiefan authored
868 * @return string
e7f3c31 @gwoo going lithium
gwoo authored
869 */
94759a2 @gwoo adding test coverage and fixes to `\test\Unit`
gwoo authored
870 protected function _message(&$data = array(), $message = null) {
e7f3c31 @gwoo going lithium
gwoo authored
871 if (!empty($data[0])) {
94759a2 @gwoo adding test coverage and fixes to `\test\Unit`
gwoo authored
872 foreach ($data as $key => $value) {
873 $message = (!empty($data[$key][0])) ? $message : null;
874 $message .= $this->_message($value, $message);
875 unset($data[$key]);
e7f3c31 @gwoo going lithium
gwoo authored
876 }
94759a2 @gwoo adding test coverage and fixes to `\test\Unit`
gwoo authored
877 return $message;
e7f3c31 @gwoo going lithium
gwoo authored
878 }
879 $defaults = array('trace' => null, 'expected' => null, 'result' => null);
94759a2 @gwoo adding test coverage and fixes to `\test\Unit`
gwoo authored
880 $result = (array) $data + $defaults;
8bfcfe4 @gwoo updating test suite handling. Re-Adding `\test\Controller` for browse…
gwoo authored
881
c7e00dd @pointlessjon removing trace line from `\lithium\test\Unit::_message()` output when…
pointlessjon authored
882 $message = null;
883 if (!empty($result['trace'])) {
884 $message = sprintf("trace: %s\n", $result['trace']);
885 }
b49ef92 @gwoo 91% coverage for `\test\Unit`
gwoo authored
886 if (is_object($result['expected'])) {
887 $result['expected'] = get_object_vars($result['expected']);
888 }
889 if (is_object($result['result'])) {
890 $result['result'] = get_object_vars($result['result']);
891 }
c7e00dd @pointlessjon removing trace line from `\lithium\test\Unit::_message()` output when…
pointlessjon authored
892 return $message . sprintf("expected: %s\nresult: %s\n",
94759a2 @gwoo adding test coverage and fixes to `\test\Unit`
gwoo authored
893 var_export($result['expected'], true),
894 var_export($result['result'], true)
e7f3c31 @gwoo going lithium
gwoo authored
895 );
896 }
897
898 /**
899 * Generates all permutation of an array $items and returns them in a new array.
900 *
901 * @param array $items An array of items
e0cb56a @alkemann hooks fixes for lithium/test
alkemann authored
902 * @param array $perms
e7f3c31 @gwoo going lithium
gwoo authored
903 * @return array
904 */
905 protected function _arrayPermute($items, $perms = array()) {
906 static $permuted;
907
908 if (empty($perms)) {
909 $permuted = array();
910 }
911
912 if (empty($items)) {
913 $permuted[] = $perms;
2920ba5 @gwoo fixing libraries test and updating UnitTest.
gwoo authored
914 return;
e7f3c31 @gwoo going lithium
gwoo authored
915 }
2920ba5 @gwoo fixing libraries test and updating UnitTest.
gwoo authored
916 $numItems = count($items) - 1;
917
918 for ($i = $numItems; $i >= 0; --$i) {
919 $newItems = $items;
920 $newPerms = $perms;
921 list($tmp) = array_splice($newItems, $i, 1);
922 array_unshift($newPerms, $tmp);
923 $this->_arrayPermute($newItems, $newPerms);
924 }
925 return $permuted;
e7f3c31 @gwoo going lithium
gwoo authored
926 }
1b37b2f @gwoo adding Unit::_cleanUp to assist in clearing stuff in temp
gwoo authored
927
928 /**
929 * Removes everything from `resources/tmp/tests` directory.
930 * Call from inside of your test method or `tearDown()`.
931 *
932 * @param string $path path to directory of contents to remove
933 * if first character is NOT `/` prepend `LITHIUM_APP_PATH/resources/tmp/`
934 * @return void
935 */
936 protected function _cleanUp($path = null) {
cccbfc5 @Howard3 Command:
Howard3 authored
937 $resources = Libraries::get(true, 'resources');
938 $path = $path ?: $resources . '/tmp/tests';
939 $path = preg_match('/^\w:|^\//', $path) ? $path : $resources . '/tmp/' . $path;
1d135a6 @nateabele Refactoring `\core\Libraries` to allow the resources directory path t…
nateabele authored
940
2920ba5 @gwoo fixing libraries test and updating UnitTest.
gwoo authored
941 if (!is_dir($path)) {
942 return;
943 }
1b37b2f @gwoo adding Unit::_cleanUp to assist in clearing stuff in temp
gwoo authored
944 $dirs = new RecursiveDirectoryIterator($path);
945 $iterator = new RecursiveIteratorIterator($dirs, RecursiveIteratorIterator::CHILD_FIRST);
1d135a6 @nateabele Refactoring `\core\Libraries` to allow the resources directory path t…
nateabele authored
946
1b37b2f @gwoo adding Unit::_cleanUp to assist in clearing stuff in temp
gwoo authored
947 foreach ($iterator as $item) {
5aa1aa2 @jperras Updating test\Unit::_cleanUp() to skip over dot paths ('.' and '..').
jperras authored
948 if ($item->getPathname() === "{$path}/empty" || $iterator->isDot()) {
25e5f82 @indiefan Updated Unit class to potentially break on fail (for Integration tests)
indiefan authored
949 continue;
950 }
1b37b2f @gwoo adding Unit::_cleanUp to assist in clearing stuff in temp
gwoo authored
951 ($item->isDir()) ? rmdir($item->getPathname()) : unlink($item->getPathname());
952 }
953 }
0fe57ca @indiefan Added Base Integration test class and unit testing of said class.
indiefan authored
954
955 /**
956 * Returns the current results
957 *
958 * @return array The Results, currently
959 */
960 public function results() {
961 return $this->_results;
962 }
5386306 @daschl refactoring internet connection check into \test\Unit. It is now poss…
daschl authored
963
964 /**
965 * Checks for a working internet connection.
966 *
967 * This method is used to check for a working connection to lithify.me, both
968 * testing for proper dns resolution and reading the actual URL.
969 *
30ab4c1 @daschl QA: Miscc QA fixes, including trailing commas, param documentation an…
daschl authored
970 * @param array $config Override the default URI to check.
5386306 @daschl refactoring internet connection check into \test\Unit. It is now poss…
daschl authored
971 * @return boolean True if a network connection is established, false otherwise.
972 */
973 protected function _hasNetwork($config = array()) {
974 $defaults = array(
975 'scheme' => 'http',
976 'host' => 'lithify.me'
977 );
978 $config += $defaults;
979
980 $url = "{$config['scheme']}://{$config['host']}";
981 $failed = false;
982
983 set_error_handler(function($errno, $errstr) use (&$failed) {
984 $failed = true;
985 });
986
987 $dnsCheck = dns_check_record($config['host'], "ANY");
988 $fileCheck = fopen($url, "r");
989
990 restore_error_handler();
991 return !$failed;
992 }
e7f3c31 @gwoo going lithium
gwoo authored
993 }
994
995 ?>
Something went wrong with that request. Please try again.