Group.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. <?php
  2. /**
  3. * Lithium: the most rad php framework
  4. *
  5. * @copyright Copyright 2013, Union of RAD (http://union-of-rad.org)
  6. * @license http://opensource.org/licenses/bsd-license.php The BSD License
  7. */
  8. namespace lithium\test;
  9. use Exception;
  10. use lithium\test\Unit;
  11. use lithium\core\Libraries;
  12. use lithium\util\Collection;
  13. /**
  14. * A `Collection` of tests that represents a test group.
  15. *
  16. * Tests are added to this group either on `construct` by passing a fully-namespaced test class
  17. * or namespace string-based path, e.g.
  18. *
  19. * {{{
  20. * $group = new Group(array('data' => array(
  21. * 'data\ModelTest',
  22. * new \lithium\tests\cases\core\ObjectTest()
  23. * )));
  24. * }}}
  25. *
  26. * Or they can be added programmatically:
  27. *
  28. * {{{
  29. * $group->add('data\ModelTest');
  30. * }}}
  31. */
  32. class Group extends \lithium\util\Collection {
  33. /**
  34. * auto init for setting up items passed into constructor
  35. *
  36. * @return void
  37. */
  38. protected function _init() {
  39. parent::_init();
  40. $data = $this->_data;
  41. $this->_data = array();
  42. foreach ($data as $item) {
  43. $this->add($item);
  44. }
  45. }
  46. /**
  47. * Get all test cases. By default, does not include function or integration tests.
  48. *
  49. * @param array $options
  50. * @return array
  51. */
  52. public static function all(array $options = array()) {
  53. $defaults = array(
  54. 'filter' => '/cases/',
  55. 'exclude' => '/mock/',
  56. 'recursive' => true
  57. );
  58. return Libraries::locate('tests', null, $options + $defaults);
  59. }
  60. /**
  61. * Add a tests to the group.
  62. *
  63. * @param string $test The test to be added.
  64. * @param array $options Method options. Currently not used in this method.
  65. * @return array Updated list of tests contained within this collection.
  66. */
  67. public function add($test = null, array $options = array()) {
  68. $resolve = function($self, $test) {
  69. switch (true) {
  70. case !$test:
  71. return array();
  72. case is_object($test) && $test instanceof Unit:
  73. return array(get_class($test));
  74. case is_string($test) && !file_exists(Libraries::path($test)):
  75. return $self->invokeMethod('_resolve', array($test));
  76. default:
  77. return (array) $test;
  78. }
  79. };
  80. if (is_array($test)) {
  81. foreach ($test as $t) {
  82. $this->_data = array_filter(array_merge($this->_data, $resolve($this, $t)));
  83. }
  84. return $this->_data;
  85. }
  86. return $this->_data = array_merge($this->_data, $resolve($this, $test));
  87. }
  88. /**
  89. * Get the collection of tests
  90. *
  91. * @param string|array $params
  92. * @param array $options
  93. * @return lithium\util\Collection
  94. */
  95. public function tests($params = array(), array $options = array()) {
  96. $tests = new Collection();
  97. foreach ($this->_data as $test) {
  98. if (!class_exists($test)) {
  99. throw new Exception("Test case `{$test}` not found.");
  100. }
  101. $tests[] = new $test;
  102. }
  103. return $tests;
  104. }
  105. /**
  106. * Resolves a unit test class (or classes) from a class or namespace path string.
  107. *
  108. * @param string $test The path string in which to find the test case(s). This may be a
  109. * library, a namespace, or a fully-namespaced class reference.
  110. * @return array Returns an array containing one or more fully-namespaced class references to
  111. * unit tests.
  112. */
  113. protected function _resolve($test) {
  114. if (strpos($test, '\\') === false && Libraries::get($test)) {
  115. return (array) Libraries::find($test, array(
  116. 'recursive' => true, 'filter' => '/cases|integration|functional/'
  117. ));
  118. }
  119. if (preg_match("/Test/", $test)) {
  120. return array($test);
  121. }
  122. if (!$test = trim($test, '\\')) {
  123. return array();
  124. }
  125. list($library, $path) = explode('\\', $test, 2) + array($test, null);
  126. return (array) Libraries::find($library, array(
  127. 'recursive' => true,
  128. 'path' => '/' . str_replace('\\', '/', $path),
  129. 'filter' => '/cases|integration|functional/'
  130. ));
  131. }
  132. }
  133. ?>