Fix bugs and add unit tests for BSEARCH()
Also adds running unit tests to the release/go script so we can be sure that all tests pass before we make a release.
This commit is contained in:
parent
4c07127074
commit
047a201498
7 changed files with 535 additions and 46 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -5,6 +5,7 @@ Makefile.in
|
||||||
aclocal.m4
|
aclocal.m4
|
||||||
autom4te.cache
|
autom4te.cache
|
||||||
compile
|
compile
|
||||||
|
config.cache
|
||||||
config.guess
|
config.guess
|
||||||
config.log
|
config.log
|
||||||
config.rpath
|
config.rpath
|
||||||
|
@ -107,3 +108,4 @@ obt/tests/bstest
|
||||||
obt/tests/ddtest
|
obt/tests/ddtest
|
||||||
obt/tests/linktest
|
obt/tests/linktest
|
||||||
obt/tests/watchtest
|
obt/tests/watchtest
|
||||||
|
obt/obt_unittests
|
||||||
|
|
18
Makefile.am
18
Makefile.am
|
@ -36,6 +36,9 @@ bin_PROGRAMS = \
|
||||||
tools/gnome-panel-control/gnome-panel-control \
|
tools/gnome-panel-control/gnome-panel-control \
|
||||||
tools/obxprop/obxprop
|
tools/obxprop/obxprop
|
||||||
|
|
||||||
|
noinst_PROGRAMS = \
|
||||||
|
obt/obt_unittests
|
||||||
|
|
||||||
nodist_bin_SCRIPTS = \
|
nodist_bin_SCRIPTS = \
|
||||||
data/xsession/openbox-session \
|
data/xsession/openbox-session \
|
||||||
data/xsession/openbox-gnome-session \
|
data/xsession/openbox-gnome-session \
|
||||||
|
@ -308,6 +311,21 @@ openbox_openbox_SOURCES = \
|
||||||
openbox/window.c \
|
openbox/window.c \
|
||||||
openbox/window.h
|
openbox/window.h
|
||||||
|
|
||||||
|
## obt_unittests ##
|
||||||
|
|
||||||
|
obt_obt_unittests_CPPFLAGS = \
|
||||||
|
$(GLIB_CFLAGS) \
|
||||||
|
-DLOCALEDIR=\"$(localedir)\" \
|
||||||
|
-DDATADIR=\"$(datadir)\" \
|
||||||
|
-DCONFIGDIR=\"$(configdir)\" \
|
||||||
|
-DG_LOG_DOMAIN=\"Obt-Unittests\"
|
||||||
|
obt_obt_unittests_LDADD = \
|
||||||
|
$(GLIB_LIBS) \
|
||||||
|
obt/libobt.la
|
||||||
|
obt_obt_unittests_LDFLAGS = -export-dynamic
|
||||||
|
obt_obt_unittests_SOURCES = \
|
||||||
|
obt/unittest_base.c \
|
||||||
|
obt/bsearch_unittest.c
|
||||||
|
|
||||||
## gnome-panel-control ##
|
## gnome-panel-control ##
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,8 @@ G_BEGIN_DECLS
|
||||||
|
|
||||||
/*! Setup to do a binary search on an array. */
|
/*! Setup to do a binary search on an array. */
|
||||||
#define BSEARCH_SETUP() \
|
#define BSEARCH_SETUP() \
|
||||||
register guint l_BSEARCH, r_BSEARCH, out_BSEARCH;
|
register guint l_BSEARCH, r_BSEARCH, out_BSEARCH; \
|
||||||
|
register gboolean nearest_BSEARCH; (void)nearest_BSEARCH;
|
||||||
|
|
||||||
/*! Helper macro that just returns the input */
|
/*! Helper macro that just returns the input */
|
||||||
#define BSEARCH_IS_T(t) (t)
|
#define BSEARCH_IS_T(t) (t)
|
||||||
|
@ -37,11 +38,21 @@ G_BEGIN_DECLS
|
||||||
|
|
||||||
/*! Search an array @ar, starting at index @start,
|
/*! Search an array @ar, starting at index @start,
|
||||||
with @size elements, looking for value @val of type @t,
|
with @size elements, looking for value @val of type @t,
|
||||||
using the macro @to_t to convert values in the arrau @ar to type @t.*/
|
using the macro @to_t to convert values in the arrau @ar to type @t.
|
||||||
|
|
||||||
|
If all elements in @ar are less than @val, then BSEARCH_AT() will be
|
||||||
|
the last element in @ar.
|
||||||
|
If all elements in @ar are greater than @val, then BSEARCH_AT() will be
|
||||||
|
the first element in @ar.
|
||||||
|
Otherwise, if the element @val is not found then BSEARCH_AT() will be set to
|
||||||
|
the position before the first element larger than @val.
|
||||||
|
*/
|
||||||
#define BSEARCH_CMP(t, ar, start, size, val, to_t) \
|
#define BSEARCH_CMP(t, ar, start, size, val, to_t) \
|
||||||
{ \
|
do { \
|
||||||
l_BSEARCH = (start); \
|
out_BSEARCH = (start); \
|
||||||
r_BSEARCH = (start)+(size)-1; \
|
l_BSEARCH = (size) > 0 ? (start) : (start + 1); \
|
||||||
|
r_BSEARCH = (size) > 0 ? (start)+(size)-1 : (start); \
|
||||||
|
nearest_BSEARCH = FALSE; \
|
||||||
while (l_BSEARCH <= r_BSEARCH) { \
|
while (l_BSEARCH <= r_BSEARCH) { \
|
||||||
/* m is in the middle, but to the left if there's an even number \
|
/* m is in the middle, but to the left if there's an even number \
|
||||||
of elements */ \
|
of elements */ \
|
||||||
|
@ -49,21 +60,44 @@ G_BEGIN_DECLS
|
||||||
if ((val) == to_t((ar)[out_BSEARCH])) { \
|
if ((val) == to_t((ar)[out_BSEARCH])) { \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
else if ((val) < to_t((ar)[out_BSEARCH]) && out_BSEARCH > 0) { \
|
else if ((val) < to_t((ar)[out_BSEARCH])) { \
|
||||||
r_BSEARCH = out_BSEARCH-1; /* search to the left side */ \
|
if (out_BSEARCH > start) { \
|
||||||
|
r_BSEARCH = out_BSEARCH-1; /* search to the left side */ \
|
||||||
|
} else { \
|
||||||
|
/* reached the start of the array */ \
|
||||||
|
r_BSEARCH = out_BSEARCH; \
|
||||||
|
l_BSEARCH = out_BSEARCH + 1; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
else { \
|
||||||
|
l_BSEARCH = out_BSEARCH+1; /* search to the right side */ \
|
||||||
} \
|
} \
|
||||||
else \
|
|
||||||
l_BSEARCH = out_BSEARCH+1; /* search to the left side */ \
|
|
||||||
} \
|
} \
|
||||||
}
|
if ((size) > 0 && (val) != to_t((ar)[out_BSEARCH])) { \
|
||||||
|
if ((val) > to_t((ar)[out_BSEARCH])) { \
|
||||||
|
nearest_BSEARCH = TRUE; \
|
||||||
|
} \
|
||||||
|
else if (out_BSEARCH > start) { \
|
||||||
|
--out_BSEARCH; \
|
||||||
|
nearest_BSEARCH = (val) > to_t((ar)[out_BSEARCH]); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/*! Returns true if the element last searched for was found in the array */
|
/*! Returns true if the element last searched for was found in the array */
|
||||||
#define BSEARCH_FOUND() (l_BSEARCH <= r_BSEARCH)
|
#define BSEARCH_FOUND() (l_BSEARCH <= r_BSEARCH)
|
||||||
|
|
||||||
/*! Returns the position in the array at which the element last searched for
|
/*! Returns the position in the array at which the element last searched for
|
||||||
was found. */
|
was found. */
|
||||||
#define BSEARCH_AT() (out_BSEARCH)
|
#define BSEARCH_AT() (out_BSEARCH)
|
||||||
|
|
||||||
|
/*! Returns true if the element at BSEARCH_AT() in the array is the largest
|
||||||
|
value in the array smaller than the search key. Returns false if there was
|
||||||
|
nothing in the array smaller than the search key.
|
||||||
|
|
||||||
|
Should only be used when BSEARCH_FOUND() is false.
|
||||||
|
*/
|
||||||
|
#define BSEARCH_FOUND_NEAREST_SMALLER() (!BSEARCH_FOUND() && nearest_BSEARCH)
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
316
obt/bsearch_unittest.c
Normal file
316
obt/bsearch_unittest.c
Normal file
|
@ -0,0 +1,316 @@
|
||||||
|
#include "obt/unittest_base.h"
|
||||||
|
|
||||||
|
#include "obt/bsearch.h"
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
static void empty() {
|
||||||
|
TEST_START();
|
||||||
|
|
||||||
|
BSEARCH_SETUP();
|
||||||
|
int* array = NULL;
|
||||||
|
guint array_size = 0;
|
||||||
|
|
||||||
|
/* Search in an empty array. */
|
||||||
|
BSEARCH(int, array, 0, array_size, 10);
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(0, BSEARCH_AT());
|
||||||
|
|
||||||
|
/* Search in an empty array with a non-zero starting position. */
|
||||||
|
BSEARCH(int, array, 10, array_size, -10);
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(10, BSEARCH_AT());
|
||||||
|
|
||||||
|
TEST_END();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void single_element() {
|
||||||
|
TEST_START();
|
||||||
|
|
||||||
|
BSEARCH_SETUP();
|
||||||
|
int array[1];
|
||||||
|
guint array_size = 1;
|
||||||
|
|
||||||
|
/* Search for something smaller than the only element. */
|
||||||
|
array[0] = 20;
|
||||||
|
BSEARCH(int, array, 0, array_size, -10);
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(0, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
/* Search for something bigger than the only element. */
|
||||||
|
array[0] = 20;
|
||||||
|
BSEARCH(int, array, 0, array_size, 30);
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(0, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(TRUE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
/* Search for something smaller than the only element. */
|
||||||
|
array[0] = -20;
|
||||||
|
BSEARCH(int, array, 0, array_size, -30);
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(0, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
/* Search for something bigger than the only element. */
|
||||||
|
array[0] = -20;
|
||||||
|
BSEARCH(int, array, 0, array_size, 10);
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(0, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(TRUE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
/* Search for the only element that exists. */
|
||||||
|
array[0] = -20;
|
||||||
|
BSEARCH(int, array, 0, array_size, -20);
|
||||||
|
EXPECT_BOOL_EQ(TRUE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(0, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
TEST_END();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void single_element_nonzero_start() {
|
||||||
|
TEST_START();
|
||||||
|
|
||||||
|
BSEARCH_SETUP();
|
||||||
|
int array[10];
|
||||||
|
guint array_start = 9;
|
||||||
|
guint array_size = 1;
|
||||||
|
|
||||||
|
/* Search for something smaller than the only element. */
|
||||||
|
array[array_start] = 20;
|
||||||
|
BSEARCH(int, array, array_start, array_size, -10);
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(array_start, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
/* Search for something bigger than the only element. */
|
||||||
|
array[array_start] = 20;
|
||||||
|
BSEARCH(int, array, array_start, array_size, 30);
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(array_start, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(TRUE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
/* Search for something smaller than the only element. */
|
||||||
|
array[array_start] = -20;
|
||||||
|
BSEARCH(int, array, array_start, array_size, -30);
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(array_start, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
/* Search for something bigger than the only element. */
|
||||||
|
array[array_start] = -20;
|
||||||
|
BSEARCH(int, array, array_start, array_size, 10);
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(array_start, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(TRUE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
/* Search for the only element that exists. */
|
||||||
|
array[array_start] = -20;
|
||||||
|
BSEARCH(int, array, array_start, array_size, -20);
|
||||||
|
EXPECT_BOOL_EQ(TRUE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(array_start, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
TEST_END();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void present() {
|
||||||
|
TEST_START();
|
||||||
|
|
||||||
|
BSEARCH_SETUP();
|
||||||
|
int array[5];
|
||||||
|
guint array_start = 0;
|
||||||
|
guint array_size = 5;
|
||||||
|
|
||||||
|
array[0] = 10;
|
||||||
|
array[1] = 12;
|
||||||
|
array[2] = 14;
|
||||||
|
array[3] = 16;
|
||||||
|
array[4] = 18;
|
||||||
|
|
||||||
|
/* Search for something that is in the array. */
|
||||||
|
|
||||||
|
BSEARCH(int, array, array_start, array_size, 10);
|
||||||
|
EXPECT_BOOL_EQ(TRUE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(0, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
BSEARCH(int, array, array_start, array_size, 12);
|
||||||
|
EXPECT_BOOL_EQ(TRUE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(1, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
BSEARCH(int, array, array_start, array_size, 14);
|
||||||
|
EXPECT_BOOL_EQ(TRUE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(2, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
BSEARCH(int, array, array_start, array_size, 16);
|
||||||
|
EXPECT_BOOL_EQ(TRUE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(3, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
BSEARCH(int, array, array_start, array_size, 18);
|
||||||
|
EXPECT_BOOL_EQ(TRUE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(4, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
TEST_END();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void present_nonzero_start() {
|
||||||
|
TEST_START();
|
||||||
|
|
||||||
|
BSEARCH_SETUP();
|
||||||
|
int array[5];
|
||||||
|
guint array_start = 2;
|
||||||
|
guint array_size = 3;
|
||||||
|
|
||||||
|
array[0] = 10;
|
||||||
|
array[1] = 12;
|
||||||
|
array[2] = 14;
|
||||||
|
array[3] = 16;
|
||||||
|
array[4] = 18;
|
||||||
|
|
||||||
|
/* Search for something that is in the array. */
|
||||||
|
|
||||||
|
BSEARCH(int, array, array_start, array_size, 10);
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(array_start, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
BSEARCH(int, array, array_start, array_size, 12);
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(array_start, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
BSEARCH(int, array, array_start, array_size, 14);
|
||||||
|
EXPECT_BOOL_EQ(TRUE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(2, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
BSEARCH(int, array, array_start, array_size, 16);
|
||||||
|
EXPECT_BOOL_EQ(TRUE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(3, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
BSEARCH(int, array, array_start, array_size, 18);
|
||||||
|
EXPECT_BOOL_EQ(TRUE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(4, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
TEST_END();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void missing() {
|
||||||
|
TEST_START();
|
||||||
|
|
||||||
|
BSEARCH_SETUP();
|
||||||
|
int array[5];
|
||||||
|
guint array_start = 0;
|
||||||
|
guint array_size = 5;
|
||||||
|
|
||||||
|
array[0] = 10;
|
||||||
|
array[1] = 12;
|
||||||
|
array[2] = 14;
|
||||||
|
array[3] = 16;
|
||||||
|
array[4] = 18;
|
||||||
|
|
||||||
|
/* Search for something that is _not_ in the array. */
|
||||||
|
|
||||||
|
BSEARCH(int, array, array_start, array_size, 9);
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(0, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
BSEARCH(int, array, array_start, array_size, 11);
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(0, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(TRUE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
BSEARCH(int, array, array_start, array_size, 13);
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(1, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(TRUE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
BSEARCH(int, array, array_start, array_size, 15);
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(2, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(TRUE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
BSEARCH(int, array, array_start, array_size, 17);
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(3, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(TRUE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
BSEARCH(int, array, array_start, array_size, 19);
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(4, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(TRUE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
TEST_END();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void missing_nonzero_start() {
|
||||||
|
TEST_START();
|
||||||
|
|
||||||
|
BSEARCH_SETUP();
|
||||||
|
int array[5];
|
||||||
|
guint array_start = 2;
|
||||||
|
guint array_size = 3;
|
||||||
|
|
||||||
|
array[0] = 10;
|
||||||
|
array[1] = 12;
|
||||||
|
array[2] = 14;
|
||||||
|
array[3] = 16;
|
||||||
|
array[4] = 18;
|
||||||
|
|
||||||
|
/* Search for something that is _not_ in the array. */
|
||||||
|
|
||||||
|
BSEARCH(int, array, array_start, array_size, 9);
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(array_start, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
BSEARCH(int, array, array_start, array_size, 11);
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(array_start, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
BSEARCH(int, array, array_start, array_size, 13);
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(array_start, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
BSEARCH(int, array, array_start, array_size, 15);
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(2, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(TRUE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
BSEARCH(int, array, array_start, array_size, 17);
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(3, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(TRUE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
BSEARCH(int, array, array_start, array_size, 19);
|
||||||
|
EXPECT_BOOL_EQ(FALSE, BSEARCH_FOUND());
|
||||||
|
EXPECT_UINT_EQ(4, BSEARCH_AT());
|
||||||
|
EXPECT_BOOL_EQ(TRUE, BSEARCH_FOUND_NEAREST_SMALLER());
|
||||||
|
|
||||||
|
TEST_END();
|
||||||
|
}
|
||||||
|
|
||||||
|
void run_bsearch_unittest() {
|
||||||
|
unittest_start_suite("bsearch");
|
||||||
|
|
||||||
|
empty();
|
||||||
|
single_element();
|
||||||
|
single_element_nonzero_start();
|
||||||
|
present();
|
||||||
|
present_nonzero_start();
|
||||||
|
missing();
|
||||||
|
missing_nonzero_start();
|
||||||
|
|
||||||
|
unittest_end_suite();
|
||||||
|
}
|
55
obt/unittest_base.c
Normal file
55
obt/unittest_base.c
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "obt/unittest_base.h"
|
||||||
|
|
||||||
|
guint g_test_failures = 0;
|
||||||
|
guint g_test_failures_at_test_start = 0;
|
||||||
|
const gchar* g_active_test_suite = NULL;
|
||||||
|
const gchar* g_active_test_name = NULL;
|
||||||
|
|
||||||
|
/* Add all test suites here. Keep them sorted. */
|
||||||
|
extern void run_bsearch_unittest();
|
||||||
|
|
||||||
|
gint main(gint argc, gchar **argv)
|
||||||
|
{
|
||||||
|
/* Add all test suites here. Keep them sorted. */
|
||||||
|
run_bsearch_unittest();
|
||||||
|
|
||||||
|
return g_test_failures == 0 ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void unittest_start_suite(const char* suite_name)
|
||||||
|
{
|
||||||
|
g_assert(g_active_test_suite == NULL);
|
||||||
|
g_active_test_suite = suite_name;
|
||||||
|
printf("[--------] %s\n", suite_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unittest_end_suite()
|
||||||
|
{
|
||||||
|
g_assert(g_active_test_suite);
|
||||||
|
printf("[--------] %s\n", g_active_test_suite);
|
||||||
|
printf("\n");
|
||||||
|
g_active_test_suite = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void unittest_start(const char* test_name)
|
||||||
|
{
|
||||||
|
g_test_failures_at_test_start = g_test_failures;
|
||||||
|
g_assert(g_active_test_name == NULL);
|
||||||
|
g_active_test_name = test_name;
|
||||||
|
printf("[ RUN ] %s.%s\n", g_active_test_suite, g_active_test_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unittest_end()
|
||||||
|
{
|
||||||
|
g_assert(g_active_test_name);
|
||||||
|
if (g_test_failures_at_test_start == g_test_failures) {
|
||||||
|
printf("[ OK ] %s.%s\n",
|
||||||
|
g_active_test_suite, g_active_test_name);
|
||||||
|
} else {
|
||||||
|
printf("[ FAILED ] %s.%s\n",
|
||||||
|
g_active_test_suite, g_active_test_name);
|
||||||
|
}
|
||||||
|
g_active_test_name = NULL;
|
||||||
|
}
|
65
obt/unittest_base.h
Normal file
65
obt/unittest_base.h
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
#ifndef __obt_unittest_base_h
|
||||||
|
#define __obt_unittest_base_h
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
extern guint g_test_failures;
|
||||||
|
extern guint g_test_failures_at_test_start;
|
||||||
|
extern const gchar* g_active_test_suite;
|
||||||
|
extern const gchar* g_active_test_name;
|
||||||
|
|
||||||
|
#define ADD_FAILURE() { ++g_test_failures; }
|
||||||
|
|
||||||
|
#define FAILURE_AT() \
|
||||||
|
fprintf(stderr, "Failure at %s:%u\n", __FILE__, __LINE__); \
|
||||||
|
ADD_FAILURE();
|
||||||
|
|
||||||
|
#define EXPECT_BOOL_EQ(expected, actual) \
|
||||||
|
if ((expected) != (actual)) { \
|
||||||
|
FAILURE_AT(); \
|
||||||
|
fprintf(stderr, "Expected: %s\nActual: %s\n", \
|
||||||
|
((expected) ? "true" : "false"), \
|
||||||
|
((actual) ? "true" : "false")); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EXPECT_CHAR_EQ(expected, actual) \
|
||||||
|
if ((expected) != (actual)) { \
|
||||||
|
FAILURE_AT(); \
|
||||||
|
fprintf(stderr, "Expected: %c\nActual: %c\n", (expected), (actual)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EXPECT_INT_EQ(expected, actual) \
|
||||||
|
if ((expected) != (actual)) { \
|
||||||
|
FAILURE_AT(); \
|
||||||
|
fprintf(stderr, "Expected: %d\nActual: %d\n", (expected), (actual)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EXPECT_UINT_EQ(expected, actual) \
|
||||||
|
if ((expected) != (actual)) { \
|
||||||
|
FAILURE_AT(); \
|
||||||
|
fprintf(stderr, "Expected: %u\nActual: %u\n", (expected), (actual)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EXPECT_STRING_EQ(expected, actual) \
|
||||||
|
if ((expected) != (actual)) { \
|
||||||
|
FAILURE_AT(); \
|
||||||
|
fprintf(stderr, "Expected: %s\nActual: %s\n", \
|
||||||
|
((expected) ? (expected) : "NULL"), \
|
||||||
|
((actual) ? (actual) : NULL)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
void unittest_start_suite(const char* suite_name);
|
||||||
|
void unittest_end_suite();
|
||||||
|
|
||||||
|
void unittest_start(const char* test_name);
|
||||||
|
void unittest_end();
|
||||||
|
|
||||||
|
#define TEST_START() unittest_start(__func__);
|
||||||
|
#define TEST_END() unittest_end();
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif
|
71
release/go
71
release/go
|
@ -10,6 +10,13 @@ help() {
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
build_and_test() {
|
||||||
|
style=$1
|
||||||
|
make >/dev/null 2>/dev/null || error "make failed ($style)"
|
||||||
|
./obt/obt_unittests > /dev/null || error "unittest failed ($style)"
|
||||||
|
make distclean >/dev/null || error "make distclean failed"
|
||||||
|
}
|
||||||
|
|
||||||
REV="$1"
|
REV="$1"
|
||||||
test -z "$REV" && help
|
test -z "$REV" && help
|
||||||
VERSION="$2"
|
VERSION="$2"
|
||||||
|
@ -33,84 +40,76 @@ test "$a" = "y" || error "aborted"
|
||||||
BAD_PO="$(grep Project-Id-Version po/en*.po|grep -v "openbox $VERSION\\\\n")"
|
BAD_PO="$(grep Project-Id-Version po/en*.po|grep -v "openbox $VERSION\\\\n")"
|
||||||
test -z "$BAD_PO" || error "wrong version in po files" "$BAD_PO"
|
test -z "$BAD_PO" || error "wrong version in po files" "$BAD_PO"
|
||||||
|
|
||||||
#### TEST COMPILATION ####
|
#### RESET THE REPO TO A CLEAN STATE ####
|
||||||
|
|
||||||
# check that it builds
|
|
||||||
./bootstrap >/dev/null || "bootstrap failed"
|
|
||||||
#CFLAGS="-Werror -isystem /usr/lib/glib-2.0" \
|
|
||||||
./configure -C --enable-debug >/dev/null || \
|
|
||||||
error "configure (with debug) failed"
|
|
||||||
make || error "make (with debug and Werror) failed"
|
|
||||||
git clean -f -x -d -q
|
git clean -f -x -d -q
|
||||||
|
|
||||||
# check that it builds with each optional featureset
|
#### TEST ALL OPTIONAL COMPILATION FLAGS ####
|
||||||
./bootstrap >/dev/null || "bootstrap failed"
|
|
||||||
|
|
||||||
|
# check that it builds
|
||||||
|
echo Bootstrapping
|
||||||
|
./bootstrap >/dev/null 2>/dev/null || "bootstrap failed"
|
||||||
|
|
||||||
|
echo Check compile with debug and all options enabled
|
||||||
|
CFLAGS="-Werror -isystem /usr/lib/glib-2.0" \
|
||||||
|
./configure -C --enable-debug >/dev/null || \
|
||||||
|
error "configure (with debug) failed"
|
||||||
|
build_and_test "with debug and Werror"
|
||||||
|
|
||||||
|
# check that it builds with each optional featureset
|
||||||
echo Check compile with all options enabled
|
echo Check compile with all options enabled
|
||||||
./configure -C >/dev/null || \
|
./configure -C >/dev/null || \
|
||||||
error "configure failed"
|
error "configure failed"
|
||||||
make >/dev/null 2>/dev/null || \
|
|
||||||
error "make failed"
|
|
||||||
grep "XKB 1" config.log >/dev/null || error "missing xkb extension"
|
grep "XKB 1" config.log >/dev/null || error "missing xkb extension"
|
||||||
grep "XRANDR 1" config.log >/dev/null || error "missing xrandr extension"
|
grep "XRANDR 1" config.log >/dev/null || error "missing xrandr extension"
|
||||||
grep "XINERAMA 1" config.log >/dev/null || error "missing xinerama extension"
|
grep "XINERAMA 1" config.log >/dev/null || error "missing xinerama extension"
|
||||||
grep "SYNC 1" config.log >/dev/null || error "missing sync extension"
|
grep "SYNC 1" config.log >/dev/null || error "missing sync extension"
|
||||||
make clean >/dev/null || error "make clean failed"
|
grep "USE_XCURSOR 1" config.log >/dev/null || error "missing xcursor extension"
|
||||||
|
grep "USE_IMLIB2 1" config.log >/dev/null || error "missing imlib2 library"
|
||||||
|
grep "USE_LIBRSVG 1" config.log >/dev/null || error "missing librsvg library"
|
||||||
|
grep "USE_SM 1" config.log >/dev/null || error "missing session management extension"
|
||||||
|
build_and_test
|
||||||
|
|
||||||
echo Check compile with startup notification disabled
|
echo Check compile with startup notification disabled
|
||||||
./configure -C --disable-startup-notification >/dev/null || \
|
./configure -C --disable-startup-notification >/dev/null || \
|
||||||
error "configure failed"
|
error "configure failed"
|
||||||
make >/dev/null 2>/dev/null || \
|
build_and_test "with --disable-startup-notification"
|
||||||
error "make (with --disable-startup-notification) failed"
|
|
||||||
make clean >/dev/null || error "make clean failed"
|
|
||||||
|
|
||||||
echo Check compile with xcursor disabled
|
echo Check compile with xcursor disabled
|
||||||
./configure -C --disable-xcursor >/dev/null || \
|
./configure -C --disable-xcursor >/dev/null || \
|
||||||
error "configure failed"
|
error "configure failed"
|
||||||
make >/dev/null 2>/dev/null || \
|
build_and_test "with --disable-xcursor"
|
||||||
error "make (with --disable-xcursor) failed"
|
|
||||||
make clean >/dev/null || error "make clean failed"
|
|
||||||
|
|
||||||
echo Check compile with imlib2 disabled
|
echo Check compile with imlib2 disabled
|
||||||
./configure -C --disable-imlib2 >/dev/null || \
|
./configure -C --disable-imlib2 >/dev/null || \
|
||||||
error "configure failed"
|
error "configure failed"
|
||||||
make >/dev/null 2>/dev/null || \
|
build_and_test "with --disable-imlib2"
|
||||||
error "make (with --disable-imlib2) failed"
|
|
||||||
make clean >/dev/null || error "make clean failed"
|
|
||||||
|
|
||||||
echo Check compile with librsvg disabled
|
echo Check compile with librsvg disabled
|
||||||
./configure -C --disable-imlib2 >/dev/null || \
|
./configure -C --disable-librsvg >/dev/null || \
|
||||||
error "configure failed"
|
error "configure failed"
|
||||||
make >/dev/null 2>/dev/null || \
|
build_and_test "with --disable-librsvg"
|
||||||
error "make (with --disable-librsvg) failed"
|
|
||||||
make clean >/dev/null || error "make clean failed"
|
|
||||||
|
|
||||||
echo Check compile with session management disabled
|
echo Check compile with session management disabled
|
||||||
./configure -C --disable-session-management >/dev/null || \
|
./configure -C --disable-session-management >/dev/null || \
|
||||||
error "configure failed"
|
error "configure failed"
|
||||||
make >/dev/null 2>/dev/null || \
|
build_and_test "with --disable-session-management"
|
||||||
error "make (with --disable-session-management) failed"
|
|
||||||
make clean >/dev/null || error "make clean failed"
|
|
||||||
|
|
||||||
echo Check compile with xkb disabled
|
echo Check compile with xkb disabled
|
||||||
./configure -C --disable-xkb >/dev/null || error "configure failed"
|
./configure -C --disable-xkb >/dev/null || error "configure failed"
|
||||||
make >/dev/null 2>/dev/null || error "make (with --disable-xkb) failed"
|
build_and_test "with --disable-xkb"
|
||||||
make clean >/dev/null || error "make clean failed"
|
|
||||||
|
|
||||||
echo Check compile with xrandr disabled
|
echo Check compile with xrandr disabled
|
||||||
./configure -C --disable-xrandr >/dev/null || error "configure failed"
|
./configure -C --disable-xrandr >/dev/null || error "configure failed"
|
||||||
make >/dev/null 2>/dev/null || error "make (with --disable-xrandr) failed"
|
build_and_test "with --disable-xrandr"
|
||||||
make clean >/dev/null || error "make clean failed"
|
|
||||||
|
|
||||||
echo Check compile with xinerama disabled
|
echo Check compile with xinerama disabled
|
||||||
./configure -C --disable-xinerama >/dev/null || error "configure failed"
|
./configure -C --disable-xinerama >/dev/null || error "configure failed"
|
||||||
make >/dev/null 2>/dev/null || error "make (with --disable-xinerama) failed"
|
build_and_test("with --disable-xinerama")
|
||||||
make clean >/dev/null || error "make clean failed"
|
|
||||||
|
|
||||||
echo Check compile with xsync disabled
|
echo Check compile with xsync disabled
|
||||||
./configure -C --disable-xsync >/dev/null || error "configure failed"
|
./configure -C --disable-xsync >/dev/null || error "configure failed"
|
||||||
make >/dev/null 2>/dev/null || error "make (with --disable-xsync) failed"
|
build_and_test("with --disable-xsync")
|
||||||
make clean >/dev/null || error "make clean failed"
|
|
||||||
|
|
||||||
# check that it installs sanely
|
# check that it installs sanely
|
||||||
echo Check installation correctness
|
echo Check installation correctness
|
||||||
|
|
Loading…
Reference in a new issue