summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/options.rst17
-rw-r--r--options/options.c4
-rw-r--r--options/options.h1
-rw-r--r--player/main.c6
-rw-r--r--test/chmap.c86
-rw-r--r--test/chmap_sel.c136
-rw-r--r--test/gl_video.c28
-rw-r--r--test/index.c51
-rw-r--r--test/index.h29
-rw-r--r--test/json.c22
-rw-r--r--test/linked_list.c17
-rw-r--r--test/test_helpers.c29
-rw-r--r--test/test_helpers.h23
-rw-r--r--wscript10
-rw-r--r--wscript_build.py21
15 files changed, 271 insertions, 209 deletions
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index 27b24d0e98..4c208fe025 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -6184,3 +6184,20 @@ Miscellaneous
See the FFmpeg libavfilter documentation for details on the available
filters.
+
+Debugging
+---------
+
+``--unittest=<name>``
+ Run an internal unit test. There are multiple, and the name specifies which.
+
+ The special value ``all-simple`` runs all tests which do not need further
+ setup (other arguments and such). Some tests may need additional arguments
+ to do anything useful.
+
+ On success, the player binary exits with exit status 0, otherwise it returns
+ with an undefined non-0 exit status (it may crash or abort itself on test
+ failures).
+
+ This is only enabled if built with ``--enable-tests``, and should normally
+ be enabled and used by developers only.
diff --git a/options/options.c b/options/options.c
index 79ae3ca5ab..53cf82abd8 100644
--- a/options/options.c
+++ b/options/options.c
@@ -347,6 +347,10 @@ const m_option_t mp_opts[] = {
OPT_PRINT("version", print_version),
OPT_PRINT("V", print_version),
+#if HAVE_TESTS
+ OPT_STRING("unittest", test_mode, CONF_NOCFG | M_OPT_FIXED | M_OPT_NOPROP),
+#endif
+
OPT_CHOICE("player-operation-mode", operation_mode,
M_OPT_FIXED | M_OPT_PRE_PARSE | M_OPT_NOPROP,
({"cplayer", 0}, {"pseudo-gui", 1})),
diff --git a/options/options.h b/options/options.h
index 7af86ab9fb..2f7e368446 100644
--- a/options/options.h
+++ b/options/options.h
@@ -123,6 +123,7 @@ typedef struct MPOpts {
int msg_time;
char *log_file;
+ char *test_mode;
int operation_mode;
char **reset_options;
diff --git a/player/main.c b/player/main.c
index 70697a2a6e..8894988e99 100644
--- a/player/main.c
+++ b/player/main.c
@@ -56,6 +56,7 @@
#include "demux/demux.h"
#include "misc/thread_tools.h"
#include "sub/osd.h"
+#include "test/index.h"
#include "video/out/vo.h"
#include "core.h"
@@ -427,6 +428,11 @@ int mp_initialize(struct MPContext *mpctx, char **options)
if (opts->force_vo == 2 && handle_force_window(mpctx, false) < 0)
return -1;
+#if HAVE_TESTS
+ if (opts->test_mode && opts->test_mode[0])
+ return run_tests(mpctx) ? 1 : -1;
+#endif
+
MP_STATS(mpctx, "end init");
return 0;
diff --git a/test/chmap.c b/test/chmap.c
index 395b716b74..6484698f4c 100644
--- a/test/chmap.c
+++ b/test/chmap.c
@@ -1,9 +1,81 @@
-#include "test_helpers.h"
#include "audio/chmap.h"
+#include "audio/chmap_sel.h"
+#include "index.h"
+#include "test_helpers.h"
+
+#define LAYOUTS(...) (char*[]){__VA_ARGS__, NULL}
+
+static void test_sel(const char *input, const char *expected_selection,
+ char **layouts)
+{
+ struct mp_chmap_sel s = {0};
+ struct mp_chmap input_map;
+ struct mp_chmap expected_map;
+
+ assert_true(mp_chmap_from_str(&input_map, bstr0(input)));
+ assert_true(mp_chmap_from_str(&expected_map, bstr0(expected_selection)));
+
+ for (int n = 0; layouts[n]; n++) {
+ struct mp_chmap tmp;
+ assert_true(mp_chmap_from_str(&tmp, bstr0(layouts[n])));
+ int count = s.num_chmaps;
+ mp_chmap_sel_add_map(&s, &tmp);
+ assert_true(s.num_chmaps > count); // assure validity and max. count
+ }
+
+ assert_true(mp_chmap_sel_fallback(&s, &input_map));
+ // We convert expected_map to a chmap and then back to a string to avoid
+ // problems with ambiguous layouts.
+ assert_string_equal(mp_chmap_to_str(&input_map),
+ mp_chmap_to_str(&expected_map));
+}
-static void test_mp_chmap_diff(void **state) {
+static void run(void)
+{
struct mp_chmap a;
struct mp_chmap b;
+ struct mp_chmap_sel s = {0};
+
+ test_sel("5.1", "7.1", LAYOUTS("7.1"));
+ test_sel("7.1", "5.1", LAYOUTS("5.1"));
+ test_sel("7.1(wide-side)", "7.1", LAYOUTS("7.1"));
+ test_sel("7.1(wide-side)", "5.1(side)", LAYOUTS("7.1", "5.1(side)"));
+ test_sel("3.1", "5.1", LAYOUTS("7.1", "5.1", "2.1", "stereo", "mono"));
+ test_sel("5.1", "7.1(rear)", LAYOUTS("7.1(rear)"));
+ test_sel("5.1(side)", "5.1", LAYOUTS("5.1", "7.1"));
+ test_sel("5.1", "7.1(alsa)", LAYOUTS("7.1(alsa)"));
+ test_sel("mono", "stereo", LAYOUTS("stereo", "5.1"));
+ test_sel("stereo", "stereo", LAYOUTS("stereo", "5.1"));
+ test_sel("5.1(side)", "7.1(rear)", LAYOUTS("stereo", "7.1(rear)"));
+ test_sel("7.1", "fl-fr-lfe-fc-bl-br-flc-frc",
+ LAYOUTS("fl-fr-lfe-fc-bl-br-flc-frc", "3.0(back)"));
+
+ mp_chmap_set_unknown(&a, 2);
+
+ mp_chmap_from_str(&b, bstr0("5.1"));
+
+ mp_chmap_sel_add_map(&s, &a);
+ assert_false(mp_chmap_sel_fallback(&s, &b));
+ assert_string_equal(mp_chmap_to_str(&b), "5.1");
+
+ test_sel("quad", "quad(side)", LAYOUTS("quad(side)", "stereo"));
+ test_sel("quad", "quad(side)", LAYOUTS("quad(side)", "7.0"));
+ test_sel("quad", "quad(side)", LAYOUTS("7.0", "quad(side)"));
+ test_sel("quad", "7.1(wide-side)", LAYOUTS("7.1(wide-side)", "stereo"));
+ test_sel("quad", "7.1(wide-side)", LAYOUTS("stereo", "7.1(wide-side)"));
+ test_sel("quad", "fl-fr-sl-sr",
+ LAYOUTS("fl-fr-fc-bl-br", "fl-fr-sl-sr"));
+ test_sel("quad", "fl-fr-bl-br-na-na-na-na",
+ LAYOUTS("fl-fr-bl-br-na-na-na-na", "quad(side)", "stereo"));
+ test_sel("quad", "fl-fr-bl-br-na-na-na-na",
+ LAYOUTS("stereo", "quad(side)", "fl-fr-bl-br-na-na-na-na"));
+ test_sel("fl-fr-fc-lfe-sl-sr", "fl-fr-lfe-fc-bl-br-na-na",
+ LAYOUTS("fl-fr-lfe-fc-bl-br-na-na", "fl-fr-lfe-fc-bl-br-sdl-sdr"));
+ test_sel("fl-fr-fc-lfe-sl-sr", "fl-fr-lfe-fc-bl-br-na-na",
+ LAYOUTS("fl-fr-lfe-fc-bl-br-sdl-sdr", "fl-fr-lfe-fc-bl-br-na-na"));
+
+ test_sel("na-fl-fr", "na-fl-fr", LAYOUTS("na-fl-fr-na", "fl-na-fr", "na-fl-fr",
+ "fl-fr-na-na", "na-na-fl-fr"));
mp_chmap_from_str(&a, bstr0("3.1"));
mp_chmap_from_str(&b, bstr0("2.1"));
@@ -15,9 +87,7 @@ static void test_mp_chmap_diff(void **state) {
assert_int_equal(mp_chmap_diffn(&b, &a), 3);
}
-int main(void) {
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_mp_chmap_diff),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
+const struct unittest test_chmap = {
+ .name = "chmap",
+ .run_simple = run,
+};
diff --git a/test/chmap_sel.c b/test/chmap_sel.c
deleted file mode 100644
index 38a5254073..0000000000
--- a/test/chmap_sel.c
+++ /dev/null
@@ -1,136 +0,0 @@
-#include "test_helpers.h"
-#include "audio/chmap_sel.h"
-
-#define LAYOUTS(...) (char*[]){__VA_ARGS__, NULL}
-
-static void test_sel(const char *input, const char *expected_selection,
- char **layouts)
-{
- struct mp_chmap_sel s = {0};
- struct mp_chmap input_map;
- struct mp_chmap expected_map;
-
- assert_true(mp_chmap_from_str(&input_map, bstr0(input)));
- assert_true(mp_chmap_from_str(&expected_map, bstr0(expected_selection)));
-
- for (int n = 0; layouts[n]; n++) {
- struct mp_chmap tmp;
- assert_true(mp_chmap_from_str(&tmp, bstr0(layouts[n])));
- int count = s.num_chmaps;
- mp_chmap_sel_add_map(&s, &tmp);
- assert_true(s.num_chmaps > count); // assure validity and max. count
- }
-
- assert_true(mp_chmap_sel_fallback(&s, &input_map));
- // We convert expected_map to a chmap and then back to a string to avoid
- // problems with ambiguous layouts.
- assert_string_equal(mp_chmap_to_str(&input_map),
- mp_chmap_to_str(&expected_map));
-}
-
-static void test_mp_chmap_sel_fallback_upmix(void **state) {
- test_sel("5.1", "7.1", LAYOUTS("7.1"));
-}
-
-static void test_mp_chmap_sel_fallback_downmix(void **state) {
- test_sel("7.1", "5.1", LAYOUTS("5.1"));
-}
-
-static void test_mp_chmap_sel_fallback_incompatible(void **state) {
- test_sel("7.1(wide-side)", "7.1", LAYOUTS("7.1"));
-}
-
-static void test_mp_chmap_sel_fallback_prefer_compatible(void **state) {
- test_sel("7.1(wide-side)", "5.1(side)", LAYOUTS("7.1", "5.1(side)"));
-}
-
-static void test_mp_chmap_sel_fallback_prefer_closest_upmix(void **state) {
- test_sel("3.1", "5.1", LAYOUTS("7.1", "5.1", "2.1", "stereo", "mono"));
-}
-
-static void test_mp_chmap_sel_fallback_use_replacements(void **state) {
- test_sel("5.1", "7.1(rear)", LAYOUTS("7.1(rear)"));
-}
-
-static void test_mp_chmap_sel_fallback_inexact_equivalent(void **state) {
- test_sel("5.1(side)", "5.1", LAYOUTS("5.1", "7.1"));
-}
-
-static void test_mp_chmap_sel_fallback_works_on_alsa_chmaps(void **state) {
- test_sel("5.1", "7.1(alsa)", LAYOUTS("7.1(alsa)"));
-}
-
-static void test_mp_chmap_sel_fallback_mono_to_stereo(void **state) {
- test_sel("mono", "stereo", LAYOUTS("stereo", "5.1"));
-}
-
-static void test_mp_chmap_sel_fallback_stereo_to_stereo(void **state) {
- test_sel("stereo", "stereo", LAYOUTS("stereo", "5.1"));
-}
-
-static void test_mp_chmap_sel_fallback_no_downmix(void **state) {
- test_sel("5.1(side)", "7.1(rear)", LAYOUTS("stereo", "7.1(rear)"));
-}
-
-static void test_mp_chmap_sel_fallback_minimal_downmix(void **state) {
- test_sel("7.1", "fl-fr-lfe-fc-bl-br-flc-frc",
- LAYOUTS("fl-fr-lfe-fc-bl-br-flc-frc", "3.0(back)"));
-}
-
-static void test_mp_chmap_sel_fallback_reject_unknown(void **state) {
- struct mp_chmap a;
- struct mp_chmap b;
- struct mp_chmap_sel s = {0};
-
- mp_chmap_set_unknown(&a, 2);
-
- mp_chmap_from_str(&b, bstr0("5.1"));
-
- mp_chmap_sel_add_map(&s, &a);
- assert_false(mp_chmap_sel_fallback(&s, &b));
- assert_string_equal(mp_chmap_to_str(&b), "5.1");
-}
-
-static void test_mp_chmap_sel_fallback_more_replacements(void **state) {
- test_sel("quad", "quad(side)", LAYOUTS("quad(side)", "stereo"));
- test_sel("quad", "quad(side)", LAYOUTS("quad(side)", "7.0"));
- test_sel("quad", "quad(side)", LAYOUTS("7.0", "quad(side)"));
- test_sel("quad", "7.1(wide-side)", LAYOUTS("7.1(wide-side)", "stereo"));
- test_sel("quad", "7.1(wide-side)", LAYOUTS("stereo", "7.1(wide-side)"));
- test_sel("quad", "fl-fr-sl-sr",
- LAYOUTS("fl-fr-fc-bl-br", "fl-fr-sl-sr"));
- test_sel("quad", "fl-fr-bl-br-na-na-na-na",
- LAYOUTS("fl-fr-bl-br-na-na-na-na", "quad(side)", "stereo"));
- test_sel("quad", "fl-fr-bl-br-na-na-na-na",
- LAYOUTS("stereo", "quad(side)", "fl-fr-bl-br-na-na-na-na"));
- test_sel("fl-fr-fc-lfe-sl-sr", "fl-fr-lfe-fc-bl-br-na-na",
- LAYOUTS("fl-fr-lfe-fc-bl-br-na-na", "fl-fr-lfe-fc-bl-br-sdl-sdr"));
- test_sel("fl-fr-fc-lfe-sl-sr", "fl-fr-lfe-fc-bl-br-na-na",
- LAYOUTS("fl-fr-lfe-fc-bl-br-sdl-sdr", "fl-fr-lfe-fc-bl-br-na-na"));
-}
-
-static void test_mp_chmap_sel_fallback_na_channels(void **state) {
- test_sel("na-fl-fr", "na-fl-fr", LAYOUTS("na-fl-fr-na", "fl-na-fr", "na-fl-fr",
- "fl-fr-na-na", "na-na-fl-fr"));
-}
-
-int main(void) {
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_mp_chmap_sel_fallback_upmix),
- cmocka_unit_test(test_mp_chmap_sel_fallback_downmix),
- cmocka_unit_test(test_mp_chmap_sel_fallback_incompatible),
- cmocka_unit_test(test_mp_chmap_sel_fallback_prefer_compatible),
- cmocka_unit_test(test_mp_chmap_sel_fallback_prefer_closest_upmix),
- cmocka_unit_test(test_mp_chmap_sel_fallback_use_replacements),
- cmocka_unit_test(test_mp_chmap_sel_fallback_inexact_equivalent),
- cmocka_unit_test(test_mp_chmap_sel_fallback_works_on_alsa_chmaps),
- cmocka_unit_test(test_mp_chmap_sel_fallback_mono_to_stereo),
- cmocka_unit_test(test_mp_chmap_sel_fallback_stereo_to_stereo),
- cmocka_unit_test(test_mp_chmap_sel_fallback_no_downmix),
- cmocka_unit_test(test_mp_chmap_sel_fallback_minimal_downmix),
- cmocka_unit_test(test_mp_chmap_sel_fallback_reject_unknown),
- cmocka_unit_test(test_mp_chmap_sel_fallback_more_replacements),
- cmocka_unit_test(test_mp_chmap_sel_fallback_na_channels),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/test/gl_video.c b/test/gl_video.c
index 91271bd2d6..dd866c955c 100644
--- a/test/gl_video.c
+++ b/test/gl_video.c
@@ -1,42 +1,30 @@
+#include "index.h"
#include "test_helpers.h"
#include "video/out/gpu/video.h"
-static void test_scale_ambient_lux_limits(void **state) {
+static void run(void)
+{
float x;
+
x = gl_video_scale_ambient_lux(16.0, 64.0, 2.40, 1.961, 16.0);
assert_float_equal(x, 2.40f, FLT_EPSILON);
x = gl_video_scale_ambient_lux(16.0, 64.0, 2.40, 1.961, 64.0);
assert_float_equal(x, 1.961f, FLT_EPSILON);
-}
-static void test_scale_ambient_lux_sign(void **state) {
- float x;
x = gl_video_scale_ambient_lux(16.0, 64.0, 1.961, 2.40, 64.0);
assert_float_equal(x, 2.40f, FLT_EPSILON);
-}
-static void test_scale_ambient_lux_clamping(void **state) {
- float x;
x = gl_video_scale_ambient_lux(16.0, 64.0, 2.40, 1.961, 0.0);
assert_float_equal(x, 2.40f, FLT_EPSILON);
-}
-static void test_scale_ambient_lux_log10_midpoint(void **state) {
- float x;
// 32 corresponds to the the midpoint after converting lux to the log10 scale
x = gl_video_scale_ambient_lux(16.0, 64.0, 2.40, 1.961, 32.0);
float mid_gamma = (2.40 - 1.961) / 2 + 1.961;
assert_float_equal(x, mid_gamma, FLT_EPSILON);
}
-int main(void) {
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_scale_ambient_lux_limits),
- cmocka_unit_test(test_scale_ambient_lux_sign),
- cmocka_unit_test(test_scale_ambient_lux_clamping),
- cmocka_unit_test(test_scale_ambient_lux_log10_midpoint),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
-
+const struct unittest test_gl_video = {
+ .name = "gl_video",
+ .run_simple = run,
+};
diff --git a/test/index.c b/test/index.c
new file mode 100644
index 0000000000..64f3f85344
--- /dev/null
+++ b/test/index.c
@@ -0,0 +1,51 @@
+#include "index.h"
+#include "player/core.h"
+
+static const struct unittest *unittests[] = {
+ &test_chmap,
+ &test_gl_video,
+ &test_json,
+ &test_linked_list,
+ NULL
+};
+
+bool run_tests(struct MPContext *mpctx)
+{
+ char *sel = mpctx->opts->test_mode;
+ assert(sel && sel[0]);
+
+ if (strcmp(sel, "help") == 0) {
+ MP_INFO(mpctx, "Available tests:\n");
+ for (int n = 0; unittests[n]; n++)
+ MP_INFO(mpctx, " %s\n", unittests[n]->name);
+ MP_INFO(mpctx, " all-simple\n");
+ return true;
+ }
+
+ int num_run = 0;
+
+ for (int n = 0; unittests[n]; n++) {
+ const struct unittest *t = unittests[n];
+
+ // Exactly 1 entrypoint please.
+ assert(MP_IS_POWER_OF_2(
+ (t->run_simple ? (1 << 0) : 0) |
+ (t->run ? (1 << 1) : 0)));
+
+ bool run = false;
+ run |= strcmp(sel, "all-simple") == 0 && !!t->run_simple;
+ run |= strcmp(sel, t->name);
+
+ if (run) {
+ if (t->run_simple)
+ t->run_simple();
+ if (t->run)
+ t->run(mpctx->global, mpctx->log);
+ num_run++;
+ }
+ }
+
+ MP_INFO(mpctx, "%d unittests successfully run.\n", num_run);
+
+ return num_run > 0; // still error if none
+}
diff --git a/test/index.h b/test/index.h
new file mode 100644
index 0000000000..6060eb699f
--- /dev/null
+++ b/test/index.h
@@ -0,0 +1,29 @@
+#pragma once
+
+#include <stdbool.h>
+
+struct mpv_global;
+struct mp_log;
+struct MPContext;
+
+bool run_tests(struct MPContext *mpctx);
+
+struct unittest {
+ // This is used to select the test on command line with --unittest=<name>.
+ const char *name;
+
+ // Entrypoints. There are various for various purposes. Only 1 of them must
+ // be set.
+
+ // Entrypoint for tests which don't depend on the mpv core.
+ void (*run_simple)(void);
+
+ // Entrypoint for tests which have a simple dependency on the mpv core. The
+ // core is sufficiently initialized at this point.
+ void (*run)(struct mpv_global *global, struct mp_log *log);
+};
+
+extern const struct unittest test_chmap;
+extern const struct unittest test_gl_video;
+extern const struct unittest test_json;
+extern const struct unittest test_linked_list;
diff --git a/test/json.c b/test/json.c
index 0a4462bc21..e8499bee39 100644
--- a/test/json.c
+++ b/test/json.c
@@ -1,8 +1,8 @@
-#include "test_helpers.h"
-
#include "common/common.h"
+#include "index.h"
#include "misc/json.h"
#include "misc/node.h"
+#include "test_helpers.h"
struct entry {
const char *src;
@@ -67,19 +67,20 @@ static const struct entry entries[] = {
#define MAX_DEPTH 10
-static void test_json(void **state)
+static void run(void)
{
for (int n = 0; n < MP_ARRAY_SIZE(entries); n++) {
const struct entry *e = &entries[n];
- print_message("%d: %s\n", n, e->src);
void *tmp = talloc_new(NULL);
char *s = talloc_strdup(tmp, e->src);
json_skip_whitespace(&s);
struct mpv_node res;
bool ok = json_parse(tmp, &res, &s, MAX_DEPTH) >= 0;
assert_true(ok != e->expect_fail);
- if (!ok)
+ if (!ok) {
+ talloc_free(tmp);
continue;
+ }
char *d = talloc_strdup(tmp, "");
assert_true(json_write(&d, &res) >= 0);
assert_string_equal(e->out_txt, d);
@@ -88,10 +89,7 @@ static void test_json(void **state)
}
}
-int main(void) {
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_json),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
-
+const struct unittest test_json = {
+ .name = "json",
+ .run_simple = run,
+};
diff --git a/test/linked_list.c b/test/linked_list.c
index a7b5b6b171..c679d8cc28 100644
--- a/test/linked_list.c
+++ b/test/linked_list.c
@@ -1,7 +1,7 @@
-#include "test_helpers.h"
-
#include "common/common.h"
+#include "index.h"
#include "misc/linked_list.h"
+#include "test_helpers.h"
struct list_item {
int v;
@@ -56,7 +56,7 @@ static bool do_check_list(struct the_list *lst, int *c, int num_c)
return true;
}
-static void test_linked_list(void **state)
+static void run(void)
{
struct the_list lst = {0};
struct list_item e1 = {1};
@@ -159,10 +159,7 @@ static void test_linked_list(void **state)
check_list(3, 4, 5, 2, 1, 6);
}
-int main(void) {
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_linked_list),
- };
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
-
+const struct unittest test_linked_list = {
+ .name = "linked_list",
+ .run_simple = run,
+};
diff --git a/test/test_helpers.c b/test/test_helpers.c
new file mode 100644
index 0000000000..187ff73c61
--- /dev/null
+++ b/test/test_helpers.c
@@ -0,0 +1,29 @@
+#include <inttypes.h>
+
+#include "test_helpers.h"
+
+void assert_int_equal_impl(const char *file, int line, int64_t a, int64_t b)
+{
+ if (a != b) {
+ printf("%s:%d: %"PRId64" != %"PRId64"\n", file, line, a, b);
+ abort();
+ }
+}
+
+void assert_string_equal_impl(const char *file, int line,
+ const char *a, const char *b)
+{
+ if (strcmp(a, b) != 0) {
+ printf("%s:%d: '%s' != '%s'\n", file, line, a, b);
+ abort();
+ }
+}
+
+void assert_float_equal_impl(const char *file, int line,
+ double a, double b, double tolerance)
+{
+ if (fabs(a - b) > tolerance) {
+ printf("%s:%d: %f != %f\n", file, line, a, b);
+ abort();
+ }
+}
diff --git a/test/test_helpers.h b/test/test_helpers.h
index 8a8669c624..6ca3cd99b3 100644
--- a/test/test_helpers.h
+++ b/test/test_helpers.h
@@ -1,13 +1,24 @@
#ifndef MP_TESTS_H
#define MP_TESTS_H
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-
-#include <stdio.h>
#include <math.h>
#include <float.h>
+#include "common/common.h"
+
+#define assert_true(x) assert(x)
+#define assert_false(x) assert(!(x))
+#define assert_int_equal(a, b) \
+ assert_int_equal_impl(__FILE__, __LINE__, (a), (b))
+#define assert_string_equal(a, b) \
+ assert_string_equal_impl(__FILE__, __LINE__, (a), (b))
+#define assert_float_equal(a, b, tolerance) \
+ assert_float_equal_impl(__FILE__, __LINE__, (a), (b), (tolerance))
+
+void assert_int_equal_impl(const char *file, int line, int64_t a, int64_t b);
+void assert_string_equal_impl(const char *file, int line,
+ const char *a, const char *b);
+void assert_float_equal_impl(const char *file, int line,
+ double a, double b, double tolerance);
+
#endif
diff --git a/wscript b/wscript
index 0fae0c2941..aea318d2b6 100644
--- a/wscript
+++ b/wscript
@@ -81,6 +81,11 @@ build_options = [
'default': 'enable',
'func': check_true
}, {
+ 'name': '--tests',
+ 'desc': 'unit tests (development only)',
+ 'default': 'disable',
+ 'func': check_true
+ }, {
'name': '--manpage-build',
'desc': 'manpage generation',
'func': check_ctx_vars('RST2MAN')
@@ -110,11 +115,6 @@ build_options = [
'default': 'enable',
'func': check_true,
}, {
- 'name': '--test',
- 'desc': 'test suite (using cmocka)',
- 'func': check_pkg_config('cmocka', '>= 1.1.5'),
- 'default': 'disable',
- }, {
'name': '--clang-database',
'desc': 'generate a clang compilation database',
'func': check_true,
diff --git a/wscript_build.py b/wscript_build.py
index 951584ec9d..547d0968fe 100644
--- a/wscript_build.py
+++ b/wscript_build.py
@@ -394,6 +394,14 @@ def build(ctx):
( "sub/sd_ass.c", "libass" ),
( "sub/sd_lavc.c" ),
+ ## Tests
+ ( "test/chmap.c", "tests" ),
+ ( "test/gl_video.c", "tests" ),
+ ( "test/index.c", "tests" ),
+ ( "test/json.c", "tests" ),
+ ( "test/linked_list.c", "tests" ),
+ ( "test/test_helpers.c", "tests" ),
+
## Video
( "video/csputils.c" ),
( "video/d3d.c", "d3d-hwaccel" ),
@@ -581,7 +589,7 @@ def build(ctx):
ctx.path.find_node('osdep/mpv.rc'),
version)
- if ctx.dependency_satisfied('cplayer') or ctx.dependency_satisfied('test'):
+ if ctx.dependency_satisfied('cplayer'):
ctx(
target = "objects",
source = ctx.filtered_sources(sources),
@@ -628,17 +636,6 @@ def build(ctx):
wrapctx.env.CFLAGS = ctx.env.CFLAGS + wrapflags
wrapctx.env.LAST_LINKFLAGS = ctx.env.LAST_LINKFLAGS + wrapflags
- if ctx.dependency_satisfied('test'):
- for test in ctx.path.ant_glob("test/*.c"):
- ctx(
- target = os.path.splitext(test.srcpath())[0],
- source = test.srcpath(),
- use = ctx.dependencies_use() + ['objects'],
- includes = _all_includes(ctx),
- features = "c cprogram",
- install_path = None,
- )
-
build_shared = ctx.dependency_satisfied('libmpv-shared')
build_static = ctx.dependency_satisfied('libmpv-static')
if build_shared or build_static: