Files
legado-ios/Tests/LegadoCoreTests/BookSourceRemoteProbe.swift
T
Aminark 67bc212ffd feat: 支持 EPUB 阅读并改善规则兼容与阅读稳定性
支持 EPUB 2/3 导入、目录、封面和章节插图,保留本地书管理与阅读进度。
修复 JSON 模板、动态替换与请求参数兼容,以及 RSS 翻页和连续滚动定位。
更新编辑器工具栏和回归测试,发布版本为 0.1.12(build 18)。
2026-10-24 00:58:11 +08:00

90 lines
5.1 KiB
Swift

import Foundation
import Testing
@testable import LegadoCore
// Opt-in only: point LEGADO_SOURCE_PROBE_FILE at a downloaded JSON source pack.
// No remote source or response is included in the application or normal test run.
struct BookSourceRemoteProbe {
@Test(.enabled(if: ProcessInfo.processInfo.environment["LEGADO_SOURCE_CHAIN_FILE"] != nil))
func sampleReadingPipelines() async throws {
let path = try #require(ProcessInfo.processInfo.environment["LEGADO_SOURCE_CHAIN_FILE"])
let sources = try BookSourceImporter().decode(Data(contentsOf: URL(fileURLWithPath: path)))
var reports: [BookSourceDebugReport] = []
let transport = ProbeTransport()
let keyword = ProcessInfo.processInfo.environment["LEGADO_SOURCE_PROBE_KEYWORD"] ?? "斗罗大陆"
for source in sources {
var report = await BookSourceDebugger(transport: transport).run(source: source, keyword: keyword)
report.contentPreview = nil
reports.append(report)
print("SOURCE_CHAIN \(source.bookSourceName) " + String(decoding: try JSONEncoder().encode(report), as: UTF8.self))
}
if let output = ProcessInfo.processInfo.environment["LEGADO_SOURCE_CHAIN_OUTPUT"] {
try JSONEncoder().encode(reports).write(to: URL(fileURLWithPath: output))
try JSONEncoder().encode(await transport.records()).write(to: URL(fileURLWithPath: output + ".requests.json"))
}
#expect(reports.count == sources.count)
}
@Test(.enabled(if: ProcessInfo.processInfo.environment["LEGADO_SOURCE_PROBE_FILE"] != nil))
func sampleSearches() async throws {
guard let path = ProcessInfo.processInfo.environment["LEGADO_SOURCE_PROBE_FILE"] else { return }
let sources = try BookSourceImporter().decode(Data(contentsOf: URL(fileURLWithPath: path)))
let transport = ProbeTransport()
let service = BookSearchService(transport: transport, networkPolicy: .init(), history: .init())
let keyword = ProcessInfo.processInfo.environment["LEGADO_SOURCE_PROBE_KEYWORD"] ?? "斗罗大陆"
let page = Int(ProcessInfo.processInfo.environment["LEGADO_SOURCE_PROBE_PAGE"] ?? "1") ?? 1
var rows: [[String: JSONValue]] = []
for await outcome in service.searchOutcomes(keyword: keyword, page: page, sources: sources, maximumConcurrentSources: 3, includeDisabled: true) {
let source = try #require(sources.first { $0.id == outcome.sourceID })
let row: [String: JSONValue] = [
"name": .string(source.bookSourceName), "source": .string(source.id),
"count": .number(Double(outcome.books.count)),
"books": .array(outcome.books.prefix(3).map { .object([
"name": .string($0.name), "url": .string($0.bookURL), "author": .string($0.author),
"cover": .string($0.coverURL ?? ""), "wordCount": .string($0.wordCount ?? "")
]) }),
"diagnostics": .array(outcome.diagnostics.map { .object(["code": .string($0.code), "message": .string($0.message), "rule": .string($0.rule)]) })
]
rows.append(row)
print("SOURCE_PROBE " + JSONValue.object(row).stringValue)
}
let report = JSONValue.object(["keyword": .string(keyword), "page": .number(Double(page)), "outcomes": .array(rows.map(JSONValue.object)), "requests": .array(await transport.records())])
if let output = ProcessInfo.processInfo.environment["LEGADO_SOURCE_PROBE_OUTPUT"] {
try JSONEncoder().encode(report).write(to: URL(fileURLWithPath: output))
}
#expect(rows.count == Set(sources.map(\.id)).count)
}
}
private actor ProbeTransport: HTTPTransport {
private var values: [JSONValue] = []
private let transport = URLSessionHTTPTransport()
func data(for request: URLRequest) async throws -> HTTPResponse {
do {
let response = try await transport.data(for: request)
var record: [String: JSONValue] = [
"url": .string(request.url?.absoluteString ?? ""),
"finalURL": .string(response.finalURL.absoluteString),
"status": .number(Double(response.statusCode)),
"bytes": .number(Double(response.data.count)),
"preview": .string(String(response.decodedText.prefix(240)))
]
if let directory = ProcessInfo.processInfo.environment["LEGADO_SOURCE_PROBE_SNAPSHOT_DIR"] {
let folder = URL(fileURLWithPath: directory, isDirectory: true)
try FileManager.default.createDirectory(at: folder, withIntermediateDirectories: true)
let file = folder.appendingPathComponent(UUID().uuidString + ".response")
try response.data.write(to: file)
record["snapshot"] = .string(file.path)
}
values.append(.object(record))
return response
} catch {
values.append(.object(["url": .string(request.url?.absoluteString ?? ""), "error": .string(error.localizedDescription)]))
throw error
}
}
func records() -> [JSONValue] { values }
}