BrewBar/BrewBarTests/BrewBarTests.swift
maxsoch 7b3468126a add typed JSON parser for brew outdated
parseOutdatedJSON decodes brew outdated --json into OutdatedPackages,
which separates formulae from casks — the plain-text output is just
names with no type information. Codable structs mirror the JSON shape,
with convertFromSnakeCase mapping installed_versions to Swift naming.
Undecodable input (brew error text, empty output) parses as .none.

The legacy line parser stays until callers switch over next commit.
Covered by 4 new unit tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 22:26:12 +02:00

90 lines
2.8 KiB
Swift

@testable import BrewBar
import XCTest
final class BrewParserTests: XCTestCase {
// MARK: - parseOutdated
func testParseOutdated_multiplePackages() {
let output = "wget\nffmpeg\ngit\n"
XCTAssertEqual(BrewParser.parseOutdated(output), ["wget", "ffmpeg", "git"])
}
func testParseOutdated_emptyOutput() {
XCTAssertEqual(BrewParser.parseOutdated(""), [])
}
func testParseOutdated_singlePackage() {
XCTAssertEqual(BrewParser.parseOutdated("wget\n"), ["wget"])
}
func testParseOutdated_trailingNewlinesIgnored() {
let output = "wget\n\n\n"
XCTAssertEqual(BrewParser.parseOutdated(output), ["wget"])
}
// MARK: - parseOutdatedJSON
func testParseOutdatedJSON_formulaeAndCasks() {
let output = """
{
"formulae": [
{
"name": "wget",
"installed_versions": ["1.21.3"],
"current_version": "1.21.4",
"pinned": false,
"pinned_version": null
}
],
"casks": [
{
"name": "tailscale-app",
"installed_versions": ["1.98.5"],
"current_version": "1.98.8",
"pinned": false,
"pinned_version": null
}
]
}
"""
let result = BrewParser.parseOutdatedJSON(output)
XCTAssertEqual(result.formulae.map(\.name), ["wget"])
XCTAssertEqual(result.casks.map(\.name), ["tailscale-app"])
XCTAssertEqual(result.count, 2)
XCTAssertFalse(result.isEmpty)
XCTAssertEqual(result.all.map(\.name), ["wget", "tailscale-app"])
}
func testParseOutdatedJSON_nothingOutdated() {
let result = BrewParser.parseOutdatedJSON("{\"formulae\": [], \"casks\": []}")
XCTAssertTrue(result.isEmpty)
XCTAssertEqual(result.count, 0)
}
func testParseOutdatedJSON_invalidInputReturnsNone() {
XCTAssertEqual(BrewParser.parseOutdatedJSON(""), .none)
XCTAssertEqual(BrewParser.parseOutdatedJSON("Error: some brew failure"), .none)
}
func testParseOutdatedJSON_packageLabel() {
let package = OutdatedPackage(name: "wget", installedVersions: ["1.21.3"], currentVersion: "1.21.4")
XCTAssertEqual(package.label, "wget 1.21.3 → 1.21.4")
}
// MARK: - parseVersion
func testParseVersion_picksFirstLine() {
let output = "Homebrew 4.3.0\nHomebrew/homebrew-core (git revision abc123)\n"
XCTAssertEqual(BrewParser.parseVersion(output), "Homebrew 4.3.0")
}
func testParseVersion_emptyOutput() {
XCTAssertEqual(BrewParser.parseVersion(""), "Unknown")
}
func testParseVersion_singleLine() {
XCTAssertEqual(BrewParser.parseVersion("Homebrew 4.3.0"), "Homebrew 4.3.0")
}
}