mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
Tame a few tests that relied on pairs being somewhat deterministic (#6371)
* Mangle stupid defaults test so that it compares tables, and not a non-deterministic string representation of one. It's still extremely dumb and annoying to update. (i.e., feel free to kill it with fire in a subsequent PR, I think everybody would cheer). * Rewrite DepGraph to be deterministic i.e., fully array based, no more hashes, which means no more pairs randomly re-ordering stuff. Insertion order is now preserved. Pretty sure a couple of bugs have been fixed and/or added along the way ;p. * Resync frontend/apps/filemanager/lib/md.lua w/ upstream And use orderedPairs in the attribute parsing code, just to make that stupid test happy.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
-- From https://github.com/bakpakin/luamd revision 5e8fa39173afecd73913d27e0f0e63649b01fb5b
|
||||
-- From https://github.com/bakpakin/luamd revision 388ce799d93e899e4d673cdc6d522f12310822bd
|
||||
local FFIUtil = require("ffi/util")
|
||||
|
||||
--[[
|
||||
Copyright (c) 2016 Calvin Rose <calsrose@gmail.com>
|
||||
@@ -63,7 +64,7 @@ end
|
||||
-- Line Level Operations
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local lineDelimiters = {'`', '__', '**', '_', '*'}
|
||||
local lineDelimiters = {'`', '__', '**', '_', '*', '~~'}
|
||||
local function findDelim(str, start, max)
|
||||
local delim = nil
|
||||
local min = 1/0
|
||||
@@ -111,7 +112,7 @@ local function linkEscape(str, t)
|
||||
if nomatches then externalLinkEscape(str, t) end
|
||||
end
|
||||
|
||||
local lineDeimiterNames = {['`'] = 'code', ['__'] = 'strong', ['**'] = 'strong', ['_'] = 'em', ['*'] = 'em' }
|
||||
local lineDeimiterNames = {['`'] = 'code', ['__'] = 'strong', ['**'] = 'strong', ['_'] = 'em', ['*'] = 'em', ['~~'] = 'strike' }
|
||||
local function lineRead(str, start, finish)
|
||||
start, finish = start or 1, finish or #str
|
||||
local searchIndex = start
|
||||
@@ -419,7 +420,8 @@ end
|
||||
|
||||
local function renderAttributes(attributes)
|
||||
local accum = {}
|
||||
for k, v in pairs(attributes) do
|
||||
-- KOReader: oderedPairs instead of pairs
|
||||
for k, v in FFIUtil.orderedPairs(attributes) do
|
||||
accum[#accum + 1] = format("%s=\"%s\"", k, v)
|
||||
end
|
||||
return concat(accum, ' ')
|
||||
|
||||
@@ -11,6 +11,8 @@ Example:
|
||||
-- The return value of dg:serialize() will be:
|
||||
-- {'a2', 'c1', 'b1', 'a1'}
|
||||
|
||||
NOTE: Insertion order is preserved, duplicates are automatically prevented (both as main nodes and as deps).
|
||||
|
||||
]]
|
||||
|
||||
local DepGraph = {}
|
||||
@@ -23,97 +25,217 @@ function DepGraph:new(new_o)
|
||||
return o
|
||||
end
|
||||
|
||||
function DepGraph:addNode(node_key, deps)
|
||||
if not self.nodes[node_key] then
|
||||
self.nodes[node_key] = {}
|
||||
-- Check if node exists, and is active
|
||||
function DepGraph:checkNode(id)
|
||||
for _, n in ipairs(self.nodes) do
|
||||
if n.key == id and not n.disabled then
|
||||
return true
|
||||
end
|
||||
end
|
||||
if not deps then return end
|
||||
|
||||
local node_deps = {}
|
||||
for _,dep_node_key in ipairs(deps) do
|
||||
if not self.nodes[dep_node_key] then
|
||||
self.nodes[dep_node_key] = {}
|
||||
end
|
||||
table.insert(node_deps, dep_node_key)
|
||||
end
|
||||
self.nodes[node_key].deps = node_deps
|
||||
return false
|
||||
end
|
||||
|
||||
function DepGraph:removeNode(node_key)
|
||||
-- We should not remove it from self.nodes if it has
|
||||
-- a .deps array (it is the other nodes, that had this
|
||||
-- one in their override=, that have added themselves in
|
||||
-- this node's .deps). We don't want to lose these
|
||||
-- dependencies if we later re-addNode this node.
|
||||
local node = self.nodes[node_key]
|
||||
if node then
|
||||
if not node.deps or #node.deps == 0 then
|
||||
self.nodes[node_key] = nil
|
||||
-- Returns a (node, node_index) tuple
|
||||
function DepGraph:getNode(id)
|
||||
for i, n in ipairs(self.nodes) do
|
||||
if n.key == id then
|
||||
return n, i
|
||||
end
|
||||
end
|
||||
-- But we should remove it from the .deps of other nodes.
|
||||
for curr_node_key, curr_node in pairs(self.nodes) do
|
||||
if curr_node.deps then
|
||||
local remove_idx
|
||||
for idx, dep_node_key in ipairs(self.nodes) do
|
||||
|
||||
return nil, nil
|
||||
end
|
||||
|
||||
-- Like getNode, but only for active nodes:
|
||||
-- if node is nil but index is set, node is disabled
|
||||
function DepGraph:getActiveNode(id)
|
||||
local node, index = self:getNode(id)
|
||||
if node and node.disabled then
|
||||
return nil, index
|
||||
end
|
||||
|
||||
return node, index
|
||||
end
|
||||
|
||||
-- Add a node, with an optional list of dependencies
|
||||
-- If dependencies don't exist as proper nodes yet, they'll be created, in order.
|
||||
-- If node already exists, the new list of dependencies is *appended* to the existing one, without duplicates.
|
||||
function DepGraph:addNode(node_key, deps)
|
||||
-- Find main node if it already exists
|
||||
local node = self:getNode(node_key)
|
||||
|
||||
if node then
|
||||
-- If it exists, but was disabled, re-enable it
|
||||
if node.disabled then
|
||||
node.disabled = nil
|
||||
end
|
||||
else
|
||||
-- If it doesn't exist at all, create it
|
||||
node = { key = node_key }
|
||||
table.insert(self.nodes, node)
|
||||
end
|
||||
|
||||
-- No dependencies? We're done!
|
||||
if not deps then
|
||||
return
|
||||
end
|
||||
|
||||
-- Create dep nodes if they don't already exist
|
||||
local node_deps = node.deps or {}
|
||||
for _, dep_node_key in ipairs(deps) do
|
||||
local dep_node = self:getNode(dep_node_key)
|
||||
|
||||
if dep_node then
|
||||
-- If it exists, but was disabled, re-enable it
|
||||
if dep_node.disabled then
|
||||
dep_node.disabled = nil
|
||||
end
|
||||
else
|
||||
-- Create dep node itself if need be
|
||||
dep_node = { key = dep_node_key }
|
||||
table.insert(self.nodes, dep_node)
|
||||
end
|
||||
|
||||
-- Update deps array the long way 'round, and prevent duplicates, in case deps was funky as hell.
|
||||
local exists = false
|
||||
for _, k in ipairs(node_deps) do
|
||||
if k == dep_node_key then
|
||||
exists = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not exists then
|
||||
table.insert(node_deps, dep_node_key)
|
||||
end
|
||||
end
|
||||
-- Update main node with its updated deps
|
||||
node.deps = node_deps
|
||||
end
|
||||
|
||||
-- Attempt to remove a node, as well as all traces of it from other nodes' deps
|
||||
-- If node has deps, it's kept, but marked as disabled, c.f., lenghty comment below.
|
||||
function DepGraph:removeNode(node_key)
|
||||
-- We shouldn't remove a node if it has dependencies (as these may have been added via addNodeDep
|
||||
-- (as opposed to the optional deps list passed to addNode), like what InputContainer does with overrides,
|
||||
-- overrides originating from completely *different* nodes,
|
||||
-- meaning those other nodes basically add themselves to another's deps).
|
||||
-- We don't want to lose the non-native dependency on these other nodes in case we later re-addNode this one
|
||||
-- with its stock dependency list.
|
||||
local node, index = self:getNode(node_key)
|
||||
if node then
|
||||
if not node.deps or #node.deps == 0 then
|
||||
-- No dependencies, can be wiped safely
|
||||
table.remove(self.nodes, index)
|
||||
else
|
||||
-- Can't remove it, just flag it as disabled instead
|
||||
node.disabled = true
|
||||
end
|
||||
end
|
||||
-- On the other hand, we definitely should remove it from the deps of every *other* node.
|
||||
for _, curr_node in ipairs(self.nodes) do
|
||||
-- Is not the to be removed node, and has deps
|
||||
if curr_node.key ~= node_key and curr_node.deps then
|
||||
-- Walk that node's deps to check if it depends on us
|
||||
for idx, dep_node_key in ipairs(curr_node.deps) do
|
||||
-- If it did, wipe ourselves from there
|
||||
if dep_node_key == node_key then
|
||||
remove_idx = idx
|
||||
table.remove(curr_node.deps, idx)
|
||||
break
|
||||
end
|
||||
end
|
||||
if remove_idx then table.remove(curr_node.deps, remove_idx) end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function DepGraph:checkNode(id)
|
||||
if self.nodes[id] then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
-- Add a single dep_node_key to node_key's deps
|
||||
function DepGraph:addNodeDep(node_key, dep_node_key)
|
||||
local node = self.nodes[node_key]
|
||||
if not node then
|
||||
node = {}
|
||||
self.nodes[node_key] = node
|
||||
-- Check the main node
|
||||
local node = self:getNode(node_key)
|
||||
|
||||
if node then
|
||||
-- If it exists, but was disabled, re-enable it
|
||||
if node.disabled then
|
||||
node.disabled = nil
|
||||
end
|
||||
else
|
||||
-- If it doesn't exist at all, create it
|
||||
node = { key = node_key }
|
||||
table.insert(self.nodes, node)
|
||||
end
|
||||
|
||||
-- Then check the dep node
|
||||
local dep_node = self:getNode(dep_node_key)
|
||||
|
||||
if dep_node then
|
||||
-- If it exists, but was disabled, re-enable it
|
||||
if dep_node.disabled then
|
||||
dep_node.disabled = nil
|
||||
end
|
||||
else
|
||||
-- Create dep node itself if need be
|
||||
dep_node = { key = dep_node_key }
|
||||
table.insert(self.nodes, dep_node)
|
||||
end
|
||||
|
||||
-- If main node currently doesn't have deps, start with an empty array
|
||||
if not node.deps then
|
||||
node.deps = {}
|
||||
end
|
||||
|
||||
-- Prevent duplicate deps
|
||||
local exists = false
|
||||
for _, k in ipairs(node.deps) do
|
||||
if k == dep_node_key then
|
||||
exists = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not exists then
|
||||
table.insert(node.deps, dep_node_key)
|
||||
end
|
||||
if not node.deps then node.deps = {} end
|
||||
table.insert(node.deps, dep_node_key)
|
||||
end
|
||||
|
||||
-- Remove a single dep_node_key from node_key's deps
|
||||
function DepGraph:removeNodeDep(node_key, dep_node_key)
|
||||
local node = self.nodes[node_key]
|
||||
if not node.deps then node.deps = {} end
|
||||
for i, dep_key in ipairs(node.deps) do
|
||||
if dep_key == dep_node_key then
|
||||
self.nodes[node_key]["deps"][i] = nil
|
||||
local node = self:getNode(node_key)
|
||||
if node.deps then
|
||||
for idx, dep_key in ipairs(node.deps) do
|
||||
if dep_key == dep_node_key then
|
||||
table.remove(node.deps, idx)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Return a list (array) of node keys, ordered by insertion order and dependency.
|
||||
-- Dependencies come first (and are also ordered by insertion order themselves).
|
||||
function DepGraph:serialize()
|
||||
local visited = {}
|
||||
local ordered_nodes = {}
|
||||
for node_key,_ in pairs(self.nodes) do
|
||||
|
||||
for _, n in ipairs(self.nodes) do
|
||||
local node_key = n.key
|
||||
if not visited[node_key] then
|
||||
local queue = {node_key}
|
||||
local queue = { node_key }
|
||||
while #queue > 0 do
|
||||
local pos = #queue
|
||||
local curr_node_key = queue[pos]
|
||||
local curr_node = self.nodes[curr_node_key]
|
||||
local curr_node = self:getActiveNode(curr_node_key)
|
||||
local all_deps_visited = true
|
||||
if curr_node.deps then
|
||||
if curr_node and curr_node.deps then
|
||||
for _, dep_node_key in ipairs(curr_node.deps) do
|
||||
if not visited[dep_node_key] then
|
||||
-- only insert to queue for later process if node
|
||||
-- has dependencies
|
||||
if self.nodes[dep_node_key].deps then
|
||||
table.insert(queue, dep_node_key)
|
||||
else
|
||||
table.insert(ordered_nodes, dep_node_key)
|
||||
-- Only insert to queue for later process if node has dependencies
|
||||
local dep_node = self:getActiveNode(dep_node_key)
|
||||
-- Only if it was active!
|
||||
if dep_node then
|
||||
if dep_node.deps then
|
||||
table.insert(queue, dep_node_key)
|
||||
else
|
||||
table.insert(ordered_nodes, dep_node_key)
|
||||
end
|
||||
end
|
||||
visited[dep_node_key] = true
|
||||
all_deps_visited = false
|
||||
@@ -124,7 +246,10 @@ function DepGraph:serialize()
|
||||
if all_deps_visited then
|
||||
visited[curr_node_key] = true
|
||||
table.remove(queue, pos)
|
||||
table.insert(ordered_nodes, curr_node_key)
|
||||
-- Only if it was active!
|
||||
if curr_node then
|
||||
table.insert(ordered_nodes, curr_node_key)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -33,7 +33,7 @@ end
|
||||
function MenuSorter:mergeAndSort(config_prefix, item_table, order)
|
||||
local user_order = self:readMSSettings(config_prefix)
|
||||
if user_order then
|
||||
for user_order_id,user_order_item in pairs(user_order) do
|
||||
for user_order_id, user_order_item in pairs(user_order) do
|
||||
order[user_order_id] = user_order_item
|
||||
end
|
||||
end
|
||||
@@ -48,13 +48,13 @@ function MenuSorter:sort(item_table, order)
|
||||
local menu_table = {}
|
||||
local sub_menus = {}
|
||||
-- the actual sorting of menu items
|
||||
for order_id, order_item in pairs (order) do
|
||||
for order_id, order_item in pairs(order) do
|
||||
-- user might define non-existing menu item
|
||||
if item_table[order_id] ~= nil then
|
||||
local tmp_menu_table = {}
|
||||
menu_table[order_id] = item_table[order_id]
|
||||
menu_table[order_id].id = order_id
|
||||
for order_number,order_number_id in ipairs(order_item) do
|
||||
for order_number, order_number_id in ipairs(order_item) do
|
||||
-- this is a submenu, mark it for later
|
||||
if item_table[order_number_id] ~= nil and order[order_number_id] then
|
||||
table.insert(sub_menus, order_number_id)
|
||||
@@ -114,7 +114,7 @@ function MenuSorter:sort(item_table, order)
|
||||
while changed do
|
||||
changed = false
|
||||
-- now do the submenus
|
||||
for i,sub_menu in ipairs(sub_menus) do
|
||||
for i, sub_menu in ipairs(sub_menus) do
|
||||
if menu_table[sub_menu] ~= nil then
|
||||
local sub_menu_position = self:findById(menu_table["KOMenu:menu_buttons"], sub_menu)
|
||||
if sub_menu_position then
|
||||
@@ -135,7 +135,7 @@ function MenuSorter:sort(item_table, order)
|
||||
-- they should, however have one going in
|
||||
-- Also, compress the menu table.
|
||||
local menu_buttons_offset = 0
|
||||
for i,top_menu in ipairs(menu_table["KOMenu:menu_buttons"]) do
|
||||
for i, top_menu in ipairs(menu_table["KOMenu:menu_buttons"]) do
|
||||
local menu_button = menu_table["KOMenu:menu_buttons"][i].sub_item_table
|
||||
menu_table["KOMenu:menu_buttons"][i] = nil
|
||||
if menu_button then
|
||||
@@ -146,7 +146,7 @@ function MenuSorter:sort(item_table, order)
|
||||
end
|
||||
-- handle disabled
|
||||
if order["KOMenu:disabled"] then
|
||||
for _,item in ipairs(order["KOMenu:disabled"]) do
|
||||
for _, item in ipairs(order["KOMenu:disabled"]) do
|
||||
if item_table[item] then
|
||||
-- remove reference from input so it won't show up as orphaned
|
||||
item_table[item] = nil
|
||||
@@ -158,7 +158,7 @@ function MenuSorter:sort(item_table, order)
|
||||
item_table["KOMenu:menu_buttons"] = nil
|
||||
|
||||
-- attach orphans based on sorting_hint, or with a NEW prefix in the first menu if none found
|
||||
for k,v in pairs(item_table) do
|
||||
for k, v in pairs(item_table) do
|
||||
local sorting_hint = v.sorting_hint
|
||||
|
||||
-- normally there should be menu text but check to be sure
|
||||
@@ -170,7 +170,7 @@ function MenuSorter:sort(item_table, order)
|
||||
-- deal with orphaned submenus
|
||||
if #v > 0 then
|
||||
v.sub_item_table = {}
|
||||
for i=1,#v do
|
||||
for i=1, #v do
|
||||
v.sub_item_table[i] = v[i]
|
||||
end
|
||||
end
|
||||
@@ -193,7 +193,7 @@ end
|
||||
function MenuSorter:findById(tbl, needle_id)
|
||||
local items = {}
|
||||
|
||||
for _,item in pairs(tbl) do
|
||||
for _, item in pairs(tbl) do
|
||||
if item ~= "KOMenu:menu_buttons" then
|
||||
table.insert(items, item)
|
||||
end
|
||||
@@ -208,7 +208,7 @@ function MenuSorter:findById(tbl, needle_id)
|
||||
if id_match then
|
||||
return v
|
||||
elseif sub_table then
|
||||
for _,item in pairs(sub_table) do
|
||||
for _, item in pairs(sub_table) do
|
||||
if type(item) == "table" and item.id then
|
||||
table.insert(items, item)
|
||||
end
|
||||
|
||||
@@ -28,32 +28,11 @@ describe("defaults module", function()
|
||||
assert.is_same("DTAP_ZONE_BACKWARD", Defaults.defaults_name[85])
|
||||
assert.is_same("DCREREADER_CONFIG_WORD_SPACING_LARGE", Defaults.defaults_name[50])
|
||||
assert.is_same("DCREREADER_CONFIG_H_MARGIN_SIZES_XXX_LARGE", Defaults.defaults_name[20])
|
||||
local fd = io.open(persistent_filename, "r")
|
||||
assert.Equals(
|
||||
[[-- For configuration changes that persists between updates
|
||||
DCREREADER_CONFIG_WORD_SPACING_LARGE = {
|
||||
[1] = 100,
|
||||
[2] = 90
|
||||
}
|
||||
DTAP_ZONE_BACKWARD = {
|
||||
["y"] = 0,
|
||||
["x"] = 0,
|
||||
["h"] = 1,
|
||||
["w"] = 0.25
|
||||
}
|
||||
DCREREADER_CONFIG_H_MARGIN_SIZES_XXX_LARGE = {
|
||||
[1] = 50,
|
||||
[2] = 50
|
||||
}
|
||||
DDOUBLE_TAP_ZONE_PREV_CHAPTER = {
|
||||
["y"] = 0,
|
||||
["x"] = 0,
|
||||
["h"] = 0.25,
|
||||
["w"] = 0.25
|
||||
}
|
||||
]],
|
||||
fd:read("*a"))
|
||||
fd:close()
|
||||
dofile(persistent_filename)
|
||||
assert.is_same(DCREREADER_CONFIG_WORD_SPACING_LARGE, { [1] = 100, [2] = 90 })
|
||||
assert.is_same(DTAP_ZONE_BACKWARD, { ["y"] = 0, ["x"] = 0, ["h"] = 1, ["w"] = 0.25 })
|
||||
assert.is_same(DCREREADER_CONFIG_H_MARGIN_SIZES_XXX_LARGE, { [1] = 50, [2] = 50 })
|
||||
assert.is_same(DDOUBLE_TAP_ZONE_PREV_CHAPTER, { ["y"] = 0, ["x"] = 0, ["h"] = 0.25, ["w"] = 0.25 })
|
||||
|
||||
-- in persistent
|
||||
Defaults:init()
|
||||
@@ -72,32 +51,21 @@ DDOUBLE_TAP_ZONE_PREV_CHAPTER = {
|
||||
w = 20.75
|
||||
}
|
||||
Defaults:saveSettings()
|
||||
fd = io.open(persistent_filename)
|
||||
assert.Equals(
|
||||
[[-- For configuration changes that persists between updates
|
||||
DCREREADER_CONFIG_WORD_SPACING_LARGE = {
|
||||
[2] = 90,
|
||||
[1] = 100
|
||||
}
|
||||
DDOUBLE_TAP_ZONE_PREV_CHAPTER = {
|
||||
["y"] = 0,
|
||||
["x"] = 0,
|
||||
["h"] = 0.25,
|
||||
["w"] = 0.75
|
||||
}
|
||||
DCREREADER_CONFIG_H_MARGIN_SIZES_XXX_LARGE = {
|
||||
[2] = 50,
|
||||
[1] = 50
|
||||
}
|
||||
DTAP_ZONE_BACKWARD = {
|
||||
["y"] = 10,
|
||||
["x"] = 10.125,
|
||||
["h"] = 20.25,
|
||||
["w"] = 20.75
|
||||
}
|
||||
]],
|
||||
fd:read("*a"))
|
||||
fd:close()
|
||||
dofile(persistent_filename)
|
||||
assert.is_same(DCREREADER_CONFIG_WORD_SPACING_LARGE, { [2] = 90, [1] = 100 })
|
||||
assert.is_same(DDOUBLE_TAP_ZONE_PREV_CHAPTER, {
|
||||
["y"] = 0,
|
||||
["x"] = 0,
|
||||
["h"] = 0.25,
|
||||
["w"] = 0.75
|
||||
})
|
||||
assert.is_same(DCREREADER_CONFIG_H_MARGIN_SIZES_XXX_LARGE, { [2] = 50, [1] = 50 })
|
||||
assert.is_same(DTAP_ZONE_BACKWARD, {
|
||||
["y"] = 10,
|
||||
["x"] = 10.125,
|
||||
["h"] = 20.25,
|
||||
["w"] = 20.75
|
||||
})
|
||||
os.remove(persistent_filename)
|
||||
end)
|
||||
|
||||
@@ -120,19 +88,14 @@ DHINTCOUNT = 2
|
||||
Defaults.changed[57] = true
|
||||
Defaults.defaults_value[57] = 1
|
||||
Defaults:saveSettings()
|
||||
fd = io.open(persistent_filename)
|
||||
assert.Equals(
|
||||
[[-- For configuration changes that persists between updates
|
||||
DCREREADER_VIEW_MODE = "page"
|
||||
DCREREADER_CONFIG_H_MARGIN_SIZES_LARGE = {
|
||||
[2] = 15,
|
||||
[1] = 15
|
||||
}
|
||||
DGLOBAL_CACHE_FREE_PROPORTION = 1
|
||||
DHINTCOUNT = 2
|
||||
]],
|
||||
fd:read("*a"))
|
||||
fd:close()
|
||||
dofile(persistent_filename)
|
||||
assert.Equals(DCREREADER_VIEW_MODE, "page")
|
||||
assert.is_same(DCREREADER_CONFIG_H_MARGIN_SIZES_LARGE, {
|
||||
[2] = 15,
|
||||
[1] = 15
|
||||
})
|
||||
assert.Equals(DGLOBAL_CACHE_FREE_PROPORTION, 1)
|
||||
assert.Equals(DHINTCOUNT, 2)
|
||||
os.remove(persistent_filename)
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -29,17 +29,17 @@ describe("DepGraph module", function()
|
||||
dg:addNode('paging_pan_release', {})
|
||||
assert.are.same({
|
||||
'readerfooter_tap',
|
||||
'readerfooter_hold',
|
||||
'readermenu_tap',
|
||||
'tap_backward',
|
||||
'readerhighlight_hold_pan',
|
||||
'paging_pan_release',
|
||||
'readerfooter_hold',
|
||||
'readerhighlight_hold',
|
||||
'paging_pan',
|
||||
'paging_swipe',
|
||||
'tap_forward',
|
||||
'readerhighlight_tap',
|
||||
'readerhighlight_hold',
|
||||
'readerhighlight_hold_release',
|
||||
'readerhighlight_hold_pan',
|
||||
'paging_swipe',
|
||||
'paging_pan',
|
||||
'paging_pan_release',
|
||||
}, dg:serialize())
|
||||
end)
|
||||
|
||||
@@ -56,14 +56,14 @@ describe("DepGraph module", function()
|
||||
dg:addNode('readermenu_tap', {'readerfooter_tap'})
|
||||
assert.are.same({
|
||||
'readerfooter_tap',
|
||||
'readermenu_tap',
|
||||
'readerhighlight_tap',
|
||||
'tap_backward',
|
||||
'readerhighlight_hold_pan',
|
||||
'readerfooter_hold',
|
||||
'readerhighlight_hold',
|
||||
'readerhighlight_tap',
|
||||
'readermenu_tap',
|
||||
'tap_backward',
|
||||
'tap_forward',
|
||||
'readerhighlight_hold',
|
||||
'readerhighlight_hold_release',
|
||||
'readerhighlight_hold_pan',
|
||||
}, dg:serialize())
|
||||
end)
|
||||
|
||||
@@ -85,17 +85,17 @@ describe("DepGraph module", function()
|
||||
dg:addNode('paging_pan_release', {})
|
||||
assert.are.same({
|
||||
'readerfooter_tap',
|
||||
'readerfooter_hold',
|
||||
'readermenu_tap',
|
||||
'tap_backward',
|
||||
'readerhighlight_hold_pan',
|
||||
'paging_pan_release',
|
||||
'readerfooter_hold',
|
||||
'readerhighlight_hold',
|
||||
'paging_pan',
|
||||
'paging_swipe',
|
||||
'tap_forward',
|
||||
'readerhighlight_tap',
|
||||
'readerhighlight_hold',
|
||||
'readerhighlight_hold_release',
|
||||
'readerhighlight_hold_pan',
|
||||
'paging_swipe',
|
||||
'paging_pan',
|
||||
'paging_pan_release',
|
||||
}, dg:serialize())
|
||||
end)
|
||||
|
||||
@@ -132,9 +132,65 @@ describe("DepGraph module", function()
|
||||
"tap_backward",
|
||||
"tap_forward",
|
||||
}, dg:serialize())
|
||||
assert.is_true(type(dg.nodes["tap_forward"].deps) == "table")
|
||||
assert.is_true(#dg.nodes["tap_forward"].deps > 0)
|
||||
assert.is_true(type(dg.nodes["tap_backward"].deps) == "table")
|
||||
assert.is_true(#dg.nodes["tap_backward"].deps > 0)
|
||||
local tapFwdNode = dg:getNode("tap_forward")
|
||||
assert.is_true(type(tapFwdNode.deps) == "table")
|
||||
assert.is_true(#tapFwdNode.deps > 0)
|
||||
local tapBwdNode = dg:getNode("tap_backward")
|
||||
assert.is_true(type(tapBwdNode.deps) == "table")
|
||||
assert.is_true(#tapBwdNode.deps > 0)
|
||||
end)
|
||||
|
||||
it("should not serialize removed/disabled nodes", function()
|
||||
local dg = DepGraph:new{}
|
||||
dg:addNode('foo')
|
||||
dg:addNode('bar')
|
||||
dg:addNode('baz',
|
||||
{'foo', 'bar', 'bam'})
|
||||
dg:addNode('feh')
|
||||
dg:removeNode('baz')
|
||||
dg:removeNode('bar')
|
||||
dg:addNode('blah', {'bla', 'h', 'bamf'})
|
||||
dg:removeNode('bamf')
|
||||
assert.are.same({
|
||||
'foo',
|
||||
'bam',
|
||||
'feh',
|
||||
'bla',
|
||||
'h',
|
||||
'blah',
|
||||
}, dg:serialize())
|
||||
|
||||
-- Check that bamf was removed from blah's deps
|
||||
assert.are.same({
|
||||
'bla',
|
||||
'h',
|
||||
}, dg:getNode('blah').deps)
|
||||
|
||||
-- Check that baz is re-enabled w/ its full deps (minus bar, that we removed earlier) if re-Added as a dep
|
||||
dg:addNode('whee', {'baz'})
|
||||
assert.are.same({
|
||||
'foo',
|
||||
'bam',
|
||||
}, dg:getNode('baz').deps)
|
||||
assert.are.same({
|
||||
'foo',
|
||||
'bam',
|
||||
'baz',
|
||||
'feh',
|
||||
'bla',
|
||||
'h',
|
||||
'blah',
|
||||
'whee',
|
||||
}, dg:serialize())
|
||||
|
||||
-- Check that re-adding an existing node with new deps properly *appends* to its existing deps
|
||||
dg:addNode('baz', {'wham', 'bang'})
|
||||
assert.are.same({
|
||||
'foo',
|
||||
'bam',
|
||||
'wham',
|
||||
'bang',
|
||||
}, dg:getNode('baz').deps)
|
||||
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
describe("MenuSorter module", function()
|
||||
local MenuSorter
|
||||
local equals
|
||||
setup(function()
|
||||
require("commonrequire")
|
||||
MenuSorter = require("ui/menusorter")
|
||||
equals = require("util").tableEquals
|
||||
end)
|
||||
|
||||
it("should put menu items in the defined order", function()
|
||||
@@ -153,7 +151,7 @@ describe("MenuSorter module", function()
|
||||
["id"] = "KOMenu:menu_buttons"
|
||||
}
|
||||
|
||||
assert.is_true( equals(result_menu, test_menu) )
|
||||
assert.is_same(result_menu, test_menu)
|
||||
end)
|
||||
it("should display submenu of orphaned submenu", function()
|
||||
local menu_items = {
|
||||
@@ -178,6 +176,8 @@ describe("MenuSorter module", function()
|
||||
}
|
||||
|
||||
local test_menu = MenuSorter:sort(menu_items, order)
|
||||
--- @fixme: Currently broken because pairs (c.f., https://github.com/koreader/koreader/pull/6371#issuecomment-657251137)
|
||||
--print(require("dump")(test_menu))
|
||||
|
||||
-- all four should be in the first menu
|
||||
assert.is_true(#test_menu[1] == 4)
|
||||
|
||||
@@ -145,11 +145,11 @@ describe("InputContainer widget", function()
|
||||
assert.is.same('readerfooter_tap', ic._ordered_touch_zones[1].def.id)
|
||||
assert.is.same('readerhighlight_tap', ic._ordered_touch_zones[2].def.id)
|
||||
assert.is.same('readermenu_tap', ic._ordered_touch_zones[3].def.id)
|
||||
assert.is.same('tap_backward', ic._ordered_touch_zones[4].def.id)
|
||||
assert.is.same('readerhighlight_hold_pan', ic._ordered_touch_zones[5].def.id)
|
||||
assert.is.same('tap_forward', ic._ordered_touch_zones[4].def.id)
|
||||
assert.is.same('tap_backward', ic._ordered_touch_zones[5].def.id)
|
||||
assert.is.same('readerfooter_hold', ic._ordered_touch_zones[6].def.id)
|
||||
assert.is.same('readerhighlight_hold', ic._ordered_touch_zones[7].def.id)
|
||||
assert.is.same('tap_forward', ic._ordered_touch_zones[8].def.id)
|
||||
assert.is.same('readerhighlight_hold_release', ic._ordered_touch_zones[9].def.id)
|
||||
assert.is.same('readerhighlight_hold_release', ic._ordered_touch_zones[8].def.id)
|
||||
assert.is.same('readerhighlight_hold_pan', ic._ordered_touch_zones[9].def.id)
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -19,6 +19,7 @@ describe("Menu widget", function()
|
||||
callback = cb2
|
||||
},
|
||||
})
|
||||
--- @fixme: Currently broken because pairs (c.f., https://github.com/koreader/koreader/pull/6371#issuecomment-657251302)
|
||||
assert.are.same(re, {
|
||||
{
|
||||
text = 'navi',
|
||||
|
||||
Reference in New Issue
Block a user