191 lines
6.5 KiB
Swift
191 lines
6.5 KiB
Swift
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 = """
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<application>
|
|
<component name="AIAssistantQuotaManager2">
|
|
<option name="quotaInfo" value="\(quotaInfo)" />
|
|
<option name="nextRefill" value="\(nextRefill)" />
|
|
</component>
|
|
</application>
|
|
"""
|
|
|
|
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 = """
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<application>
|
|
<component name="AIAssistantQuotaManager2">
|
|
<option name="quotaInfo" value="\(quotaInfo)" />
|
|
</component>
|
|
</application>
|
|
"""
|
|
|
|
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 = """
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<application>
|
|
<component name="AIAssistantQuotaManager2">
|
|
<option value="\(quotaInfo)" name="quotaInfo" />
|
|
</component>
|
|
</application>
|
|
"""
|
|
|
|
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 = """
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<application>
|
|
<component name="AIAssistantQuotaManager2">
|
|
<option name="quotaInfo" value="\(quotaInfo)" />
|
|
</component>
|
|
</application>
|
|
"""
|
|
|
|
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 = """
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<application>
|
|
<component name="AIAssistantQuotaManager2">
|
|
</component>
|
|
</application>
|
|
"""
|
|
|
|
let data = Data(xml.utf8)
|
|
#expect(throws: JetBrainsStatusProbeError.noQuotaInfo) {
|
|
_ = try JetBrainsStatusProbe.parseXMLData(data, detectedIDE: nil)
|
|
}
|
|
}
|
|
|
|
@Test
|
|
func throwsOnMissingComponent() throws {
|
|
let xml = """
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<application>
|
|
<component name="SomeOtherComponent">
|
|
<option name="quotaInfo" value="{}" />
|
|
</component>
|
|
</application>
|
|
"""
|
|
|
|
let data = Data(xml.utf8)
|
|
#expect(throws: JetBrainsStatusProbeError.noQuotaInfo) {
|
|
_ = try JetBrainsStatusProbe.parseXMLData(data, detectedIDE: nil)
|
|
}
|
|
}
|
|
|
|
@Test
|
|
func throwsOnEmptyQuotaInfo() throws {
|
|
let xml = """
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<application>
|
|
<component name="AIAssistantQuotaManager2">
|
|
<option name="quotaInfo" value="" />
|
|
</component>
|
|
</application>
|
|
"""
|
|
|
|
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 = """
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<application>
|
|
<component name='AIAssistantQuotaManager2'>
|
|
<option name='quotaInfo' value='\(quotaInfo)' />
|
|
</component>
|
|
</application>
|
|
"""
|
|
|
|
let data = Data(xml.utf8)
|
|
let snapshot = try JetBrainsStatusProbe.parseXMLData(data, detectedIDE: nil)
|
|
|
|
#expect(snapshot.quotaInfo.type == "single")
|
|
#expect(snapshot.quotaInfo.maximum == 10000)
|
|
}
|
|
}
|