class completeCase

  1. 8.0.x tests/completeTest.php completeCase
  2. 6.x tests/completeTest.php completeCase
  3. 7.x tests/completeTest.php completeCase
  4. 5.x tests/completeTest.php completeCase
  5. master tests/completeTest.php completeCase

@group base




Expanded class hierarchy of completeCase


Contains filters are case sensitive
Namesort descending Modifiers Type Description
CommandUnishTestCase::$coverage_data protected property Code coverage data collected during a single test.
CommandUnishTestCase::$defaultIdleTimeout private property Default idle timeout for commands.
CommandUnishTestCase::$defaultTimeout private property Default timeout for commands.
CommandUnishTestCase::$idleTimeout protected property Idle timeouts for commands.
CommandUnishTestCase::$process private property Process of last executed command.
CommandUnishTestCase::$timeout protected property Timeout for command.
CommandUnishTestCase::assertLogHasMessage function Ensure that an expected log message appears in the Drush log.
CommandUnishTestCase::drush function Invoke drush in via execute().
CommandUnishTestCase::drush_major_version function
CommandUnishTestCase::execute function Actually runs the command.
CommandUnishTestCase::EXIT_ERROR constant
CommandUnishTestCase::EXIT_SUCCESS constant
CommandUnishTestCase::getErrorOutput function Accessor for the last stderr output, trimmed.
CommandUnishTestCase::getErrorOutputAsList function Accessor for the last stderr output, rtrimmed and split on newlines.
CommandUnishTestCase::getErrorOutputRaw function Accessor for the last stderr output, non-trimmed.
CommandUnishTestCase::getOutput function Accessor for the last output, trimmed.
CommandUnishTestCase::getOutputAsList function Accessor for the last output, rtrimmed and split on newlines.
CommandUnishTestCase::getOutputFromJSON function Accessor for the last output, decoded from json.
CommandUnishTestCase::getOutputRaw function Accessor for the last output, non-trimmed.
CommandUnishTestCase::parse_backend_output function A slightly less functional copy of drush_backend_parse_output().
CommandUnishTestCase::run public function Override the run method, so we can add in our code coverage data after the test has run.
CommandUnishTestCase::UNISH_EXITCODE_USER_ABORT constant
completeCase::setUpBeforeClass static function Write a config file that contains our configuration file. Overrides UnishTestCase::setUpBeforeClass
completeCase::testComplete public function
completeCase::verifyComplete function Helper function to call completion and make common checks.
UnishTestCase::$sites private static property A list of Drupal sites that have been recently installed. They key is the site name and values are details about each site.
UnishTestCase::bit_bucket function Borrowed from Drush. Checks operating system and returns supported bit bucket folder.
UnishTestCase::convert_path function Converts a Windows path (dir1\dir2\dir3) into a Unix path (dir1/dir2/dir3). Also converts a cygwin "drive emulation" path (/cygdrive/c/dir1) into a proper drive path, still with Unix slashes (c:/dir1).
UnishTestCase::db_driver function
UnishTestCase::db_url function
UnishTestCase::directory_cache function
UnishTestCase::drupalSitewideDirectory function
UnishTestCase::escapeshellarg public static function
UnishTestCase::fetchInstallDrupal function
UnishTestCase::getSites function
UnishTestCase::get_tar_executable public static function
UnishTestCase::is_windows public static function
UnishTestCase::log function Print a log message to the console.
UnishTestCase::log_level function
UnishTestCase::mkdir public function
UnishTestCase::randomString public function Helper function to generate a random string of arbitrary length.
UnishTestCase::recursive_copy public function
UnishTestCase::setUpDrupal function
UnishTestCase::setUpFreshSandBox public static function Remove any pre-existing sandbox, then create a new one.
UnishTestCase::tearDownAfterClass public static function Runs after all tests in a class are run. Remove sandbox directory.
UnishTestCase::tick function Print out a tick mark.
UnishTestCase::unish_file_aliases function Prepare the contents of an aliases file.
UnishTestCase::webroot function
UnishTestCase::writeSiteAlias function
UnishTestCase::_escapeshellarg_windows public static function
UnishTestCase::__construct function


tests/completeTest.php, line 8

View source
class completeCase extends CommandUnishTestCase {
   * Write a config file that contains our configuration file.
  static function setUpBeforeClass() {
    $contents = "

      \$options['shell-aliases'] = array(
        'uninstall' => 'pm-uninstall',
    file_put_contents(UNISH_SANDBOX . '/drushrc.php', trim($contents));

  public function testComplete() {
    // $this->markTestSkipped('@todo Bootstrap refactor has broken this.');

    // We copy our completetest commandfile into our path.
    // We cannot use --include since complete deliberately avoids drush
    // command dispatch.
    copy(dirname(__FILE__) . '/', getenv('HOME') . '/.drush/');

    $sites = $this->setUpDrupal(2);
    $env = key($sites);
    $root = $this->webroot();
    // We copy the unit test command into (only) our dev site, so we have a
    // detectable difference we can use to detect cache correctness between
    // sites.
    copy(dirname(__FILE__) . '/', "$root/sites/$env/modules/");
    // Clear the cache, so it finds our test command.
    $this->drush('php-eval', array('drush_cache_clear_all();'), array(), '@' . $env);

    // Create a sample directory and file to test file/directory completion.
    touch('astronaut/yuri gagarin.tar.gz');

    // Create directory for temporary debug logs.
    mkdir(UNISH_SANDBOX . '/complete-debug');

    // Test cache clearing for global cache, which should affect all
    // environments. First clear the cache:
    $this->drush('php-eval', array('drush_complete_cache_clear();'));
    // Confirm we get cache rebuilds for runs both in and out of a site
    // which is expected since these should resolve to separate cache IDs.
    $this->verifyComplete('@dev aaaaaaaard-', 'aaaaaaaard-ant', 'aaaaaaaard-zebra', FALSE);
    $this->verifyComplete('aaaaaaaard-', 'aaaaaaaard-ant', 'aaaaaaaard-wolf', FALSE);
    // Next, rerun and check results to confirm cache IDs are generated
    // correctly on our fast bootstrap when returning the cached result.
    $this->verifyComplete('@dev aaaaaaaard-', 'aaaaaaaard-ant', 'aaaaaaaard-zebra');
    $this->verifyComplete('aaaaaaaard-', 'aaaaaaaard-ant', 'aaaaaaaard-wolf');

    // Test cache clearing for a completion type, which should be effective only
    // for current environment - i.e. a specific site should not be effected.
    $this->drush('php-eval', array('drush_complete_cache_clear("command-names");'));
    $this->verifyComplete('@dev aaaaaaaard-', 'aaaaaaaard-ant', 'aaaaaaaard-zebra');
    $this->verifyComplete('aaaaaaaard-', 'aaaaaaaard-ant', 'aaaaaaaard-wolf', FALSE);

    // Test cache clearing for a command specific completion type, which should
    // be effective only for current environment. Prime caches first.
    $this->verifyComplete('@dev aaaaaaaard a', 'aardvark', 'aardwolf', FALSE);
    $this->verifyComplete('aaaaaaaard a', 'aardvark', 'aardwolf', FALSE);
    $this->drush('php-eval', array('drush_complete_cache_clear("arguments", "aaaaaaaard");'));
    // We cleared the global cache for this argument, not the site specific
    // cache should still exist.
    $this->verifyComplete('@dev aaaaaaaard a', 'aardvark', 'aardwolf');
    $this->verifyComplete('aaaaaaaard a', 'aardvark', 'aardwolf', FALSE);

    // Test overall context sensitivity - almost all of these are cache hits.
    // No context (i.e. "drush <tab>"), should list aliases and commands.
    $this->verifyComplete('""', '@dev', 'zzzzzzzzebra');
    // Site alias alone.
    $this->verifyComplete('@', '@dev', '@stage');
    // Command alone.
    $this->verifyComplete('aaaaaaaa', 'aaaaaaaard', 'aaaaaaaard-wolf');
    // Command with single result.
    $this->verifyComplete('aaaaaaaard-v', 'aaaaaaaard-vark', 'aaaaaaaard-vark');
    // Command with no results should produce no output.
    $this->verifyComplete('dont-name-a-command-like-this', '', '');
    // Commands that start the same as another command (i.e. aaaaaaaard is a
    // valid command, but we should still list aaaaaaaardwolf when completing on
    // "aaaaaaaard").
    $this->verifyComplete('@dev aaaaaaaard', 'aaaaaaaard', 'aaaaaaaard-zebra');
    // Global option alone.
    $this->verifyComplete('--n', '--no', '--notify-audio');
    // Site alias + command.
    $this->verifyComplete('@dev aaaaaaaa', 'aaaaaaaard', 'aaaaaaaard-zebra');
    // Site alias + command, should allow no further site aliases or commands.
    $this->verifyComplete('@dev aaaaaaaard-wolf @', '', '', FALSE);
    $this->verifyComplete('@dev aaaaaaaard-wolf aaaaaaaa', '', '');
    // Command + command option.
    $this->verifyComplete('aaaaaaaard --', '--ears', '--nose');
    // Site alias + command + command option.
    $this->verifyComplete('@dev aaaaaaaard --', '--ears', '--nose');
    // Command + all arguments
    $this->verifyComplete('aaaaaaaard ""', 'aardvark', 'zebra');
    // Command + argument.
    $this->verifyComplete('aaaaaaaard a', 'aardvark', 'aardwolf');
    // Site alias + command + regular argument.
    // Note: this is checked implicitly by the argument cache testing above.

    if ($this->is_windows()) {
      $this->markTestSkipped('Complete tests not fully working nor needed on Windows.');

    // Site alias + command + file/directory argument tests.
    // Current directory substrings.
    // NOTE: This command arg has not been used yet, so cache miss is expected.
    $this->verifyComplete('archive-restore ""', 'asteroid/', 'zodiac.tar.gz', FALSE);
    $this->verifyComplete('archive-restore a', 'asteroid/', 'astronaut/');
    $this->verifyComplete('archive-restore ast', 'asteroid/', 'astronaut/');
    $this->verifyComplete('archive-restore aste', 'asteroid/', 'asteroid/');
    $this->verifyComplete('archive-restore asteroid', 'asteroid/', 'asteroid/');
    $this->verifyComplete('archive-restore asteroid/', 'ceres', 'chiron');
    $this->verifyComplete('archive-restore asteroid/ch', 'asteroid/chiron/', 'asteroid/chiron/');
    $this->verifyComplete('archive-restore astronaut/', 'aldrin.tar.gz', 'yuri gagarin.tar.gz');
    $this->verifyComplete('archive-restore astronaut/y', 'astronaut/yuri\ gagarin.tar.gz', 'astronaut/yuri\ gagarin.tar.gz');
    // Leading dot style current directory substrings.
    $this->verifyComplete('archive-restore .', './asteroid/', './zodiac.tar.gz');
    $this->verifyComplete('archive-restore ./', './asteroid/', './zodiac.tar.gz');
    $this->verifyComplete('archive-restore ./a', './asteroid/', './astronaut/');
    $this->verifyComplete('archive-restore ./ast', './asteroid/', './astronaut/');
    $this->verifyComplete('archive-restore ./aste', './asteroid/', './asteroid/');
    $this->verifyComplete('archive-restore ./asteroid', './asteroid/', './asteroid/');
    $this->verifyComplete('archive-restore ./asteroid/', 'ceres', 'chiron');
    $this->verifyComplete('archive-restore ./asteroid/ch', './asteroid/chiron/', './asteroid/chiron/');
    $this->verifyComplete('archive-restore ./astronaut/', 'aldrin.tar.gz', 'yuri gagarin.tar.gz');
    $this->verifyComplete('archive-restore ./astronaut/y', './astronaut/yuri\ gagarin.tar.gz', './astronaut/yuri\ gagarin.tar.gz');
    // Absolute path substrings.
    $path = getcwd();
    $this->verifyComplete('archive-restore ' . $path, $path . '/', $path . '/');
    $this->verifyComplete('archive-restore ' . $path . '/', 'asteroid', 'zodiac.tar.gz');
    $this->verifyComplete('archive-restore ' . $path . '/a', $path . '/asteroid', $path . '/astronaut');
    $this->verifyComplete('archive-restore ' . $path . '/ast', 'asteroid', 'astronaut');
    $this->verifyComplete('archive-restore ' . $path . '/aste', $path . '/asteroid/', $path . '/asteroid/');
    $this->verifyComplete('archive-restore ' . $path . '/asteroid', $path . '/asteroid/', $path . '/asteroid/');
    $this->verifyComplete('archive-restore ' . $path . '/asteroid/', $path . '/asteroid/ceres', $path . '/asteroid/chiron');
    $this->verifyComplete('archive-restore ' . $path . '/asteroid/ch', $path . '/asteroid/chiron/', $path . '/asteroid/chiron/');
    $this->verifyComplete('archive-restore ' . $path . '/astronaut/', 'aldrin.tar.gz', 'yuri gagarin.tar.gz');
    $this->verifyComplete('archive-restore ' . $path . '/astronaut/y', $path . '/astronaut/yuri\ gagarin.tar.gz', $path . '/astronaut/yuri\ gagarin.tar.gz');
    // Absolute via parent path substrings.
    $this->verifyComplete('archive-restore ' . $path . '/asteroid/../astronaut/', 'aldrin.tar.gz', 'yuri gagarin.tar.gz');
    $this->verifyComplete('archive-restore ' . $path . '/asteroid/../astronaut/y', $path . '/asteroid/../astronaut/yuri\ gagarin.tar.gz', $path . '/asteroid/../astronaut/yuri\ gagarin.tar.gz');
    // Parent directory path substrings.
    $this->verifyComplete('archive-restore ../../astronaut/', 'aldrin.tar.gz', 'yuri gagarin.tar.gz');
    $this->verifyComplete('archive-restore ../../astronaut/y', '../../astronaut/yuri\ gagarin.tar.gz', '../../astronaut/yuri\ gagarin.tar.gz');

   * Helper function to call completion and make common checks.
   * @param $command
   *   The command line to attempt to complete.
   * @param $first
   *   String indicating the expected first completion suggestion.
   * @param $last
   *   String indicating the expected last completion suggestion.
   * @param bool $cache_hit
   *   Optional parameter, if TRUE or omitted the debug log is checked to
   *   ensure a cache hit on the last cache debug log entry, if FALSE then a
   *   cache miss is checked for.
  function verifyComplete($command, $first, $last, $cache_hit = TRUE) {
    // We capture debug output to a separate file, so we can check for cache
    // hits/misses.
    $debug_file = tempnam(UNISH_SANDBOX . '/complete-debug', 'complete-debug');
    // Commands should take the format:
    // drush --early=includes/ [--complete-debug] drush [@alias] [command]...
    $exec = sprintf('%s --early=includes/ --config=%s --complete-debug %s %s 2> %s', UNISH_DRUSH, UNISH_SANDBOX . '/drushrc.php', UNISH_DRUSH, $command, $debug_file);
    $result = $this->getOutputAsList();
    $actual = reset($result);
    $this->assertEquals("$command: (f) $first", "$command: (f) $actual");
    $actual = end($result);
    $this->assertEquals("$command: (l) $last", "$command: (l) $actual");
    // If checking for HIT, we ensure no MISS exists, if checking for MISS we
    // ensure no HIT exists. However, we exclude the first cache report, since
    // it is expected that the command-names cache (loaded when matching
    // command names) may sometimes be a HIT even when we are testing for a MISS
    // in the actual cache we are loading to complete against.
    $check_not_exist = 'HIT';
    if ($cache_hit) {
      $check_not_exist = 'MISS';
    $contents = file_get_contents($debug_file);
    // Find the all cache messages of type "-complete-"
    preg_match_all("/Cache [A-Z]* cid:.*-complete-/", $contents, $matches);
    $contents = implode("\n", $matches[0]);
    $first_cache_pos = strpos($contents, 'Cache ') + 6;
    $this->assertFalse(strpos($contents, 'Cache ' . $check_not_exist . ' cid', $first_cache_pos));