AutoCompleterTest.php 5.07 KB
Newer Older
jhon committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
<?php

/*
 * This file is part of Psy Shell.
 *
 * (c) 2012-2015 Justin Hileman
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Psy\Test\TabCompletion;

use Psy\Command\ListCommand;
use Psy\Command\ShowCommand;
use Psy\Configuration;
use Psy\Context;
use Psy\ContextAware;
use Psy\TabCompletion\Matcher;

class AutoCompleterTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @param $line
     * @param $mustContain
     * @param $mustNotContain
     * @dataProvider classesInput
     */
    public function testClassesCompletion($line, $mustContain, $mustNotContain)
    {
        $context = new Context();

        $commands = array(
            new ShowCommand(),
            new ListCommand(),
        );

        $matchers = array(
            new Matcher\VariablesMatcher(),
            new Matcher\ClassNamesMatcher(),
            new Matcher\ConstantsMatcher(),
            new Matcher\FunctionsMatcher(),
            new Matcher\ObjectMethodsMatcher(),
            new Matcher\ObjectAttributesMatcher(),
            new Matcher\KeywordsMatcher(),
            new Matcher\ClassAttributesMatcher(),
            new Matcher\ClassMethodsMatcher(),
            new Matcher\CommandsMatcher($commands),
        );

        $config = new Configuration();
        $tabCompletion = $config->getAutoCompleter();
        foreach ($matchers as $matcher) {
            if ($matcher instanceof ContextAware) {
                $matcher->setContext($context);
            }
            $tabCompletion->addMatcher($matcher);
        }

        $context->setAll(array('foo' => 12, 'bar' => new \DOMDocument()));

        $code = $tabCompletion->processCallback('', 0, array(
           'line_buffer' => $line,
           'point'       => 0,
           'end'         => strlen($line),
        ));

        foreach ($mustContain as $mc) {
            $this->assertContains($mc, $code);
        }

        foreach ($mustNotContain as $mnc) {
            $this->assertNotContains($mnc, $code);
        }
    }

    /**
     * TODO
     * ====
     * draft, open to modifications
     * - [ ] if the variable is an array, return the square bracket for completion
     * - [ ] if the variable is a constructor or method, reflect to complete as a function call
     * - [ ] if the preceding token is a variable, call operators or keywords compatible for completion
     * - [X] a command always should be the second token after php_open_tag
     * - [X] keywords are never consecutive
     * - [X] namespacing completion should work just fine
     * - [X] after a new keyword, should always be a class constructor, never a function call or keyword, constant,
     *       or variable that does not contain a existing class name.
     * - [X] on a namespaced constructor the completion must show the classes related, not constants.
     *
     * @return array
     */
    public function classesInput()
    {
        return array(
            // input, must had, must not had
            array('T_OPE', array('T_OPEN_TAG'), array()),
            array('st', array('stdClass'), array()),
            array('stdCla', array('stdClass'), array()),
            array('new s', array('stdClass'), array()),
            array(
                'new ',
                array('stdClass', 'Psy\\Context', 'Psy\\Configuration'),
                array('require', 'array_search', 'T_OPEN_TAG', '$foo'),
            ),
            array('new Psy\\C', array('Context'), array('CASE_LOWER')),
            array('\s', array('stdClass'), array()),
            array('array_', array('array_search', 'array_map', 'array_merge'), array()),
            array('$bar->', array('load'), array()),
            array('$b', array('bar'), array()),
            array('6 + $b', array('bar'), array()),
            array('$f', array('foo'), array()),
            array('l', array('ls'), array()),
            array('ls ', array(), array('ls')),
            array('sho', array('show'), array()),
            array('12 + clone $', array('foo'), array()),
            // array(
            //   '$foo ',
            //   array('+', 'clone'),
            //   array('$foo', 'DOMDocument', 'array_map')
            // ), requires a operator matcher?
            array('$', array('foo', 'bar'), array('require', 'array_search', 'T_OPEN_TAG', 'Psy')),
            array(
                'Psy\\',
                array('Context', 'TabCompletion\\Matcher\\AbstractMatcher'),
                array('require', 'array_search'),
            ),
            array(
                'Psy\Test\TabCompletion\StaticSample::CO',
                array('Psy\Test\TabCompletion\StaticSample::CONSTANT_VALUE'),
                array(),
            ),
            array(
                'Psy\Test\TabCompletion\StaticSample::',
                array('Psy\Test\TabCompletion\StaticSample::$staticVariable'),
                array(),
            ),
            array(
                'Psy\Test\TabCompletion\StaticSample::',
                array('Psy\Test\TabCompletion\StaticSample::staticFunction'),
                array(),
            ),
        );
    }
}