Merge pull request #502 from bebehei/coveragereport

Coveragereport and test suite improvements
This commit is contained in:
Benedikt Heine 2018-11-18 13:34:57 +01:00 committed by GitHub
commit 0410a9369b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 183 additions and 126 deletions

20
.gitignore vendored
View File

@ -1,10 +1,16 @@
dunst
*.o
*.gcda
*.gcno
*.gcov
core
vgcore.*
dunst.1
org.knopwob.dunst.service
dunst.systemd.service
dunstify
test/test
docs/internal/html
/docs/dunst.1
/docs/internal/coverage
/docs/internal/html
/dunst
/dunstify
/dunst.systemd.service
/org.knopwob.dunst.service
/test/test

View File

@ -18,19 +18,22 @@ dist: trusty
sudo: false
language: c
git:
depth: false
before_install:
- pip install --user cpp-coveralls
script:
- CFLAGS="-Werror" make all dunstify test-valgrind doc-doxygen
- make clean
- CFLAGS="-Werror -fprofile-arcs -ftest-coverage -O0" make test
- CFLAGS="-Werror" make clean
- CFLAGS="-Werror" make test-coverage
matrix:
include:
- compiler: gcc
after_success:
- coveralls --exclude 'test'
- coveralls
- compiler: clang
after_success:
- coveralls --exclude 'test' --gcov llvm-cov --gcov-options gcov
- coveralls --gcov llvm-cov --gcov-options gcov

View File

@ -42,8 +42,8 @@ $(error "$(PKG_CONFIG) failed!")
endif
endif
CFLAGS := ${DEFAULT_CPPFLAGS} ${CPPFLAGS} ${DEFAULT_CFLAGS} ${CFLAGS} -I. ${INCS}
LDFLAGS := ${DEFAULT_LDFLAGS} ${LDFLAGS} -L. ${LIBS}
CFLAGS := ${DEFAULT_CPPFLAGS} ${CPPFLAGS} ${DEFAULT_CFLAGS} ${CFLAGS} ${INCS}
LDFLAGS := ${DEFAULT_LDFLAGS} ${LDFLAGS} ${LIBS}
SRC := $(sort $(shell find src/ -name '*.c'))
OBJ := ${SRC:.c=.o}
@ -69,23 +69,37 @@ dunst: ${OBJ} main.o
dunstify: dunstify.o
${CC} -o ${@} dunstify.o ${CFLAGS} ${LDFLAGS}
.PHONY: test test-valgrind
test: test/test
cd test && ./test
.PHONY: test test-valgrind test-coverage
test: test/test clean-coverage-run
./test/test
test-valgrind: test/test
cd ./test \
&& valgrind \
--suppressions=../.valgrind.suppressions \
--leak-check=full \
--show-leak-kinds=definite \
--errors-for-leak-kinds=definite \
--num-callers=40 \
--error-exitcode=123 \
./test
valgrind \
--suppressions=.valgrind.suppressions \
--leak-check=full \
--show-leak-kinds=definite \
--errors-for-leak-kinds=definite \
--num-callers=40 \
--error-exitcode=123 \
./test/test
test-coverage: CFLAGS += -fprofile-arcs -ftest-coverage -O0
test-coverage: test
test-coverage-report: test-coverage
mkdir -p docs/internal/coverage
gcovr \
-r . \
--exclude=test \
--html \
--html-details \
-o docs/internal/coverage/index.html
test/%.o: test/%.c src/%.c
${CC} -o $@ -c $< ${CFLAGS}
test/test: ${OBJ} ${TEST_OBJ}
${CC} -o ${@} ${TEST_OBJ} ${OBJ} ${CFLAGS} ${LDFLAGS}
${CC} -o ${@} ${TEST_OBJ} $(filter-out ${TEST_OBJ:test/%=src/%},${OBJ}) ${CFLAGS} ${LDFLAGS}
.PHONY: doc doc-doxygen
doc: docs/dunst.1
@ -104,8 +118,8 @@ service-systemd:
@sed "s|##PREFIX##|$(PREFIX)|" dunst.systemd.service.in > dunst.systemd.service
endif
.PHONY: clean clean-dunst clean-dunstify clean-doc clean-tests
clean: clean-dunst clean-dunstify clean-doc clean-tests
.PHONY: clean clean-dunst clean-dunstify clean-doc clean-tests clean-coverage clean-coverage-run
clean: clean-dunst clean-dunstify clean-doc clean-tests clean-coverage clean-coverage-run
clean-dunst:
rm -f dunst ${OBJ} main.o
@ -119,10 +133,19 @@ clean-dunstify:
clean-doc:
rm -f docs/dunst.1
rm -fr docs/internal/html
rm -fr docs/internal/coverage
clean-tests:
rm -f test/test test/*.o
clean-coverage: clean-coverage-run
find . -type f -name '*.gcno' -delete
find . -type f -name '*.gcna' -delete
# Cleans the coverage data before every run to not double count any lines
clean-coverage-run:
find . -type f -name '*.gcov' -delete
find . -type f -name '*.gcda' -delete
.PHONY: install install-dunst install-doc \
install-service install-service-dbus install-service-systemd \
uninstall \

View File

@ -12,7 +12,7 @@ struct settings defaults = {
.lowfgcolor = "#000000",
.format = "%s %b", /* default format */
.timeouts = { 10*G_USEC_PER_SEC, 10*G_USEC_PER_SEC, 0 }, /* low, normal, critical */
.timeouts = { S2US(10), S2US(10), S2US(0) }, /* low, normal, critical */
.icons = { "dialog-information", "dialog-information", "dialog-warning" }, /* low, normal, critical */
.transparency = 0, /* transparency */

