mirror of
https://github.com/Aminark/legado-ios.git
synced 2026-10-24 12:51:22 +08:00
fix: 修复书源导入、阅读外观和书签状态
- 修复书源文件选择、访问权限与导入预览流程,支持查看分组内的书源 - 修复背景图片、字体选择与主题切换,限制背景图片解码尺寸 - 根据已保存书签恢复当前位置状态,避免重复添加 - 补充模型、阅读器和文件选择回归测试及测试样本 - 更新应用版本为 0.1.10(build 16) Fixes #1
This commit is contained in:
@@ -207,6 +207,30 @@ struct ReaderRegressionTests {
|
||||
#expect(bookmark.resolvedChapterIndex(in: chapters) == nil)
|
||||
}
|
||||
|
||||
@Test func bookmarkSelectionUsesSavedPositionAndCurrentPageAfterReopening() {
|
||||
let book = Book(bookUrl: "demo://bookmarks", name: "书", author: "作者")
|
||||
let chapters = (0..<2).map { BookChapter(url: "demo://\($0)", title: "第\($0)章", bookUrl: book.bookUrl, index: $0) }
|
||||
var saved = Bookmark(time: 1, bookName: book.name, bookAuthor: book.author)
|
||||
saved.chapterIndex = 0
|
||||
saved.chapterName = chapters[0].title
|
||||
saved.chapterPosition = 40
|
||||
var otherBook = saved
|
||||
otherBook.bookAuthor = "其他作者"
|
||||
var otherChapter = saved
|
||||
otherChapter.chapterIndex = 1
|
||||
otherChapter.chapterName = chapters[1].title
|
||||
let bookmarks = [saved, otherBook, otherChapter]
|
||||
let reopened = ReaderViewModel(demoBook: book, chapters: chapters, initialIndex: 0, content: "正文")
|
||||
|
||||
#expect(reopened.bookmarks(at: 40, in: bookmarks) == [saved])
|
||||
#expect(reopened.bookmarks(at: 0, in: bookmarks, pageRange: NSRange(location: 0, length: 80)) == [saved])
|
||||
#expect(reopened.bookmarks(at: 80, in: bookmarks, pageRange: NSRange(location: 80, length: 80)).isEmpty)
|
||||
#expect(reopened.bookmarks(at: 41, in: bookmarks).isEmpty)
|
||||
#expect(reopened.bookmarks(at: 40, in: []).isEmpty)
|
||||
reopened.select(index: 1)
|
||||
#expect(reopened.bookmarks(at: 40, in: bookmarks) == [otherChapter])
|
||||
}
|
||||
|
||||
@Test func continuousReadingExtendsPastThreeChaptersWithoutNavigating() async {
|
||||
let book = Book(bookUrl: "demo://continuous", name: "书")
|
||||
let chapters = (0..<20).map { BookChapter(url: "demo://\($0)", title: "第\($0)章", bookUrl: book.bookUrl, index: $0) }
|
||||
|
||||
@@ -25,6 +25,51 @@ private actor ImportFixtureTransport: HTTPTransport {
|
||||
|
||||
@MainActor
|
||||
struct RuleLibraryRegressionTests {
|
||||
@Test func pickedJSONFilesAreReadTogetherAndReviewedBeforeImport() async throws {
|
||||
let directory = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString)
|
||||
try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true)
|
||||
defer { try? FileManager.default.removeItem(at: directory) }
|
||||
let inputs = [
|
||||
("书源.json", #"{"bookSourceUrl":"https://picked-json.test","bookSourceName":"JSON 书源"}"#),
|
||||
("大写扩展名.JSON", #"[{"bookSourceUrl":"https://picked-uppercase.test","bookSourceName":"大写扩展名"}]"#),
|
||||
("书源.txt", #"{"bookSourceUrl":"https://picked-text.test","bookSourceName":"文本扩展名"}"#)
|
||||
]
|
||||
let files = try inputs.map { name, content in
|
||||
let url = directory.appendingPathComponent(name)
|
||||
try Data(content.utf8).write(to: url)
|
||||
return SourceImportFile(url: url)
|
||||
}
|
||||
let model = SourceLibraryModel.demo(sources: [])
|
||||
|
||||
await model.previewPickedFiles(files)
|
||||
|
||||
#expect(model.notice == nil)
|
||||
#expect(!model.isWorking)
|
||||
#expect(model.pendingImport?.validCount == 3)
|
||||
#expect(model.sources.isEmpty)
|
||||
let selectedIDs = Set(try #require(model.pendingImport).items.map(\.id))
|
||||
await model.commitPendingImport(selectedIDs: selectedIDs, keepOriginalName: false, keepOriginalGroup: false,
|
||||
keepOriginalEnabled: false, customGroup: nil, addCustomGroup: true)
|
||||
#expect(model.sources.count == 3)
|
||||
#expect(model.pendingImport == nil)
|
||||
}
|
||||
|
||||
@Test func missingOrDirectoryImportReportsFailureWithoutChangingSources() async throws {
|
||||
let directory = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString)
|
||||
try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true)
|
||||
defer { try? FileManager.default.removeItem(at: directory) }
|
||||
let original = BookSource(bookSourceUrl: "https://existing-source.test", bookSourceName: "原有书源")
|
||||
for url in [directory, directory.appendingPathComponent("missing.json")] {
|
||||
let model = SourceLibraryModel.demo(sources: [original])
|
||||
await model.load()
|
||||
await model.previewFiles([url])
|
||||
#expect(model.notice?.kind == .error)
|
||||
#expect(model.pendingImport == nil)
|
||||
#expect(model.sources == [original])
|
||||
#expect(!model.isWorking)
|
||||
}
|
||||
}
|
||||
|
||||
@Test func largeImportKeepsTheMainActorResponsive() async throws {
|
||||
let comment = String(repeating: "规则说明", count: 1_024)
|
||||
let entries = (0..<1_000).map { index in
|
||||
|
||||
Reference in New Issue
Block a user