2
0
mirror of https://github.com/koreader/koreader synced 2024-10-31 21:20:20 +00:00
koreader/spec/unit/readerhighlight_spec.lua
NiLuJe fadee1f5dc
Clarify our OOP semantics across the codebase (#9586)
Basically:

* Use `extend` for class definitions
* Use `new` for object instantiations

That includes some minor code cleanups along the way:

* Updated `Widget`'s docs to make the semantics clearer.
* Removed `should_restrict_JIT` (it's been dead code since https://github.com/koreader/android-luajit-launcher/pull/283)
* Minor refactoring of LuaSettings/LuaData/LuaDefaults/DocSettings to behave (mostly, they are instantiated via `open` instead of `new`) like everything else and handle inheritance properly (i.e., DocSettings is now a proper LuaSettings subclass).
* Default to `WidgetContainer` instead of `InputContainer` for stuff that doesn't actually setup key/gesture events.
* Ditto for explicit `*Listener` only classes, make sure they're based on `EventListener` instead of something uselessly fancier.
* Unless absolutely necessary, do not store references in class objects, ever; only values. Instead, always store references in instances, to avoid both sneaky inheritance issues, and sneaky GC pinning of stale references.
  * ReaderUI: Fix one such issue with its `active_widgets` array, with critical implications, as it essentially pinned *all* of ReaderUI's modules, including their reference to the `Document` instance (i.e., that was a big-ass leak).
* Terminal: Make sure the shell is killed on plugin teardown.
* InputText: Fix Home/End/Del physical keys to behave sensibly.
* InputContainer/WidgetContainer: If necessary, compute self.dimen at paintTo time (previously, only InputContainers did, which might have had something to do with random widgets unconcerned about input using it as a baseclass instead of WidgetContainer...).
* OverlapGroup: Compute self.dimen at *init* time, because for some reason it needs to do that, but do it directly in OverlapGroup instead of going through a weird WidgetContainer method that it was the sole user of.
* ReaderCropping: Under no circumstances should a Document instance member (here, self.bbox) risk being `nil`ed!
* Kobo: Minor code cleanups.
2022-10-06 02:14:48 +02:00

317 lines
14 KiB
Lua

describe("Readerhighlight module", function()
local DocumentRegistry, ReaderUI, UIManager, Screen, Geom, Event
setup(function()
require("commonrequire")
package.unloadAll()
require("document/canvascontext"):init(require("device"))
DocumentRegistry = require("document/documentregistry")
Event = require("ui/event")
Geom = require("ui/geometry")
ReaderUI = require("apps/reader/readerui")
Screen = require("device").screen
UIManager = require("ui/uimanager")
end)
local function highlight_single_word(readerui, pos0)
local s = spy.on(readerui.languagesupport, "improveWordSelection")
readerui.highlight:onHold(nil, { pos = pos0 })
readerui.highlight:onHoldRelease()
readerui.highlight:onHighlight()
assert.spy(s).was_called()
assert.spy(s).was_called_with(match.is_ref(readerui.languagesupport),
match.is_ref(readerui.highlight.selected_text))
-- Reset in case we're called more than once.
readerui.languagesupport.improveWordSelection:revert()
UIManager:scheduleIn(1, function()
UIManager:close(readerui.dictionary.dict_window)
UIManager:close(readerui)
-- We haven't torn it down yet
ReaderUI.instance = readerui
UIManager:quit()
end)
UIManager:run()
end
local function highlight_text(readerui, pos0, pos1)
readerui.highlight:onHold(nil, { pos = pos0 })
readerui.highlight:onHoldPan(nil, { pos = pos1 })
local next_slot
for i = #UIManager._window_stack, 0, -1 do
local top_window = UIManager._window_stack[i]
-- skip modal window
if not top_window or not top_window.widget.modal then
next_slot = i + 1
break
end
end
readerui.highlight:onHoldRelease()
assert.truthy(readerui.highlight.highlight_dialog)
assert.truthy(UIManager._window_stack[next_slot].widget
== readerui.highlight.highlight_dialog)
readerui.highlight:onHighlight()
UIManager:scheduleIn(1, function()
UIManager:close(readerui.highlight.highlight_dialog)
UIManager:close(readerui)
-- We haven't torn it down yet
ReaderUI.instance = readerui
UIManager:quit()
end)
UIManager:run()
end
local function tap_highlight_text(readerui, pos0, pos1, pos2)
readerui.highlight:onHold(nil, { pos = pos0 })
readerui.highlight:onHoldPan(nil, { pos = pos1 })
readerui.highlight:onHoldRelease()
readerui.highlight:onHighlight()
readerui.highlight:clear()
UIManager:close(readerui.highlight.highlight_dialog)
readerui.highlight:onTap(nil, { pos = pos2 })
assert.truthy(readerui.highlight.edit_highlight_dialog)
UIManager:nextTick(function()
UIManager:close(readerui.highlight.edit_highlight_dialog)
UIManager:close(readerui)
-- We haven't torn it down yet
ReaderUI.instance = readerui
UIManager:quit()
end)
UIManager:run()
end
describe("highlight for EPUB documents", function()
local page = 10
local readerui, selection_spy
setup(function()
local sample_epub = "spec/front/unit/data/juliet.epub"
readerui = ReaderUI:new{
dimen = Screen:getSize(),
document = DocumentRegistry:openDocument(sample_epub),
}
selection_spy = spy.on(readerui.languagesupport, "improveWordSelection")
end)
teardown(function()
readerui:closeDocument()
readerui:onClose()
end)
before_each(function()
UIManager:quit()
readerui.rolling:onGotoPage(page)
UIManager:show(readerui)
selection_spy:clear()
--- @fixme HACK: Mock UIManager:run x and y for readerui.dimen
--- @todo Refactor readerview's dimen handling so we can get rid of
-- this workaround
readerui:paintTo(Screen.bb, 0, 0)
end)
after_each(function()
readerui.highlight:clear()
end)
it("should highlight single word", function()
highlight_single_word(readerui, Geom:new{ x = 400, y = 70 })
Screen:shot("screenshots/reader_highlight_single_word_epub.png")
assert.spy(selection_spy).was_called()
assert.truthy(readerui.view.highlight.saved[page])
end)
it("should highlight text", function()
highlight_text(readerui,
Geom:new{ x = 400, y = 110 },
Geom:new{ x = 400, y = 170 })
Screen:shot("screenshots/reader_highlight_text_epub.png")
assert.spy(selection_spy).was_called()
assert.truthy(readerui.view.highlight.saved[page])
end)
it("should response on tap gesture", function()
tap_highlight_text(readerui,
Geom:new{ x = 130, y = 100 },
Geom:new{ x = 350, y = 395 },
Geom:new{ x = 80, y = 265 })
Screen:shot("screenshots/reader_tap_highlight_text_epub.png")
assert.spy(selection_spy).was_called()
end)
end)
describe("highlight for PDF documents in page mode", function()
local readerui
setup(function()
local sample_pdf = "spec/front/unit/data/sample.pdf"
readerui = ReaderUI:new{
dimen = Screen:getSize(),
document = DocumentRegistry:openDocument(sample_pdf),
}
readerui:handleEvent(Event:new("SetScrollMode", false))
end)
teardown(function()
readerui:closeDocument()
readerui:onClose()
end)
describe("for scanned page with text layer", function()
before_each(function()
UIManager:quit()
UIManager:show(readerui)
readerui.paging:onGotoPage(10)
end)
after_each(function()
readerui.highlight:clear()
end)
it("should highlight single word", function()
highlight_single_word(readerui, Geom:new{ x = 260, y = 70 })
Screen:shot("screenshots/reader_highlight_single_word_pdf.png")
end)
it("should highlight text", function()
highlight_text(readerui, Geom:new{ x = 260, y = 70 }, Geom:new{ x = 260, y = 150 })
Screen:shot("screenshots/reader_highlight_text_pdf.png")
end)
it("should response on tap gesture", function()
tap_highlight_text(readerui,
Geom:new{ x = 260, y = 70 },
Geom:new{ x = 260, y = 150 },
Geom:new{ x = 280, y = 110 })
Screen:shot("screenshots/reader_tap_highlight_text_pdf.png")
end)
end)
describe("for scanned page without text layer", function()
before_each(function()
UIManager:quit()
UIManager:show(readerui)
readerui.paging:onGotoPage(28)
end)
after_each(function()
readerui.highlight:clear()
end)
it("should highlight single word", function()
highlight_single_word(readerui, Geom:new{ x = 260, y = 70 })
Screen:shot("screenshots/reader_highlight_single_word_pdf_scanned.png")
end)
it("should highlight text", function()
highlight_text(readerui, Geom:new{ x = 260, y = 70 }, Geom:new{ x = 260, y = 150 })
Screen:shot("screenshots/reader_highlight_text_pdf_scanned.png")
end)
it("should respond to tap gesture", function()
tap_highlight_text(readerui, Geom:new{ x = 260, y = 70 }, Geom:new{ x = 260, y = 150 }, Geom:new{ x = 280, y = 110 })
Screen:shot("screenshots/reader_tap_highlight_text_pdf_scanned.png")
end)
end)
describe("for reflowed page", function()
before_each(function()
UIManager:quit()
readerui.document.configurable.text_wrap = 1
UIManager:show(readerui)
readerui.paging:onGotoPage(31)
end)
after_each(function()
readerui.highlight:clear()
readerui.document.configurable.text_wrap = 0
UIManager:close(readerui) -- close to flush settings
-- We haven't torn it down yet
ReaderUI.instance = readerui
end)
it("should highlight single word", function()
highlight_single_word(readerui, Geom:new{ x = 260, y = 70 })
Screen:shot("screenshots/reader_highlight_single_word_pdf_reflowed.png")
end)
it("should highlight text", function()
highlight_text(readerui, Geom:new{ x = 260, y = 70 }, Geom:new{ x = 260, y = 150 })
Screen:shot("screenshots/reader_highlight_text_pdf_reflowed.png")
end)
it("should response on tap gesture", function()
tap_highlight_text(readerui, Geom:new{ x = 260, y = 70 }, Geom:new{ x = 260, y = 150 }, Geom:new{ x = 280, y = 110 })
Screen:shot("screenshots/reader_tap_highlight_text_pdf_reflowed.png")
end)
end)
end)
describe("highlight for PDF documents in scroll mode", function()
local readerui
setup(function()
local sample_pdf = "spec/front/unit/data/sample.pdf"
readerui = ReaderUI:new{
dimen = Screen:getSize(),
document = DocumentRegistry:openDocument(sample_pdf),
}
readerui:handleEvent(Event:new("SetScrollMode", true))
end)
teardown(function()
readerui:closeDocument()
readerui:onClose()
end)
describe("for scanned page with text layer", function()
before_each(function()
UIManager:quit()
UIManager:show(readerui)
readerui.paging:onGotoPage(10)
readerui.zooming:setZoomMode("contentwidth")
end)
after_each(function()
readerui.highlight:clear()
end)
it("should highlight single word", function()
highlight_single_word(readerui, Geom:new{ x = 260, y = 70 })
Screen:shot("screenshots/reader_highlight_single_word_pdf_scroll.png")
end)
it("should highlight text", function()
highlight_text(readerui, Geom:new{ x = 260, y = 70 }, Geom:new{ x = 260, y = 150 })
Screen:shot("screenshots/reader_highlight_text_pdf_scroll.png")
end)
it("should response on tap gesture", function()
tap_highlight_text(readerui,
Geom:new{ x = 260, y = 70 },
Geom:new{ x = 260, y = 150 },
Geom:new{ x = 280, y = 110 })
Screen:shot("screenshots/reader_tap_highlight_text_pdf_scroll.png")
end)
end)
describe("for scanned page without text layer", function()
before_each(function()
UIManager:quit()
UIManager:show(readerui)
readerui.paging:onGotoPage(28)
readerui.zooming:setZoomMode("contentwidth")
end)
after_each(function()
readerui.highlight:clear()
end)
it("should highlight single word", function()
highlight_single_word(readerui, Geom:new{ x = 260, y = 70 })
Screen:shot("screenshots/reader_highlight_single_word_pdf_scanned_scroll.png")
end)
it("should highlight text", function()
highlight_text(readerui, Geom:new{x = 192, y = 186}, Geom:new{x = 280, y = 186})
Screen:shot("screenshots/reader_highlight_text_pdf_scanned_scroll.png")
end)
it("should response on tap gesture", function()
tap_highlight_text(readerui, Geom:new{ x = 260, y = 70 }, Geom:new{ x = 260, y = 150 }, Geom:new{ x = 280, y = 110 })
Screen:shot("screenshots/reader_tap_highlight_text_pdf_scanned_scroll.png")
end)
end)
describe("for reflowed page", function()
before_each(function()
UIManager:quit()
readerui.document.configurable.text_wrap = 1
UIManager:show(readerui)
readerui.paging:onGotoPage(31)
end)
after_each(function()
readerui.highlight:clear()
readerui.document.configurable.text_wrap = 0
UIManager:close(readerui) -- close to flush settings
-- We haven't torn it down yet
ReaderUI.instance = readerui
end)
it("should highlight single word", function()
highlight_single_word(readerui, Geom:new{ x = 260, y = 70 })
Screen:shot("screenshots/reader_highlight_single_word_pdf_reflowed_scroll.png")
end)
it("should highlight text", function()
highlight_text(readerui, Geom:new{ x = 260, y = 70 }, Geom:new{ x = 260, y = 150 })
Screen:shot("screenshots/reader_highlight_text_pdf_reflowed_scroll.png")
end)
it("should response on tap gesture", function()
tap_highlight_text(readerui, Geom:new{ x = 260, y = 70 }, Geom:new{ x = 260, y = 150 }, Geom:new{ x = 280, y = 110 })
Screen:shot("screenshots/reader_tap_highlight_text_pdf_reflowed_scroll.png")
end)
end)
end)
end)