From f804a2a9fc4a0499152a63dffcda3755b0d1ac2f Mon Sep 17 00:00:00 2001 From: Humza Shahid Date: Thu, 16 Oct 2025 12:02:20 +0100 Subject: [PATCH] add tests for 'd$' motion, including one failing test whose implementation needs to be fixed --- shell/shell.sml | 1 + test/normal-delete.sml | 176 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 157 insertions(+), 20 deletions(-) diff --git a/shell/shell.sml b/shell/shell.sml index 68413ed..3a96ae3 100644 --- a/shell/shell.sml +++ b/shell/shell.sml @@ -84,6 +84,7 @@ struct (* load file intol gap buffer and create initial app *) val io = TextIO.openIn "temp.txt" val lineGap = ioToLineGap (io, LineGap.empty) + val lineGap = LineGap.fromString "hello\nworld" val _ = TextIO.closeIn io val app = AppType.init (lineGap, 1920, 1080, Time.now ()) diff --git a/test/normal-delete.sml b/test/normal-delete.sml index 800ca62..1b5828e 100644 --- a/test/normal-delete.sml +++ b/test/normal-delete.sml @@ -2957,28 +2957,164 @@ struct ] val dDlrDelete = describe "delete motion 'd$'" - [test - "deletes only last character on line \ - \when cursor is on last character" - (fn _ => - let - (* arrange *) - val originalString = "hello\nworld\n" - val app = TestUtils.init originalString - val app = AppWith.idx (app, 4) + [ test + "deletes only the last character on the line \ + \and moves cursor back by one index \ + \when cursor is on last character" + (fn _ => + let + (* arrange *) + val originalString = "hello\nworld\n" + val app = TestUtils.init originalString + val app = AppWith.idx (app, 4) - (* act *) - val {buffer, cursorIdx, ...} = TestUtils.updateMany (app, "d$") + (* act *) + val {buffer, cursorIdx, ...} = TestUtils.updateMany (app, "d$") - (* assert *) - val actualString = LineGap.toString buffer - val expectedString = originalString - val expectedCursorIdx = 3 - in - Expect.isTrue - (actualString = expectedString - andalso cursorIdx = expectedCursorIdx) - end)] + (* assert *) + val actualString = LineGap.toString buffer + val expectedString = "hell\nworld\n" + val expectedCursorIdx = 3 + in + Expect.isTrue + (actualString = expectedString + andalso cursorIdx = expectedCursorIdx) + end) + , test + "deletes from first character in buffer \ + \up to (and excluding) the first newline \ + \when the cursor is on the first character in the buffer" + (fn _ => + let + (* arrange *) + val originalString = "hello\nworld\n" + val app = TestUtils.init originalString + val app = AppWith.idx (app, 0) + + (* act *) + val {buffer, cursorIdx, ...} = TestUtils.updateMany (app, "d$") + + (* assert *) + val actualString = LineGap.toString buffer + val expectedString = "\nworld\n" + val expectedCursorIdx = 0 + in + Expect.isTrue + (actualString = expectedString + andalso cursorIdx = expectedCursorIdx) + end) + , test + "deletes from first character in line \ + \up to (and excluding) the next newline \ + \when the cursor is on the first character of second newline" + (fn _ => + let + (* arrange *) + val originalString = "hello\nworld\nagain\n" + val app = TestUtils.init originalString + val app = AppWith.idx (app, 6) + + (* act *) + val {buffer, cursorIdx, ...} = TestUtils.updateMany (app, "d$") + + (* assert *) + val actualString = LineGap.toString buffer + val expectedString = "hello\n\nagain\n" + val expectedCursorIdx = 6 + in + Expect.isTrue + (actualString = expectedString + andalso cursorIdx = expectedCursorIdx) + end) + , test + "deletes from middle character on line to last character in line \ + \when cursor is on middle character" + (fn _ => + let + (* arrange *) + val originalString = "hello\nworld\n" + val app = TestUtils.init originalString + val app = AppWith.idx (app, 2) + + (* act *) + val {buffer, cursorIdx, ...} = TestUtils.updateMany (app, "d$") + + (* assert *) + val actualString = LineGap.toString buffer + val expectedString = "he\nworld\n" + val expectedCursorIdx = 1 + in + Expect.isTrue + (actualString = expectedString + andalso cursorIdx = expectedCursorIdx) + end) + , test + "does not delete when cursor is on a line \ + \which contains only a single newline and nothing else" + (fn _ => + let + (* arrange *) + val originalString = "hello\n\nworld\n" + val app = TestUtils.init originalString + val app = AppWith.idx (app, 6) + + (* act *) + val {buffer, cursorIdx, ...} = TestUtils.updateMany (app, "d$") + + (* assert *) + val actualString = LineGap.toString buffer + val expectedString = originalString + val expectedCursorIdx = 6 + in + Expect.isTrue + (actualString = expectedString + andalso cursorIdx = expectedCursorIdx) + end) + , test + "deletes from middle character on last line \ + \when the last line ends with a newline" + (fn _ => + let + (* arrange *) + val originalString = "hello\nworld\n" + val app = TestUtils.init originalString + val app = AppWith.idx (app, 7) + + (* act *) + val {buffer, cursorIdx, ...} = TestUtils.updateMany (app, "d$") + + (* assert *) + val actualString = LineGap.toString buffer + val expectedString = "hello\nw\n" + val expectedCursorIdx = 6 + in + Expect.isTrue + (actualString = expectedString + andalso cursorIdx = expectedCursorIdx) + end) + , test + "deletes from middle character on last line \ + \when the last line does not end with a newline" + (fn _ => + let + (* arrange *) + val originalString = "hello\nworld" + val app = TestUtils.init originalString + val app = AppWith.idx (app, 7) + + (* act *) + val {buffer, cursorIdx, ...} = TestUtils.updateMany (app, "d$") + + (* assert *) + val actualString = LineGap.toString buffer + val expectedString = "hello\nw" + val expectedCursorIdx = 6 + in + Expect.isTrue + (actualString = expectedString + andalso cursorIdx = expectedCursorIdx) + end) + ] val tests = [ dhDelete