crossmate

A collaborative crossword app for iOS
Log | Files | Refs | LICENSE

DriveMonitorTests.swift (2094B)


      1 import Foundation
      2 import Testing
      3 
      4 @testable import Crossmate
      5 
      6 /// Pins down the Imported-tab read boundary: `readSource` streams through
      7 /// `PuzzleFileReader`, so an oversized file fails before it is materialized
      8 /// rather than after an unbounded read.
      9 @Suite("DriveMonitor")
     10 @MainActor
     11 struct DriveMonitorTests {
     12 
     13     private static let validXD = """
     14     Title: Test Puzzle
     15     Author: Alice
     16 
     17 
     18     ABC
     19     D#E
     20     FGH
     21 
     22 
     23     A1. Across 1 ~ ABC
     24     A4. Across 4 ~ DE
     25     A5. Across 5 ~ FGH
     26     D1. Down 1 ~ ADF
     27     D2. Down 2 ~ BG
     28     D3. Down 3 ~ CEH
     29     """
     30 
     31     private func writeTemp(_ data: Data, ext: String) throws -> URL {
     32         let url = FileManager.default.temporaryDirectory
     33             .appendingPathComponent("drive-monitor-\(UUID().uuidString)")
     34             .appendingPathExtension(ext)
     35         try data.write(to: url)
     36         return url
     37     }
     38 
     39     @Test("readSource returns a valid .xd under the cap")
     40     func readSourceReturnsValidXD() throws {
     41         let url = try writeTemp(Data(Self.validXD.utf8), ext: "xd")
     42         defer { try? FileManager.default.removeItem(at: url) }
     43 
     44         let monitor = DriveMonitor()
     45         #expect(try monitor.readSource(at: url) == Self.validXD)
     46     }
     47 
     48     @Test("readSource rejects an oversized .xd")
     49     func readSourceRejectsOversizedXD() throws {
     50         let url = try writeTemp(
     51             Data(repeating: UInt8(ascii: "A"), count: XD.maxSourceBytes + 1),
     52             ext: "xd"
     53         )
     54         defer { try? FileManager.default.removeItem(at: url) }
     55 
     56         let monitor = DriveMonitor()
     57         #expect(throws: DriveError.self) {
     58             _ = try monitor.readSource(at: url)
     59         }
     60     }
     61 
     62     @Test("readSource rejects an oversized .puz")
     63     func readSourceRejectsOversizedPUZ() throws {
     64         let url = try writeTemp(
     65             Data(count: PUZToXDConverter.maxSourceBytes + 1),
     66             ext: "puz"
     67         )
     68         defer { try? FileManager.default.removeItem(at: url) }
     69 
     70         let monitor = DriveMonitor()
     71         #expect(throws: DriveError.self) {
     72             _ = try monitor.readSource(at: url)
     73         }
     74     }
     75 }