feat: 支持 EPUB 阅读并改善规则兼容与阅读稳定性

支持 EPUB 2/3 导入、目录、封面和章节插图,保留本地书管理与阅读进度。
修复 JSON 模板、动态替换与请求参数兼容,以及 RSS 翻页和连续滚动定位。
更新编辑器工具栏和回归测试,发布版本为 0.1.12(build 18)。
This commit is contained in:
Aminark
2026-10-24 00:58:11 +08:00
parent 3322fd71db
commit 67bc212ffd
58 changed files with 2331 additions and 244 deletions
@@ -5,6 +5,26 @@ import LegadoCore
@MainActor
struct SearchRegressionTests {
@Test func arithmeticPageExpressionCanLoadTheSecondPage() async throws {
let transport = GatedModelSearchTransport()
await transport.release()
let model = model(transport: transport, repository: InMemorySearchBookRepository())
defer { model.cancel(reset: true) }
var source = source("formula")
source.searchUrl = #"/search,{"method":"POST","body":"keyword={{key}}&page={{page-1}}"}"#
model.search(keyword: "书", sources: [source])
try await waitUntil { model.state == .finished }
#expect(model.hasMore)
model.loadMore()
try await waitUntil { !model.isLoadingMore }
let requests = await transport.requests()
#expect(requests.count == 2)
#expect(requests.compactMap(\.httpBody).map { String(decoding: $0, as: UTF8.self) } == [
"keyword=%E4%B9%A6&page=0", "keyword=%E4%B9%A6&page=1"
])
#expect(!model.hasMore)
}
@Test func cachedResultsAppearBeforeNetworkAndFreshResultsReplaceTheirMetadata() async throws {
let source = source("slow")
let cached = SearchBook(bookURL: source.id + "/cached", origin: source.id, originName: "源", type: 0, name: "书", author: "作者")