Chris@13: bind($definition); Chris@13: } Chris@13: Chris@13: public function testInputOptionWithGivenString() Chris@13: { Chris@13: $definition = new InputDefinition([ Chris@13: new InputOption('foo', null, InputOption::VALUE_REQUIRED), Chris@13: new CodeArgument('code', null, CodeArgument::REQUIRED), Chris@13: ]); Chris@13: Chris@13: $input = new ShellInput('--foo=bar echo "baz\\\\n";'); Chris@13: $input->bind($definition); Chris@13: $this->assertSame('bar', $input->getOption('foo')); Chris@13: $this->assertSame('echo "baz\n";', $input->getArgument('code')); Chris@13: } Chris@13: Chris@13: public function testInputOptionWithoutCodeArguments() Chris@13: { Chris@13: $definition = new InputDefinition([ Chris@13: new InputOption('foo', null, InputOption::VALUE_REQUIRED), Chris@16: new InputOption('qux', 'q', InputOption::VALUE_REQUIRED), Chris@13: new InputArgument('bar', null, InputArgument::REQUIRED), Chris@13: new InputArgument('baz', null, InputArgument::REQUIRED), Chris@13: ]); Chris@13: Chris@16: $input = new ShellInput('--foo=foo -q qux bar "baz\\\\n"'); Chris@13: $input->bind($definition); Chris@13: $this->assertSame('foo', $input->getOption('foo')); Chris@16: $this->assertSame('qux', $input->getOption('qux')); Chris@13: $this->assertSame('bar', $input->getArgument('bar')); Chris@13: $this->assertSame('baz\\n', $input->getArgument('baz')); Chris@13: } Chris@13: Chris@16: public function testInputWithDashDash() Chris@16: { Chris@16: $definition = new InputDefinition([ Chris@16: new InputOption('foo', null, InputOption::VALUE_REQUIRED), Chris@16: new CodeArgument('code', null, CodeArgument::REQUIRED), Chris@16: ]); Chris@16: Chris@16: $input = new ShellInput('-- echo --foo::$bar'); Chris@16: $input->bind($definition); Chris@16: $this->assertNull($input->getOption('foo')); Chris@16: $this->assertSame('echo --foo::$bar', $input->getArgument('code')); Chris@16: } Chris@16: Chris@16: public function testInputWithEmptyString() Chris@16: { Chris@16: $definition = new InputDefinition([ Chris@16: new InputOption('foo', null, InputOption::VALUE_REQUIRED), Chris@16: new CodeArgument('code', null, CodeArgument::REQUIRED), Chris@16: ]); Chris@16: Chris@16: $input = new ShellInput('"" --foo bar'); Chris@16: $input->bind($definition); Chris@16: $this->assertSame('"" --foo bar', $input->getArgument('code')); Chris@16: } Chris@16: Chris@16: /** Chris@16: * @dataProvider getTokenizeData Chris@16: */ Chris@16: public function testTokenize($input, $tokens, $message) Chris@16: { Chris@16: $input = new ShellInput($input); Chris@16: $r = new \ReflectionClass('Psy\Input\ShellInput'); Chris@16: $p = $r->getProperty('tokenPairs'); Chris@16: $p->setAccessible(true); Chris@16: $this->assertSame($tokens, $p->getValue($input), $message); Chris@16: } Chris@16: Chris@13: public function getTokenizeData() Chris@13: { Chris@13: // Test all the cases from StringInput test, ensuring they have an appropriate $rest token. Chris@13: return [ Chris@13: [ Chris@13: '', Chris@13: [], Chris@13: '->tokenize() parses an empty string', Chris@13: ], Chris@13: [ Chris@13: 'foo', Chris@13: [['foo', 'foo']], Chris@13: '->tokenize() parses arguments', Chris@13: ], Chris@13: [ Chris@13: ' foo bar ', Chris@13: [['foo', 'foo bar '], ['bar', 'bar ']], Chris@13: '->tokenize() ignores whitespaces between arguments', Chris@13: ], Chris@13: [ Chris@13: '"quoted"', Chris@13: [['quoted', '"quoted"']], Chris@13: '->tokenize() parses quoted arguments', Chris@13: ], Chris@13: [ Chris@13: "'quoted'", Chris@13: [['quoted', "'quoted'"]], Chris@13: '->tokenize() parses quoted arguments', Chris@13: ], Chris@13: [ Chris@13: "'a\rb\nc\td'", Chris@13: [["a\rb\nc\td", "'a\rb\nc\td'"]], Chris@13: '->tokenize() parses whitespace chars in strings', Chris@13: ], Chris@13: [ Chris@13: "'a'\r'b'\n'c'\t'd'", Chris@13: [ Chris@13: ['a', "'a'\r'b'\n'c'\t'd'"], Chris@13: ['b', "'b'\n'c'\t'd'"], Chris@13: ['c', "'c'\t'd'"], Chris@13: ['d', "'d'"], Chris@13: ], Chris@13: '->tokenize() parses whitespace chars between args as spaces', Chris@13: ], Chris@13: Chris@13: /* Chris@13: * These don't play nice with unescaping input, but the end result Chris@13: * is correct, so disable the tests for now. Chris@13: * Chris@13: * @todo Sort this out and re-enable these test cases. Chris@13: */ Chris@13: // [ Chris@13: // '\"quoted\"', Chris@13: // [['"quoted"', '\"quoted\"']], Chris@13: // '->tokenize() parses escaped-quoted arguments', Chris@13: // ], Chris@13: // [ Chris@13: // "\'quoted\'", Chris@13: // [['\'quoted\'', "\'quoted\'"]], Chris@13: // '->tokenize() parses escaped-quoted arguments', Chris@13: // ], Chris@13: Chris@13: [ Chris@13: '-a', Chris@13: [['-a', '-a']], Chris@13: '->tokenize() parses short options', Chris@13: ], Chris@13: [ Chris@13: '-azc', Chris@13: [['-azc', '-azc']], Chris@13: '->tokenize() parses aggregated short options', Chris@13: ], Chris@13: [ Chris@13: '-awithavalue', Chris@13: [['-awithavalue', '-awithavalue']], Chris@13: '->tokenize() parses short options with a value', Chris@13: ], Chris@13: [ Chris@13: '-a"foo bar"', Chris@13: [['-afoo bar', '-a"foo bar"']], Chris@13: '->tokenize() parses short options with a value', Chris@13: ], Chris@13: [ Chris@13: '-a"foo bar""foo bar"', Chris@13: [['-afoo barfoo bar', '-a"foo bar""foo bar"']], Chris@13: '->tokenize() parses short options with a value', Chris@13: ], Chris@13: [ Chris@13: '-a\'foo bar\'', Chris@13: [['-afoo bar', '-a\'foo bar\'']], Chris@13: '->tokenize() parses short options with a value', Chris@13: ], Chris@13: [ Chris@13: '-a\'foo bar\'\'foo bar\'', Chris@13: [['-afoo barfoo bar', '-a\'foo bar\'\'foo bar\'']], Chris@13: '->tokenize() parses short options with a value', Chris@13: ], Chris@13: [ Chris@13: '-a\'foo bar\'"foo bar"', Chris@13: [['-afoo barfoo bar', '-a\'foo bar\'"foo bar"']], Chris@13: '->tokenize() parses short options with a value', Chris@13: ], Chris@13: [ Chris@13: '--long-option', Chris@13: [['--long-option', '--long-option']], Chris@13: '->tokenize() parses long options', Chris@13: ], Chris@13: [ Chris@13: '--long-option=foo', Chris@13: [['--long-option=foo', '--long-option=foo']], Chris@13: '->tokenize() parses long options with a value', Chris@13: ], Chris@13: [ Chris@13: '--long-option="foo bar"', Chris@13: [['--long-option=foo bar', '--long-option="foo bar"']], Chris@13: '->tokenize() parses long options with a value', Chris@13: ], Chris@13: [ Chris@13: '--long-option="foo bar""another"', Chris@13: [['--long-option=foo baranother', '--long-option="foo bar""another"']], Chris@13: '->tokenize() parses long options with a value', Chris@13: ], Chris@13: [ Chris@13: '--long-option=\'foo bar\'', Chris@13: [['--long-option=foo bar', '--long-option=\'foo bar\'']], Chris@13: '->tokenize() parses long options with a value', Chris@13: ], Chris@13: [ Chris@13: "--long-option='foo bar''another'", Chris@13: [['--long-option=foo baranother', "--long-option='foo bar''another'"]], Chris@13: '->tokenize() parses long options with a value', Chris@13: ], Chris@13: [ Chris@13: "--long-option='foo bar'\"another\"", Chris@13: [['--long-option=foo baranother', "--long-option='foo bar'\"another\""]], Chris@13: '->tokenize() parses long options with a value', Chris@13: ], Chris@13: [ Chris@13: 'foo -a -ffoo --long bar', Chris@13: [ Chris@13: ['foo', 'foo -a -ffoo --long bar'], Chris@13: ['-a', '-a -ffoo --long bar'], Chris@13: ['-ffoo', '-ffoo --long bar'], Chris@13: ['--long', '--long bar'], Chris@13: ['bar', 'bar'], Chris@13: ], Chris@13: '->tokenize() parses when several arguments and options', Chris@13: ], Chris@13: ]; Chris@13: } Chris@13: }