@@ -584,6 +584,109 @@ public function testAutocompleteAddsSpaceAfterComplete()
584584 $ this ->assertEquals ('exit ' , $ this ->readline ->getInput ());
585585 }
586586
587+ public function testAutocompleteAddsSpaceAfterSecondWordIsComplete ()
588+ {
589+ $ this ->readline ->setAutocomplete (function () { return array ('exit ' ); });
590+
591+ $ this ->readline ->setInput ('exit ex ' );
592+
593+ $ this ->readline ->onKeyTab ();
594+
595+ $ this ->assertEquals ('exit exit ' , $ this ->readline ->getInput ());
596+ }
597+
598+ public function testAutocompleteAddsSpaceAfterCompleteWithClosingDoubleQuote ()
599+ {
600+ $ this ->readline ->setAutocomplete (function () { return array ('exit ' ); });
601+
602+ $ this ->readline ->setInput ('"exit ' );
603+
604+ $ this ->readline ->onKeyTab ();
605+
606+ $ this ->assertEquals ('"exit" ' , $ this ->readline ->getInput ());
607+ }
608+
609+ public function testAutocompleteAddsSpaceAfterCompleteWithClosingSingleQuote ()
610+ {
611+ $ this ->readline ->setAutocomplete (function () { return array ('exit ' ); });
612+
613+ $ this ->readline ->setInput ('\'exit ' );
614+
615+ $ this ->readline ->onKeyTab ();
616+
617+ $ this ->assertEquals ('\'exit \' ' , $ this ->readline ->getInput ());
618+ }
619+
620+ public function testAutocompleteAddsSpaceAfterSecondWordIsCompleteWithClosingDoubleQuote ()
621+ {
622+ $ this ->readline ->setAutocomplete (function () { return array ('exit ' ); });
623+
624+ $ this ->readline ->setInput ('exit "exit ' );
625+
626+ $ this ->readline ->onKeyTab ();
627+
628+ $ this ->assertEquals ('exit "exit" ' , $ this ->readline ->getInput ());
629+ }
630+
631+ public function testAutocompleteStaysInQuotedStringAtEnd ()
632+ {
633+ $ this ->readline ->setAutocomplete (function () { return array ('exit ' ); });
634+
635+ // move cursor before closing quote
636+ $ this ->readline ->setInput ('exit "ex" ' );
637+ $ this ->readline ->moveCursorBy (-1 );
638+
639+ $ this ->readline ->onKeyTab ();
640+
641+ $ this ->assertEquals ('exit "exit" ' , $ this ->readline ->getInput ());
642+ $ this ->assertEquals (10 , $ this ->readline ->getCursorPosition ());
643+ }
644+
645+ public function testAutocompleteStaysInQuotedStringInMiddle ()
646+ {
647+ $ this ->readline ->setAutocomplete (function () { return array ('exit ' ); });
648+
649+ // move cursor before closing quote
650+ $ this ->readline ->setInput ('exit "ex" exit ' );
651+ $ this ->readline ->moveCursorTo (8 );
652+
653+ $ this ->readline ->onKeyTab ();
654+
655+ $ this ->assertEquals ('exit "exit" exit ' , $ this ->readline ->getInput ());
656+ $ this ->assertEquals (10 , $ this ->readline ->getCursorPosition ());
657+ }
658+
659+ public function testAutocompleteAddsClosingSingleQuoteAndSpaceWhenMatchingEmptyString ()
660+ {
661+ $ this ->readline ->setAutocomplete (function () { return array ('' ); });
662+
663+ $ this ->readline ->setInput ('\'' );
664+
665+ $ this ->readline ->onKeyTab ();
666+
667+ $ this ->assertEquals ('\'\' ' , $ this ->readline ->getInput ());
668+ }
669+
670+ public function testAutocompleteAddsClosingDoubleQuoteAndSpaceWhenMatchingEmptyString ()
671+ {
672+ $ this ->readline ->setAutocomplete (function () { return array ('' ); });
673+
674+ $ this ->readline ->setInput ('" ' );
675+
676+ $ this ->readline ->onKeyTab ();
677+
678+ $ this ->assertEquals ('"" ' , $ this ->readline ->getInput ());
679+ }
680+
681+ public function testAutocompleteAddsSingleQuotesAndSpaceWhenMatchingEmptyString ()
682+ {
683+ $ this ->readline ->setAutocomplete (function () { return array ('' ); });
684+
685+ $ this ->readline ->onKeyTab ();
686+
687+ $ this ->assertEquals ('\'\' ' , $ this ->readline ->getInput ());
688+ }
689+
587690 public function testAutocompletePicksFirstComplete ()
588691 {
589692 $ this ->readline ->setAutocomplete (function () { return array ('exit ' ); });
@@ -633,18 +736,32 @@ public function testAutocompleteUsesCommonPrefixWhenMultipleMatch()
633736 $ this ->assertEquals ('fir ' , $ this ->readline ->getInput ());
634737 }
635738
636- public function testAutocompleteUsesExactMatchWhenDuplicateMatch ()
739+ public function testAutocompleteUsesCommonPrefixWithoutClosingQUotesWhenMultipleMatchAfterQuotes ()
637740 {
638- $ this ->readline ->setAutocomplete (function () { return array ('first ' , 'first ' ); });
741+ $ this ->readline ->setAutocomplete (function () { return array ('first ' , 'firm ' ); });
742+
743+ $ this ->readline ->setInput ('" ' );
639744
640745 $ this ->readline ->onKeyTab ();
641746
642- $ this ->assertEquals ('first ' , $ this ->readline ->getInput ());
747+ $ this ->assertEquals ('"fir ' , $ this ->readline ->getInput ());
748+ }
749+
750+ public function testAutocompleteUsesCommonPrefixBetweenQuotesWhenMultipleMatchBetweenQuotes ()
751+ {
752+ $ this ->readline ->setAutocomplete (function () { return array ('first ' , 'firm ' ); });
753+
754+ $ this ->readline ->setInput ('"" ' );
755+ $ this ->readline ->moveCursorBy (-1 );
756+
757+ $ this ->readline ->onKeyTab ();
758+
759+ $ this ->assertEquals ('"fir" ' , $ this ->readline ->getInput ());
643760 }
644761
645- public function testAutocompleteUsesExactMatchWhenDuplicateOrEmptyMatch ()
762+ public function testAutocompleteUsesExactMatchWhenDuplicateMatch ()
646763 {
647- $ this ->readline ->setAutocomplete (function () { return array ('' , ' first ' , ' ' , 'first ' ); });
764+ $ this ->readline ->setAutocomplete (function () { return array ('first ' , 'first ' ); });
648765
649766 $ this ->readline ->onKeyTab ();
650767
@@ -674,6 +791,20 @@ public function testAutocompleteShowsAvailableOptionsWhenMultipleMatch()
674791 $ this ->assertContains ("\na b \n" , $ buffer );
675792 }
676793
794+ public function testAutocompleteShowsAvailableOptionsWhenMultipleMatchWithEmptyWord ()
795+ {
796+ $ buffer = '' ;
797+ $ this ->output ->expects ($ this ->atLeastOnce ())->method ('write ' )->will ($ this ->returnCallback (function ($ data ) use (&$ buffer ) {
798+ $ buffer .= $ data ;
799+ }));
800+
801+ $ this ->readline ->setAutocomplete (function () { return array ('' , 'a ' ); });
802+
803+ $ this ->readline ->onKeyTab ();
804+
805+ $ this ->assertContains ("\n a \n" , $ buffer );
806+ }
807+
677808 public function testAutocompleteShowsAvailableOptionsWhenMultipleMatchIncompleteWord ()
678809 {
679810 $ buffer = '' ;
0 commit comments