diff --git a/core/modules/breakpoint/lib/Drupal/breakpoint/Tests/BreakpointMediaQueryTest.php b/core/modules/breakpoint/tests/Drupal/breakpoint/Tests/BreakpointMediaQueryTest.php similarity index 94% rename from core/modules/breakpoint/lib/Drupal/breakpoint/Tests/BreakpointMediaQueryTest.php rename to core/modules/breakpoint/tests/Drupal/breakpoint/Tests/BreakpointMediaQueryTest.php index d0ee5fb..1e2524f 100644 --- a/core/modules/breakpoint/lib/Drupal/breakpoint/Tests/BreakpointMediaQueryTest.php +++ b/core/modules/breakpoint/tests/Drupal/breakpoint/Tests/BreakpointMediaQueryTest.php @@ -6,14 +6,16 @@ namespace Drupal\breakpoint\Tests; -use Drupal\simpletest\UnitTestBase; +use Drupal\Tests\UnitTestCase; use Drupal\breakpoint\Plugin\Core\Entity\Breakpoint; use Drupal\breakpoint\InvalidBreakpointMediaQueryException; /** * Tests for media queries in a breakpoint. + * + * @group Breakpoint */ -class BreakpointMediaQueryTest extends UnitTestBase { +class BreakpointMediaQueryTest extends UnitTestCase { public static function getInfo() { return array( @@ -116,7 +118,7 @@ public function testInvalidMediaQueries() { $this->assertFalse(Breakpoint::isValidMediaQuery($media_query), $media_query . ' is not valid.'); } catch (InvalidBreakpointMediaQueryException $e) { - $this->assertTrue(TRUE, format_string('%media_query is not valid.', array('%media_query' => $media_query))); + $this->assertTrue(TRUE, sprintf('%s is not valid.', $media_query)); } } } diff --git a/core/modules/simpletest/simpletest.module b/core/modules/simpletest/simpletest.module index d7adb65..6ceb4fd 100644 --- a/core/modules/simpletest/simpletest.module +++ b/core/modules/simpletest/simpletest.module @@ -130,6 +130,18 @@ function simpletest_run_tests($test_list, $reporter = 'drupal') { ->useDefaults(array('test_id')) ->execute(); + $phpunit_tests = isset($test_list['UnitTest']) ? $test_list['UnitTest'] : array(); + $phpunit_results = simpletest_run_phpunit_tests($test_id, $phpunit_tests); + simpletest_process_phpunit_results($phpunit_results); + + if (!array_key_exists('WebTest', $test_list) || empty($test_list['WebTest'])) { + // Early return if there are no WebTests to run. + return $test_id; + } + + // Contine with SimpleTests only. + $test_list = $test_list['WebTest']; + // Clear out the previous verbose files. file_unmanaged_delete_recursive('public://simpletest/verbose'); @@ -157,6 +169,102 @@ function simpletest_run_tests($test_list, $reporter = 'drupal') { } /** + * Executes phpunit tests and returns the results of the run. + * + * @param $test_id + * The current test ID. + * @param $unescaped_test_classnames + * An array of test class names, including full namespaces, to be passed as + * a regular expression to phpunit's --filter option. + * + * @return array + * The parsed results of phpunit's junit xml output, in the format of the + * simpletest table's schema. + */ +function simpletest_run_phpunit_tests($test_id, array $unescaped_test_classnames) { + $phpunit_file = simpletest_phpunit_xml_filepath($test_id); + simpletest_phpunit_run_command($unescaped_test_classnames, $phpunit_file); + return simpletest_phpunit_xml_to_rows($test_id, $phpunit_file); +} + +/** + * Inserts the parsed phpunit results into the simpletest table. + * + * @param array $phpunit_results + * An array of test results returned from simpletest_phpunit_xml_to_rows. + */ +function simpletest_process_phpunit_results($phpunit_results) { + // Insert the results of the phpunit test run into the db so the results are + // displayed along with simpletest's results. + if (!empty($phpunit_results)) { + $query = db_insert('simpletest')->fields(array_keys($phpunit_results[0])); + foreach ($phpunit_results as $result) { + $query->values($result); + } + $query->execute(); + } +} + +/** + * Returns the path to use for phpunit's --log-junit option. + * + * @param $test_id + * The current test ID. + * @return string + * Path to the phpunit xml file to use for the current test_id. + */ +function simpletest_phpunit_xml_filepath($test_id) { + return drupal_realpath('public://simpletest') . '/phpunit-' . $test_id . '.xml'; +} + +/** + * Returns the path to core's phpunit.xml.dist configuration file. + * + * @return string + * Path to core's phpunit.xml.dist configuration file. + */ +function simpletest_phpunit_configuration_filepath() { + return DRUPAL_ROOT . '/core/phpunit.xml.dist'; +} + +/** + * Executes the phpunit command. We do this via exec in a subshell so that the + * environment is isolated when running tests via the simpletest UI. + * + * @param array $unescaped_test_classnames + * An array of test class names, including full namespaces, to be passed as + * a regular expression to phpunit's --filter option. + * @param string $phpunit_file + * A filepath to use for phpunit's --log-junit option. + */ +function simpletest_phpunit_run_command(array $unescaped_test_classnames, $phpunit_file) { + $phpunit_bin = DRUPAL_ROOT . "/core/vendor/bin/phpunit"; + + // Double escape namespaces so they'll work in a regexp. + $escaped_test_classnames = array_map(function($class) { + return addslashes($class); + }, $unescaped_test_classnames); + + $filter_string = implode("|", $escaped_test_classnames); + + $command = array( + $phpunit_bin, + '--filter', + escapeshellarg($filter_string), + '--log-junit', + escapeshellarg($phpunit_file), + ); + + // Need to change directories before running the command so that we can use + // relative paths in the configuration file's exclusions. + $old_cwd = getcwd(); + chdir(DRUPAL_ROOT . "/core"); + $ret = exec(join($command, " ")); + chdir($old_cwd); + return $ret; +} + +/** * Batch operation callback. */ function _simpletest_batch_operation($test_list_init, $test_id, &$context) { @@ -397,10 +505,23 @@ function simpletest_classloader_register() { $matches = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.' . $info['extension'] . '$/', $info['dir']); foreach ($matches as $name => $file) { drupal_classloader_register($name, dirname($file->uri)); + drupal_classloader()->registerNamespace('Drupal\\' . $name . '\\Tests', DRUPAL_ROOT . '/' . dirname($file->uri) . '/tests'); // While being there, prime drupal_get_filename(). drupal_get_filename($type, $name, $file->uri); } } + + // Register the core test directory so we can find Drupal\UnitTestCase. + drupal_classloader()->registerNamespace('Drupal\\Tests', DRUPAL_ROOT . '/core/tests'); + + // Manually register phpunit prefixes because they use a classmap instead of a + // prefix. This can be safely removed if we move to using composer's + // autoloader with a classmap. + drupal_classloader()->registerPrefixes(array( + 'PHPUnit' => DRUPAL_ROOT . '/core/vendor/phpunit/phpunit', + 'File_Iterator' => DRUPAL_ROOT . '/core/vendor/phpunit/php-file-iterator/', + 'PHP_Timer' => DRUPAL_ROOT . '/core/vendor/phpunit/php-timer/', + )); } /** @@ -568,3 +689,64 @@ function simpletest_library_info() { return $libraries; } + +/** + * Get PHPUnit Classes + * + * @param bool $name_only + * If TRUE, returns a flat array of class names only. + */ +function simpletest_phpunit_get_available_tests() { + // Load the PHPUnit configuration file, which tells us where to find the tests. + $phpunit_config = simpletest_phpunit_configuration_filepath(); + $configuration = PHPUnit_Util_Configuration::getInstance($phpunit_config); + // Find all the tests and get a list of unique class names. + $test_suite = $configuration->getTestSuiteConfiguration(NULL); + $test_classes = array(); + foreach ($test_suite AS $test) { + $name = get_class($test); + if (!array_key_exists($name, $test_classes)) { + $test_classes[$name] = $test->getInfo(); + } + } + + return $test_classes; +} + +/** + * Converts phpunit's junit xml output to an array of rows that can be inserted + * into the simpletest results table. + * + * @param $test_id + * The current test ID. + * @param $phpunit_xml_file + * Path to the phpunit xml file. + */ +function simpletest_phpunit_xml_to_rows($test_id, $phpunit_xml_file) { + $contents = file_get_contents($phpunit_xml_file); + $xml = new SimpleXMLElement($contents); + $records = array(); + foreach ($xml->testsuite as $testsuite) { + foreach ($testsuite as $suite) { + foreach ($suite as $testcase) { + $message = ''; + if ($testcase->failure) { + $lines = explode("\n", $testcase->failure); + $message = $lines[2]; + } + $attributes = $testcase->attributes(); + $records[] = array( + 'test_id' => $test_id, + 'test_class' => (string)$attributes->class, + 'status' => empty($testcase->failure) ? 'pass' : 'fail', + 'message' => $message, + 'message_group' => 'Other', // TODO: Check on the proper values for this. + 'function' => $attributes->class . '->' . $attributes->name . '()', + 'line' => (string)$attributes->line, + 'file' => (string)$attributes->file, + ); + } + } + } + return $records; +} diff --git a/core/modules/simpletest/simpletest.pages.inc b/core/modules/simpletest/simpletest.pages.inc index 7fe64d7..61a4f82 100644 --- a/core/modules/simpletest/simpletest.pages.inc +++ b/core/modules/simpletest/simpletest.pages.inc @@ -8,7 +8,7 @@ /** * List tests arranged in groups that can be selected and run. */ -function simpletest_test_form($form) { +function simpletest_test_form($form, &$form_state) { $form['tests'] = array( '#type' => 'details', '#title' => t('Tests'), @@ -21,6 +21,9 @@ function simpletest_test_form($form) { // Generate the list of tests arranged by group. $groups = simpletest_test_get_all(); + $groups['PHPUnit'] = simpletest_phpunit_get_available_tests(); + $form_state['storage']['PHPUnit'] = $groups['PHPUnit']; + foreach ($groups as $group => $tests) { $form['tests']['table'][$group] = array( '#collapsed' => TRUE, @@ -180,11 +183,15 @@ function simpletest_test_form_submit($form, &$form_state) { // Get list of tests. $tests_list = array(); simpletest_classloader_register(); + + $phpunit_all = array_keys($form_state['storage']['PHPUnit']); + foreach ($form_state['values'] as $class_name => $value) { // Since class_exists() will likely trigger an autoload lookup, // we do the fast check first. if ($value === 1 && class_exists($class_name)) { - $tests_list[] = $class_name; + $test_type = in_array($class_name, $phpunit_all) ? 'UnitTest' : 'WebTest'; + $tests_list[$test_type][] = $class_name; } } if (count($tests_list) > 0 ) { diff --git a/core/phpunit.xml.dist b/core/phpunit.xml.dist new file mode 100644 index 0000000..6ca7e89 --- /dev/null +++ b/core/phpunit.xml.dist @@ -0,0 +1,16 @@ + + + + + + ./tests/* + ./modules/*/tests/* + ../modules/*/tests/* + ../sites/*/modules/*/tests/* + + ./modules/config/tests/config_test/lib/Drupal/config_test + ./modules/views/tests/views_test_data/lib/Drupal/views_test_data + + + + diff --git a/core/scripts/run-tests.sh b/core/scripts/run-tests.sh index 3609bd7..30087ef 100755 --- a/core/scripts/run-tests.sh +++ b/core/scripts/run-tests.sh @@ -51,7 +51,7 @@ // Display all available tests. echo "\nAvailable test groups & classes\n"; echo "-------------------------------\n\n"; - $groups = simpletest_test_get_all(); + $groups = simpletest_script_get_all_tests(); foreach ($groups as $group => $tests) { echo $group . "\n"; foreach ($tests as $class => $info) { @@ -316,22 +316,67 @@ function simpletest_script_init($server_software) { } /** + * Get all available tests from simpletest and PHPUnit. + * + * @return + * An array of tests keyed with the groups specified in each of the tests + * getInfo() method and then keyed by the test class. An example of the array + * structure is provided below. + * + * @code + * $groups['Block'] => array( + * 'BlockTestCase' => array( + * 'name' => 'Block functionality', + * 'description' => 'Add, edit and delete custom block...', + * 'group' => 'Block', + * ), + * ); + * @endcode + */ +function simpletest_script_get_all_tests() { + $tests = simpletest_test_get_all(); + $tests['PHPUnit'] = simpletest_phpunit_get_available_tests(); + return $tests; +} + +/** * Execute a batch of tests. */ -function simpletest_script_execute_batch($test_classes) { +function simpletest_script_execute_batch($test_groups) { global $args, $test_ids; + // Separate PHPUnit tests from simpletest. + if (isset($test_groups['PHPUnit'])) { + $phpunit_tests = $test_groups['PHPUnit']; + unset($test_groups['PHPUnit']); + } + + // Flatten the simpletest tests into an array of classnames. + $test_classes = array(); + foreach ($test_groups as $group) { + $test_classes = array_merge($test_classes, array_values($group)); + } + // Multi-process execution. $children = array(); - while (!empty($test_classes) || !empty($children)) { + while (!empty($test_classes) || !empty($children) || isset($phpunit_tests)) { while (count($children) < $args['concurrency']) { - if (empty($test_classes)) { + if (empty($test_classes) && !isset($phpunit_tests)) { break; } - // Fork a child process. $test_id = db_insert('simpletest_test_id')->useDefaults(array('test_id'))->execute(); $test_ids[] = $test_id; + + // Process phpunit tests immediately since they are fast and we don't need + // to fork for them. + if (isset($phpunit_tests)) { + simpletest_script_run_phpunit($test_id, $phpunit_tests); + unset($phpunit_tests); + continue; + } + + // Fork a child process. $test_class = array_shift($test_classes); $command = simpletest_script_command($test_id, $test_class); $process = proc_open($command, array(), $pipes, NULL, NULL, array('bypass_shell' => TRUE)); @@ -384,6 +429,51 @@ function simpletest_script_execute_batch($test_classes) { } /** + * Run a group of phpunit tests. + */ +function simpletest_script_run_phpunit($test_id, $phpunit_tests) { + $results = simpletest_run_phpunit_tests($test_id, $phpunit_tests); + simpletest_process_phpunit_results($results); + + // Map phpunit results to a data structure we can pass to + // _simpletest_format_summary_line. + $summaries = array(); + foreach ($results as $result) { + if (!isset($summaries[$result['test_class']])) { + $summaries[$result['test_class']] = array( + '#pass' => 0, + '#fail' => 0, + '#exception' => 0, + '#debug' => 0, + ); + } + + switch ($result['status']) { + case 'pass': + $summaries[$result['test_class']]['#pass']++; + break; + case 'fail': + $summaries[$result['test_class']]['#fail']++; + break; + case 'exception': + $summaries[$result['test_class']]['#exception']++; + break; + case 'debug': + $summary['#exception']++; + break; + } + } + + foreach ($summaries as $class => $summary) { + $had_fails = $summary['#fail'] > 0; + $had_exceptions = $summary['#exception'] > 0; + $status = ($had_fails || $had_exceptions ? 'fail' : 'pass'); + $info = call_user_func(array($class, 'getInfo')); + simpletest_script_print($info['name'] . ' ' . _simpletest_format_summary_line($summary) . "\n", simpletest_script_color_code($status)); + } +} + +/** * Bootstrap Drupal and run a single test. */ function simpletest_script_run_one_test($test_id, $test_class) { @@ -535,10 +625,10 @@ function simpletest_script_get_test_list() { $test_list = array(); if ($args['all']) { - $groups = simpletest_test_get_all(); + $groups = simpletest_script_get_all_tests(); $all_tests = array(); foreach ($groups as $group => $tests) { - $all_tests = array_merge($all_tests, array_keys($tests)); + $all_tests[$group] = array_keys($tests); } $test_list = $all_tests; } @@ -578,20 +668,28 @@ function simpletest_script_get_test_list() { // Extract all class names. // Abstract classes are excluded on purpose. preg_match_all('@^class ([^ ]+)@m', $content, $matches); + + require $file; if (!$namespace) { - $test_list = array_merge($test_list, $matches[1]); + $info = $matches[1][0]::getInfo(); + $test_list[$info[$group]] = $matches[1][0]; } else { + $class = '\\' . $namespace . '\\' . $matches[1][0]; + $info = $class::getInfo(); foreach ($matches[1] as $class_name) { - $test_list[] = $namespace . '\\' . $class_name; + if (!isset($test_list[$info['group']])) { + $test_list[$info['group']] = array(); + } + $test_list[$info['group']][] = $namespace . '\\' . $class_name; } } } } else { - $groups = simpletest_test_get_all(); + $groups = simpletest_script_get_all_tests(); foreach ($args['test_names'] as $group_name) { - $test_list = array_merge($test_list, array_keys($groups[$group_name])); + $test_list[$group_name] = array_keys($groups[$group_name]); } } } @@ -626,9 +724,11 @@ function simpletest_script_reporter_init() { } else { echo "Tests to be run:\n"; - foreach ($test_list as $class_name) { - $info = call_user_func(array($class_name, 'getInfo')); - echo " - " . $info['name'] . ' (' . $class_name . ')' . "\n"; + foreach ($test_list as $group) { + foreach ($group as $class_name) { + $info = call_user_func(array($class_name, 'getInfo')); + echo " - " . $info['name'] . ' (' . $class_name . ')' . "\n"; + } } echo "\n"; } diff --git a/core/modules/system/lib/Drupal/system/Tests/Cache/BackendChainImplementationUnitTest.php b/core/tests/Drupal/Tests/Core/Cache/BackendChainImplementationUnitTest.php similarity index 72% rename from core/modules/system/lib/Drupal/system/Tests/Cache/BackendChainImplementationUnitTest.php rename to core/tests/Drupal/Tests/Core/Cache/BackendChainImplementationUnitTest.php index 9c528ce..ed1f24a 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Cache/BackendChainImplementationUnitTest.php +++ b/core/tests/Drupal/Tests/Core/Cache/BackendChainImplementationUnitTest.php @@ -2,20 +2,22 @@ /** * @file - * Definition of Drupal\system\Tests\Cache\BackendChainImplementationUnitTest. + * Definition of Drupal\Tests\Core\Cache\BackendChainImplementationUnitTest. */ -namespace Drupal\system\Tests\Cache; +namespace Drupal\Tests\Core\Cache; use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Cache\BackendChain; use Drupal\Core\Cache\MemoryBackend; -use Drupal\simpletest\UnitTestBase; +use Drupal\Tests\UnitTestCase; /** * Tests implementation-specific functionality of the BackendChain backend. + * + * @group Cache */ -class BackendChainImplementationUnitTest extends UnitTestBase { +class BackendChainImplementationUnitTest extends UnitTestCase { public static function getInfo() { return array( @@ -95,16 +97,16 @@ public function setUp() { */ public function testGet() { $cached = $this->chain->get('t123'); - $this->assertNotIdentical(FALSE, $cached, 'Got key that is on all backends'); - $this->assertIdentical(1231, $cached->data, 'Got the key from the backend 1'); + $this->assertNotSame(FALSE, $cached, 'Got key that is on all backends'); + $this->assertSame(1231, $cached->data, 'Got the key from the backend 1'); $cached = $this->chain->get('t23'); - $this->assertNotIdentical(FALSE, $cached, 'Got key that is on backends 2 and 3'); - $this->assertIdentical(232, $cached->data, 'Got the key from the backend 2'); + $this->assertNotSame(FALSE, $cached, 'Got key that is on backends 2 and 3'); + $this->assertSame(232, $cached->data, 'Got the key from the backend 2'); $cached = $this->chain->get('t3'); - $this->assertNotIdentical(FALSE, $cached, 'Got key that is on the backend 3'); - $this->assertIdentical(33, $cached->data, 'Got the key from the backend 3'); + $this->assertNotSame(FALSE, $cached, 'Got key that is on the backend 3'); + $this->assertSame(33, $cached->data, 'Got the key from the backend 3'); } /** @@ -114,15 +116,15 @@ public function testGetMultiple() { $cids = array('t123', 't23', 't3', 't4'); $ret = $this->chain->getMultiple($cids); - $this->assertIdentical($ret['t123']->data, 1231, 'Got key 123 and value is from the first backend'); - $this->assertIdentical($ret['t23']->data, 232, 'Got key 23 and value is from the second backend'); - $this->assertIdentical($ret['t3']->data, 33, 'Got key 3 and value is from the third backend'); + $this->assertSame($ret['t123']->data, 1231, 'Got key 123 and value is from the first backend'); + $this->assertSame($ret['t23']->data, 232, 'Got key 23 and value is from the second backend'); + $this->assertSame($ret['t3']->data, 33, 'Got key 3 and value is from the third backend'); $this->assertFalse(array_key_exists('t4', $ret), "Didn't get the nonexistent key"); $this->assertFalse(in_array('t123', $cids), "Existing key 123 has been removed from &\$cids"); $this->assertFalse(in_array('t23', $cids), "Existing key 23 has been removed from &\$cids"); $this->assertFalse(in_array('t3', $cids), "Existing key 3 has been removed from &\$cids"); - $this->assert(in_array('t4', $cids), "Non existing key 4 is still in &\$cids"); + $this->assertTrue(in_array('t4', $cids), "Non existing key 4 is still in &\$cids"); } /** @@ -132,16 +134,16 @@ public function testSet() { $this->chain->set('test', 123); $cached = $this->firstBackend->get('test'); - $this->assertNotIdentical(FALSE, $cached, 'Test key is in the first backend'); - $this->assertIdentical(123, $cached->data, 'Test key has the right value'); + $this->assertNotSame(FALSE, $cached, 'Test key is in the first backend'); + $this->assertSame(123, $cached->data, 'Test key has the right value'); $cached = $this->secondBackend->get('test'); - $this->assertNotIdentical(FALSE, $cached, 'Test key is in the second backend'); - $this->assertIdentical(123, $cached->data, 'Test key has the right value'); + $this->assertNotSame(FALSE, $cached, 'Test key is in the second backend'); + $this->assertSame(123, $cached->data, 'Test key has the right value'); $cached = $this->thirdBackend->get('test'); - $this->assertNotIdentical(FALSE, $cached, 'Test key is in the third backend'); - $this->assertIdentical(123, $cached->data, 'Test key has the right value'); + $this->assertNotSame(FALSE, $cached, 'Test key is in the third backend'); + $this->assertSame(123, $cached->data, 'Test key has the right value'); } /** @@ -151,20 +153,20 @@ public function testDelete() { $this->chain->set('test', 5); $cached = $this->firstBackend->get('test'); - $this->assertNotIdentical(FALSE, $cached, 'Test key has been added to the first backend'); + $this->assertNotSame(FALSE, $cached, 'Test key has been added to the first backend'); $cached = $this->secondBackend->get('test'); - $this->assertNotIdentical(FALSE, $cached, 'Test key has been added to the first backend'); + $this->assertNotSame(FALSE, $cached, 'Test key has been added to the first backend'); $cached = $this->thirdBackend->get('test'); - $this->assertNotIdentical(FALSE, $cached, 'Test key has been added to the first backend'); + $this->assertNotSame(FALSE, $cached, 'Test key has been added to the first backend'); $this->chain->delete('test'); $cached = $this->firstBackend->get('test'); - $this->assertIdentical(FALSE, $cached, 'Test key is removed from the first backend'); + $this->assertSame(FALSE, $cached, 'Test key is removed from the first backend'); $cached = $this->secondBackend->get('test'); - $this->assertIdentical(FALSE, $cached, 'Test key is removed from the second backend'); + $this->assertSame(FALSE, $cached, 'Test key is removed from the second backend'); $cached = $this->thirdBackend->get('test'); - $this->assertIdentical(FALSE, $cached, 'Test key is removed from the third backend'); + $this->assertSame(FALSE, $cached, 'Test key is removed from the third backend'); } /** @@ -173,13 +175,13 @@ public function testDelete() { public function testGetHasPropagated() { $this->chain->get('t23'); $cached = $this->firstBackend->get('t23'); - $this->assertNotIdentical(FALSE, $cached, 'Test 2 has been propagated to the first backend'); + $this->assertNotSame(FALSE, $cached, 'Test 2 has been propagated to the first backend'); $this->chain->get('t3'); $cached = $this->firstBackend->get('t3'); - $this->assertNotIdentical(FALSE, $cached, 'Test 3 has been propagated to the first backend'); + $this->assertNotSame(FALSE, $cached, 'Test 3 has been propagated to the first backend'); $cached = $this->secondBackend->get('t3'); - $this->assertNotIdentical(FALSE, $cached, 'Test 3 has been propagated to the second backend'); + $this->assertNotSame(FALSE, $cached, 'Test 3 has been propagated to the second backend'); } /** @@ -190,15 +192,15 @@ public function testGetMultipleHasPropagated() { $this->chain->getMultiple($cids); $cached = $this->firstBackend->get('t3'); - $this->assertNotIdentical(FALSE, $cached, 'Test 3 has been propagated to the first backend'); - $this->assertIdentical(33, $cached->data, 'And value has been kept'); + $this->assertNotSame(FALSE, $cached, 'Test 3 has been propagated to the first backend'); + $this->assertSame(33, $cached->data, 'And value has been kept'); $cached = $this->secondBackend->get('t3'); - $this->assertNotIdentical(FALSE, $cached, 'Test 3 has been propagated to the second backend'); - $this->assertIdentical(33, $cached->data, 'And value has been kept'); + $this->assertNotSame(FALSE, $cached, 'Test 3 has been propagated to the second backend'); + $this->assertSame(33, $cached->data, 'And value has been kept'); $cached = $this->firstBackend->get('t23'); - $this->assertNotIdentical(FALSE, $cached, 'Test 2 has been propagated to the first backend'); - $this->assertIdentical(232, $cached->data, 'And value has been kept'); + $this->assertNotSame(FALSE, $cached, 'Test 2 has been propagated to the first backend'); + $this->assertSame(232, $cached->data, 'And value has been kept'); } /** @@ -209,7 +211,7 @@ public function testNotEmptyIfOneBackendHasTheKey() { // This is the only test that needs to start with an empty chain. $this->chain->deleteAll(); - $this->assert($this->chain->isEmpty(), 'Chain have been emptied by the deleteAll() call'); + $this->assertTrue($this->chain->isEmpty(), 'Chain have been emptied by the deleteAll() call'); $this->secondBackend->set('test', 5); $this->assertFalse($this->chain->isEmpty(), 'Chain is not empty anymore now that the second backend has something'); @@ -237,7 +239,7 @@ public function testDeleteTagsPropagation() { // Create two cache entries with the same tag and tag value. $this->chain->set('test_cid_clear1', 'foo', CacheBackendInterface::CACHE_PERMANENT, array('test_tag' => 2)); $this->chain->set('test_cid_clear2', 'foo', CacheBackendInterface::CACHE_PERMANENT, array('test_tag' => 2)); - $this->assertNotIdentical(FALSE, $this->firstBackend->get('test_cid_clear1') + $this->assertNotSame(FALSE, $this->firstBackend->get('test_cid_clear1') && $this->firstBackend->get('test_cid_clear2') && $this->secondBackend->get('test_cid_clear1') && $this->secondBackend->get('test_cid_clear2') @@ -247,7 +249,7 @@ public function testDeleteTagsPropagation() { // Invalidate test_tag of value 1. This should invalidate both entries. $this->chain->deleteTags(array('test_tag' => 2)); - $this->assertIdentical(FALSE, $this->firstBackend->get('test_cid_clear1') + $this->assertSame(FALSE, $this->firstBackend->get('test_cid_clear1') && $this->firstBackend->get('test_cid_clear2') && $this->secondBackend->get('test_cid_clear1') && $this->secondBackend->get('test_cid_clear2') @@ -258,7 +260,7 @@ public function testDeleteTagsPropagation() { // Create two cache entries with the same tag and an array tag value. $this->chain->set('test_cid_clear1', 'foo', CacheBackendInterface::CACHE_PERMANENT, array('test_tag' => array(1))); $this->chain->set('test_cid_clear2', 'foo', CacheBackendInterface::CACHE_PERMANENT, array('test_tag' => array(1))); - $this->assertNotIdentical(FALSE, $this->firstBackend->get('test_cid_clear1') + $this->assertNotSame(FALSE, $this->firstBackend->get('test_cid_clear1') && $this->firstBackend->get('test_cid_clear2') && $this->secondBackend->get('test_cid_clear1') && $this->secondBackend->get('test_cid_clear2') @@ -268,7 +270,7 @@ public function testDeleteTagsPropagation() { // Invalidate test_tag of value 1. This should invalidate both entries. $this->chain->deleteTags(array('test_tag' => array(1))); - $this->assertIdentical(FALSE, $this->firstBackend->get('test_cid_clear1') + $this->assertSame(FALSE, $this->firstBackend->get('test_cid_clear1') && $this->firstBackend->get('test_cid_clear2') && $this->secondBackend->get('test_cid_clear1') && $this->secondBackend->get('test_cid_clear2') @@ -280,7 +282,7 @@ public function testDeleteTagsPropagation() { $this->chain->set('test_cid_clear1', 'foo', CacheBackendInterface::CACHE_PERMANENT, array('test_tag' => array(1))); $this->chain->set('test_cid_clear2', 'foo', CacheBackendInterface::CACHE_PERMANENT, array('test_tag' => array(2))); $this->chain->set('test_cid_clear3', 'foo', CacheBackendInterface::CACHE_PERMANENT, array('test_tag_foo' => array(3))); - $this->assertNotIdentical(FALSE, $this->firstBackend->get('test_cid_clear1') + $this->assertNotSame(FALSE, $this->firstBackend->get('test_cid_clear1') && $this->firstBackend->get('test_cid_clear2') && $this->firstBackend->get('test_cid_clear3') && $this->secondBackend->get('test_cid_clear1') @@ -292,7 +294,7 @@ public function testDeleteTagsPropagation() { 'Three cached items were created in all backends.'); $this->chain->deleteTags(array('test_tag_foo' => array(3))); - $this->assertNotIdentical(FALSE, $this->firstBackend->get('test_cid_clear1') + $this->assertNotSame(FALSE, $this->firstBackend->get('test_cid_clear1') && $this->firstBackend->get('test_cid_clear2') && $this->secondBackend->get('test_cid_clear1') && $this->secondBackend->get('test_cid_clear2') @@ -300,7 +302,7 @@ public function testDeleteTagsPropagation() { && $this->thirdBackend->get('test_cid_clear2'), 'Cached items not matching the tag were not cleared from any of the backends.'); - $this->assertIdentical(FALSE, $this->firstBackend->get('test_cid_clear3') + $this->assertSame(FALSE, $this->firstBackend->get('test_cid_clear3') && $this->secondBackend->get('test_cid_clear3') && $this->thirdBackend->get('test_cid_clear3'), 'Cached item matching the tag was removed from all backends.'); diff --git a/core/modules/system/lib/Drupal/system/Tests/Cache/NullBackendTest.php b/core/tests/Drupal/Tests/Core/Cache/NullBackendTest.php similarity index 77% rename from core/modules/system/lib/Drupal/system/Tests/Cache/NullBackendTest.php rename to core/tests/Drupal/Tests/Core/Cache/NullBackendTest.php index 3882401..fc3a700 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Cache/NullBackendTest.php +++ b/core/tests/Drupal/Tests/Core/Cache/NullBackendTest.php @@ -2,18 +2,20 @@ /** * @file - * Definition of Drupal\system\Tests\Cache\NullBackendTest. + * Definition of Drupal\Tests\Core\Cache\NullBackendTest. */ -namespace Drupal\system\Tests\Cache; +namespace Drupal\Tests\Core\Cache; use Drupal\Core\Cache\NullBackend; -use Drupal\simpletest\UnitTestBase; +use Drupal\Tests\UnitTestCase; /** * Tests the cache NullBackend. + * + * @group Cache */ -class NullBackendTest extends UnitTestBase { +class NullBackendTest extends UnitTestCase { public static function getInfo() { return array( diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/NestedArrayUnitTest.php b/core/tests/Drupal/Tests/Core/NestedArrayUnitTest.php similarity index 70% rename from core/modules/system/lib/Drupal/system/Tests/Common/NestedArrayUnitTest.php rename to core/tests/Drupal/Tests/Core/NestedArrayUnitTest.php index ff61ae6..1da86af 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Common/NestedArrayUnitTest.php +++ b/core/tests/Drupal/Tests/Core/NestedArrayUnitTest.php @@ -2,18 +2,20 @@ /** * @file - * Contains \Drupal\system\Tests\Common\NestedArrayUnitTest. + * Contains \Drupal\Core\NestedArrayUnitTest. */ -namespace Drupal\system\Tests\Common; +namespace Drupal\Tests\Core; use Drupal\Component\Utility\NestedArray; -use Drupal\simpletest\UnitTestBase; +use Drupal\Tests\UnitTestCase; /** * Tests the NestedArray helper class. + * + * @group System */ -class NestedArrayUnitTest extends UnitTestBase { +class NestedArrayUnitTest extends UnitTestCase { /** * Form array to check. @@ -51,26 +53,26 @@ function setUp() { function testGetValue() { // Verify getting a value of a nested element. $value = NestedArray::getValue($this->form, $this->parents); - $this->assertEqual($value['#value'], 'Nested element', 'Nested element value found.'); + $this->assertEquals($value['#value'], 'Nested element', 'Nested element value found.'); // Verify changing a value of a nested element by reference. $value = &NestedArray::getValue($this->form, $this->parents); $value['#value'] = 'New value'; $value = NestedArray::getValue($this->form, $this->parents); - $this->assertEqual($value['#value'], 'New value', 'Nested element value was changed by reference.'); - $this->assertEqual($this->form['details']['element']['#value'], 'New value', 'Nested element value was changed by reference.'); + $this->assertEquals($value['#value'], 'New value', 'Nested element value was changed by reference.'); + $this->assertEquals($this->form['details']['element']['#value'], 'New value', 'Nested element value was changed by reference.'); // Verify that an existing key is reported back. $key_exists = NULL; NestedArray::getValue($this->form, $this->parents, $key_exists); - $this->assertIdentical($key_exists, TRUE, 'Existing key found.'); + $this->assertSame($key_exists, TRUE, 'Existing key found.'); // Verify that a non-existing key is reported back and throws no errors. $key_exists = NULL; $parents = $this->parents; $parents[] = 'foo'; NestedArray::getValue($this->form, $parents, $key_exists); - $this->assertIdentical($key_exists, FALSE, 'Non-existing key not found.'); + $this->assertSame($key_exists, FALSE, 'Non-existing key not found.'); } /** @@ -84,8 +86,8 @@ function testSetValue() { // Verify setting the value of a nested element. NestedArray::setValue($this->form, $this->parents, $new_value); - $this->assertEqual($this->form['details']['element']['#value'], 'New value', 'Changed nested element value found.'); - $this->assertIdentical($this->form['details']['element']['#required'], TRUE, 'New nested element value found.'); + $this->assertEquals($this->form['details']['element']['#value'], 'New value', 'Changed nested element value found.'); + $this->assertSame($this->form['details']['element']['#required'], TRUE, 'New nested element value found.'); } /** @@ -99,13 +101,13 @@ function testUnsetValue() { $parents[] = 'foo'; NestedArray::unsetValue($this->form, $parents, $key_existed); $this->assertTrue(isset($this->form['details']['element']['#value']), 'Outermost nested element key still exists.'); - $this->assertIdentical($key_existed, FALSE, 'Non-existing key not found.'); + $this->assertSame($key_existed, FALSE, 'Non-existing key not found.'); // Verify unsetting a nested element. $key_existed = NULL; NestedArray::unsetValue($this->form, $this->parents, $key_existed); $this->assertFalse(isset($this->form['details']['element']), 'Removed nested element not found.'); - $this->assertIdentical($key_existed, TRUE, 'Existing key was found.'); + $this->assertSame($key_existed, TRUE, 'Existing key was found.'); } /** @@ -113,12 +115,12 @@ function testUnsetValue() { */ function testKeyExists() { // Verify that existing key is found. - $this->assertIdentical(NestedArray::keyExists($this->form, $this->parents), TRUE, 'Nested key found.'); + $this->assertSame(NestedArray::keyExists($this->form, $this->parents), TRUE, 'Nested key found.'); // Verify that non-existing keys are not found. $parents = $this->parents; $parents[] = 'foo'; - $this->assertIdentical(NestedArray::keyExists($this->form, $parents), FALSE, 'Non-existing nested key not found.'); + $this->assertSame(NestedArray::keyExists($this->form, $parents), FALSE, 'Non-existing nested key not found.'); } /** @@ -141,6 +143,6 @@ function testMergeDeepArray() { 'language' => 'en', 'html' => TRUE, ); - $this->assertIdentical(NestedArray::mergeDeepArray(array($link_options_1, $link_options_2)), $expected, 'NestedArray::mergeDeepArray() returned a properly merged array.'); + $this->assertSame(NestedArray::mergeDeepArray(array($link_options_1, $link_options_2)), $expected, 'NestedArray::mergeDeepArray() returned a properly merged array.'); } } diff --git a/core/tests/Drupal/Tests/UnitTestCase.php b/core/tests/Drupal/Tests/UnitTestCase.php new file mode 100644 index 0000000..97309cc --- /dev/null +++ b/core/tests/Drupal/Tests/UnitTestCase.php @@ -0,0 +1,59 @@ + 'Something Test', + * 'description' => 'Tests Something', + * 'group' => 'Something', + * ) + */ + public static function getInfo() { + throw new \BadMethodCallException("Sub-class must implement the getInfo method!"); + } + + /** + * Generates a random string containing letters and numbers. + * + * The string will always start with a letter. The letters may be upper or + * lower case. This method is better for restricted inputs that do not + * accept certain characters. For example, when testing input fields that + * require machine readable values (i.e. without spaces and non-standard + * characters) this method is best. + * + * Do not use this method when testing unvalidated user input. Instead, use + * Drupal\simpletest\TestBase::randomString(). + * + * @param $length + * Length of random string to generate. + * + * @return + * Randomly generated string. + * + * @see Drupal\simpletest\TestBase::randomString() + */ + public static function randomName($length = 8) { + $values = array_merge(range(65, 90), range(97, 122), range(48, 57)); + $max = count($values) - 1; + $str = chr(mt_rand(97, 122)); + for ($i = 1; $i < $length; $i++) { + $str .= chr($values[mt_rand(0, $max)]); + } + return $str; + } +} diff --git a/core/tests/bootstrap.php b/core/tests/bootstrap.php new file mode 100644 index 0000000..6c947df --- /dev/null +++ b/core/tests/bootstrap.php @@ -0,0 +1,13 @@ +add('Drupal\\', __DIR__); +$loader->add('Drupal\Core', __DIR__ . "/../../core/lib"); +$loader->add('Drupal\Component', __DIR__ . "/../../core/lib"); + +foreach (scandir(__DIR__ . "/../modules") as $module) { + $loader->add('Drupal\\' . $module, __DIR__ . "/../modules/" . $module . "/lib"); +} +// Look into removing this later. +define('REQUEST_TIME', (int) $_SERVER['REQUEST_TIME']);