PlayerSessionNavigationTests.swift (5479B)
1 import Foundation 2 import Testing 3 4 @testable import Crossmate 5 6 @Suite("PlayerSession navigation", .serialized) 7 @MainActor 8 struct PlayerSessionNavigationTests { 9 @Test("Next clue from final across moves to first down") 10 func nextClueFromFinalAcrossMovesToFirstDown() throws { 11 let session = try makeNavigationSession() 12 let finalAcross = try #require(session.puzzle.acrossClues.last) 13 let firstDown = try #require(session.puzzle.downClues.first) 14 15 session.selectClue(direction: .across, number: finalAcross.number) 16 session.goToNextClue() 17 18 #expect(session.direction == .down) 19 #expect(session.currentClue()?.number == firstDown.number) 20 } 21 22 @Test("Previous clue from first down moves to final across") 23 func previousClueFromFirstDownMovesToFinalAcross() throws { 24 let session = try makeNavigationSession() 25 let finalAcross = try #require(session.puzzle.acrossClues.last) 26 let firstDown = try #require(session.puzzle.downClues.first) 27 28 session.selectClue(direction: .down, number: firstDown.number) 29 session.goToPreviousClue() 30 31 #expect(session.direction == .across) 32 #expect(session.currentClue()?.number == finalAcross.number) 33 } 34 35 @Test("Next clue from final down moves to first across") 36 func nextClueFromFinalDownMovesToFirstAcross() throws { 37 let session = try makeNavigationSession() 38 let firstAcross = try #require(session.puzzle.acrossClues.first) 39 let finalDown = try #require(session.puzzle.downClues.last) 40 41 session.selectClue(direction: .down, number: finalDown.number) 42 session.goToNextClue() 43 44 #expect(session.direction == .across) 45 #expect(session.currentClue()?.number == firstAcross.number) 46 } 47 48 @Test("Typing past final across moves to first down") 49 func typingPastFinalAcrossMovesToFirstDown() throws { 50 let session = try makeNavigationSession() 51 let finalAcross = try #require(session.puzzle.acrossClues.last) 52 let firstDown = try #require(session.puzzle.downClues.first) 53 54 session.selectClue(direction: .across, number: finalAcross.number) 55 session.select(row: 2, col: 2) 56 session.setDirection(.across) 57 session.enter("H") 58 59 #expect(session.direction == .down) 60 #expect(session.currentClue()?.number == firstDown.number) 61 } 62 63 @Test("Typing past final down moves to first across") 64 func typingPastFinalDownMovesToFirstAcross() throws { 65 let session = try makeNavigationSession() 66 let firstAcross = try #require(session.puzzle.acrossClues.first) 67 let finalDown = try #require(session.puzzle.downClues.last) 68 69 session.selectClue(direction: .down, number: finalDown.number) 70 session.select(row: 2, col: 2) 71 session.setDirection(.down) 72 session.enter("H") 73 74 #expect(session.direction == .across) 75 #expect(session.currentClue()?.number == firstAcross.number) 76 } 77 78 @Test("Backspace from first down moves to final across end") 79 func backspaceFromFirstDownMovesToFinalAcrossEnd() throws { 80 let session = try makeNavigationSession() 81 let finalAcross = try #require(session.puzzle.acrossClues.last) 82 let firstDown = try #require(session.puzzle.downClues.first) 83 84 session.selectClue(direction: .down, number: firstDown.number) 85 session.deleteBackward() 86 87 #expect(session.direction == .across) 88 #expect(session.currentClue()?.number == finalAcross.number) 89 #expect(session.selectedRow == 2) 90 #expect(session.selectedCol == 2) 91 } 92 93 @Test("Backspace from first across moves to final down end") 94 func backspaceFromFirstAcrossMovesToFinalDownEnd() throws { 95 let session = try makeNavigationSession() 96 let firstAcross = try #require(session.puzzle.acrossClues.first) 97 let finalDown = try #require(session.puzzle.downClues.last) 98 99 session.selectClue(direction: .across, number: firstAcross.number) 100 session.deleteBackward() 101 102 #expect(session.direction == .down) 103 #expect(session.currentClue()?.number == finalDown.number) 104 #expect(session.selectedRow == 2) 105 #expect(session.selectedCol == 2) 106 } 107 108 @Test("Backspace from final across start moves to previous across end") 109 func backspaceFromFinalAcrossStartMovesToPreviousAcrossEnd() throws { 110 let session = try makeNavigationSession() 111 let firstAcross = try #require(session.puzzle.acrossClues.first) 112 let finalAcross = try #require(session.puzzle.acrossClues.last) 113 114 session.selectClue(direction: .across, number: finalAcross.number) 115 session.deleteBackward() 116 117 #expect(session.direction == .across) 118 #expect(session.currentClue()?.number == firstAcross.number) 119 #expect(session.selectedRow == 0) 120 #expect(session.selectedCol == 2) 121 } 122 123 private func makeNavigationSession() throws -> PlayerSession { 124 let source = """ 125 Title: Navigation Test 126 Author: Test 127 128 129 ABC 130 D#E 131 FGH 132 133 134 A1. First across ~ ABC 135 A3. Final across ~ FGH 136 D1. First down ~ ADF 137 D2. Final down ~ CEH 138 """ 139 140 let puzzle = Puzzle(xd: try XD.parse(source)) 141 let game = Game(puzzle: puzzle) 142 let mutator = GameMutator(game: game, gameID: UUID(), movesUpdater: nil) 143 return PlayerSession(game: game, mutator: mutator) 144 } 145 }