import CodexBarCore
import Foundation
import Testing
/// Tests for the regex-based JetBrains XML parser used on Linux.
/// These tests verify that the non-libxml2 implementation correctly parses
/// JetBrains AI Assistant quota files.
@Suite
struct JetBrainsParserLinuxTests {
@Test
func parsesQuotaXMLWithBothOptions() throws {
let quotaInfo = [
"{
"type": "Available",",
"
"current": "7478.3",",
"
"maximum": "1000000",",
"
"until": "2026-11-09T21:00:00Z",",
"
"tariffQuota": {",
"
"current": "7478.3",",
"
"maximum": "1000000",",
"
"available": "992521.7"",
"
}
}",
].joined()
let nextRefill = [
"{
"type": "Known",",
"
"next": "2026-01-16T14:00:54.939Z",",
"
"tariff": {",
"
"amount": "1000000",",
"
"duration": "PT720H"",
"
}
}",
].joined()
let xml = """
"""
let data = Data(xml.utf8)
let snapshot = try JetBrainsStatusProbe.parseXMLData(data, detectedIDE: nil)
#expect(snapshot.quotaInfo.type == "Available")
#expect(snapshot.quotaInfo.used == 7478.3)
#expect(snapshot.quotaInfo.maximum == 1_000_000)
#expect(snapshot.quotaInfo.available == 992_521.7)
#expect(snapshot.refillInfo?.type == "Known")
#expect(snapshot.refillInfo?.amount == 1_000_000)
}
@Test
func parsesQuotaXMLWithOnlyQuotaInfo() throws {
let quotaInfo = "{"type":"free","current":"5000","maximum":"100000"}"
let xml = """
"""
let data = Data(xml.utf8)
let snapshot = try JetBrainsStatusProbe.parseXMLData(data, detectedIDE: nil)
#expect(snapshot.quotaInfo.type == "free")
#expect(snapshot.quotaInfo.used == 5000)
#expect(snapshot.quotaInfo.maximum == 100_000)
#expect(snapshot.refillInfo == nil)
}
@Test
func parsesXMLWithReversedAttributeOrder() throws {
// Test that parser handles value before name (different attribute order)
let quotaInfo = "{"type":"paid","current":"1000","maximum":"50000"}"
let xml = """
"""
let data = Data(xml.utf8)
let snapshot = try JetBrainsStatusProbe.parseXMLData(data, detectedIDE: nil)
#expect(snapshot.quotaInfo.type == "paid")
#expect(snapshot.quotaInfo.used == 1000)
#expect(snapshot.quotaInfo.maximum == 50000)
}
@Test
func handlesHTMLEntities() throws {
let quotaInfo = [
"{"type":"test"",
","current":"0"",
","maximum":"50000"}",
].joined()
let xml = """
"""
let data = Data(xml.utf8)
let snapshot = try JetBrainsStatusProbe.parseXMLData(data, detectedIDE: nil)
#expect(snapshot.quotaInfo.type == "test")
#expect(snapshot.quotaInfo.maximum == 50000)
}
@Test
func throwsOnMissingQuotaInfo() throws {
let xml = """
"""
let data = Data(xml.utf8)
#expect(throws: JetBrainsStatusProbeError.noQuotaInfo) {
_ = try JetBrainsStatusProbe.parseXMLData(data, detectedIDE: nil)
}
}
@Test
func throwsOnMissingComponent() throws {
let xml = """
"""
let data = Data(xml.utf8)
#expect(throws: JetBrainsStatusProbeError.noQuotaInfo) {
_ = try JetBrainsStatusProbe.parseXMLData(data, detectedIDE: nil)
}
}
@Test
func throwsOnEmptyQuotaInfo() throws {
let xml = """
"""
let data = Data(xml.utf8)
#expect(throws: JetBrainsStatusProbeError.noQuotaInfo) {
_ = try JetBrainsStatusProbe.parseXMLData(data, detectedIDE: nil)
}
}
@Test
func parsesXMLWithSingleQuotes() throws {
let quotaInfo = "{"type":"single","current":"100","maximum":"10000"}"
let xml = """
"""
let data = Data(xml.utf8)
let snapshot = try JetBrainsStatusProbe.parseXMLData(data, detectedIDE: nil)
#expect(snapshot.quotaInfo.type == "single")
#expect(snapshot.quotaInfo.maximum == 10000)
}
}