2026-09-06 21:22:14 -07:00
|
|
|
/*
|
|
|
|
|
streamer-tools OBS Camera Plugin - minimal test harness
|
|
|
|
|
Copyright (C) 2026 CyberCoveLLC <jknapp85@gmail.com>
|
|
|
|
|
|
2026-09-07 04:44:16 -07:00
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
|
You may obtain a copy of the License at
|
2026-09-06 21:22:14 -07:00
|
|
|
|
2026-09-07 04:44:16 -07:00
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
2026-09-06 21:22:14 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
// Deliberately dependency-free (no gtest/catch2) so the core library's test
|
|
|
|
|
// targets add no package-manager or network step to any of the three CI
|
|
|
|
|
// platforms. Unlike bare assert(), this keeps running after a failure and
|
|
|
|
|
// prints a real pass/fail count, so CI output says how much actually ran.
|
|
|
|
|
|
|
|
|
|
#include <cstdio>
|
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
|
|
namespace st_test_detail {
|
|
|
|
|
inline int &checks_run()
|
|
|
|
|
{
|
|
|
|
|
static int n = 0;
|
|
|
|
|
return n;
|
|
|
|
|
}
|
|
|
|
|
inline int &checks_failed()
|
|
|
|
|
{
|
|
|
|
|
static int n = 0;
|
|
|
|
|
return n;
|
|
|
|
|
}
|
|
|
|
|
inline std::string to_display(const std::string &v)
|
|
|
|
|
{
|
|
|
|
|
return "\"" + v + "\"";
|
|
|
|
|
}
|
|
|
|
|
inline std::string to_display(const char *v)
|
|
|
|
|
{
|
|
|
|
|
return v ? ("\"" + std::string(v) + "\"") : std::string("(null)");
|
|
|
|
|
}
|
|
|
|
|
inline std::string to_display(bool v)
|
|
|
|
|
{
|
|
|
|
|
return v ? "true" : "false";
|
|
|
|
|
}
|
|
|
|
|
template<typename T> inline std::string to_display(const T &v)
|
|
|
|
|
{
|
|
|
|
|
return std::to_string(v);
|
|
|
|
|
}
|
|
|
|
|
} // namespace st_test_detail
|
|
|
|
|
|
|
|
|
|
#define ST_ASSERT(expr) \
|
|
|
|
|
do { \
|
|
|
|
|
++st_test_detail::checks_run(); \
|
|
|
|
|
if (!(expr)) { \
|
|
|
|
|
++st_test_detail::checks_failed(); \
|
|
|
|
|
std::fprintf(stderr, "FAIL %s:%d: %s\n", __FILE__, __LINE__, #expr); \
|
|
|
|
|
} \
|
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
|
|
#define ST_ASSERT_EQ(actual, expected) \
|
|
|
|
|
do { \
|
|
|
|
|
++st_test_detail::checks_run(); \
|
|
|
|
|
auto _st_a = (actual); \
|
|
|
|
|
auto _st_e = (expected); \
|
|
|
|
|
if (!(_st_a == _st_e)) { \
|
|
|
|
|
++st_test_detail::checks_failed(); \
|
|
|
|
|
std::fprintf(stderr, "FAIL %s:%d: %s\n actual: %s\n expected: %s\n", \
|
|
|
|
|
__FILE__, __LINE__, #actual " == " #expected, \
|
|
|
|
|
st_test_detail::to_display(_st_a).c_str(), \
|
|
|
|
|
st_test_detail::to_display(_st_e).c_str()); \
|
|
|
|
|
} \
|
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
|
|
inline int st_test_report(const char *suite)
|
|
|
|
|
{
|
|
|
|
|
const int run = st_test_detail::checks_run();
|
|
|
|
|
const int failed = st_test_detail::checks_failed();
|
|
|
|
|
if (failed == 0) {
|
|
|
|
|
std::printf("%s: %d checks passed\n", suite, run);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
std::printf("%s: %d/%d checks FAILED\n", suite, failed, run);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|