local awful = require("awful") local beautiful = require("beautiful") local test_client = require("_client") local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1) local callback_called = false -- Magic table to store tests local tests = {} local tb_height = awful.util.round(beautiful.get_font_height() * 1.5) -- local border_width = beautiful.border_width -- Detect "manage" race conditions local real_apply = awful.rules.apply function awful.rules.apply(c) assert(#c:tags() == 0) return real_apply(c) end local function test_rule(rule) rule.rule = rule.rule or {} -- Create a random class. The number need to be large as "rule1" and "rule10" would collide -- The math.ceil is necessary to remove the floating point, this create an invalid dbus name local class = string.format("rule%010d", 42+#tests) rule.rule.class = rule.rule.class or class test_client(rule.rule.class, rule.properties.name or "Foo") if rule.test then local t = rule.test table.insert(tests, function() return t(rule.rule.class) end) rule.test = nil end table.insert(awful.rules.rules, rule) end -- Helper function to search clients local function get_client_by_class(class) for _, c in ipairs(client.get()) do if class == c.class then return c end end end -- Test callback and floating test_rule { properties = { floating = true }, callback = function(c) assert(type(c) == "client") callback_called = true end, test = function(class) -- Test if callbacks works assert(callback_called) -- Make sure "smart" dynamic properties are applied assert(get_client_by_class(class).floating) -- The size should not have changed local geo = get_client_by_class(class):geometry() assert(geo.width == 100 and geo.height == 100+tb_height) return true end } -- Test ontop test_rule { properties = { ontop = true }, test = function(class) -- Make sure C-API properties are applied assert(get_client_by_class(class).ontop) return true end } -- Test placement test_rule { properties = { floating = true, placement = "bottom_right" }, test = function(class) -- Test placement local sgeo = mouse.screen.workarea local c = get_client_by_class(class) local geo = c:geometry() assert(geo.y+geo.height+2*c.border_width == sgeo.y+sgeo.height) assert(geo.x+geo.width+2*c.border_width == sgeo.x+sgeo.width) return true end } -- Create a tag named after the class name test_rule { properties = { new_tag=true }, test = function(class) local c_new_tag1 = get_client_by_class(class) assert(#c_new_tag1:tags()[1]:clients() == 1) assert(c_new_tag1:tags()[1].name == class) return true end } -- Create a tag named Foo Tag with a magnifier layout test_rule { properties = { new_tag = { name = "Foo Tag", layout = awful.layout.suit.magnifier } }, test = function(class) local t_new_tag2 = get_client_by_class(class):tags()[1] assert( #t_new_tag2:clients() == 1 ) assert( t_new_tag2.name == "Foo Tag" ) assert( t_new_tag2.layout.name == "magnifier" ) return true end } -- Create a tag named "Bar Tag" test_rule { properties = { new_tag= "Bar Tag" }, test = function(class) local c_new_tag3 = get_client_by_class(class) assert(#c_new_tag3:tags()[1]:clients() == 1) assert(c_new_tag3:tags()[1].name == "Bar Tag") return true end } -- Test if setting the geometry work test_rule { properties = { floating = true, x = 200, y = 200, width = 200, height = 200, }, test = function(class) local c = get_client_by_class(class) local geo = c:geometry() -- Give it some time if geo.y < 180 then return end assert(geo.x == 200) assert(geo.y == 200) assert(geo.width == 200) assert(geo.height == 200) return true end } -- Test if setting a partial geometry preserve the other attributes test_rule { properties = { floating = true, x = 200, geometry = { height = 220 } }, test = function(class) local c = get_client_by_class(class) local geo = c:geometry() -- Give it some time if geo.height < 200 then return end assert(geo.x == 200) assert(geo.width == 100) assert(geo.height == 220) return true end } -- Test maximized_horizontal test_rule { properties = { maximized_horizontal = true }, test = function(class) local c = get_client_by_class(class) -- Make sure C-API properties are applied assert(c.maximized_horizontal) local geo = c:geometry() local sgeo = c.screen.workarea assert(geo.x==sgeo.x) assert(geo.width+2*c.border_width==sgeo.width) return true end } -- Test maximized_vertical test_rule { properties = { maximized_vertical = true }, test = function(class) local c = get_client_by_class(class) -- Make sure C-API properties are applied assert(c.maximized_vertical) local geo = c:geometry() local sgeo = c.screen.workarea assert(geo.y==sgeo.y) assert(geo.height+2*c.border_width==sgeo.height) return true end } -- Test fullscreen test_rule { properties = { fullscreen = true }, test = function(class) local c = get_client_by_class(class) -- Make sure C-API properties are applied assert(c.fullscreen) local geo = c:geometry() local sgeo = c.screen.geometry assert(geo.x==sgeo.x) assert(geo.y==sgeo.y) assert(geo.height+2*c.border_width==sgeo.height) assert(geo.width+2*c.border_width==sgeo.width) return true end } -- Test tag and switchtotag test_rule { properties = { tag = "9", switchtotag = true }, test = function(class) local c = get_client_by_class(class) -- Make sure C-API properties are applied assert(#c:tags() == 1) assert(c:tags()[1].name == "9") assert(c.screen.selected_tag.name == "9") return true end } test_rule { properties = { tag = "8", switchtotag = false }, test = function(class) local c = get_client_by_class(class) -- Make sure C-API properties are applied assert(#c:tags() == 1) assert(c:tags()[1].name == "8") assert(c.screen.selected_tag.name ~= "8") return true end } -- Wait until all the auto-generated clients are ready local function spawn_clients() if #client.get() >= #tests then -- Set tiled awful.layout.inc(1) return true end end require("_runner").run_steps{spawn_clients, unpack(tests)}