View File

@ -4,17 +4,17 @@
#include <cairo.h>
#include <math.h>
#include <pango/pango-attributes.h>
#include <pango/pangocairo.h>
#include <pango/pango-font.h>
#include <pango/pango-layout.h>
#include <pango/pango-types.h>
#include <pango/pangocairo.h>
#include <stdlib.h>
#include "dunst.h"
#include "icon.h"
#include "log.h"
#include "markup.h"
#include "notification.h"
#include "log.h"
#include "queues.h"
#include "x11/x.h"

View File

@ -1,7 +1,7 @@
#ifndef DUNST_DRAW_H
#define DUNST_DRAW_H
#include "src/x11/x.h"
#include "x11/x.h"
extern struct window_x11 *win; // Temporary
void draw_setup(void);

View File

@ -2,13 +2,13 @@
#include "dunst.h"
#include <X11/Xlib.h>
#include <glib-unix.h>
#include <glib.h>
#include <glib-unix.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include "dbus.h"
#include "draw.h"
@ -22,12 +22,6 @@
#include "x11/screen.h"
#include "x11/x.h"
#ifndef VERSION
#define VERSION "version info needed"
#endif
/* index of colors fit to urgency level */
GMainLoop *mainloop = NULL;
/* misc functions */
@ -162,7 +156,7 @@ int dunst_main(int argc, char *argv[])
n->summary = g_strdup("startup");
n->body = g_strdup("dunst is up and running");
n->progress = -1;
n->timeout = 10 * G_USEC_PER_SEC;
n->timeout = S2US(10);
n->markup = MARKUP_NO;
n->urgency = URG_LOW;
notification_init(n);

View File

@ -3,10 +3,10 @@
#include "markup.h"
#include <assert.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "log.h"
#include "settings.h"

View File

@ -490,7 +490,7 @@ gint64 queues_get_next_datachange(gint64 time)
if (age > settings.show_age_threshold)
// sleep exactly until the next shift of the second happens
sleep = MIN(sleep, ((G_USEC_PER_SEC) - (age % (G_USEC_PER_SEC))));
sleep = MIN(sleep, (S2US(1) - (age % S2US(1))));
else if (n->timeout == 0 || ttl > settings.show_age_threshold)
sleep = MIN(sleep, settings.show_age_threshold);
}

View File

@ -6,15 +6,16 @@
#include <stdio.h>
#include <string.h>
#include "rules.h" // put before config.h to fix missing include
#include "config.h"
#include "dunst.h"
#include "log.h"
#include "notification.h"
#include "option_parser.h"
#include "rules.h"
#include "utils.h"
#include "x11/x.h"
#include "../config.h"
struct settings settings;
static const char *follow_mode_to_string(enum follow_mode f_mode)

View File

