Version 1
[yaffs-website] / vendor / drush / drush / tests / completeTest.php
1 <?php
2
3 namespace Unish;
4
5 /**
6  * @group base
7  */
8 class completeCase extends CommandUnishTestCase {
9   /**
10    * Write a config file that contains our configuration file.
11    */
12   static function setUpBeforeClass() {
13     parent::setUpBeforeClass();
14     $contents = "
15       <?php
16
17       \$options['shell-aliases'] = array(
18         'uninstall' => 'pm-uninstall',
19       );
20     ";
21     file_put_contents(UNISH_SANDBOX . '/drushrc.php', trim($contents));
22   }
23
24   
25
26   public function testComplete() {
27     if ($this->is_windows()) {
28       $this->markTestSkipped('Complete tests not fully working nor needed on Windows.');
29     }
30
31     // We copy our completetest commandfile into our path.
32     // We cannot use --include since complete deliberately avoids drush
33     // command dispatch.
34     copy(dirname(__FILE__) . '/completetest.drush.inc', getenv('HOME') . '/.drush/completetest.drush.inc');
35
36     $sites = $this->setUpDrupal(2);
37     $env = key($sites);
38     $root = $this->webroot();
39     // We copy the unit test command into (only) our dev site, so we have a
40     // detectable difference we can use to detect cache correctness between
41     // sites.
42     mkdir("$root/sites/$env/modules");
43     copy(dirname(__FILE__) . '/completetestsite.drush.inc', "$root/sites/$env/modules/completetestsite.drush.inc");
44     // Clear the cache, so it finds our test command.
45     $this->drush('php-eval', array('drush_cache_clear_all();'), array(), '@' . $env);
46
47     // Create a sample directory and file to test file/directory completion.
48     mkdir("astronaut");
49     mkdir("asteroid");
50     mkdir("asteroid/ceres");
51     mkdir("asteroid/chiron");
52     touch('astronaut/aldrin.tar.gz');
53     touch('astronaut/armstrong.tar.gz');
54     touch('astronaut/yuri gagarin.tar.gz');
55     touch('zodiac.tar.gz');
56     touch('zodiac.txt');
57
58     // Create directory for temporary debug logs.
59     mkdir(UNISH_SANDBOX . '/complete-debug');
60
61     // Test cache clearing for global cache, which should affect all
62     // environments. First clear the cache:
63     $this->drush('php-eval', array('drush_complete_cache_clear();'));
64     // Confirm we get cache rebuilds for runs both in and out of a site
65     // which is expected since these should resolve to separate cache IDs.
66     $this->verifyComplete('@dev aaaaaaaard-', 'aaaaaaaard-ant', 'aaaaaaaard-zebra', FALSE);
67     $this->verifyComplete('aaaaaaaard-', 'aaaaaaaard-ant', 'aaaaaaaard-wolf', FALSE);
68     // Next, rerun and check results to confirm cache IDs are generated
69     // correctly on our fast bootstrap when returning the cached result.
70     $this->verifyComplete('@dev aaaaaaaard-', 'aaaaaaaard-ant', 'aaaaaaaard-zebra');
71     $this->verifyComplete('aaaaaaaard-', 'aaaaaaaard-ant', 'aaaaaaaard-wolf');
72
73     // Test cache clearing for a completion type, which should be effective only
74     // for current environment - i.e. a specific site should not be effected.
75     $this->drush('php-eval', array('drush_complete_cache_clear("command-names");'));
76     $this->verifyComplete('@dev aaaaaaaard-', 'aaaaaaaard-ant', 'aaaaaaaard-zebra');
77     $this->verifyComplete('aaaaaaaard-', 'aaaaaaaard-ant', 'aaaaaaaard-wolf', FALSE);
78
79     // Test cache clearing for a command specific completion type, which should
80     // be effective only for current environment. Prime caches first.
81     $this->verifyComplete('@dev aaaaaaaard a', 'aardvark', 'aardwolf', FALSE);
82     $this->verifyComplete('aaaaaaaard a', 'aardvark', 'aardwolf', FALSE);
83     $this->drush('php-eval', array('drush_complete_cache_clear("arguments", "aaaaaaaard");'));
84     // We cleared the global cache for this argument, not the site specific
85     // cache should still exist.
86     $this->verifyComplete('@dev aaaaaaaard a', 'aardvark', 'aardwolf');
87     $this->verifyComplete('aaaaaaaard a', 'aardvark', 'aardwolf', FALSE);
88
89     // Test overall context sensitivity - almost all of these are cache hits.
90     // No context (i.e. "drush <tab>"), should list aliases and commands.
91     $this->verifyComplete('""', '@dev', 'zzzzzzzzebra');
92     // Site alias alone.
93     $this->verifyComplete('@', '@dev', '@stage');
94     // Command alone.
95     $this->verifyComplete('aaaaaaaa', 'aaaaaaaard', 'aaaaaaaard-wolf');
96     // Command with single result.
97     $this->verifyComplete('aaaaaaaard-v', 'aaaaaaaard-vark', 'aaaaaaaard-vark');
98     // Command with no results should produce no output.
99     $this->verifyComplete('dont-name-a-command-like-this', '', '');
100     // Commands that start the same as another command (i.e. aaaaaaaard is a
101     // valid command, but we should still list aaaaaaaardwolf when completing on
102     // "aaaaaaaard").
103     $this->verifyComplete('@dev aaaaaaaard', 'aaaaaaaard', 'aaaaaaaard-zebra');
104     // Global option alone.
105     $this->verifyComplete('--n', '--no', '--notify-audio');
106     // Site alias + command.
107     $this->verifyComplete('@dev aaaaaaaa', 'aaaaaaaard', 'aaaaaaaard-zebra');
108     // Site alias + command, should allow no further site aliases or commands.
109     $this->verifyComplete('@dev aaaaaaaard-wolf @', '', '', FALSE);
110     $this->verifyComplete('@dev aaaaaaaard-wolf aaaaaaaa', '', '');
111     // Command + command option.
112     $this->verifyComplete('aaaaaaaard --', '--ears', '--nose');
113     // Site alias + command + command option.
114     $this->verifyComplete('@dev aaaaaaaard --', '--ears', '--nose');
115     // Command + all arguments
116     $this->verifyComplete('aaaaaaaard ""', 'aardvark', 'zebra');
117     // Command + argument.
118     $this->verifyComplete('aaaaaaaard a', 'aardvark', 'aardwolf');
119     // Site alias + command + regular argument.
120     // Note: this is checked implicitly by the argument cache testing above.
121
122     // Site alias + command + file/directory argument tests.
123     // Current directory substrings.
124     // NOTE: This command arg has not been used yet, so cache miss is expected.
125     $this->verifyComplete('archive-restore ""', 'asteroid/', 'zodiac.tar.gz', FALSE);
126     $this->verifyComplete('archive-restore a', 'asteroid/', 'astronaut/');
127     $this->verifyComplete('archive-restore ast', 'asteroid/', 'astronaut/');
128     $this->verifyComplete('archive-restore aste', 'asteroid/', 'asteroid/');
129     $this->verifyComplete('archive-restore asteroid', 'asteroid/', 'asteroid/');
130     $this->verifyComplete('archive-restore asteroid/', 'ceres', 'chiron');
131     $this->verifyComplete('archive-restore asteroid/ch', 'asteroid/chiron/', 'asteroid/chiron/');
132     $this->verifyComplete('archive-restore astronaut/', 'aldrin.tar.gz', 'yuri gagarin.tar.gz');
133     $this->verifyComplete('archive-restore astronaut/y', 'astronaut/yuri\ gagarin.tar.gz', 'astronaut/yuri\ gagarin.tar.gz');
134     // Leading dot style current directory substrings.
135     $this->verifyComplete('archive-restore .', './asteroid/', './zodiac.tar.gz');
136     $this->verifyComplete('archive-restore ./', './asteroid/', './zodiac.tar.gz');
137     $this->verifyComplete('archive-restore ./a', './asteroid/', './astronaut/');
138     $this->verifyComplete('archive-restore ./ast', './asteroid/', './astronaut/');
139     $this->verifyComplete('archive-restore ./aste', './asteroid/', './asteroid/');
140     $this->verifyComplete('archive-restore ./asteroid', './asteroid/', './asteroid/');
141     $this->verifyComplete('archive-restore ./asteroid/', 'ceres', 'chiron');
142     $this->verifyComplete('archive-restore ./asteroid/ch', './asteroid/chiron/', './asteroid/chiron/');
143     $this->verifyComplete('archive-restore ./astronaut/', 'aldrin.tar.gz', 'yuri gagarin.tar.gz');
144     $this->verifyComplete('archive-restore ./astronaut/y', './astronaut/yuri\ gagarin.tar.gz', './astronaut/yuri\ gagarin.tar.gz');
145     // Absolute path substrings.
146     $path = getcwd();
147     $this->verifyComplete('archive-restore ' . $path, $path . '/', $path . '/');
148     $this->verifyComplete('archive-restore ' . $path . '/', 'asteroid', 'zodiac.tar.gz');
149     $this->verifyComplete('archive-restore ' . $path . '/a', $path . '/asteroid', $path . '/astronaut');
150     $this->verifyComplete('archive-restore ' . $path . '/ast', 'asteroid', 'astronaut');
151     $this->verifyComplete('archive-restore ' . $path . '/aste', $path . '/asteroid/', $path . '/asteroid/');
152     $this->verifyComplete('archive-restore ' . $path . '/asteroid', $path . '/asteroid/', $path . '/asteroid/');
153     $this->verifyComplete('archive-restore ' . $path . '/asteroid/', $path . '/asteroid/ceres', $path . '/asteroid/chiron');
154     $this->verifyComplete('archive-restore ' . $path . '/asteroid/ch', $path . '/asteroid/chiron/', $path . '/asteroid/chiron/');
155     $this->verifyComplete('archive-restore ' . $path . '/astronaut/', 'aldrin.tar.gz', 'yuri gagarin.tar.gz');
156     $this->verifyComplete('archive-restore ' . $path . '/astronaut/y', $path . '/astronaut/yuri\ gagarin.tar.gz', $path . '/astronaut/yuri\ gagarin.tar.gz');
157     // Absolute via parent path substrings.
158     $this->verifyComplete('archive-restore ' . $path . '/asteroid/../astronaut/', 'aldrin.tar.gz', 'yuri gagarin.tar.gz');
159     $this->verifyComplete('archive-restore ' . $path . '/asteroid/../astronaut/y', $path . '/asteroid/../astronaut/yuri\ gagarin.tar.gz', $path . '/asteroid/../astronaut/yuri\ gagarin.tar.gz');
160     // Parent directory path substrings.
161     chdir('asteroid/chiron');
162     $this->verifyComplete('archive-restore ../../astronaut/', 'aldrin.tar.gz', 'yuri gagarin.tar.gz');
163     $this->verifyComplete('archive-restore ../../astronaut/y', '../../astronaut/yuri\ gagarin.tar.gz', '../../astronaut/yuri\ gagarin.tar.gz');
164     chdir($path);
165   }
166
167   /**
168    * Helper function to call completion and make common checks.
169    *
170    * @param $command
171    *   The command line to attempt to complete.
172    * @param $first
173    *   String indicating the expected first completion suggestion.
174    * @param $last
175    *   String indicating the expected last completion suggestion.
176    * @param bool $cache_hit
177    *   Optional parameter, if TRUE or omitted the debug log is checked to
178    *   ensure a cache hit on the last cache debug log entry, if FALSE then a
179    *   cache miss is checked for.
180    */
181   function verifyComplete($command, $first, $last, $cache_hit = TRUE) {
182     // We capture debug output to a separate file, so we can check for cache
183     // hits/misses.
184     $debug_file = tempnam(UNISH_SANDBOX . '/complete-debug', 'complete-debug');
185     // Commands should take the format:
186     // drush --early=includes/complete.inc [--complete-debug] drush [@alias] [command]...
187     $exec = sprintf('%s --early=includes/complete.inc --config=%s --complete-debug %s %s 2> %s', UNISH_DRUSH, UNISH_SANDBOX . '/drushrc.php', UNISH_DRUSH, $command, $debug_file);
188     $this->execute($exec);
189     $result = $this->getOutputAsList();
190     $actual = reset($result);
191     $this->assertEquals("$command: (f) $first", "$command: (f) $actual");
192     $actual = end($result);
193     $this->assertEquals("$command: (l) $last", "$command: (l) $actual");
194     // If checking for HIT, we ensure no MISS exists, if checking for MISS we
195     // ensure no HIT exists. However, we exclude the first cache report, since
196     // it is expected that the command-names cache (loaded when matching
197     // command names) may sometimes be a HIT even when we are testing for a MISS
198     // in the actual cache we are loading to complete against.
199     $check_not_exist = 'HIT';
200     if ($cache_hit) {
201       $check_not_exist = 'MISS';
202     }
203     $contents = file_get_contents($debug_file);
204     // Find the all cache messages of type "-complete-"
205     preg_match_all("/Cache [A-Z]* cid:.*-complete-/", $contents, $matches);
206     $contents = implode("\n", $matches[0]);
207     $first_cache_pos = strpos($contents, 'Cache ') + 6;
208     $this->assertFalse(strpos($contents, 'Cache ' . $check_not_exist . ' cid', $first_cache_pos));
209     unlink($debug_file);
210   }
211 }