mirror of
https://github.com/Zygo/bees.git
synced 2025-06-16 01:26:18 +02:00
bees: remove local cruft, throw at github
This commit is contained in:
5
test/.gitignore
vendored
Normal file
5
test/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
*
|
||||
!Makefile
|
||||
!*.c
|
||||
!*.cc
|
||||
!*.h
|
36
test/Makefile
Normal file
36
test/Makefile
Normal file
@ -0,0 +1,36 @@
|
||||
PROGRAMS = \
|
||||
chatter \
|
||||
crc64 \
|
||||
execpipe \
|
||||
fd \
|
||||
interp \
|
||||
limits \
|
||||
path \
|
||||
process \
|
||||
|
||||
all: test
|
||||
|
||||
test: $(PROGRAMS)
|
||||
set -x; for prog in $(PROGRAMS); do ./$$prog || exit 1; done
|
||||
|
||||
include ../makeflags
|
||||
|
||||
LIBS = -lcrucible
|
||||
LDFLAGS = -L../lib -Wl,-rpath=$(shell realpath ../lib)
|
||||
|
||||
depends.mk: *.cc
|
||||
for x in *.cc; do $(CXX) $(CXXFLAGS) -M "$$x"; done >> depends.mk.new
|
||||
mv -fv depends.mk.new depends.mk
|
||||
|
||||
-include depends.mk
|
||||
|
||||
%.o: %.cc %.h ../makeflags
|
||||
-echo "Implicit rule %.o: %.cc" >&2
|
||||
$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
|
||||
|
||||
%: %.o ../makeflags
|
||||
-echo "Implicit rule %: %.o" >&2
|
||||
$(CXX) $(CXXFLAGS) -o "$@" "$<" $(LDFLAGS) $(LIBS)
|
||||
|
||||
clean:
|
||||
-rm -fv *.o
|
49
test/chatter.cc
Normal file
49
test/chatter.cc
Normal file
@ -0,0 +1,49 @@
|
||||
#include "tests.h"
|
||||
|
||||
#include "crucible/chatter.h"
|
||||
|
||||
#include <ios>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace crucible;
|
||||
|
||||
static
|
||||
void
|
||||
test_chatter_one()
|
||||
{
|
||||
cerr << endl;
|
||||
CHATTER("simple chatter case");
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_chatter_two()
|
||||
{
|
||||
cerr << endl;
|
||||
CHATTER("two lines\nof chatter");
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_chatter_three()
|
||||
{
|
||||
cerr << endl;
|
||||
Chatter c("tct");
|
||||
c << "More complicated";
|
||||
c << "\ncase with\n";
|
||||
c << "some \\ns";
|
||||
}
|
||||
|
||||
int
|
||||
main(int, char**)
|
||||
{
|
||||
RUN_A_TEST(test_chatter_one());
|
||||
RUN_A_TEST(test_chatter_two());
|
||||
RUN_A_TEST(test_chatter_three());
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
39
test/crc64.cc
Normal file
39
test/crc64.cc
Normal file
@ -0,0 +1,39 @@
|
||||
#include "tests.h"
|
||||
#include "crucible/crc64.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
using namespace crucible;
|
||||
|
||||
static
|
||||
void
|
||||
test_getcrc64_strings()
|
||||
{
|
||||
assert(Digest::CRC::crc64("John") == 5942451273432301568);
|
||||
assert(Digest::CRC::crc64("Paul") == 5838402100630913024);
|
||||
assert(Digest::CRC::crc64("George") == 6714394476893704192);
|
||||
assert(Digest::CRC::crc64("Ringo") == 6038837226071130112);
|
||||
assert(Digest::CRC::crc64("") == 0);
|
||||
assert(Digest::CRC::crc64("\377\277\300\200") == 15615382887346470912ULL);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_getcrc64_byte_arrays()
|
||||
{
|
||||
assert(Digest::CRC::crc64("John", 4) == 5942451273432301568);
|
||||
assert(Digest::CRC::crc64("Paul", 4) == 5838402100630913024);
|
||||
assert(Digest::CRC::crc64("George", 6) == 6714394476893704192);
|
||||
assert(Digest::CRC::crc64("Ringo", 5) == 6038837226071130112);
|
||||
assert(Digest::CRC::crc64("", 0) == 0);
|
||||
assert(Digest::CRC::crc64("\377\277\300\200", 4) == 15615382887346470912ULL);
|
||||
}
|
||||
|
||||
int
|
||||
main(int, char**)
|
||||
{
|
||||
RUN_A_TEST(test_getcrc64_strings());
|
||||
RUN_A_TEST(test_getcrc64_byte_arrays());
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
64
test/execpipe.cc
Normal file
64
test/execpipe.cc
Normal file
@ -0,0 +1,64 @@
|
||||
#include "tests.h"
|
||||
|
||||
#include "crucible/execpipe.h"
|
||||
|
||||
#include <ios>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace crucible;
|
||||
using namespace std;
|
||||
|
||||
#if 1 // Needs rework
|
||||
static inline
|
||||
void
|
||||
test_hello_world()
|
||||
{
|
||||
// alarm(9);
|
||||
Fd fd = popen([]() { return system("echo Hello, World!"); });
|
||||
char buf[1024];
|
||||
size_t rv = -1;
|
||||
read_partial_or_die(fd, buf, rv);
|
||||
assert(rv > 0);
|
||||
string b(buf, buf + rv - 1);
|
||||
// cerr << "hello_world says: '" << b << "'" << endl;
|
||||
assert(b == "Hello, World!");
|
||||
}
|
||||
|
||||
static inline
|
||||
void
|
||||
test_read_limit(size_t limit = 4096)
|
||||
{
|
||||
alarm(9);
|
||||
Fd fd = popen([]() { return system("yes Hello!"); });
|
||||
try {
|
||||
string b = read_all(fd, limit);
|
||||
} catch (out_of_range &re) {
|
||||
return;
|
||||
}
|
||||
assert(!"no exception thrown by read_all");
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace crucible {
|
||||
extern bool assert_no_leaked_fds();
|
||||
};
|
||||
|
||||
int
|
||||
main(int, char**)
|
||||
{
|
||||
#if 1
|
||||
RUN_A_TEST(test_hello_world());
|
||||
assert(assert_no_leaked_fds());
|
||||
RUN_A_TEST(test_read_limit(4095));
|
||||
RUN_A_TEST(test_read_limit(4096));
|
||||
RUN_A_TEST(test_read_limit(4097));
|
||||
assert(assert_no_leaked_fds());
|
||||
#endif
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
393
test/fd.cc
Normal file
393
test/fd.cc
Normal file
@ -0,0 +1,393 @@
|
||||
// TEST DATA DO NOT REMOVE THIS LINE
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
#include "crucible/chatter.h"
|
||||
#include "crucible/error.h"
|
||||
#include "crucible/fd.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <ios>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace crucible;
|
||||
|
||||
static
|
||||
void
|
||||
test_default_constructor_and_destructor()
|
||||
{
|
||||
Fd f;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_basic_read()
|
||||
{
|
||||
Fd f = open_or_die("fd.cc");
|
||||
const char test_string[] = "// TEST DATA DO NOT REMOVE THIS LINE";
|
||||
const int test_string_len = sizeof(test_string) - 1;
|
||||
char read_buf[test_string_len];
|
||||
read_or_die(f, read_buf);
|
||||
assert(!strncmp(read_buf, test_string, test_string_len));
|
||||
f->close();
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_create_read_write()
|
||||
{
|
||||
Fd f = open_or_die("tmp/fd-read-write", O_CREAT | O_RDWR | O_TRUNC);
|
||||
|
||||
struct test_str_out {
|
||||
int i;
|
||||
float f;
|
||||
} tso = {
|
||||
.i = 5,
|
||||
.f = 3.14159,
|
||||
}, tsi = {
|
||||
.i = 0,
|
||||
.f = 0,
|
||||
};
|
||||
|
||||
size_t bytes_read = 0;
|
||||
read_partial_or_die(f, tsi, bytes_read);
|
||||
assert(bytes_read == 0);
|
||||
assert(tsi.i == 0);
|
||||
assert(tsi.f == 0);
|
||||
|
||||
pwrite_or_die(f, tso, 1024);
|
||||
pread_or_die(f, tsi, 1024);
|
||||
assert(!memcmp(&tsi, &tso, sizeof(tsi)));
|
||||
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_flags()
|
||||
{
|
||||
#define FLAG_TEST(x) cerr << #x << ": " << flush; cerr << x << endl;
|
||||
|
||||
FLAG_TEST(o_flags_ntoa(O_RDONLY));
|
||||
FLAG_TEST(o_flags_ntoa(O_WRONLY));
|
||||
FLAG_TEST(o_flags_ntoa(O_RDWR));
|
||||
FLAG_TEST(o_flags_ntoa(O_CREAT|O_WRONLY|O_TRUNC));
|
||||
FLAG_TEST(o_mode_ntoa(0001));
|
||||
FLAG_TEST(o_mode_ntoa(0002));
|
||||
FLAG_TEST(o_mode_ntoa(0004));
|
||||
FLAG_TEST(o_mode_ntoa(0010));
|
||||
FLAG_TEST(o_mode_ntoa(0020));
|
||||
FLAG_TEST(o_mode_ntoa(0040));
|
||||
FLAG_TEST(o_mode_ntoa(0100));
|
||||
FLAG_TEST(o_mode_ntoa(0200));
|
||||
FLAG_TEST(o_mode_ntoa(0400));
|
||||
FLAG_TEST(o_mode_ntoa(01000));
|
||||
FLAG_TEST(o_mode_ntoa(02000));
|
||||
FLAG_TEST(o_mode_ntoa(04000));
|
||||
FLAG_TEST(o_mode_ntoa(010000));
|
||||
FLAG_TEST(o_mode_ntoa(020000));
|
||||
FLAG_TEST(o_mode_ntoa(040000));
|
||||
FLAG_TEST(o_mode_ntoa(0777));
|
||||
FLAG_TEST(o_mode_ntoa(02775));
|
||||
FLAG_TEST(o_mode_ntoa(01777));
|
||||
FLAG_TEST(o_mode_ntoa(022));
|
||||
FLAG_TEST(o_mode_ntoa(077));
|
||||
}
|
||||
|
||||
// Test code
|
||||
namespace crucible {
|
||||
extern bool assert_no_leaked_fds();
|
||||
};
|
||||
|
||||
struct FdChecker {
|
||||
~FdChecker()
|
||||
{
|
||||
assert_no_leaked_fds();
|
||||
}
|
||||
};
|
||||
|
||||
static FdChecker fd_destructor_check;
|
||||
|
||||
static inline void assert_is_closed(int i, bool closed = true)
|
||||
{
|
||||
pid_t self_pid = getpid();
|
||||
char buf[1024];
|
||||
snprintf(buf, sizeof(buf), "/proc/%d/fd/%d", self_pid, i);
|
||||
assert(access(buf, F_OK) ? closed : !closed);
|
||||
}
|
||||
|
||||
static void test_construct_destroy()
|
||||
{
|
||||
int i;
|
||||
{
|
||||
Fd fd(open("fd.cc", O_RDONLY));
|
||||
i = fd;
|
||||
}
|
||||
assert_is_closed(i);
|
||||
}
|
||||
|
||||
static void test_construct_copy()
|
||||
{
|
||||
int i;
|
||||
{
|
||||
Fd fd(open("fd.cc", O_RDONLY));
|
||||
i = fd;
|
||||
Fd fd2(fd);
|
||||
int j = fd2;
|
||||
assert(i == j);
|
||||
}
|
||||
assert_is_closed(i);
|
||||
}
|
||||
|
||||
static void test_construct_default_assign()
|
||||
{
|
||||
int i;
|
||||
{
|
||||
i = open("fd.cc", O_RDONLY);
|
||||
Fd fd;
|
||||
fd = i;
|
||||
Fd fd2;
|
||||
fd2 = fd;
|
||||
int j = fd2;
|
||||
assert(i == j);
|
||||
}
|
||||
assert_is_closed(i);
|
||||
}
|
||||
|
||||
static void test_assign_int()
|
||||
{
|
||||
int i;
|
||||
{
|
||||
i = open("fd.cc", O_RDONLY);
|
||||
Fd fd;
|
||||
fd = i;
|
||||
Fd fd2;
|
||||
fd2 = i;
|
||||
int j = fd2;
|
||||
assert(i == j);
|
||||
}
|
||||
assert_is_closed(i);
|
||||
}
|
||||
|
||||
static void test_assign_int_survives_scope()
|
||||
{
|
||||
int i, j;
|
||||
{
|
||||
Fd fd2;
|
||||
{
|
||||
i = open("fd.cc", O_RDONLY);
|
||||
Fd fd;
|
||||
fd = i;
|
||||
fd2 = i;
|
||||
j = fd2;
|
||||
assert(i == j);
|
||||
}
|
||||
assert_is_closed(i, false);
|
||||
}
|
||||
assert_is_closed(i, true);
|
||||
}
|
||||
|
||||
static void test_assign_int_close()
|
||||
{
|
||||
int i;
|
||||
{
|
||||
Fd fd(open("fd.cc", O_RDONLY));
|
||||
i = fd;
|
||||
assert_is_closed(i, false);
|
||||
fd = -1;
|
||||
assert_is_closed(i, true);
|
||||
int j = fd;
|
||||
assert(j == -1);
|
||||
// Bonus conversion operator tests
|
||||
assert(fd == -1);
|
||||
// Chasing a closed ref now triggers an exception
|
||||
assert(catch_all([&]() { return fd->get_fd() == -1; }));
|
||||
}
|
||||
assert_is_closed(i, true);
|
||||
}
|
||||
|
||||
static void test_assign_int_close_2()
|
||||
{
|
||||
int i;
|
||||
{
|
||||
Fd fd(open("fd.cc", O_RDONLY));
|
||||
i = fd;
|
||||
assert_is_closed(i, false);
|
||||
// -2 is null...
|
||||
fd = -2;
|
||||
assert_is_closed(i, true);
|
||||
int j = fd;
|
||||
// ...but it will come back as -1
|
||||
assert(j == -1);
|
||||
// Bonus conversion operator tests
|
||||
assert(fd == -1);
|
||||
// Chasing a closed ref now triggers an exception
|
||||
assert(catch_all([&]() { return fd->get_fd() == -1; }));
|
||||
}
|
||||
assert_is_closed(i, true);
|
||||
}
|
||||
|
||||
static void test_map()
|
||||
{
|
||||
int a, b, c;
|
||||
map<string, Fd> fds;
|
||||
{
|
||||
Fd fd_dot_cc = open("fd.cc", O_RDONLY);
|
||||
a = fd_dot_cc;
|
||||
assert_is_closed(a, false);
|
||||
Fd fd_tests_h = open("tests.h", O_RDONLY);
|
||||
b = fd_tests_h;
|
||||
assert_is_closed(b, false);
|
||||
Fd fd_makefile = open("Makefile", O_RDONLY);
|
||||
c = fd_makefile;
|
||||
assert_is_closed(c, false);
|
||||
fds["fd.cc"] = fd_dot_cc;
|
||||
fds.insert(make_pair("tests.h", fd_tests_h));
|
||||
int j = fds["Makefile"];
|
||||
assert(j == -1);
|
||||
fds["Makefile"] = fd_makefile;
|
||||
assert_is_closed(a, false);
|
||||
assert_is_closed(b, false);
|
||||
assert_is_closed(c, false);
|
||||
}
|
||||
assert_is_closed(a, false);
|
||||
assert_is_closed(b, false);
|
||||
assert_is_closed(c, false);
|
||||
}
|
||||
|
||||
static void test_close_method()
|
||||
{
|
||||
Fd fd = open("fd.cc", O_RDONLY);
|
||||
int i = fd;
|
||||
assert_is_closed(i, false);
|
||||
fd->close();
|
||||
assert_is_closed(i, true);
|
||||
}
|
||||
|
||||
static void test_shared_close_method()
|
||||
{
|
||||
Fd fd = open("fd.cc", O_RDONLY);
|
||||
int i = fd;
|
||||
Fd fd2 = fd;
|
||||
assert_is_closed(i, false);
|
||||
assert_is_closed(fd2, false);
|
||||
fd->close();
|
||||
assert_is_closed(i, true);
|
||||
assert_is_closed(fd2, true);
|
||||
}
|
||||
|
||||
struct DerivedFdResource : public Fd::resource_type {
|
||||
string m_name;
|
||||
DerivedFdResource(string name) : m_name(name) {
|
||||
Fd::resource_type::operator=(open(name.c_str(), O_RDONLY));
|
||||
assert_is_closed(this->get_fd(), false);
|
||||
}
|
||||
const string &name() const { return m_name; }
|
||||
};
|
||||
|
||||
struct DerivedFd : public Fd {
|
||||
using resource_type = DerivedFdResource;
|
||||
DerivedFd(string name) {
|
||||
shared_ptr<DerivedFdResource> ptr = make_shared<DerivedFdResource>(name);
|
||||
Fd::operator=(static_pointer_cast<Fd::resource_type>(ptr));
|
||||
}
|
||||
shared_ptr<DerivedFdResource> operator->() const {
|
||||
shared_ptr<DerivedFdResource> rv = cast<DerivedFdResource>();
|
||||
THROW_CHECK1(out_of_range, rv, rv);
|
||||
return rv;
|
||||
}
|
||||
private:
|
||||
DerivedFd() = default;
|
||||
};
|
||||
|
||||
static void test_derived_resource_type()
|
||||
{
|
||||
DerivedFd fd("fd.cc");
|
||||
assert_is_closed(fd, false);
|
||||
assert(fd->name() == "fd.cc");
|
||||
DerivedFd fd3(fd);
|
||||
assert_is_closed(fd, false);
|
||||
assert_is_closed(fd3, false);
|
||||
Fd fd2(fd3);
|
||||
assert_is_closed(fd, false);
|
||||
assert_is_closed(fd2, false);
|
||||
assert_is_closed(fd3, false);
|
||||
}
|
||||
|
||||
static void test_derived_cast()
|
||||
{
|
||||
DerivedFd fd("fd.cc");
|
||||
assert_is_closed(fd, false);
|
||||
Fd fd2(fd);
|
||||
Fd fd3 = open("fd.cc", O_RDONLY);
|
||||
assert(fd->name() == "fd.cc");
|
||||
assert(fd.cast<Fd::resource_type>());
|
||||
assert(fd.cast<DerivedFd::resource_type>());
|
||||
assert(fd2.cast<Fd::resource_type>());
|
||||
assert(fd2.cast<DerivedFd::resource_type>());
|
||||
assert(fd3.cast<Fd::resource_type>());
|
||||
assert(catch_all([&](){ assert(!fd3.cast<DerivedFd::resource_type>()); } ));
|
||||
}
|
||||
|
||||
static void test_derived_map()
|
||||
{
|
||||
int a, b, c;
|
||||
map<string, Fd> fds;
|
||||
{
|
||||
DerivedFd fd_dot_cc("fd.cc");
|
||||
a = fd_dot_cc;
|
||||
assert_is_closed(a, false);
|
||||
Fd fd_tests_h = open("tests.h", O_RDONLY);
|
||||
b = fd_tests_h;
|
||||
assert_is_closed(b, false);
|
||||
DerivedFd fd_makefile("Makefile");
|
||||
c = fd_makefile;
|
||||
assert_is_closed(c, false);
|
||||
fds["fd.cc"] = fd_dot_cc;
|
||||
fds.insert(make_pair("tests.h", fd_tests_h));
|
||||
int j = fds["Makefile"];
|
||||
assert(j == -1);
|
||||
fds["Makefile"] = fd_makefile;
|
||||
assert_is_closed(a, false);
|
||||
assert_is_closed(b, false);
|
||||
assert_is_closed(c, false);
|
||||
}
|
||||
assert_is_closed(a, false);
|
||||
assert_is_closed(b, false);
|
||||
assert_is_closed(c, false);
|
||||
}
|
||||
|
||||
int main(int, const char **)
|
||||
{
|
||||
|
||||
RUN_A_TEST(test_default_constructor_and_destructor());
|
||||
RUN_A_TEST(test_basic_read());
|
||||
RUN_A_TEST(test_create_read_write());
|
||||
|
||||
RUN_A_TEST(test_flags());
|
||||
|
||||
RUN_A_TEST(test_construct_destroy());
|
||||
RUN_A_TEST(test_construct_copy());
|
||||
RUN_A_TEST(test_construct_default_assign());
|
||||
RUN_A_TEST(test_assign_int());
|
||||
RUN_A_TEST(test_assign_int_survives_scope());
|
||||
RUN_A_TEST(test_assign_int_close());
|
||||
RUN_A_TEST(test_assign_int_close_2());
|
||||
RUN_A_TEST(test_map());
|
||||
RUN_A_TEST(test_close_method());
|
||||
RUN_A_TEST(test_shared_close_method());
|
||||
RUN_A_TEST(test_derived_resource_type());
|
||||
RUN_A_TEST(test_derived_map());
|
||||
RUN_A_TEST(test_derived_cast());
|
||||
|
||||
assert_no_leaked_fds();
|
||||
|
||||
return 0;
|
||||
}
|
88
test/interp.cc
Normal file
88
test/interp.cc
Normal file
@ -0,0 +1,88 @@
|
||||
#include "tests.h"
|
||||
|
||||
#include "crucible/interp.h"
|
||||
|
||||
using namespace crucible;
|
||||
using namespace std;
|
||||
|
||||
/***********************************************************************
|
||||
|
||||
How this should work:
|
||||
|
||||
Interpreter reads an arg list:
|
||||
|
||||
argv[0] --method0args --method1arg arg1 --method1arg=arg1 -- args...
|
||||
|
||||
argv[0] should look up a shared_ptr<Command> which creates an object of
|
||||
type shared_ptr<Process>. This object is used to receive args by
|
||||
method calls or one at a time.
|
||||
|
||||
<Command> and <Process> can be the same object, or not.
|
||||
|
||||
Process p methods:
|
||||
|
||||
p->spawn(Interp*) -> Process
|
||||
p->exec(ArgList) -> Process / Result
|
||||
p->method (from ArgParser<>)
|
||||
p->finish() -> void (destroys object without early destruction warnings...?)
|
||||
p->~Process() -> complains loudly if finish() not called first...?
|
||||
|
||||
Result might be a pair of Process, string. Or just string.
|
||||
|
||||
ArgParser should be more like GetOpt:
|
||||
|
||||
build a dictionary and an arg list from arguments
|
||||
Process methods should interrogate ArgParser
|
||||
ArgParser might have a table of boolean and string option names so it can reject invalid options
|
||||
but if it had that, we could also pass in Process and have it call methods on it
|
||||
...but that is a _lot_ of pointer-hiding when we could KISS
|
||||
...but if we had that solved, argparser tables look like lists of method names
|
||||
ArgParser<T> has a table of names and methods on object of type T
|
||||
ArgParser hides everything behind void* and hands off to a compiled implementation to do callbacks
|
||||
|
||||
Extreme simplification: arguments are themselves executable
|
||||
|
||||
so '--method_foo arg' really means construct MethodFoo(arg) and cast to shared_ptr<ProcArg>
|
||||
then Process->invokeSomething(ProcArg)
|
||||
too extreme, use argparser instead
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
void
|
||||
test_arg_parser()
|
||||
{
|
||||
ArgParser ap;
|
||||
ArgList al( { "abc", "--def", "ghi" } );
|
||||
ap.parse(NULL, al);
|
||||
}
|
||||
|
||||
struct Thing {
|
||||
int m_i;
|
||||
double m_d;
|
||||
string m_s;
|
||||
|
||||
void set_i(int i) { cerr << "i = " << i << endl; m_i = i; }
|
||||
void set_d(double d) { cerr << "d = " << d << endl; m_d = d; }
|
||||
void set_s(string s) { cerr << "s = " << s << endl; m_s = s; }
|
||||
};
|
||||
|
||||
template <typename F, typename T, typename A>
|
||||
void
|
||||
assign(T& t, F f, A a)
|
||||
{
|
||||
cerr << __PRETTY_FUNCTION__ << " - a = " << a << endl;
|
||||
(t.*f)(a);
|
||||
}
|
||||
|
||||
int
|
||||
main(int, char**)
|
||||
{
|
||||
RUN_A_TEST(test_arg_parser());
|
||||
|
||||
Thing p;
|
||||
assign(p, &Thing::set_i, 5);
|
||||
|
||||
cerr << "p.m_i = " << p.m_i << endl;
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
325
test/limits.cc
Normal file
325
test/limits.cc
Normal file
@ -0,0 +1,325 @@
|
||||
#include "tests.h"
|
||||
#include "crucible/error.h"
|
||||
#include "crucible/limits.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
using namespace crucible;
|
||||
|
||||
// Like catch_all but don't bother printing anything
|
||||
static
|
||||
int
|
||||
silent_catch_all(const function<void()> &f)
|
||||
{
|
||||
try {
|
||||
f();
|
||||
return 0;
|
||||
} catch (const exception &) {
|
||||
return 1;
|
||||
} catch (...) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define SHOULD_FAIL(expr) assert(1 == silent_catch_all([&]() { (expr); }))
|
||||
|
||||
#define SHOULD_PASS(expr, result) assert(0 == silent_catch_all([&]() { assert((result) == (expr)); }))
|
||||
|
||||
static
|
||||
void
|
||||
test_cast_signed_negative_to_unsigned()
|
||||
{
|
||||
off_t tv = -1;
|
||||
SHOULD_FAIL(ranged_cast<uint64_t>(tv));
|
||||
SHOULD_FAIL(ranged_cast<uint32_t>(tv));
|
||||
SHOULD_FAIL(ranged_cast<uint16_t>(tv));
|
||||
SHOULD_FAIL(ranged_cast<uint8_t>(tv));
|
||||
SHOULD_FAIL(ranged_cast<unsigned long long>(tv));
|
||||
SHOULD_FAIL(ranged_cast<unsigned long>(tv));
|
||||
SHOULD_FAIL(ranged_cast<unsigned int>(tv));
|
||||
SHOULD_FAIL(ranged_cast<unsigned short>(tv));
|
||||
SHOULD_FAIL(ranged_cast<unsigned char>(tv));
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_cast_1_to_things()
|
||||
{
|
||||
auto tv = 1;
|
||||
SHOULD_PASS(ranged_cast<off_t>(tv), 1);
|
||||
SHOULD_PASS(ranged_cast<uint64_t>(tv), 1);
|
||||
SHOULD_PASS(ranged_cast<uint32_t>(tv), 1);
|
||||
SHOULD_PASS(ranged_cast<uint16_t>(tv), 1);
|
||||
SHOULD_PASS(ranged_cast<uint8_t>(tv), 1);
|
||||
SHOULD_PASS(ranged_cast<int64_t>(tv), 1);
|
||||
SHOULD_PASS(ranged_cast<int32_t>(tv), 1);
|
||||
SHOULD_PASS(ranged_cast<int16_t>(tv), 1);
|
||||
SHOULD_PASS(ranged_cast<int8_t>(tv), 1);
|
||||
SHOULD_PASS(ranged_cast<unsigned long long>(tv), 1);
|
||||
SHOULD_PASS(ranged_cast<unsigned long>(tv), 1);
|
||||
SHOULD_PASS(ranged_cast<unsigned int>(tv), 1);
|
||||
SHOULD_PASS(ranged_cast<unsigned short>(tv), 1);
|
||||
SHOULD_PASS(ranged_cast<unsigned char>(tv), 1);
|
||||
SHOULD_PASS(ranged_cast<signed long long>(tv), 1);
|
||||
SHOULD_PASS(ranged_cast<signed long>(tv), 1);
|
||||
SHOULD_PASS(ranged_cast<signed int>(tv), 1);
|
||||
SHOULD_PASS(ranged_cast<signed short>(tv), 1);
|
||||
SHOULD_PASS(ranged_cast<signed char>(tv), 1);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_cast_128_to_things()
|
||||
{
|
||||
auto tv = 128;
|
||||
SHOULD_PASS(ranged_cast<off_t>(tv), 128);
|
||||
SHOULD_PASS(ranged_cast<uint64_t>(tv), 128);
|
||||
SHOULD_PASS(ranged_cast<uint32_t>(tv), 128);
|
||||
SHOULD_PASS(ranged_cast<uint16_t>(tv), 128);
|
||||
SHOULD_PASS(ranged_cast<uint8_t>(tv), 128);
|
||||
SHOULD_PASS(ranged_cast<int64_t>(tv), 128);
|
||||
SHOULD_PASS(ranged_cast<int32_t>(tv), 128);
|
||||
SHOULD_PASS(ranged_cast<int16_t>(tv), 128);
|
||||
SHOULD_FAIL(ranged_cast<int8_t>(tv));
|
||||
SHOULD_PASS(ranged_cast<unsigned long long>(tv), 128);
|
||||
SHOULD_PASS(ranged_cast<unsigned long>(tv), 128);
|
||||
SHOULD_PASS(ranged_cast<unsigned int>(tv), 128);
|
||||
SHOULD_PASS(ranged_cast<unsigned short>(tv), 128);
|
||||
SHOULD_PASS(ranged_cast<unsigned char>(tv), 128);
|
||||
SHOULD_PASS(ranged_cast<signed long long>(tv), 128);
|
||||
SHOULD_PASS(ranged_cast<signed long>(tv), 128);
|
||||
SHOULD_PASS(ranged_cast<signed int>(tv), 128);
|
||||
SHOULD_PASS(ranged_cast<signed short>(tv), 128);
|
||||
SHOULD_FAIL(ranged_cast<signed char>(tv));
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_cast_256_to_things()
|
||||
{
|
||||
auto tv = 256;
|
||||
SHOULD_PASS(ranged_cast<off_t>(tv), 256);
|
||||
SHOULD_PASS(ranged_cast<uint64_t>(tv), 256);
|
||||
SHOULD_PASS(ranged_cast<uint32_t>(tv), 256);
|
||||
SHOULD_PASS(ranged_cast<uint16_t>(tv), 256);
|
||||
SHOULD_FAIL(ranged_cast<uint8_t>(tv));
|
||||
SHOULD_PASS(ranged_cast<int64_t>(tv), 256);
|
||||
SHOULD_PASS(ranged_cast<int32_t>(tv), 256);
|
||||
SHOULD_PASS(ranged_cast<int16_t>(tv), 256);
|
||||
SHOULD_FAIL(ranged_cast<int8_t>(tv));
|
||||
SHOULD_PASS(ranged_cast<unsigned long long>(tv), 256);
|
||||
SHOULD_PASS(ranged_cast<unsigned long>(tv), 256);
|
||||
SHOULD_PASS(ranged_cast<unsigned int>(tv), 256);
|
||||
SHOULD_PASS(ranged_cast<unsigned short>(tv), 256);
|
||||
SHOULD_FAIL(ranged_cast<unsigned char>(tv));
|
||||
SHOULD_PASS(ranged_cast<signed long long>(tv), 256);
|
||||
SHOULD_PASS(ranged_cast<signed long>(tv), 256);
|
||||
SHOULD_PASS(ranged_cast<signed int>(tv), 256);
|
||||
SHOULD_PASS(ranged_cast<signed short>(tv), 256);
|
||||
SHOULD_FAIL(ranged_cast<signed char>(tv));
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_cast_0x80000000_to_things()
|
||||
{
|
||||
auto sv = 0x80000000LL;
|
||||
auto uv = 0x80000000ULL;
|
||||
SHOULD_PASS(ranged_cast<off_t>(sv), sv);
|
||||
SHOULD_PASS(ranged_cast<uint64_t>(uv), uv);
|
||||
SHOULD_PASS(ranged_cast<uint32_t>(uv), uv);
|
||||
SHOULD_FAIL(ranged_cast<uint16_t>(uv));
|
||||
SHOULD_FAIL(ranged_cast<uint8_t>(uv));
|
||||
SHOULD_PASS(ranged_cast<int64_t>(sv), sv);
|
||||
SHOULD_FAIL(ranged_cast<int32_t>(sv));
|
||||
SHOULD_FAIL(ranged_cast<int16_t>(sv));
|
||||
SHOULD_FAIL(ranged_cast<int8_t>(sv));
|
||||
SHOULD_PASS(ranged_cast<unsigned long long>(uv), uv);
|
||||
SHOULD_PASS(ranged_cast<unsigned long>(uv), uv);
|
||||
SHOULD_PASS(ranged_cast<unsigned int>(uv), uv);
|
||||
SHOULD_FAIL(ranged_cast<unsigned short>(uv));
|
||||
SHOULD_FAIL(ranged_cast<unsigned char>(uv));
|
||||
SHOULD_PASS(ranged_cast<signed long long>(sv), sv);
|
||||
SHOULD_PASS(ranged_cast<signed long>(sv), sv);
|
||||
SHOULD_FAIL(ranged_cast<signed short>(sv));
|
||||
SHOULD_FAIL(ranged_cast<signed char>(sv));
|
||||
if (sizeof(int) == 4) {
|
||||
SHOULD_FAIL(ranged_cast<signed int>(sv));
|
||||
} else if (sizeof(int) == 8) {
|
||||
SHOULD_PASS(ranged_cast<signed int>(sv), sv);
|
||||
} else {
|
||||
assert(!"unhandled case, please add code here");
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_cast_0xffffffff_to_things()
|
||||
{
|
||||
auto sv = 0xffffffffLL;
|
||||
auto uv = 0xffffffffULL;
|
||||
SHOULD_PASS(ranged_cast<off_t>(sv), sv);
|
||||
SHOULD_PASS(ranged_cast<uint64_t>(uv), uv);
|
||||
SHOULD_PASS(ranged_cast<uint32_t>(uv), uv);
|
||||
SHOULD_FAIL(ranged_cast<uint16_t>(uv));
|
||||
SHOULD_FAIL(ranged_cast<uint8_t>(uv));
|
||||
SHOULD_PASS(ranged_cast<int64_t>(sv), sv);
|
||||
SHOULD_FAIL(ranged_cast<int32_t>(sv));
|
||||
SHOULD_FAIL(ranged_cast<int16_t>(sv));
|
||||
SHOULD_FAIL(ranged_cast<int8_t>(sv));
|
||||
SHOULD_PASS(ranged_cast<unsigned long long>(uv), uv);
|
||||
SHOULD_PASS(ranged_cast<unsigned long>(uv), uv);
|
||||
SHOULD_PASS(ranged_cast<unsigned int>(uv), uv);
|
||||
SHOULD_FAIL(ranged_cast<unsigned short>(uv));
|
||||
SHOULD_FAIL(ranged_cast<unsigned char>(uv));
|
||||
SHOULD_PASS(ranged_cast<signed long long>(sv), sv);
|
||||
SHOULD_PASS(ranged_cast<signed long>(sv), sv);
|
||||
SHOULD_FAIL(ranged_cast<signed short>(sv));
|
||||
SHOULD_FAIL(ranged_cast<signed char>(sv));
|
||||
if (sizeof(int) == 4) {
|
||||
SHOULD_FAIL(ranged_cast<signed int>(sv));
|
||||
} else if (sizeof(int) == 8) {
|
||||
SHOULD_PASS(ranged_cast<signed int>(sv), sv);
|
||||
} else {
|
||||
assert(!"unhandled case, please add code here");
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_cast_0xfffffffff_to_things()
|
||||
{
|
||||
auto sv = 0xfffffffffLL;
|
||||
auto uv = 0xfffffffffULL;
|
||||
SHOULD_PASS(ranged_cast<off_t>(sv), sv);
|
||||
SHOULD_PASS(ranged_cast<uint64_t>(uv), uv);
|
||||
SHOULD_FAIL(ranged_cast<uint32_t>(uv));
|
||||
SHOULD_FAIL(ranged_cast<uint16_t>(uv));
|
||||
SHOULD_FAIL(ranged_cast<uint8_t>(uv));
|
||||
SHOULD_PASS(ranged_cast<int64_t>(sv), sv);
|
||||
SHOULD_FAIL(ranged_cast<int32_t>(sv));
|
||||
SHOULD_FAIL(ranged_cast<int16_t>(sv));
|
||||
SHOULD_FAIL(ranged_cast<int8_t>(sv));
|
||||
SHOULD_PASS(ranged_cast<unsigned long long>(uv), uv);
|
||||
SHOULD_FAIL(ranged_cast<unsigned short>(uv));
|
||||
SHOULD_FAIL(ranged_cast<unsigned char>(uv));
|
||||
SHOULD_PASS(ranged_cast<signed long long>(sv), sv);
|
||||
SHOULD_FAIL(ranged_cast<signed short>(sv));
|
||||
SHOULD_FAIL(ranged_cast<signed char>(sv));
|
||||
if (sizeof(int) == 4) {
|
||||
SHOULD_FAIL(ranged_cast<signed int>(sv));
|
||||
SHOULD_FAIL(ranged_cast<unsigned int>(uv));
|
||||
} else if (sizeof(int) == 8) {
|
||||
SHOULD_PASS(ranged_cast<signed int>(sv), sv);
|
||||
SHOULD_PASS(ranged_cast<unsigned int>(uv), uv);
|
||||
} else {
|
||||
assert(!"unhandled case, please add code here");
|
||||
}
|
||||
if (sizeof(long) == 4) {
|
||||
SHOULD_FAIL(ranged_cast<signed long>(sv));
|
||||
SHOULD_FAIL(ranged_cast<unsigned long>(uv));
|
||||
} else if (sizeof(long) == 8) {
|
||||
SHOULD_PASS(ranged_cast<signed long>(sv), sv);
|
||||
SHOULD_PASS(ranged_cast<unsigned long>(uv), uv);
|
||||
} else {
|
||||
assert(!"unhandled case, please add code here");
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_cast_0x8000000000000000_to_things()
|
||||
{
|
||||
auto sv = 0x8000000000000000LL;
|
||||
auto uv = 0x8000000000000000ULL;
|
||||
SHOULD_FAIL(ranged_cast<off_t>(sv));
|
||||
SHOULD_PASS(ranged_cast<uint64_t>(uv), uv);
|
||||
SHOULD_FAIL(ranged_cast<uint32_t>(uv));
|
||||
SHOULD_FAIL(ranged_cast<uint16_t>(uv));
|
||||
SHOULD_FAIL(ranged_cast<uint8_t>(uv));
|
||||
SHOULD_FAIL(ranged_cast<int64_t>(sv));
|
||||
SHOULD_FAIL(ranged_cast<int32_t>(sv));
|
||||
SHOULD_FAIL(ranged_cast<int16_t>(sv));
|
||||
SHOULD_FAIL(ranged_cast<int8_t>(sv));
|
||||
SHOULD_PASS(ranged_cast<unsigned long long>(uv), uv);
|
||||
SHOULD_FAIL(ranged_cast<unsigned short>(uv));
|
||||
SHOULD_FAIL(ranged_cast<unsigned char>(uv));
|
||||
SHOULD_FAIL(ranged_cast<signed long long>(sv));
|
||||
SHOULD_FAIL(ranged_cast<signed long>(sv));
|
||||
SHOULD_FAIL(ranged_cast<signed int>(sv));
|
||||
SHOULD_FAIL(ranged_cast<signed short>(sv));
|
||||
SHOULD_FAIL(ranged_cast<signed char>(sv));
|
||||
if (sizeof(int) == 4) {
|
||||
SHOULD_FAIL(ranged_cast<unsigned int>(uv));
|
||||
} else if (sizeof(int) == 8) {
|
||||
SHOULD_PASS(ranged_cast<unsigned int>(uv), uv);
|
||||
} else {
|
||||
assert(!"unhandled case, please add code here");
|
||||
}
|
||||
if (sizeof(long) == 4) {
|
||||
SHOULD_FAIL(ranged_cast<unsigned long>(uv));
|
||||
} else if (sizeof(long) == 8) {
|
||||
SHOULD_PASS(ranged_cast<unsigned long>(uv), uv);
|
||||
} else {
|
||||
assert(!"unhandled case, please add code here");
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_cast_0xffffffffffffffff_to_things()
|
||||
{
|
||||
auto sv = 0xffffffffffffffffLL;
|
||||
auto uv = 0xffffffffffffffffULL;
|
||||
SHOULD_FAIL(ranged_cast<off_t>(sv));
|
||||
SHOULD_PASS(ranged_cast<uint64_t>(uv), uv);
|
||||
SHOULD_FAIL(ranged_cast<uint32_t>(uv));
|
||||
SHOULD_FAIL(ranged_cast<uint16_t>(uv));
|
||||
SHOULD_FAIL(ranged_cast<uint8_t>(uv));
|
||||
SHOULD_FAIL(ranged_cast<int64_t>(sv));
|
||||
SHOULD_FAIL(ranged_cast<int32_t>(sv));
|
||||
SHOULD_FAIL(ranged_cast<int16_t>(sv));
|
||||
SHOULD_FAIL(ranged_cast<int8_t>(sv));
|
||||
SHOULD_PASS(ranged_cast<unsigned long long>(uv), uv);
|
||||
SHOULD_FAIL(ranged_cast<unsigned short>(uv));
|
||||
SHOULD_FAIL(ranged_cast<unsigned char>(uv));
|
||||
SHOULD_FAIL(ranged_cast<signed long long>(sv));
|
||||
SHOULD_FAIL(ranged_cast<signed long>(sv));
|
||||
SHOULD_FAIL(ranged_cast<signed int>(sv));
|
||||
SHOULD_FAIL(ranged_cast<signed short>(sv));
|
||||
SHOULD_FAIL(ranged_cast<signed char>(sv));
|
||||
if (sizeof(int) == 4) {
|
||||
SHOULD_FAIL(ranged_cast<unsigned int>(uv));
|
||||
} else if (sizeof(int) == 8) {
|
||||
SHOULD_PASS(ranged_cast<unsigned int>(uv), uv);
|
||||
} else {
|
||||
assert(!"unhandled case, please add code here");
|
||||
}
|
||||
if (sizeof(long) == 4) {
|
||||
SHOULD_FAIL(ranged_cast<unsigned long>(uv));
|
||||
} else if (sizeof(long) == 8) {
|
||||
SHOULD_PASS(ranged_cast<unsigned long>(uv), uv);
|
||||
} else {
|
||||
assert(!"unhandled case, please add code here");
|
||||
}
|
||||
}
|
||||
|
||||
// OK enough with the small values. We want to know if 32-bit machines break.
|
||||
|
||||
int
|
||||
main(int, char**)
|
||||
{
|
||||
RUN_A_TEST(test_cast_signed_negative_to_unsigned());
|
||||
RUN_A_TEST(test_cast_1_to_things());
|
||||
RUN_A_TEST(test_cast_128_to_things());
|
||||
RUN_A_TEST(test_cast_256_to_things());
|
||||
RUN_A_TEST(test_cast_0x80000000_to_things());
|
||||
RUN_A_TEST(test_cast_0xffffffff_to_things());
|
||||
RUN_A_TEST(test_cast_0xfffffffff_to_things());
|
||||
RUN_A_TEST(test_cast_0x8000000000000000_to_things());
|
||||
RUN_A_TEST(test_cast_0xffffffffffffffff_to_things());
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
40
test/path.cc
Normal file
40
test/path.cc
Normal file
@ -0,0 +1,40 @@
|
||||
#include "tests.h"
|
||||
|
||||
#include "crucible/path.h"
|
||||
|
||||
#include <ios>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace crucible;
|
||||
|
||||
unsigned failures = 0;
|
||||
static
|
||||
void
|
||||
test_path_basename(string input, string expected)
|
||||
{
|
||||
string result = basename(input);
|
||||
if (expected != result) {
|
||||
std::cerr << "result was \"" << result << "\"" << std::endl;
|
||||
++failures;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int, char**)
|
||||
{
|
||||
RUN_A_TEST(test_path_basename("/foo/bar.c", "bar.c"));
|
||||
RUN_A_TEST(test_path_basename("/foo/bar/", ""));
|
||||
RUN_A_TEST(test_path_basename("/foo/", ""));
|
||||
RUN_A_TEST(test_path_basename("/", ""));
|
||||
RUN_A_TEST(test_path_basename("foo/bar.c", "bar.c"));
|
||||
RUN_A_TEST(test_path_basename("bar.c", "bar.c"));
|
||||
RUN_A_TEST(test_path_basename("", ""));
|
||||
|
||||
assert(!failures);
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
65
test/process.cc
Normal file
65
test/process.cc
Normal file
@ -0,0 +1,65 @@
|
||||
#include "tests.h"
|
||||
|
||||
#include "crucible/process.h"
|
||||
|
||||
#include <ios>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace crucible;
|
||||
using namespace std;
|
||||
|
||||
static inline
|
||||
int
|
||||
return_value(int val)
|
||||
{
|
||||
// cerr << "pid " << getpid() << " returning " << val << endl;
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline
|
||||
int
|
||||
return_value_2(int val, int val2)
|
||||
{
|
||||
return val + val2;
|
||||
}
|
||||
|
||||
static inline
|
||||
void
|
||||
test_fork_return(int val)
|
||||
{
|
||||
Pid child(return_value, val);
|
||||
assert(child == child->get_id());
|
||||
assert(child == child->native_handle());
|
||||
int status = child->join();
|
||||
int rv_status = WEXITSTATUS(status);
|
||||
assert(WIFEXITED(status));
|
||||
assert(rv_status == val);
|
||||
}
|
||||
|
||||
static inline
|
||||
void
|
||||
test_fork_return(int val, int val2)
|
||||
{
|
||||
Pid child(return_value_2, val, val2);
|
||||
int status = child->join();
|
||||
int rv_status = WEXITSTATUS(status);
|
||||
assert(WIFEXITED(status));
|
||||
assert(rv_status == val + val2);
|
||||
}
|
||||
|
||||
int
|
||||
main(int, char**)
|
||||
{
|
||||
RUN_A_TEST(test_fork_return(0));
|
||||
RUN_A_TEST(test_fork_return(1));
|
||||
RUN_A_TEST(test_fork_return(9));
|
||||
RUN_A_TEST(test_fork_return(2, 3));
|
||||
RUN_A_TEST(test_fork_return(7, 9));
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
14
test/tests.h
Normal file
14
test/tests.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef CRUCIBLE_TESTS_H
|
||||
#define CRUCIBLE_TESTS_H
|
||||
|
||||
#undef NDEBUG
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#define RUN_A_TEST(test) do { \
|
||||
std::cerr << "Testing " << #test << "..." << std::flush; \
|
||||
do { test ; } while (0); \
|
||||
std::cerr << "OK" << std::endl; \
|
||||
} while (0)
|
||||
|
||||
#endif // CRUCIBLE_TESTS_H
|
1
test/tmp/.gitignore
vendored
Normal file
1
test/tmp/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*
|
Reference in New Issue
Block a user