import XCTest @testable import TVAnarchyCore final class CommandTemplateTests: XCTestCase { func testSubstitutionAndOptionalDrop() { let t = ["/usr/local/bin/black-tv", "play-show", "{query}", "{season?}", "{episode?}"] // optional episode absent → its word is dropped entirely let r = CommandTemplate.render(t, ["query": "Psych", "season": "3", "episode": nil]) XCTAssertEqual(r, "'/usr/local/bin/black-tv' 'play-show' 'Psych' '3'") } func testAllOptionalsPresent() { let t = ["btv", "play-show", "{query}", "{season?}", "{episode?}"] XCTAssertEqual(CommandTemplate.render(t, ["query": "X", "season": "1", "episode": "4"]), "'btv' 'play-show' 'X' '1' '4'") } func testShqEscapesDangerousValues() { // apostrophes, spaces, and shell metachars must be neutralized let r = CommandTemplate.render(["btv", "play", "{path}"], ["path": "/m/It's $HOME & co/ep.mkv"]) // Fully single-quoted (only the apostrophe is broken out & re-escaped), so // the remote shell sees one literal word — `$HOME`/`&` can't expand or split. XCTAssertEqual(r, "'btv' 'play' '/m/It'\\''s $HOME & co/ep.mkv'") } func testRequiredMissingBecomesEmptyWord() { XCTAssertEqual(CommandTemplate.render(["a", "{x}"], [:]), "'a' ''") } func testPlaceholderParsing() { XCTAssertEqual(CommandTemplate.placeholder("{query}")?.name, "query") XCTAssertEqual(CommandTemplate.placeholder("{query}")?.optional, false) XCTAssertEqual(CommandTemplate.placeholder("{season?}")?.optional, true) XCTAssertNil(CommandTemplate.placeholder("literal")) XCTAssertNil(CommandTemplate.placeholder("{}")) } }