aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--test/meson.build17
-rw-r--r--test/test_cairo.c93
-rw-r--r--test/test_size.c138
-rw-r--r--test/test_strerror.c41
-rw-r--r--test/test_stub_hints.c18
-rw-r--r--test/test_view.c103
-rw-r--r--test/test_world.c50
7 files changed, 460 insertions, 0 deletions
diff --git a/test/meson.build b/test/meson.build
index 340a7dd..47ef87f 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -2,15 +2,23 @@ basic_tests = [
'realize',
'redisplay',
'show_hide',
+ 'size',
+ 'strerror',
'stub_hints',
'timer',
'update',
+ 'view',
+ 'world',
]
gl_tests = [
'gl_hints'
]
+cairo_tests = [
+ 'cairo'
+]
+
includes = [
'.',
'../include',
@@ -31,3 +39,12 @@ if opengl_dep.found()
dependencies: [pugl_dep, gl_backend_dep]))
endforeach
endif
+
+if cairo_dep.found()
+ foreach test : cairo_tests
+ test(test,
+ executable('test_' + test, 'test_@0@.c'.format(test),
+ include_directories: include_directories(includes),
+ dependencies: [pugl_dep, cairo_backend_dep]))
+ endforeach
+endif
diff --git a/test/test_cairo.c b/test/test_cairo.c
new file mode 100644
index 0000000..704a31d
--- /dev/null
+++ b/test/test_cairo.c
@@ -0,0 +1,93 @@
+/*
+ Copyright 2021 David Robillard <d@drobilla.net>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+// Tests that creating a view with a Cairo backend works
+
+#undef NDEBUG
+
+#include "test_utils.h"
+
+#include "pugl/cairo.h"
+#include "pugl/pugl.h"
+
+#include <cairo.h>
+
+#include <assert.h>
+#include <stdbool.h>
+
+typedef struct {
+ PuglWorld* world;
+ PuglView* view;
+ PuglTestOptions opts;
+ bool exposed;
+} PuglTest;
+
+static void
+onExpose(PuglView* const view, const PuglEventExpose* const event)
+{
+ cairo_t* const cr = (cairo_t*)puglGetContext(view);
+
+ assert(cr);
+
+ cairo_rectangle(cr, event->x, event->y, event->width, event->height);
+ cairo_set_source_rgb(cr, 0, 1, 0);
+ cairo_fill(cr);
+}
+
+static PuglStatus
+onEvent(PuglView* const view, const PuglEvent* const event)
+{
+ PuglTest* const test = (PuglTest*)puglGetHandle(view);
+
+ if (test->opts.verbose) {
+ printEvent(event, "Event: ", true);
+ }
+
+ if (event->type == PUGL_EXPOSE) {
+ onExpose(view, &event->expose);
+ test->exposed = true;
+ }
+
+ return PUGL_SUCCESS;
+}
+
+int
+main(int argc, char** argv)
+{
+ PuglWorld* const world = puglNewWorld(PUGL_PROGRAM, 0);
+ PuglView* const view = puglNewView(world);
+ const PuglTestOptions opts = puglParseTestOptions(&argc, &argv);
+ PuglTest test = {world, view, opts, false};
+
+ // Set up and show view
+ puglSetClassName(test.world, "Pugl Test");
+ puglSetHandle(test.view, &test);
+ puglSetBackend(test.view, puglCairoBackend());
+ puglSetEventFunc(test.view, onEvent);
+ puglSetDefaultSize(test.view, 512, 512);
+ puglShow(test.view);
+
+ // Drive event loop until the view gets exposed
+ while (!test.exposed) {
+ puglUpdate(test.world, -1.0);
+ }
+
+ // Tear down
+ puglFreeView(test.view);
+ puglFreeWorld(test.world);
+
+ return 0;
+}
diff --git a/test/test_size.c b/test/test_size.c
new file mode 100644
index 0000000..c811672
--- /dev/null
+++ b/test/test_size.c
@@ -0,0 +1,138 @@
+/*
+ Copyright 2021 David Robillard <d@drobilla.net>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+// Tests basic view setup
+
+#undef NDEBUG
+
+#include "test_utils.h"
+
+#include "pugl/pugl.h"
+#include "pugl/stub.h"
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+typedef enum {
+ START,
+ CREATED,
+ CONFIGURED,
+ MAPPED,
+ DESTROYED,
+} State;
+
+typedef struct {
+ PuglWorld* world;
+ PuglView* view;
+ PuglTestOptions opts;
+ State state;
+ PuglRect configuredRect;
+} PuglTest;
+
+static PuglStatus
+onEvent(PuglView* view, const PuglEvent* event)
+{
+ PuglTest* test = (PuglTest*)puglGetHandle(view);
+
+ if (test->opts.verbose) {
+ printEvent(event, "Event: ", true);
+ }
+
+ switch (event->type) {
+ case PUGL_CREATE:
+ assert(test->state == START);
+ test->state = CREATED;
+ break;
+ case PUGL_CONFIGURE:
+ if (test->state == CREATED) {
+ test->state = CONFIGURED;
+ }
+ test->configuredRect.x = event->configure.x;
+ test->configuredRect.y = event->configure.y;
+ test->configuredRect.width = event->configure.width;
+ test->configuredRect.height = event->configure.height;
+ break;
+ case PUGL_MAP:
+ test->state = MAPPED;
+ break;
+ case PUGL_DESTROY:
+ test->state = DESTROYED;
+ break;
+ default:
+ break;
+ }
+
+ return PUGL_SUCCESS;
+}
+
+int
+main(int argc, char** argv)
+{
+ static const int minSize = 256;
+ static const int defaultSize = 512;
+ static const int maxSize = 1024;
+
+ PuglTest test = {puglNewWorld(PUGL_PROGRAM, 0),
+ NULL,
+ puglParseTestOptions(&argc, &argv),
+ START,
+ {0.0, 0.0, 0.0, 0.0}};
+
+ // Set up view with size bounds and an aspect ratio
+ test.view = puglNewView(test.world);
+ puglSetClassName(test.world, "Pugl Test");
+ puglSetWindowTitle(test.view, "Pugl View Test");
+ puglSetBackend(test.view, puglStubBackend());
+ puglSetHandle(test.view, &test);
+ puglSetEventFunc(test.view, onEvent);
+ puglSetViewHint(test.view, PUGL_RESIZABLE, PUGL_TRUE);
+ puglSetMinSize(test.view, minSize, minSize);
+ puglSetDefaultSize(test.view, defaultSize, defaultSize);
+ puglSetMaxSize(test.view, maxSize, maxSize);
+ puglSetAspectRatio(test.view, 1, 1, 1, 1);
+
+ // Create and show window
+ assert(!puglRealize(test.view));
+ assert(!puglShow(test.view));
+ while (test.state < MAPPED) {
+ assert(!puglUpdate(test.world, -1.0));
+ }
+
+ // Check that the frame matches the last configure event
+ const PuglRect frame = puglGetFrame(test.view);
+ assert(frame.x == test.configuredRect.x);
+ assert(frame.y == test.configuredRect.y);
+ assert(frame.width == test.configuredRect.width);
+ assert(frame.height == test.configuredRect.height);
+
+#if defined(_WIN32) || defined(__APPLE__)
+ /* Some window managers on Linux (particularly tiling ones) just disregard
+ these hints entirely, so we only check that the size is in bounds on MacOS
+ and Windows where this is more or less universally supported. */
+
+ assert(frame.width >= minSize);
+ assert(frame.height >= minSize);
+ assert(frame.width <= maxSize);
+ assert(frame.height <= maxSize);
+#endif
+
+ // Tear down
+ puglFreeView(test.view);
+ puglFreeWorld(test.world);
+
+ return 0;
+}
diff --git a/test/test_strerror.c b/test/test_strerror.c
new file mode 100644
index 0000000..e87c226
--- /dev/null
+++ b/test/test_strerror.c
@@ -0,0 +1,41 @@
+/*
+ Copyright 2021 David Robillard <d@drobilla.net>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+// Tests puglStrerror
+
+#undef NDEBUG
+
+#include "pugl/pugl.h"
+
+#include <assert.h>
+#include <ctype.h>
+#include <string.h>
+
+int
+main(void)
+{
+ for (unsigned i = 0; i <= PUGL_UNSUPPORTED_TYPE; ++i) {
+ const char* const string = puglStrerror((PuglStatus)i);
+
+ assert(isupper(string[0]));
+ assert(string[strlen(string) - 1] != '.');
+ assert(strcmp(string, "Unknown error"));
+ }
+
+ assert(!strcmp(puglStrerror((PuglStatus)999), "Unknown error"));
+
+ return 0;
+}
diff --git a/test/test_stub_hints.c b/test/test_stub_hints.c
index 1cc1180..75c8052 100644
--- a/test/test_stub_hints.c
+++ b/test/test_stub_hints.c
@@ -55,6 +55,21 @@ main(void)
assert(!puglSetViewHint(view, PUGL_ALPHA_BITS, PUGL_DONT_CARE));
assert(!puglSetViewHint(view, PUGL_REFRESH_RATE, PUGL_DONT_CARE));
+ // Check failure to set PUGL_DONT_CARE for hints that don't support it
+ assert(puglSetViewHint(view, PUGL_USE_COMPAT_PROFILE, PUGL_DONT_CARE) ==
+ PUGL_BAD_PARAMETER);
+ assert(puglSetViewHint(view, PUGL_USE_DEBUG_CONTEXT, PUGL_DONT_CARE) ==
+ PUGL_BAD_PARAMETER);
+ assert(puglSetViewHint(view, PUGL_CONTEXT_VERSION_MAJOR, PUGL_DONT_CARE) ==
+ PUGL_BAD_PARAMETER);
+ assert(puglSetViewHint(view, PUGL_CONTEXT_VERSION_MINOR, PUGL_DONT_CARE) ==
+ PUGL_BAD_PARAMETER);
+ assert(puglSetViewHint(view, PUGL_SWAP_INTERVAL, PUGL_DONT_CARE) ==
+ PUGL_BAD_PARAMETER);
+
+ // Check failure to set out of range hints
+ assert(puglSetViewHint(view, (PuglViewHint)999, 1) == PUGL_BAD_PARAMETER);
+
// Realize view and print all hints for debugging convenience
assert(!puglRealize(view));
printViewHints(view);
@@ -72,6 +87,9 @@ main(void)
assert(puglGetViewHint(view, PUGL_IGNORE_KEY_REPEAT) != PUGL_DONT_CARE);
assert(puglGetViewHint(view, PUGL_REFRESH_RATE) != PUGL_DONT_CARE);
+ // Check failure to get out of range hints
+ assert(puglGetViewHint(view, (PuglViewHint)999) == PUGL_DONT_CARE);
+
// Tear down
puglFreeView(view);
puglFreeWorld(world);
diff --git a/test/test_view.c b/test/test_view.c
new file mode 100644
index 0000000..86182b7
--- /dev/null
+++ b/test/test_view.c
@@ -0,0 +1,103 @@
+/*
+ Copyright 2021 David Robillard <d@drobilla.net>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+// Tests basic view setup
+
+#undef NDEBUG
+
+#include "test_utils.h"
+
+#include "pugl/pugl.h"
+#include "pugl/stub.h"
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+typedef enum {
+ START,
+ CREATED,
+ MAPPED,
+ DESTROYED,
+} State;
+
+typedef struct {
+ PuglWorld* world;
+ PuglView* view;
+ PuglTestOptions opts;
+ State state;
+} PuglTest;
+
+static PuglStatus
+onEvent(PuglView* view, const PuglEvent* event)
+{
+ PuglTest* test = (PuglTest*)puglGetHandle(view);
+
+ if (test->opts.verbose) {
+ printEvent(event, "Event: ", true);
+ }
+
+ switch (event->type) {
+ case PUGL_CREATE:
+ assert(test->state == START);
+ test->state = CREATED;
+ break;
+ case PUGL_MAP:
+ test->state = MAPPED;
+ break;
+ case PUGL_DESTROY:
+ test->state = DESTROYED;
+ break;
+ default:
+ break;
+ }
+
+ return PUGL_SUCCESS;
+}
+
+int
+main(int argc, char** argv)
+{
+ PuglTest test = {puglNewWorld(PUGL_PROGRAM, 0),
+ NULL,
+ puglParseTestOptions(&argc, &argv),
+ START};
+
+ // Set up view
+ test.view = puglNewView(test.world);
+ puglSetClassName(test.world, "Pugl Test");
+ puglSetWindowTitle(test.view, "Pugl View Test");
+ puglSetBackend(test.view, puglStubBackend());
+ puglSetHandle(test.view, &test);
+ puglSetEventFunc(test.view, onEvent);
+ puglSetDefaultSize(test.view, 512, 512);
+
+ // Create and show window
+ assert(!puglRealize(test.view));
+ assert(!puglShow(test.view));
+ while (test.state < MAPPED) {
+ assert(!puglUpdate(test.world, -1.0));
+ }
+
+ // Check that puglGetNativeWindow() returns something
+ assert(puglGetNativeWindow(test.view));
+
+ // Tear down
+ puglFreeView(test.view);
+ puglFreeWorld(test.world);
+
+ return 0;
+}
diff --git a/test/test_world.c b/test/test_world.c
new file mode 100644
index 0000000..2c5229f
--- /dev/null
+++ b/test/test_world.c
@@ -0,0 +1,50 @@
+/*
+ Copyright 2021 David Robillard <d@drobilla.net>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+/*
+ Tests basic functionality of, and access to, the world.
+*/
+
+#undef NDEBUG
+
+#include "pugl/pugl.h"
+
+#include <assert.h>
+#include <stdint.h>
+
+int
+main(void)
+{
+ PuglWorld* const world = puglNewWorld(PUGL_PROGRAM, 0);
+ PuglView* const view = puglNewView(world);
+
+ // Check that the world can be accessed from the view
+ assert(puglGetWorld(view) == world);
+
+ // Check that puglGetNativeWorld() returns something
+ assert(puglGetNativeWorld(world));
+
+ // Set and get world handle
+ uintptr_t data = 1234;
+ puglSetWorldHandle(world, &data);
+ assert(puglGetWorldHandle(world) == &data);
+
+ // Tear down
+ puglFreeView(view);
+ puglFreeWorld(world);
+
+ return 0;
+}