diff --git a/frontend/dbg.lua b/frontend/dbg.lua index ff328695b..58f64f671 100644 --- a/frontend/dbg.lua +++ b/frontend/dbg.lua @@ -47,7 +47,10 @@ function Dbg:turnOn() return unpack(values) end end - Dbg.dassert = function(check, msg) assert(check, msg) end + Dbg.dassert = function(check, msg) + assert(check, msg) + return check + end -- TODO: close ev.log fd for children -- create or clear ev log file @@ -60,7 +63,9 @@ function Dbg:turnOff() logger:setLevel(logger.levels.info) function Dbg_mt.__call() end function Dbg.guard() end - function Dbg.dassert() end + Dbg.dassert = function(check) + return check + end if self.ev_log then io.close(self.ev_log) self.ev_log = nil diff --git a/frontend/device/sdl/device.lua b/frontend/device/sdl/device.lua index 83adcd1d5..aa4581b40 100644 --- a/frontend/device/sdl/device.lua +++ b/frontend/device/sdl/device.lua @@ -59,4 +59,22 @@ function Device:init() Generic.init(self) end +function Device:simulateSuspend() + local InfoMessage = require("ui/widget/infomessage") + local UIManager = require("ui/uimanager") + local _ = require("gettext") + UIManager:show(InfoMessage:new{ + text = _("Suspend") + }) +end + +function Device:simulateResume() + local InfoMessage = require("ui/widget/infomessage") + local UIManager = require("ui/uimanager") + local _ = require("gettext") + UIManager:show(InfoMessage:new{ + text = _("Resume") + }) +end + return Device diff --git a/frontend/ui/hook_container.lua b/frontend/ui/hook_container.lua new file mode 100644 index 000000000..bc74b9b79 --- /dev/null +++ b/frontend/ui/hook_container.lua @@ -0,0 +1,101 @@ +--[[-- +HookContainer allows listeners to register and unregister a hook for speakers to execute. + +It's an experimental feature: use with cautions, it can easily pin an object in memory and unblock +GC from recycling the memory. +]] + +local HookContainer = {} + +function HookContainer:new(o) + o = o or {} + setmetatable(o, self) + self.__index = self + return o +end + +function HookContainer:_assertIsValidName(name) + assert(self ~= nil) + assert(type(name) == "string") + assert(string.len(name) > 0) +end + +function HookContainer:_assertIsValidFunction(func) + assert(self ~= nil) + assert(type(func) == "function" or type(func) == "table") +end + +function HookContainer:_assertIsValidFunctionOrNil(func) + assert(self ~= nil) + if func == nil then return end + self:_assertIsValidFunction(func) +end + +--- Register a function to name. Must be called with self. +-- @tparam string name The name of the hook. Can only be an non-empty string. +-- @tparam function func The function to handle the hook. Can only be a function. +function HookContainer:register(name, func) + self:_assertIsValidName(name) + self:_assertIsValidFunction(func) + if self[name] == nil then + self[name] = {} + end + table.insert(self[name], func) +end + +--- Register a widget to name. Must be called with self. +-- @tparam string name The name of the hook. Can only be an non-empty string. +-- @tparam table widget The widget to handle the hook. Can only be a table with required functions. +function HookContainer:registerWidget(name, widget) + self:_assertIsValidName(name) + assert(type(widget) == "table") + self:register(name, function(args) + local f = widget["on" .. name] + self:_assertIsValidFunction(f) + f(widget, args) + end) + local original_close_widget = widget.onCloseWidget + self:_assertIsValidFunctionOrNil(original_close_widget) + widget.onCloseWidget = function() + if original_close_widget then original_close_widget(widget) end + self:unregister(name, widget["on" .. name]) + end +end + +--- Unregister a function from name. Must be called with self. +-- @tparam string name The name of the hook. Can only be an non-empty string. +-- @tparam function func The function to handle the hook. Can only be a function. +-- @treturn boolean Return true if the function is found and removed, otherwise false. +function HookContainer:unregister(name, func) + self:_assertIsValidName(name) + self:_assertIsValidFunction(func) + if self[name] == nil then + return false + end + + for i, f in ipairs(self[name]) do + if f == func then + table.remove(self[name], i) + return true + end + end + return false +end + +--- Execute all registered functions of name. Must be called with self. +-- @tparam string name The name of the hook. Can only be an non-empty string. +-- @param args Any kind of arguments sending to the functions. +-- @treturn number The number of functions have been executed. +function HookContainer:execute(name, args) + self:_assertIsValidName(name) + if self[name] == nil or #self[name] == 0 then + return 0 + end + + for _, f in ipairs(self[name]) do + f(args) + end + return #self[name] +end + +return HookContainer diff --git a/frontend/ui/uimanager.lua b/frontend/ui/uimanager.lua index e487eb734..ce37d4146 100644 --- a/frontend/ui/uimanager.lua +++ b/frontend/ui/uimanager.lua @@ -8,11 +8,10 @@ local Geom = require("ui/geometry") local dbg = require("dbg") local logger = require("logger") local util = require("ffi/util") +local _ = require("gettext") local Input = Device.input local Screen = Device.screen -local _ = require("gettext") -local noop = function() end local MILLION = 1000000 -- there is only one instance of this @@ -34,6 +33,8 @@ local UIManager = { _refresh_func_stack = {}, _entered_poweroff_stage = false, _exit_code = nil, + + event_hook = require("ui/hook_container"):new() } function UIManager:init() @@ -72,28 +73,12 @@ function UIManager:init() -- We do not want auto suspend procedure to waste battery during -- suspend. So let's unschedule it when suspending, and restart it after -- resume. - self:_initAutoSuspend() self.event_handlers["Suspend"] = function() self:_beforeSuspend() - if self._stopAutoSuspend then - -- TODO(Hzj-jie): Why _stopAutoSuspend could be nil in test cases. - --[[ - frontend/ui/uimanager.lua:62: attempt to call method _stopAutoSuspend (a nil value) - - stack traceback: - frontend/ui/uimanager.lua:62: in function Suspend - frontend/ui/uimanager.lua:119: in function __default__ - frontend/ui/uimanager.lua:662: in function handleInput - frontend/ui/uimanager.lua:707: in function run - spec/front/unit/readerui_spec.lua:32: in function - --]] - self:_stopAutoSuspend() - end Device:onPowerEvent("Suspend") end self.event_handlers["Resume"] = function() Device:onPowerEvent("Resume") - self:_startAutoSuspend() self:_afterResume() end self.event_handlers["PowerPress"] = function() @@ -167,6 +152,15 @@ function UIManager:init() Device:usbPlugOut() self:_afterNotCharging() end + elseif Device:isSDL() then + self.event_handlers["Suspend"] = function() + self:_beforeSuspend() + Device:simulateSuspend() + end + self.event_handlers["Resume"] = function() + Device:simulateResume() + self:_afterResume() + end end end @@ -714,7 +708,9 @@ function UIManager:handleInput() -- delegate input_event to handler if input_event then - self:_resetAutoSuspendTimer() + if input_event.handler ~= "onInputError" then + self.event_hook:execute("InputEvent", input_event) + end local handler = self.event_handlers[input_event] if handler then handler(input_event) @@ -780,57 +776,6 @@ function UIManager:runForever() return self:run() end --- Kobo does not have an auto suspend function, so we implement it ourselves. -function UIManager:_initAutoSuspend() - local function isAutoSuspendEnabled() - return Device:isKobo() and self.auto_suspend_sec > 0 - end - - local sec = G_reader_settings:readSetting("auto_suspend_timeout_seconds") - if sec then - self.auto_suspend_sec = sec - else - -- default setting is 60 minutes - self.auto_suspend_sec = 60 * 60 - end - - if isAutoSuspendEnabled() then - self.auto_suspend_action = function() - local now = os.time() - -- Do not repeat auto suspend procedure after suspend. - if self.last_action_sec + self.auto_suspend_sec <= now then - self:suspend() - else - self:scheduleIn( - self.last_action_sec + self.auto_suspend_sec - now, - self.auto_suspend_action) - end - end - - function UIManager:_startAutoSuspend() - self.last_action_sec = os.time() - self:nextTick(self.auto_suspend_action) - end - dbg:guard(UIManager, '_startAutoSuspend', - function() - assert(isAutoSuspendEnabled()) - end) - - function UIManager:_stopAutoSuspend() - self:unschedule(self.auto_suspend_action) - end - - function UIManager:_resetAutoSuspendTimer() - self.last_action_sec = os.time() - end - - self:_startAutoSuspend() - else - self._startAutoSuspend = noop - self._stopAutoSuspend = noop - end -end - -- The common operations should be performed before suspending the device. Ditto. function UIManager:_beforeSuspend() self:flushSettings() @@ -853,7 +798,7 @@ end -- Executes all the operations of a suspending request. This function usually puts the device into -- suspension. function UIManager:suspend() - if Device:isKobo() then + if Device:isKobo() or Device:isSDL() then self.event_handlers["Suspend"]() elseif Device:isKindle() then self.event_handlers["IntoSS"]() @@ -862,7 +807,7 @@ end -- Executes all the operations of a resume request. This function usually wakes up the device. function UIManager:resume() - if Device:isKobo() then + if Device:isKobo() or Device:isSDL() then self.event_handlers["Resume"]() elseif Device:isKindle() then self.event_handlers["OutOfSS"]() @@ -879,7 +824,5 @@ function UIManager:restartKOReader() self._exit_code = 85 end -UIManager._resetAutoSuspendTimer = noop - UIManager:init() return UIManager diff --git a/plugins/autosuspend.koplugin/main.lua b/plugins/autosuspend.koplugin/main.lua new file mode 100644 index 000000000..50179eb11 --- /dev/null +++ b/plugins/autosuspend.koplugin/main.lua @@ -0,0 +1,121 @@ +local Device = require("device") + +if not Device:isKobo() and not Device:isSDL() then return { disabled = true, } end + +local DataStorage = require("datastorage") +local LuaSettings = require("luasettings") +local UIManager = require("ui/uimanager") +local WidgetContainer = require("ui/widget/container/widgetcontainer") +local logger = require("logger") +local _ = require("gettext") + +local AutoSuspend = { + settings = LuaSettings:open(DataStorage:getSettingsDir() .. "/koboautosuspend.lua"), + settings_id = 0, + last_action_sec = os.time(), +} + +function AutoSuspend:_readTimeoutSecFrom(settings) + local sec = settings:readSetting("auto_suspend_timeout_seconds") + if type(sec) == "number" then + return sec + end + return -1 +end + +function AutoSuspend:_readTimeoutSec() + local candidates = { self.settings, G_reader_settings } + for _, candidate in ipairs(candidates) do + local sec = self:_readTimeoutSecFrom(candidate) + if sec ~= -1 then + return sec + end + end + + -- default setting is 60 minutes + return 60 * 60 +end + +function AutoSuspend:_enabled() + return self.auto_suspend_sec > 0 +end + +function AutoSuspend:_schedule(settings_id) + if not self:_enabled() then + logger.dbg("AutoSuspend:_schedule is disabled") + return + end + if self.settings_id ~= settings_id then + logger.dbg("AutoSuspend:_schedule registered settings_id ", + settings_id, + " does not equal to current one ", + self.settings_id) + return + end + + local delay = self.last_action_sec + self.auto_suspend_sec - os.time() + if delay <= 0 then + logger.dbg("AutoSuspend: will suspend the device") + UIManager:suspend() + else + logger.dbg("AutoSuspend: schedule at ", os.time() + delay) + UIManager:scheduleIn(delay, function() self:_schedule(settings_id) end) + end +end + +function AutoSuspend:_deprecateLastTask() + self.settings_id = self.settings_id + 1 + logger.dbg("AutoSuspend: deprecateLastTask ", self.settings_id) +end + +function AutoSuspend:_start() + if self:_enabled() then + logger.dbg("AutoSuspend: start at ", os.time()) + self.last_action_sec = os.time() + self:_schedule(self.settings_id) + end +end + +function AutoSuspend:init() + UIManager.event_hook:registerWidget("InputEvent", self) + self.auto_suspend_sec = self:_readTimeoutSec() + self:_deprecateLastTask() + self:_start() +end + +function AutoSuspend:onInputEvent() + logger.dbg("AutoSuspend: onInputEvent") + self.last_action_sec = os.time() +end + +-- We do not want auto suspend procedure to waste battery during suspend. So let's unschedule it +-- when suspending and restart it after resume. +function AutoSuspend:onSuspend() + logger.dbg("AutoSuspend: onSuspend") + self:_deprecateLastTask() +end + +function AutoSuspend:onResume() + logger.dbg("AutoSuspend: onResume") + self:_start() +end + +AutoSuspend:init() + +local AutoSuspendWidget = WidgetContainer:new{ + name = "AutoSuspend", +} + +function AutoSuspendWidget:onInputEvent() + AutoSuspend:onInputEvent() +end + +function AutoSuspendWidget:onSuspend() + AutoSuspend:onSuspend() +end + +function AutoSuspendWidget:onResume() + AutoSuspend:onResume() +end + +return AutoSuspendWidget diff --git a/spec/unit/autosuspend_spec.lua b/spec/unit/autosuspend_spec.lua new file mode 100644 index 000000000..ad07e3548 --- /dev/null +++ b/spec/unit/autosuspend_spec.lua @@ -0,0 +1,74 @@ +describe("AutoSuspend widget tests", function() + setup(function() + require("commonrequire") + package.unloadAll() + end) + + before_each(function() + local Device = require("device") + stub(Device, "isKobo") + Device.isKobo.returns(true) + Device.input.waitEvent = function() end + local UIManager = require("ui/uimanager") + stub(UIManager, "suspend") + UIManager._run_forever = true + G_reader_settings:saveSetting("auto_suspend_timeout_seconds", 10) + require("mock_time"):install() + end) + + after_each(function() + require("device").isKobo:revert() + require("ui/uimanager").suspend:revert() + G_reader_settings:delSetting("auto_suspend_timeout_seconds") + require("mock_time"):uninstall() + end) + + it("should be able to execute suspend when timing out", function() + local mock_time = require("mock_time") + local widget_class = dofile("plugins/autosuspend.koplugin/main.lua") + local widget = widget_class:new() + local UIManager = require("ui/uimanager") + mock_time:increase(5) + UIManager:handleInput() + assert.stub(UIManager.suspend).was.called(0) + mock_time:increase(6) + UIManager:handleInput() + assert.stub(UIManager.suspend).was.called(1) + mock_time:uninstall() + end) + + it("should be able to initialize several times", function() + local mock_time = require("mock_time") + -- AutoSuspend plugin set the last_action_sec each time it is initialized. + local widget_class = dofile("plugins/autosuspend.koplugin/main.lua") + local widget1 = widget_class:new() + -- So if one more initialization happens, it won't sleep after another 5 seconds. + mock_time:increase(5) + local widget2 = widget_class:new() + local UIManager = require("ui/uimanager") + mock_time:increase(6) + UIManager:handleInput() + assert.stub(UIManager.suspend).was.called(1) + mock_time:uninstall() + end) + + it("should be able to deprecate last task", function() + local mock_time = require("mock_time") + local widget_class = dofile("plugins/autosuspend.koplugin/main.lua") + local widget = widget_class:new() + mock_time:increase(5) + local UIManager = require("ui/uimanager") + UIManager:handleInput() + assert.stub(UIManager.suspend).was.called(0) + widget:onInputEvent() + widget:onSuspend() + widget:onResume() + mock_time:increase(6) + UIManager:handleInput() + assert.stub(UIManager.suspend).was.called(0) + mock_time:increase(5) + UIManager:handleInput() + assert.stub(UIManager.suspend).was.called(1) + mock_time:uninstall() + end) +end) diff --git a/spec/unit/device_spec.lua b/spec/unit/device_spec.lua index 66e376a07..3aa1a0224 100644 --- a/spec/unit/device_spec.lua +++ b/spec/unit/device_spec.lua @@ -18,12 +18,11 @@ describe("device module", function() end } require("commonrequire") + package.unloadAll() end) before_each(function() package.loaded['ffi/framebuffer_mxcfb'] = mock_fb - package.loaded['device/kindle/device'] = nil - package.loaded['device/kobo/device'] = nil mock_input = require('device/input') stub(mock_input, "open") stub(os, "getenv") @@ -171,7 +170,6 @@ describe("device module", function() stub(Device, "isKobo") Device.isKobo.returns(true) - local saved_noop = UIManager._resetAutoSuspendTimer UIManager:init() ReaderUI:doShowReader(sample_pdf) @@ -185,9 +183,6 @@ describe("device module", function() Device.powerd.beforeSuspend:revert() Device.isKobo:revert() readerui.onFlushSettings:revert() - UIManager._startAutoSuspend = nil - UIManager._stopAutoSuspend = nil - UIManager._resetAutoSuspendTimer = saved_noop readerui:onClose() end) end) @@ -251,6 +246,7 @@ describe("device module", function() end) it("oasis should interpret orientation event", function() + package.unload('device/kindle/device') io.open = function(filename, mode) if filename == "/proc/usid" then return { diff --git a/spec/unit/filemanager_spec.lua b/spec/unit/filemanager_spec.lua index e57303a3f..185552053 100644 --- a/spec/unit/filemanager_spec.lua +++ b/spec/unit/filemanager_spec.lua @@ -2,11 +2,12 @@ describe("FileManager module", function() local FileManager, lfs, docsettings, UIManager, Screen, util setup(function() require("commonrequire") + package.unloadAll() FileManager = require("apps/filemanager/filemanager") - lfs = require("libs/libkoreader-lfs") - docsettings = require("docsettings") - UIManager = require("ui/uimanager") Screen = require("device").screen + UIManager = require("ui/uimanager") + docsettings = require("docsettings") + lfs = require("libs/libkoreader-lfs") util = require("ffi/util") end) it("should show file manager", function() diff --git a/spec/unit/hook_container_spec.lua b/spec/unit/hook_container_spec.lua new file mode 100644 index 000000000..34d946c63 --- /dev/null +++ b/spec/unit/hook_container_spec.lua @@ -0,0 +1,72 @@ +describe("HookContainer tests", function() + setup(function() + require("commonrequire") + end) + + it("should register and unregister functions", function() + local HookContainer = require("ui/hook_container"):new() + local f1 = spy.new(function() end) + local f2 = spy.new(function() end) + local f3 = spy.new(function() end) + HookContainer:register("a", f1) + HookContainer:register("a", f2) + HookContainer:register("b", f3) + assert.are.equal(HookContainer:execute("a", 100), 2) + assert.are.equal(HookContainer:execute("b", 200), 1) + assert.spy(f1).was_called(1) + assert.spy(f1).was_called_with(100) + assert.spy(f2).was_called(1) + assert.spy(f2).was_called_with(100) + assert.spy(f3).was_called(1) + assert.spy(f3).was_called_with(200) + + assert.is.truthy(HookContainer:unregister("a", f1)) + assert.is.falsy(HookContainer:unregister("b", f2)) + + assert.are.equal(HookContainer:execute("a", 300), 1) + assert.are.equal(HookContainer:execute("b", 400), 1) + assert.spy(f1).was_called(1) + assert.spy(f1).was_called_with(100) + assert.spy(f2).was_called(2) + assert.spy(f2).was_called_with(300) + assert.spy(f3).was_called(2) + assert.spy(f3).was_called_with(400) + end) + + it("should register and automatically unregister widget", function() + local HookContainer = require("ui/hook_container"):new() + local widget = require("ui/widget/widget"):new() + widget.onEvent = spy.new(function() end) + local close_widget = spy.new(function() end) + widget.onCloseWidget = close_widget + HookContainer:registerWidget("Event", widget) + assert.are.equal(HookContainer:execute("Event", { a = 100, b = 200 }), 1) + assert.spy(widget.onEvent).was_called(1) + assert.spy(widget.onEvent).was_called_with(widget, { a = 100, b = 200 }) + + widget:onCloseWidget() + assert.spy(close_widget).was_called(1) + assert.spy(close_widget).was_called_with(widget) + end) + + it("should pass widget itself", function() + local HookContainer = require("ui/hook_container"):new() + local widget = require("ui/widget/widget"):new() + local onEvent_called = false + local onCloseWidget_called = false + function widget:onEvent(args) + assert.is.truthy(self ~= nil) + assert.are.same(args, { c = 300, d = 400 }) + onEvent_called = true + end + function widget:onCloseWidget() + assert.is.truthy(self ~= nil) + onCloseWidget_called = true + end + HookContainer:registerWidget("Event", widget) + assert.are.equal(HookContainer:execute("Event", { c = 300, d = 400 }), 1) + widget:onCloseWidget() + assert.is.truthy(onEvent_called) + assert.is.truthy(onCloseWidget_called) + end) +end) diff --git a/spec/unit/mock_time.lua b/spec/unit/mock_time.lua index 6596ed314..c31b30c49 100644 --- a/spec/unit/mock_time.lua +++ b/spec/unit/mock_time.lua @@ -1,3 +1,5 @@ +local logger = require("logger") + local MockTime = { original_os_time = os.time, original_util_time = nil, @@ -11,8 +13,14 @@ function MockTime:install() self.original_util_time = util.gettime assert(self.original_util_time ~= nil) end - os.time = function() return self.value end - util.gettime = function() return self.value, 0 end + os.time = function() + logger.dbg("MockTime:os.time: ", self.value) + return self.value + end + util.gettime = function() + logger.dbg("MockTime:util.gettime: ", self.value) + return self.value, 0 + end end function MockTime:uninstall() @@ -30,6 +38,7 @@ function MockTime:set(value) return false end self.value = math.floor(value) + logger.dbg("MockTime:set ", self.value) return true end @@ -39,6 +48,7 @@ function MockTime:increase(value) return false end self.value = math.floor(self.value + value) + logger.dbg("MockTime:increase ", self.value) return true end diff --git a/spec/unit/mock_time_spec.lua b/spec/unit/mock_time_spec.lua new file mode 100644 index 000000000..cf9af9d3f --- /dev/null +++ b/spec/unit/mock_time_spec.lua @@ -0,0 +1,52 @@ +describe("MockTime tests", function() + teardown(function() + require("mock_time"):uninstall() + end) + + it("should be able to install and uninstall", function() + local mock_time = require("mock_time") + local util = require("ffi/util") + local current_time = os.time() + local current_highres_sec = util.gettime() + mock_time:install() + assert.is.truthy(mock_time:set(10)) + assert.are.equal(os.time(), 10) + local sec, usec = util.gettime() + assert.are.equal(sec, 10) + assert.are.equal(usec, 0) + mock_time:uninstall() + assert.is.truthy(os.time() >= current_time) + assert.is.truthy(util.gettime() >= current_highres_sec) + end) + + it("should be able to install several times", function() + local mock_time = require("mock_time") + local util = require("ffi/util") + local current_time = os.time() + local current_highres_sec = util.gettime() + mock_time:install() + mock_time:install() + mock_time:uninstall() + assert.is.truthy(os.time() >= current_time) + assert.is.truthy(util.gettime() >= current_highres_sec) + end) + + it("should reject invalid value", function() + local mock_time = require("mock_time") + assert.is.falsy(mock_time:set("100")) + assert.is.falsy(mock_time:set(true)) + assert.is.falsy(mock_time:set(nil)) + assert.is.falsy(mock_time:set(function() end)) + end) + + it("should increase time", function() + local mock_time = require("mock_time") + local current_time = os.time() + mock_time:install() + assert.is.truthy(mock_time:set(10.1)) + assert.are.equal(os.time(), 10) + mock_time:increase(1) + assert.are.equal(os.time(), 11) + mock_time:uninstall() + end) +end) diff --git a/spec/unit/readerfooter_spec.lua b/spec/unit/readerfooter_spec.lua index 7e9a2564e..c676ba5ce 100644 --- a/spec/unit/readerfooter_spec.lua +++ b/spec/unit/readerfooter_spec.lua @@ -4,13 +4,13 @@ describe("Readerfooter module", function() setup(function() require("commonrequire") + package.unloadAll() + DEBUG = require("dbg") DocumentRegistry = require("document/documentregistry") - ReaderUI = require("apps/reader/readerui") - ReaderUI = require("apps/reader/readerui") DocSettings = require("docsettings") - UIManager = require("ui/uimanager") MenuSorter = require("ui/menusorter") - DEBUG = require("dbg") + ReaderUI = require("apps/reader/readerui") + UIManager = require("ui/uimanager") purgeDir = require("ffi/util").purgeDir Screen = require("device").screen diff --git a/spec/unit/readerhighlight_spec.lua b/spec/unit/readerhighlight_spec.lua index 5a75f2ccd..39ac874fa 100644 --- a/spec/unit/readerhighlight_spec.lua +++ b/spec/unit/readerhighlight_spec.lua @@ -2,13 +2,14 @@ describe("Readerhighlight module", function() local DocumentRegistry, ReaderUI, UIManager, Screen, Geom, dbg, Event setup(function() require("commonrequire") + package.unloadAll() DocumentRegistry = require("document/documentregistry") + Event = require("ui/event") + Geom = require("ui/geometry") ReaderUI = require("apps/reader/readerui") - UIManager = require("ui/uimanager") Screen = require("device").screen - Geom = require("ui/geometry") + UIManager = require("ui/uimanager") dbg = require("dbg") - Event = require("ui/event") end) local function highlight_single_word(readerui, pos0) diff --git a/spec/unit/readerlink_spec.lua b/spec/unit/readerlink_spec.lua index ed5b4cefe..473014e42 100644 --- a/spec/unit/readerlink_spec.lua +++ b/spec/unit/readerlink_spec.lua @@ -3,6 +3,7 @@ describe("ReaderLink module", function() setup(function() require("commonrequire") + package.unloadAll() DocumentRegistry = require("document/documentregistry") Event = require("ui/event") ReaderUI = require("apps/reader/readerui") diff --git a/spec/unit/readerview_spec.lua b/spec/unit/readerview_spec.lua index dae5cbeab..1e3c9b9d2 100644 --- a/spec/unit/readerview_spec.lua +++ b/spec/unit/readerview_spec.lua @@ -3,6 +3,7 @@ describe("Readerview module", function() setup(function() require("commonrequire") + package.unloadAll() DocumentRegistry = require("document/documentregistry") Blitbuffer = require("ffi/blitbuffer") ReaderUI = require("apps/reader/readerui") diff --git a/spec/unit/uimanager_spec.lua b/spec/unit/uimanager_spec.lua index 62f33141a..f0ce0fd31 100644 --- a/spec/unit/uimanager_spec.lua +++ b/spec/unit/uimanager_spec.lua @@ -164,35 +164,6 @@ describe("UIManager spec", function() assert.is_true(UIManager._task_queue_dirty) end) - it("should setup auto suspend on kobo", function() - local old_reset_timer = UIManager._resetAutoSuspendTimer - local noop = old_reset_timer - assert.falsy(UIManager._startAutoSuspend) - assert.falsy(UIManager._stopAutoSuspend) - assert.truthy(old_reset_timer) - G_reader_settings:saveSetting("auto_suspend_timeout_seconds", 3600) - - UIManager:run() - UIManager:quit() - -- should skip on non-kobo devices - UIManager:_initAutoSuspend() - assert.is.same(noop, UIManager._startAutoSuspend) - assert.is.same(noop, UIManager._stopAutoSuspend) - assert.truthy(old_reset_timer) - assert.is.same(#UIManager._task_queue, 0) - -- now test kobo devices - local old_is_kobo = Device.isKobo - Device.isKobo = function() return true end - UIManager:_initAutoSuspend() - assert.truthy(UIManager._startAutoSuspend) - assert.truthy(UIManager._stopAutoSuspend) - assert.is_not.same(UIManager._resetAutoSuspendTimer, old_reset_timer) - assert.is.same(#UIManager._task_queue, 1) - assert.is.same(UIManager._task_queue[1].action, - UIManager.auto_suspend_action) - Device.isKobo = old_is_kobo - end) - it("should check active widgets in order", function() local call_signals = {false, false, false} UIManager._window_stack = {