commit 81bcea74679ed16287721106fd00b544fb94cc22
parent 67f73cc7030b556a5f809e4ac4738d1bb3c33f10
Author: Michael Camilleri <[email protected]>
Date: Thu, 2 Jul 2026 18:29:20 +0900
Normalise blank rebus commits
This commit stops an all-whitespace rebus entry from becoming an
invisible filled cell. The previous path preserved that buffer as a
non-empty entry, so an ordinary blank-looking square could count as
filled and leave the grid in filledWithErrors with nothing obvious for
the user to correct.
Now rebus commits trim surrounding whitespace in every case. Real
multi-word rebus fills keep their internal spaces, while gap squares
remain solvable because their correct state is still an empty entry.
Co-Authored-By: Codex GPT 5.5 <[email protected]>
Diffstat:
2 files changed, 39 insertions(+), 6 deletions(-)
diff --git a/Crossmate/Models/PlayerSession.swift b/Crossmate/Models/PlayerSession.swift
@@ -486,9 +486,6 @@ final class PlayerSession {
}
private func committedRebusValue(from buffer: String) -> String {
- guard buffer.rangeOfCharacter(from: CharacterSet.whitespacesAndNewlines.inverted) != nil else {
- return buffer
- }
return buffer.trimmingCharacters(in: .whitespacesAndNewlines)
}
diff --git a/Tests/Unit/PlayerSessionNavigationTests.swift b/Tests/Unit/PlayerSessionNavigationTests.swift
@@ -163,15 +163,51 @@ struct PlayerSessionNavigationTests {
#expect(session.rebusBuffer.isEmpty)
}
- @Test("Rebus commit preserves all-whitespace entries")
- func rebusCommitPreservesAllWhitespace() throws {
+ @Test("Rebus commit treats all-whitespace entries as empty")
+ func rebusCommitTreatsAllWhitespaceAsEmpty() throws {
let session = try makeNavigationSession()
session.startRebus()
session.rebusBuffer = " "
session.commitRebus()
- #expect(session.game.squares[0][0].entry == " ")
+ #expect(session.game.squares[0][0].entry.isEmpty)
+ #expect(session.game.completionState == .incomplete)
+ #expect(!session.isRebusActive)
+ #expect(session.rebusBuffer.isEmpty)
+ }
+
+ @Test("Whitespace rebus commit leaves gap cells solved")
+ func whitespaceRebusCommitLeavesGapCellsSolved() throws {
+ let source = #"""
+ Title: Gap
+ CmVer: 5
+ Rebus: 1=\space
+
+
+ TO1BE
+
+
+ A1. Repeated part of a soliloquy ~ TO BE
+ """#
+ let puzzle = Puzzle(xd: try XD.parse(source))
+ let game = Game(puzzle: puzzle)
+ let mutator = GameMutator(game: game, gameID: UUID(), movesUpdater: nil)
+ let session = PlayerSession(game: game, mutator: mutator)
+
+ for (col, letter) in [(0, "T"), (1, "O"), (3, "B"), (4, "E")] {
+ session.select(row: 0, col: col)
+ session.enter(letter)
+ }
+ #expect(game.completionState == .solved)
+
+ session.select(row: 0, col: 2)
+ session.startRebus()
+ session.rebusBuffer = " "
+ session.commitRebus()
+
+ #expect(game.squares[0][2].entry.isEmpty)
+ #expect(game.completionState == .solved)
#expect(!session.isRebusActive)
#expect(session.rebusBuffer.isEmpty)
}