public function testGetNamesWithAliases() { $ls = new Command(CommandConfig::create('ls')->addAlias('ls-alias')); $cd = new Command(CommandConfig::create('cd')->addAlias('cd-alias')); $this->collection->add($ls); $this->collection->add($cd); $this->assertSame(array('cd', 'cd-alias', 'ls', 'ls-alias'), $this->collection->getNames(true)); }
/** * Searches a command collection for similar names. * * @param string $commandName The command name that was not found. * @param CommandCollection $commands The available commands. * * @return string[] The names of similar commands. */ public static function find($commandName, CommandCollection $commands) { $threshold = 1000.0; $distancesByName = array(); // Include aliases in the search $actualNames = $commands->getNames(true); foreach ($actualNames as $actualName) { // Get Levenshtein distance between the input and each command name $distance = levenshtein($commandName, $actualName); $isSimilar = $distance <= strlen($commandName) / 3; $isSubString = false !== strpos($actualName, $commandName); if ($isSimilar || $isSubString) { $distancesByName[$actualName] = $distance; } } // Only keep results with a distance below the threshold $distancesByName = array_filter($distancesByName, function ($distance) use($threshold) { return $distance < 2 * $threshold; }); // Display results with shortest distance first asort($distancesByName); $suggestedNames = array_keys($distancesByName); return self::filterDuplicates($suggestedNames, $commands); }