Merge pull request #820 from Elv13/layout_tests

tests: Test all client layouts
This commit is contained in:
Emmanuel Lepage Vallée 2016-04-18 04:27:11 -04:00
commit bc2ddfe82d
14 changed files with 244 additions and 40 deletions

View File

@ -28,6 +28,11 @@
#include "common/atoms.h"
#include "common/util.h"
#define MAX_X11_COORDINATE INT16_MAX
#define MIN_X11_COORDINATE INT16_MIN
#define MAX_X11_SIZE UINT16_MAX
#define MIN_X11_SIZE 1
static inline char *
xutil_get_text_property_from_reply(xcb_get_property_reply_t *reply)
{

View File

@ -172,8 +172,8 @@ function layout.arrange(screen)
p.geometries = setmetatable({}, {__mode = "k"})
layout.get(screen).arrange(p)
for c, g in pairs(p.geometries) do
g.width = g.width - c.border_width * 2 - useless_gap * 2
g.height = g.height - c.border_width * 2 - useless_gap * 2
g.width = math.max(1, g.width - c.border_width * 2 - useless_gap * 2)
g.height = math.max(1, g.height - c.border_width * 2 - useless_gap * 2)
g.x = g.x + useless_gap
g.y = g.y + useless_gap
c:geometry(g)

View File

@ -171,7 +171,7 @@ local function tile_group(gs, cls, wa, orientation, fact, group)
end
total_fact = total_fact + fact[i]
end
size = math.min(size, available)
size = math.max(1, math.min(size, available))
local coord = wa[y]
local used_size = 0
@ -181,7 +181,7 @@ local function tile_group(gs, cls, wa, orientation, fact, group)
local hints = {}
local i = c - group.first +1
geom[width] = size
geom[height] = math.floor(unused * fact[i] / total_fact)
geom[height] = math.max(1, math.floor(unused * fact[i] / total_fact))
geom[x] = group.coord
geom[y] = coord
gs[cls[c]] = geom

2
luaa.c
View File

@ -181,7 +181,7 @@ luaA_load_image(lua_State *L)
static int
luaA_set_preferred_icon_size(lua_State *L)
{
globalconf.preferred_icon_size = luaL_checknumber(L, 1);
globalconf.preferred_icon_size = luaA_checkinteger_range(L, 1, 0, UINT32_MAX);
return 0;
}

68
luaa.h
View File

@ -75,6 +75,18 @@ luaA_typerror(lua_State *L, int narg, const char *tname)
return luaL_argerror(L, narg, msg);
}
static inline int
luaA_rangerror(lua_State *L, int narg, double min, double max)
{
const char *msg = lua_pushfstring(L, "value in [%f, %f] expected, got %f",
min, max, (double) lua_tonumber(L, narg));
#if LUA_VERSION_NUM >= 502
luaL_traceback(L, L, NULL, 2);
lua_concat(L, 2);
#endif
return luaL_argerror(L, narg, msg);
}
static inline void
luaA_getuservalue(lua_State *L, int idx)
{
@ -141,10 +153,37 @@ luaA_getopt_number(lua_State *L, int idx, const char *name, lua_Number def)
return def;
}
static inline lua_Number
luaA_checknumber_range(lua_State *L, int n, lua_Number min, lua_Number max)
{
lua_Number result = lua_tonumber(L, n);
if (result < min || result > max)
luaA_rangerror(L, n, min, max);
return result;
}
static inline lua_Number
luaA_optnumber_range(lua_State *L, int narg, lua_Number def, lua_Number min, lua_Number max)
{
if (lua_isnoneornil(L, narg))
return def;
return luaA_checknumber_range(L, narg, min, max);
}
static inline lua_Number
luaA_getopt_number_range(lua_State *L, int idx, const char *name, lua_Number def, lua_Number min, lua_Number max)
{
lua_getfield(L, idx, name);
if (lua_isnil(L, -1) || lua_isnumber(L, -1))
def = luaA_optnumber_range(L, -1, def, min, max);
lua_pop(L, 1);
return def;
}
static inline int
luaA_checkinteger(lua_State *L, int n)
{
double d = lua_tonumber(L, n);
lua_Number d = lua_tonumber(L, n);
if (d != (int)d)
luaA_typerror(L, n, "integer");
return d;
@ -166,6 +205,33 @@ luaA_getopt_integer(lua_State *L, int idx, const char *name, lua_Integer def)
return def;
}
static inline int
luaA_checkinteger_range(lua_State *L, int n, int min, int max)
{
int result = luaA_checkinteger(L, n);
if (result < min || result > max)
luaA_rangerror(L, n, min, max);
return result;
}
static inline lua_Integer
luaA_optinteger_range(lua_State *L, int narg, lua_Integer def, int min, int max)
{
if (lua_isnoneornil(L, narg))
return def;
return luaA_checkinteger_range(L, narg, min, max);
}
static inline int
luaA_getopt_integer_range(lua_State *L, int idx, const char *name, lua_Integer def, int min, int max)
{
lua_getfield(L, idx, name);
if (lua_isnil(L, -1) || lua_isnumber(L, -1))
def = luaA_optinteger_range(L, -1, def, min, max);
lua_pop(L, 1);
return def;
}
/** Push a area type to a table on stack.
* \param L The Lua VM state.
* \param geometry The area geometry to push.

View File

@ -31,6 +31,7 @@
#include "mouse.h"
#include "common/util.h"
#include "common/xutil.h"
#include "globalconf.h"
#include "objects/client.h"
#include "objects/drawin.h"
@ -111,7 +112,7 @@ mouse_query_pointer_root(int16_t *x, int16_t *y, xcb_window_t *child, uint16_t *
* \param y Y-coordinate inside window.
*/
static inline void
mouse_warp_pointer(xcb_window_t window, int x, int y)
mouse_warp_pointer(xcb_window_t window, int16_t x, int16_t y)
{
xcb_warp_pointer(globalconf.connection, XCB_NONE, window,
0, 0, 0, 0, x, y);
@ -223,8 +224,8 @@ luaA_mouse_coords(lua_State *L)
if(!mouse_query_pointer_root(&mouse_x, &mouse_y, NULL, &mask))
return 0;
x = luaA_getopt_number(L, 1, "x", mouse_x);
y = luaA_getopt_number(L, 1, "y", mouse_y);
x = luaA_getopt_integer_range(L, 1, "x", mouse_x, MIN_X11_COORDINATE, MAX_X11_COORDINATE);
y = luaA_getopt_integer_range(L, 1, "y", mouse_y, MIN_X11_COORDINATE, MAX_X11_COORDINATE);
if(ignore_enter_notify)
client_ignore_enterleave_events();

View File

@ -98,6 +98,8 @@
#include "systray.h"
#include "xwindow.h"
#include "math.h"
#include <xcb/xcb_atom.h>
#include <xcb/shape.h>
#include <cairo-xcb.h>
@ -2538,7 +2540,7 @@ luaA_client_titlebar_ ## name(lua_State *L) \
if (lua_isnil(L, 2)) \
titlebar_resize(L, 1, c, index, 0); \
else \
titlebar_resize(L, 1, c, index, luaL_checknumber(L, 2)); \
titlebar_resize(L, 1, c, index, ceil(luaA_checknumber_range(L, 2, 0, MAX_X11_SIZE))); \
} \
\
luaA_object_push_item(L, 1, titlebar_get_drawable(L, c, 1, index)); \
@ -2566,8 +2568,8 @@ luaA_client_geometry(lua_State *L)
area_t geometry;
luaA_checktable(L, 2);
geometry.x = luaA_getopt_number(L, 2, "x", c->geometry.x);
geometry.y = luaA_getopt_number(L, 2, "y", c->geometry.y);
geometry.x = round(luaA_getopt_number_range(L, 2, "x", c->geometry.x, MIN_X11_COORDINATE, MAX_X11_COORDINATE));
geometry.y = round(luaA_getopt_number_range(L, 2, "y", c->geometry.y, MIN_X11_COORDINATE, MAX_X11_COORDINATE));
if(client_isfixed(c))
{
geometry.width = c->geometry.width;
@ -2575,8 +2577,8 @@ luaA_client_geometry(lua_State *L)
}
else
{
geometry.width = luaA_getopt_number(L, 2, "width", c->geometry.width);
geometry.height = luaA_getopt_number(L, 2, "height", c->geometry.height);
geometry.width = ceil(luaA_getopt_number_range(L, 2, "width", c->geometry.width, MIN_X11_SIZE, MAX_X11_SIZE));
geometry.height = ceil(luaA_getopt_number_range(L, 2, "height", c->geometry.height, MIN_X11_SIZE, MAX_X11_SIZE));
}
client_resize(c, geometry, c->size_hints_honor);
@ -2600,8 +2602,8 @@ luaA_client_apply_size_hints(lua_State *L)
area_t geometry = c->geometry;
if(!client_isfixed(c))
{
geometry.width = luaL_checknumber(L, 2);
geometry.height = luaL_checknumber(L, 3);
geometry.width = ceil(luaA_checknumber_range(L, 2, MIN_X11_SIZE, MAX_X11_SIZE));
geometry.height = ceil(luaA_checknumber_range(L, 3, MIN_X11_SIZE, MAX_X11_SIZE));
}
if (c->size_hints_honor)

