cg85-v2/Tests/Np85SnakeTests/BoardTests.swift

195 lines
4.3 KiB
Swift

import Foundation
import Testing
@testable import Np85Snake
enum MockOutput: Equatable {
case text(String)
case command(SnakeCommand)
}
class MockIO: BoardIO {
var lines: [any StringProtocol] = []
var output: [MockOutput] = []
init(lines: [any StringProtocol]) {
self.lines = lines
}
func next() -> (any StringProtocol)? {
guard !lines.isEmpty else {
return nil
}
return lines.removeFirst()
}
func commit(text: String) {
output.append(MockOutput.text(text))
}
func commit(command: SnakeCommand) {
output.append(MockOutput.command(command))
}
}
struct BoardTests {
@Test func parseInvalidMalformedTest() async throws {
let lines = [
"....nya......┃..",
".....0╗....$.┃..",
"......┗━━.......",
".$..............",
"....$......O═┓..",
]
var board = Board(16, 5)
var reader = MockIO(lines: lines) as any BoardIO
#expect(throws: SnakeError.malformedBoardState) {
try board.parse(io: &reader)
}
}
@Test func parseDoorStuckTest() async throws {
let lines = [
".┏┓.....",
".┃┗━━━┓.",
"┏┛....┃.",
"┃.....┃.",
"┃.$...┃.",
"┗┓..━━┛0",
".┗━━━━━╝",
"........",
]
var board = Board(8, 8)
var reader = MockIO(lines: lines) as any BoardIO
_ = try board.parse(io: &reader)
board.calculate()
let success = board.commit(io: &reader)
#expect(!success)
}
@Test func parseDerezzedTest() async throws {
let lines = [
"....┏┓.$",
"....┃┃..",
"....┃┃..",
"....┃┃..",
"....┃┃..",
".....┃..",
".....┃..",
".0═━━┛..",
]
var board = Board(8, 8)
let mock = MockIO(lines: lines)
var reader = mock as any BoardIO
_ = try board.parse(io: &reader)
board.calculate()
let success = board.commit(io: &reader)
#expect(success)
#expect(mock.output.count == 1)
}
@Test func parseInvalidIncompleteTest() async throws {
let lines = [
".............┃..",
".....0╗....$.┃..",
"......┗━━.......",
".$..............",
]
var board = Board(16, 5)
var reader = MockIO(lines: lines) as any BoardIO
#expect(throws: SnakeError.malformedBoardLine) {
try board.parse(io: &reader)
}
}
@Test func parseInvalidExcessTest() async throws {
let lines = [
".............┃..nya",
".....0╗....$.┃..",
"......┗━━.......",
".$..............",
"....$......O═┓..",
]
var board = Board(16, 5)
var reader = MockIO(lines: lines) as any BoardIO
#expect(throws: SnakeError.malformedBoardLine) {
try board.parse(io: &reader)
}
}
@Test func parseNovelTest() async throws {
let lines = [
".............┃..",
".....0╗....$.┃..",
"......┗━━.......",
".$..............",
"....$......O═┓..",
]
var board = Board(16, 5)
var reader = MockIO(lines: lines) as any BoardIO
_ = try board.parse(io: &reader)
// todo: validate output
}
@Test func parseFunkyTest() async throws {
let lines = [
"....┏┓┏┓┏┓┏┓┏┓..",
"....0╬╋╋╋╋╋╋╋╋┓.",
".....┗┛┗┛┗┛┗┛┗┛.",
]
var board = Board(16, 3)
var reader = MockIO(lines: lines) as any BoardIO
_ = try board.parse(io: &reader)
// todo: validate output
}
@Test func startTest() async throws {
let lines = [
"32",
"64",
]
var reader = MockIO(lines: lines) as any BoardIO
let board = try Board.start(io: &reader)
#expect(board.width == 32)
#expect(board.height == 64)
#expect((reader as! MockIO).output.count == 1)
#expect((reader as! MockIO).output.first == MockOutput.text("utf8"))
}
@Test func startInvalidWidthTest() async throws {
let lines = [
"nya",
"64",
]
var reader = MockIO(lines: lines) as any BoardIO
#expect(throws: SnakeError.invalidWidth) {
_ = try Board.start(io: &reader)
}
}
@Test func startInvalidHeightTest() async throws {
let lines = [
"32",
"nya",
]
var reader = MockIO(lines: lines) as any BoardIO
#expect(throws: SnakeError.invalidHeight) {
_ = try Board.start(io: &reader)
}
}
}