@@ -21,13 +21,15 @@ public function testInputStartsEmpty()
2121 {
2222 $ this ->assertEquals ('' , $ this ->readline ->getInput ());
2323 $ this ->assertEquals (0 , $ this ->readline ->getCursorPosition ());
24+ $ this ->assertEquals (0 , $ this ->readline ->getCursorCell ());
2425 }
2526
2627 public function testGetInputAfterSetting ()
2728 {
2829 $ this ->assertSame ($ this ->readline , $ this ->readline ->setInput ('hello ' ));
2930 $ this ->assertEquals ('hello ' , $ this ->readline ->getInput ());
3031 $ this ->assertEquals (5 , $ this ->readline ->getCursorPosition ());
32+ $ this ->assertEquals (5 , $ this ->readline ->getCursorCell ());
3133 }
3234
3335 public function testSettingInputMovesCursorToEnd ()
@@ -37,13 +39,15 @@ public function testSettingInputMovesCursorToEnd()
3739
3840 $ this ->readline ->setInput ('testing ' );
3941 $ this ->assertEquals (7 , $ this ->readline ->getCursorPosition ());
42+ $ this ->assertEquals (7 , $ this ->readline ->getCursorCell ());
4043 }
4144
4245 public function testMultiByteInput ()
4346 {
4447 $ this ->readline ->setInput ('täst ' );
4548 $ this ->assertEquals ('täst ' , $ this ->readline ->getInput ());
4649 $ this ->assertEquals (4 , $ this ->readline ->getCursorPosition ());
50+ $ this ->assertEquals (4 , $ this ->readline ->getCursorCell ());
4751 }
4852
4953 public function testRedrawingReadlineWritesToOutputOnce ()
@@ -175,6 +179,7 @@ public function testKeysSimpleChars()
175179
176180 $ this ->assertEquals ('hi! ' , $ this ->readline ->getInput ());
177181 $ this ->assertEquals (3 , $ this ->readline ->getCursorPosition ());
182+ $ this ->assertEquals (3 , $ this ->readline ->getCursorCell ());
178183
179184 return $ this ->readline ;
180185 }
@@ -189,6 +194,7 @@ public function testKeysBackspaceDeletesLastCharacter(Readline $readline)
189194
190195 $ this ->assertEquals ('hi ' , $ readline ->getInput ());
191196 $ this ->assertEquals (2 , $ readline ->getCursorPosition ());
197+ $ this ->assertEquals (2 , $ readline ->getCursorCell ());
192198 }
193199
194200 public function testKeysMultiByteInput ()
@@ -197,6 +203,7 @@ public function testKeysMultiByteInput()
197203
198204 $ this ->assertEquals ('hä ' , $ this ->readline ->getInput ());
199205 $ this ->assertEquals (2 , $ this ->readline ->getCursorPosition ());
206+ $ this ->assertEquals (2 , $ this ->readline ->getCursorCell ());
200207
201208 return $ this ->readline ;
202209 }
@@ -221,6 +228,7 @@ public function testKeysBackspaceMiddle()
221228
222229 $ this ->assertEquals ('tst ' , $ this ->readline ->getInput ());
223230 $ this ->assertEquals (1 , $ this ->readline ->getCursorPosition ());
231+ $ this ->assertEquals (1 , $ this ->readline ->getCursorCell ());
224232 }
225233
226234 public function testKeysBackspaceFrontDoesNothing ()
@@ -232,6 +240,7 @@ public function testKeysBackspaceFrontDoesNothing()
232240
233241 $ this ->assertEquals ('test ' , $ this ->readline ->getInput ());
234242 $ this ->assertEquals (0 , $ this ->readline ->getCursorPosition ());
243+ $ this ->assertEquals (0 , $ this ->readline ->getCursorCell ());
235244 }
236245
237246 public function testKeysDeleteMiddle ()
@@ -243,6 +252,7 @@ public function testKeysDeleteMiddle()
243252
244253 $ this ->assertEquals ('tet ' , $ this ->readline ->getInput ());
245254 $ this ->assertEquals (2 , $ this ->readline ->getCursorPosition ());
255+ $ this ->assertEquals (2 , $ this ->readline ->getCursorCell ());
246256 }
247257
248258 public function testKeysDeleteEndDoesNothing ()
@@ -253,6 +263,7 @@ public function testKeysDeleteEndDoesNothing()
253263
254264 $ this ->assertEquals ('test ' , $ this ->readline ->getInput ());
255265 $ this ->assertEquals (4 , $ this ->readline ->getCursorPosition ());
266+ $ this ->assertEquals (4 , $ this ->readline ->getCursorCell ());
256267 }
257268
258269 public function testKeysPrependCharacterInFrontOfMultiByte ()
@@ -264,6 +275,7 @@ public function testKeysPrependCharacterInFrontOfMultiByte()
264275
265276 $ this ->assertEquals ('hü ' , $ this ->readline ->getInput ());
266277 $ this ->assertEquals (1 , $ this ->readline ->getCursorPosition ());
278+ $ this ->assertEquals (1 , $ this ->readline ->getCursorCell ());
267279 }
268280
269281 public function testKeysWriteMultiByteAfterMultiByte ()
@@ -274,6 +286,7 @@ public function testKeysWriteMultiByteAfterMultiByte()
274286
275287 $ this ->assertEquals ('üä ' , $ this ->readline ->getInput ());
276288 $ this ->assertEquals (2 , $ this ->readline ->getCursorPosition ());
289+ $ this ->assertEquals (2 , $ this ->readline ->getCursorCell ());
277290 }
278291
279292 public function testKeysPrependMultiByteInFrontOfMultiByte ()
@@ -285,6 +298,89 @@ public function testKeysPrependMultiByteInFrontOfMultiByte()
285298
286299 $ this ->assertEquals ('äü ' , $ this ->readline ->getInput ());
287300 $ this ->assertEquals (1 , $ this ->readline ->getCursorPosition ());
301+ $ this ->assertEquals (1 , $ this ->readline ->getCursorCell ());
302+ }
303+
304+ public function testDoubleWidthCharsOccupyTwoCells ()
305+ {
306+ $ this ->readline ->setInput ('現 ' );
307+
308+ $ this ->assertEquals (1 , $ this ->readline ->getCursorPosition ());
309+ $ this ->assertEquals (2 , $ this ->readline ->getCursorCell ());
310+
311+ return $ this ->readline ;
312+ }
313+
314+ /**
315+ * @depends testDoubleWidthCharsOccupyTwoCells
316+ * @param Readline $readline
317+ */
318+ public function testDoubleWidthCharMoveToStart (Readline $ readline )
319+ {
320+ $ readline ->moveCursorTo (0 );
321+
322+ $ this ->assertEquals (0 , $ readline ->getCursorPosition ());
323+ $ this ->assertEquals (0 , $ readline ->getCursorCell ());
324+
325+ return $ readline ;
326+ }
327+
328+ /**
329+ * @depends testDoubleWidthCharMoveToStart
330+ * @param Readline $readline
331+ */
332+ public function testDoubleWidthCharMovesTwoCellsForward (Readline $ readline )
333+ {
334+ $ readline ->moveCursorBy (1 );
335+
336+ $ this ->assertEquals (1 , $ readline ->getCursorPosition ());
337+ $ this ->assertEquals (2 , $ readline ->getCursorCell ());
338+
339+ return $ readline ;
340+ }
341+
342+ /**
343+ * @depends testDoubleWidthCharMovesTwoCellsForward
344+ * @param Readline $readline
345+ */
346+ public function testDoubleWidthCharMovesTwoCellsBackward (Readline $ readline )
347+ {
348+ $ readline ->moveCursorBy (-1 );
349+
350+ $ this ->assertEquals (0 , $ readline ->getCursorPosition ());
351+ $ this ->assertEquals (0 , $ readline ->getCursorCell ());
352+ }
353+
354+ public function testCursorCellIsAlwaysZeroIfEchoIsOff ()
355+ {
356+ $ this ->readline ->setInput ('test ' );
357+ $ this ->readline ->setEcho (false );
358+
359+ $ this ->assertEquals (4 , $ this ->readline ->getCursorPosition ());
360+ $ this ->assertEquals (0 , $ this ->readline ->getCursorCell ());
361+ }
362+
363+ public function testCursorCellAccountsForDoubleWidthCharacters ()
364+ {
365+ $ this ->readline ->setInput ('現現現現 ' );
366+ $ this ->readline ->moveCursorTo (3 );
367+
368+ $ this ->assertEquals (3 , $ this ->readline ->getCursorPosition ());
369+ $ this ->assertEquals (6 , $ this ->readline ->getCursorCell ());
370+
371+ return $ this ->readline ;
372+ }
373+
374+ /**
375+ * @depends testCursorCellAccountsForDoubleWidthCharacters
376+ * @param Readline $readline
377+ */
378+ public function testCursorCellObeysCustomEchoAsterisk (Readline $ readline )
379+ {
380+ $ readline ->setEcho ('* ' );
381+
382+ $ this ->assertEquals (3 , $ readline ->getCursorPosition ());
383+ $ this ->assertEquals (3 , $ readline ->getCursorCell ());
288384 }
289385
290386 private function pushInputBytes (Readline $ readline , $ bytes )
0 commit comments