View File

@ -34,6 +34,7 @@
#include "drawin.h"
#include "common/atoms.h"
#include "common/xcursor.h"
#include "common/xutil.h"
#include "event.h"
#include "ewmh.h"
#include "objects/client.h"
@ -41,6 +42,8 @@
#include "systray.h"
#include "xwindow.h"
#include "math.h"
#include <cairo-xcb.h>
#include <xcb/shape.h>
@ -406,10 +409,10 @@ luaA_drawin_geometry(lua_State *L)
area_t wingeom;
luaA_checktable(L, 2);
wingeom.x = luaA_getopt_number(L, 2, "x", drawin->geometry.x);
wingeom.y = luaA_getopt_number(L, 2, "y", drawin->geometry.y);
wingeom.width = luaA_getopt_number(L, 2, "width", drawin->geometry.width);
wingeom.height = luaA_getopt_number(L, 2, "height", drawin->geometry.height);
wingeom.x = round(luaA_getopt_number_range(L, 2, "x", drawin->geometry.x, MIN_X11_COORDINATE, MAX_X11_COORDINATE));
wingeom.y = round(luaA_getopt_number_range(L, 2, "y", drawin->geometry.y, MIN_X11_COORDINATE, MAX_X11_COORDINATE));
wingeom.width = ceil(luaA_getopt_number_range(L, 2, "width", drawin->geometry.width, MIN_X11_SIZE, MAX_X11_SIZE));
wingeom.height = ceil(luaA_getopt_number_range(L, 2, "height", drawin->geometry.height, MIN_X11_SIZE, MAX_X11_SIZE));
if(wingeom.width > 0 && wingeom.height > 0)
drawin_moveresize(L, 1, wingeom);
@ -426,7 +429,8 @@ LUA_OBJECT_EXPORT_PROPERTY(drawin, drawin_t, visible, lua_pushboolean)
static int
luaA_drawin_set_x(lua_State *L, drawin_t *drawin)
{
drawin_moveresize(L, -3, (area_t) { .x = luaA_checkinteger(L, -1),
int x = round(luaA_checknumber_range(L, -1, MIN_X11_COORDINATE, MAX_X11_COORDINATE));
drawin_moveresize(L, -3, (area_t) { .x = x,
.y = drawin->geometry.y,
.width = drawin->geometry.width,
.height = drawin->geometry.height });
@ -443,8 +447,9 @@ luaA_drawin_get_x(lua_State *L, drawin_t *drawin)
static int
luaA_drawin_set_y(lua_State *L, drawin_t *drawin)
{
int y = round(luaA_checknumber_range(L, -1, MIN_X11_COORDINATE, MAX_X11_COORDINATE));
drawin_moveresize(L, -3, (area_t) { .x = drawin->geometry.x,
.y = luaA_checkinteger(L, -1),
.y = y,
.width = drawin->geometry.width,
.height = drawin->geometry.height });
return 0;
@ -460,9 +465,7 @@ luaA_drawin_get_y(lua_State *L, drawin_t *drawin)
static int
luaA_drawin_set_width(lua_State *L, drawin_t *drawin)
{
int width = luaA_checkinteger(L, -1);
if(width <= 0)
luaL_error(L, "invalid width");
int width = ceil(luaA_checknumber_range(L, -1, MIN_X11_SIZE, MAX_X11_SIZE));
drawin_moveresize(L, -3, (area_t) { .x = drawin->geometry.x,
.y = drawin->geometry.y,
.width = width,
@ -480,9 +483,7 @@ luaA_drawin_get_width(lua_State *L, drawin_t *drawin)
static int
luaA_drawin_set_height(lua_State *L, drawin_t *drawin)
{
int height = luaA_checkinteger(L, -1);
if(height <= 0)
luaL_error(L, "invalid height");
int height = ceil(luaA_checknumber_range(L, -1, MIN_X11_SIZE, MAX_X11_SIZE));
drawin_moveresize(L, -3, (area_t) { .x = drawin->geometry.x,
.y = drawin->geometry.y,
.width = drawin->geometry.width,

View File

@ -29,6 +29,7 @@
#include "objects/window.h"
#include "common/atoms.h"
#include "common/xutil.h"
#include "ewmh.h"
#include "property.h"
#include "xwindow.h"
@ -352,7 +353,7 @@ window_set_xproperty(lua_State *L, xcb_window_t window, int prop_idx, int value_
} else if(prop->type == PROP_NUMBER || prop->type == PROP_BOOLEAN)
{
if (prop->type == PROP_NUMBER)
number = luaL_checkinteger(L, value_idx);
number = luaA_checkinteger_range(L, value_idx, 0, UINT32_MAX);
else
number = luaA_checkboolean(L, value_idx);
data = &number;
@ -475,7 +476,7 @@ window_translate_type(window_type_t type)
static int
luaA_window_set_border_width(lua_State *L, window_t *c)
{
window_set_border_width(L, -3, luaL_checknumber(L, -1));
window_set_border_width(L, -3, round(luaA_checknumber_range(L, -1, 0, MAX_X11_SIZE)));
return 0;
}

View File

@ -26,6 +26,7 @@
#include "common/luaclass.h"
#include "objects/button.h"
#include "strut.h"
#include "math.h"
/** Windows type */
typedef enum

7
root.c
View File

@ -30,9 +30,12 @@
#include "common/atoms.h"
#include "common/xcursor.h"
#include "common/xutil.h"
#include "objects/button.h"
#include "xwindow.h"
#include "math.h"
#include <xcb/xtest.h>
#include <xcb/xcb_aux.h>
#include <cairo-xcb.h>
@ -265,8 +268,8 @@ luaA_root_fake_input(lua_State *L)
{
type = XCB_MOTION_NOTIFY;
detail = luaA_checkboolean(L, 2); /* relative to the current position or not */
x = luaL_checkinteger(L, 3);
y = luaL_checkinteger(L, 4);
x = round(luaA_checknumber_range(L, 3, MIN_X11_COORDINATE, MAX_X11_COORDINATE));
y = round(luaA_checknumber_range(L, 4, MIN_X11_COORDINATE, MAX_X11_COORDINATE));
}
else
return 0;

View File

@ -21,6 +21,7 @@
#include "strut.h"
#include "luaa.h"
#include "math.h"
/** Push a strut type to a table on stack.
* \param L The Lua VM state.
@ -51,10 +52,10 @@ void
luaA_tostrut(lua_State *L, int idx, strut_t *strut)
{
luaA_checktable(L, idx);
strut->left = luaA_getopt_integer(L, idx, "left", strut->left);
strut->right = luaA_getopt_integer(L, idx, "right", strut->right);
strut->top = luaA_getopt_integer(L, idx, "top", strut->top);
strut->bottom = luaA_getopt_integer(L, idx, "bottom", strut->bottom);
strut->left = ceil(luaA_getopt_number_range(L, idx, "left", strut->left, 0, UINT16_MAX));
strut->right = ceil(luaA_getopt_number_range(L, idx, "right", strut->right, 0, UINT16_MAX));
strut->top = ceil(luaA_getopt_number_range(L, idx, "top", strut->top, 0, UINT16_MAX));
strut->bottom = ceil(luaA_getopt_number_range(L, idx, "bottom", strut->bottom, 0, UINT16_MAX));
}
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80

View File

@ -21,6 +21,7 @@
#include "systray.h"
#include "common/atoms.h"
#include "common/xutil.h"
#include "objects/drawin.h"
#include "xwindow.h"
#include "globalconf.h"
@ -324,13 +325,13 @@ luaA_systray(lua_State *L)
{
size_t bg_len;
drawin_t *w = luaA_checkudata(L, 1, &drawin_class);
int x = luaL_checkinteger(L, 2);
int y = luaL_checkinteger(L, 3);
int base_size = luaL_checkinteger(L, 4);
int x = round(luaA_checknumber_range(L, 2, MIN_X11_COORDINATE, MAX_X11_COORDINATE));
int y = round(luaA_checknumber_range(L, 3, MIN_X11_COORDINATE, MAX_X11_COORDINATE));
int base_size = ceil(luaA_checknumber_range(L, 4, MIN_X11_SIZE, MAX_X11_SIZE));
bool horiz = lua_toboolean(L, 5);
const char *bg = luaL_checklstring(L, 6, &bg_len);
bool revers = lua_toboolean(L, 7);
int spacing = luaL_checkinteger(L, 8);
int spacing = ceil(luaA_checknumber_range(L, 8, 0, MAX_X11_COORDINATE));
color_t bg_color;
bool force_redraw = false;

122
tests/test-awful-layout.lua Normal file
View File

@ -0,0 +1,122 @@
-- This test hit the client layout code paths to see if there is errors.
-- it doesn't check if the layout are correct.
local awful = require("awful")
local first_layout = nil
local t = nil
local has_spawned = false
local steps = {
-- Add enough clients
function(count)
if count <= 1 and not has_spawned then
for _=1, 5 do awful.spawn("xterm") end
has_spawned = true
elseif #client.get() >= 5 then
first_layout = client.focus:tags()[1].layout
t = client.focus:tags()[1]
return true
end
end,
}
local function next_layout()
awful.layout.inc(1)
assert(client.focus:tags()[1].layout ~= first_layout)
return true
end
-- Test most properties for each layouts
local common_steps = {
function()
assert(#t:clients() == 5)
t.master_count = 2
return true
end,
function()
t.master_count = 0
return true
end,
function()
t.master_count = 6 --more than #client.get(1)
return true
end,
function()
t.master_count = 1
return true
end,
function()
t.column_count = 2
return true
end,
function()
t.column_count = 6 --more than #client.get(1)
return true
end,
function()
t.column_count = 1
return true
end,
function()
t.master_fill_policy = t.master_fill_policy == "mwfact" and
"expand" or "mwfact"
return true
end,
function()
t.master_width_factor = 0.75
return true
end,
function()
t.master_width_factor = 0
return true
end,
function()
t.master_width_factor = 1
return true
end,
function()
t.master_width_factor = 0.5
return true
end,
function()
t.gap = t.gap == 0 and 5 or 0
return true
end,
}
local first = false
for _ in ipairs(awful.layout.layouts) do
if not first then
first = true
else
awful.util.table.merge(steps, {next_layout})
end
awful.util.table.merge(steps, common_steps)
end
require("_runner").run_steps(steps)