@ -170,7 +170,7 @@ gint64 string_to_time(const char *string)
LOG_W("Time: '%s': Unknown error.", string);
return 0;
} else if (errno == 0 && !*endptr) {
return val * G_USEC_PER_SEC;
return S2US(val);
}
// endptr may point to a separating space
@ -180,13 +180,13 @@ gint64 string_to_time(const char *string)
if (STRN_EQ(endptr, "ms", 2))
return val * 1000;
else if (STRN_EQ(endptr, "s", 1))
return val * G_USEC_PER_SEC;
return S2US(val);
else if (STRN_EQ(endptr, "m", 1))
return val * G_USEC_PER_SEC * 60;
return S2US(val) * 60;
else if (STRN_EQ(endptr, "h", 1))
return val * G_USEC_PER_SEC * 60 * 60;
return S2US(val) * 60 * 60;
else if (STRN_EQ(endptr, "d", 1))
return val * G_USEC_PER_SEC * 60 * 60 * 24;
return S2US(val) * 60 * 60 * 24;
else
return 0;
}
@ -205,7 +205,6 @@ gint64 time_monotonic_now(void)
#else
clock_gettime(CLOCK_MONOTONIC, &tv_now);
#endif
return (gint64)tv_now.tv_sec * G_USEC_PER_SEC
+ tv_now.tv_nsec / 1000;
return S2US(tv_now.tv_sec) + tv_now.tv_nsec / 1000;
}
/* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */

View File

@ -16,6 +16,9 @@
//! Test if string a and b are the same case-insensitively
#define STR_CASEQ(a, b) (strcasecmp(a, b) == 0)
//! Convert a second into the internal time representation
#define S2US(s) (((gint64)(s)) * 1000 * 1000)
/**
* Replaces all occurrences of the char \p needle with the char \p replacement in \p haystack.
*

View File

@ -1,12 +1,5 @@
#include "screen.h"
#include <X11/X.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xresource.h>
#include <X11/extensions/Xinerama.h>
#include <X11/extensions/Xrandr.h>
#include <X11/extensions/randr.h>
#include <assert.h>
#include <glib.h>
#include <locale.h>
@ -14,10 +7,17 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/extensions/randr.h>
#include <X11/extensions/Xinerama.h>
#include <X11/extensions/Xrandr.h>
#include <X11/Xatom.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xresource.h>
#include "src/log.h"
#include "src/settings.h"
#include "src/utils.h"
#include "../log.h"
#include "../settings.h"
#include "../utils.h"
#include "x.h"
struct screen_info *screens;

View File

@ -2,8 +2,8 @@
#ifndef DUNST_SCREEN_H
#define DUNST_SCREEN_H
#include <X11/Xlib.h>
#include <stdbool.h>
#include <X11/Xlib.h>
#define INRECT(x,y,rx,ry,rw,rh) ((x) >= (rx) && (x) < (rx)+(rw) && (y) >= (ry) && (y) < (ry)+(rh))

View File

@ -1,15 +1,9 @@
/* copyright 2013 Sascha Kruse and contributors (see LICENSE for licensing information) */
#include "x.h"
#include <X11/X.h>
#include <X11/XKBlib.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/shape.h>
#include <assert.h>
#include <cairo-xlib.h>
#include <cairo.h>
#include <cairo-xlib.h>
#include <glib-object.h>
#include <locale.h>
#include <math.h>
@ -18,17 +12,23 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <X11/extensions/shape.h>
#include <X11/Xatom.h>
#include <X11/X.h>
#include <X11/XKBlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "src/draw.h"
#include "src/dbus.h"
#include "src/dunst.h"
#include "src/log.h"
#include "src/markup.h"
#include "src/menu.h"
#include "src/notification.h"
#include "src/queues.h"
#include "src/settings.h"
#include "src/utils.h"
#include "../dbus.h"
#include "../draw.h"
#include "../dunst.h"
#include "../log.h"
#include "../markup.h"
#include "../menu.h"
#include "../notification.h"
#include "../queues.h"
#include "../settings.h"
#include "../utils.h"
#include "screen.h"

View File

@ -5,11 +5,11 @@
#define XLIB_ILLEGAL_ACCESS
#include <cairo.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/extensions/scrnsaver.h>
#include <glib.h>
#include <stdbool.h>
#include <X11/extensions/scrnsaver.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include "screen.h"
@ -22,7 +22,7 @@ struct keyboard_shortcut {
};
// Cyclical dependency
#include "src/settings.h"
#include "../settings.h"
struct window_x11;

View File

@ -1,9 +1,5 @@
#include "../src/icon.c"
#include "greatest.h"
#include "../src/icon.h"
#include "../src/utils.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <glib.h>
#define ICONPREFIX "/data/icons/path"
@ -14,24 +10,23 @@
#define IS_ICON_PNG(pb) 4 == gdk_pixbuf_get_width(pb)
#define IS_ICON_SVG(pb) 16 == gdk_pixbuf_get_width(pb)
extern const char *base;
TEST test_get_pixbuf_from_file_tilde(void)
{
char *cwd = g_get_current_dir();
const char *home = g_get_home_dir();
const char *iconpath = ICONPREFIX;
if (0 != strncmp(home, cwd, strlen(home))) {
g_free(cwd);
if (0 != strncmp(home, base, strlen(home))) {
SKIPm("Current directory is not a subdirectory from user's home."
" Cannot test iconpath tilde expansion.\n");
}
gchar *path = g_build_filename(cwd, iconpath, "valid", "icon1.svg", NULL);
gchar *path = g_build_filename(base, iconpath, "valid", "icon1.svg", NULL);
path = string_replace_at(path, 0, strlen(home), "~");
GdkPixbuf *pixbuf = get_pixbuf_from_file(path);
g_clear_pointer(&path, g_free);
g_clear_pointer(&cwd, g_free);
ASSERT(pixbuf);
ASSERTm("The wrong pixbuf is loaded in the icon file.", IS_ICON_SVG(pixbuf));
@ -41,14 +36,12 @@ TEST test_get_pixbuf_from_file_tilde(void)
TEST test_get_pixbuf_from_file_absolute(void)
{
char *cwd = g_get_current_dir();
const char *iconpath = ICONPREFIX;
gchar *path = g_build_filename(cwd, iconpath, "valid", "icon1.svg", NULL);
gchar *path = g_build_filename(base, iconpath, "valid", "icon1.svg", NULL);
GdkPixbuf *pixbuf = get_pixbuf_from_file(path);
g_clear_pointer(&path, g_free);
g_clear_pointer(&cwd, g_free);
ASSERT(pixbuf);
ASSERTm("The wrong pixbuf is loaded in the icon file.", IS_ICON_SVG(pixbuf));
@ -98,7 +91,7 @@ TEST test_get_pixbuf_from_icon_onlypng(void)
TEST test_get_pixbuf_from_icon_filename(void)
{
char *icon = string_append(g_get_current_dir(), "/data/icons/valid.png", NULL);
char *icon = g_strconcat(base, "/data/icons/valid.png", NULL);
GdkPixbuf *pixbuf = get_pixbuf_from_icon(icon);
ASSERT(pixbuf);
ASSERTm("PNG pixbuf isn't loaded", IS_ICON_PNG(pixbuf));
@ -110,24 +103,23 @@ TEST test_get_pixbuf_from_icon_filename(void)
TEST test_get_pixbuf_from_icon_fileuri(void)
{
char *curdir = g_get_current_dir();
char *icon = g_strconcat("file://", curdir,"/data/icons/valid.svg", NULL);
char *icon = g_strconcat("file://", base, "/data/icons/valid.svg", NULL);
GdkPixbuf *pixbuf = get_pixbuf_from_icon(icon);
ASSERT(pixbuf);
ASSERTm("SVG pixbuf isn't loaded", IS_ICON_SVG(pixbuf));
g_clear_pointer(&pixbuf, g_object_unref);
g_free(icon);
g_free(curdir);
PASS();
}
SUITE(suite_icon)
{
settings.icon_path =
"." ICONPREFIX "/invalid"
":." ICONPREFIX "/valid"
":." ICONPREFIX "/both";
settings.icon_path = g_strconcat(
base, ICONPREFIX "/invalid"
":", base, ICONPREFIX "/valid"
":", base, ICONPREFIX "/both",
NULL);
RUN_TEST(test_get_pixbuf_from_file_tilde);
RUN_TEST(test_get_pixbuf_from_file_absolute);
@ -138,6 +130,6 @@ SUITE(suite_icon)
RUN_TEST(test_get_pixbuf_from_icon_filename);
RUN_TEST(test_get_pixbuf_from_icon_fileuri);
settings.icon_path = NULL;
g_clear_pointer(&settings.icon_path, g_free);
}
/* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */

View File

@ -1,10 +1,6 @@
#include "../src/markup.c"
#include "greatest.h"
#include <stdbool.h>
#include <glib.h>
#include "src/markup.h"
TEST test_markup_strip(void)
{
char *ptr;

21
test/misc.c Normal file
View File

@ -0,0 +1,21 @@
#include "greatest.h"
// This actually tests the buildsystem to make sure,
// the build system hands over a correct version number
// This is not testable via macros
TEST assert_version_number(void)
{
ASSERTm("Version number is empty",
0 != strcmp(VERSION, ""));
ASSERTm("Version number is not seeded by git",
NULL == strstr(VERSION, "non-git"));
PASS();
}
SUITE(suite_misc)
{
RUN_TEST(assert_version_number);
}
/* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */

View File

@ -1,9 +1,10 @@
#include "../src/notification.c"
#include "greatest.h"
#include "src/notification.h"
#include "src/option_parser.h"
#include "src/settings.h"
#include <glib.h>
#include "../src/option_parser.h"
#include "../src/settings.h"
extern const char *base;
TEST test_notification_is_duplicate_field(char **field,
struct notification *a,
@ -119,7 +120,8 @@ TEST test_notification_referencing(void)
SUITE(suite_notification)
{
cmdline_load(0, NULL);
load_settings("data/dunstrc.default");
char *config_path = g_strconcat(base, "/data/dunstrc.default", NULL);
load_settings(config_path);
struct notification *a = notification_create();
a->appname = g_strdup("Test");
@ -146,6 +148,7 @@ SUITE(suite_notification)
RUN_TEST(test_notification_referencing);
g_clear_pointer(&settings.icon_path, g_free);
g_free(config_path);
}
/* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */

View File

@ -1,9 +1,7 @@
#include "../src/option_parser.c"
#include "greatest.h"
#include <stdbool.h>
#include <glib.h>
#include "src/option_parser.h"
extern const char *base;
TEST test_next_section(void)
{
@ -280,7 +278,8 @@ TEST test_option_get_bool(void)
SUITE(suite_option_parser)
{
FILE *config_file = fopen("data/test-ini", "r");
char *config_path = g_strconcat(base, "/data/test-ini", NULL);
FILE *config_file = fopen(config_path, "r");
if (!config_file) {
fputs("\nTest config file 'data/test-ini' couldn't be opened, failing.\n", stderr);
exit(1);
@ -314,6 +313,8 @@ SUITE(suite_option_parser)
RUN_TEST(test_option_get_int);
RUN_TEST(test_option_get_double);
RUN_TEST(test_option_get_bool);
g_free(config_path);
free_ini();
g_strfreev(argv);
fclose(config_file);

View File

@ -1,18 +1,31 @@
#include "greatest.h"
#include <errno.h>
#include <libgen.h>
#include <stdbool.h>
#include <stdlib.h>
#include "src/log.h"
#include "../src/log.h"
const char *base;
SUITE_EXTERN(suite_utils);
SUITE_EXTERN(suite_option_parser);
SUITE_EXTERN(suite_notification);
SUITE_EXTERN(suite_markup);
SUITE_EXTERN(suite_misc);
SUITE_EXTERN(suite_icon);
GREATEST_MAIN_DEFS();
int main(int argc, char *argv[]) {
char *prog = realpath(argv[0], NULL);
if (!prog) {
fprintf(stderr, "Cannot determine actual path of test executable: %s\n", strerror(errno));
exit(1);
}
base = dirname(prog);
// do not print out warning messages, when executing tests
dunst_log_init(true);
@ -21,7 +34,11 @@ int main(int argc, char *argv[]) {
RUN_SUITE(suite_option_parser);
RUN_SUITE(suite_notification);
RUN_SUITE(suite_markup);
RUN_SUITE(suite_misc);
RUN_SUITE(suite_icon);
GREATEST_MAIN_END();
base = NULL;
free(prog);
}
/* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */

View File

@ -1,7 +1,5 @@
#include "../src/utils.c"
#include "greatest.h"
#include "src/utils.h"
#include <glib.h>
TEST test_string_replace_char(void)
{