add some header documentation
This commit is contained in:
parent
c915f3777b
commit
fe887a8fa8
|
@ -3,23 +3,35 @@
|
|||
|
||||
#include <yachtrock/runtime.h>
|
||||
|
||||
/**
|
||||
* Basic assertion.
|
||||
*/
|
||||
#define YR_ASSERT(test, ...) do { \
|
||||
if ( !(test) ) { \
|
||||
yr_fail_assertion(#test, __FILE__, __LINE__, __FUNCTION__, "" __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Assertion that unconditionally fails.
|
||||
*/
|
||||
#define YR_FAIL(reason, ...) do { \
|
||||
yr_fail_assertion("explicit failure", __FILE__, __LINE__, __FUNCTION__, reason, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/**
|
||||
* Assert that a condition does not hold.
|
||||
*/
|
||||
#define YR_ASSERT_FALSE(test, ...) do { \
|
||||
if ( (test) ) { \
|
||||
yr_fail_assertion(#test, __FILE__, __LINE__, __FUNCTION__, "" __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Assert that two values are equal.
|
||||
*/
|
||||
#define YR_ASSERT_EQUAL(val1, val2, ...) do { \
|
||||
if ( (val1) != (val2) ) { \
|
||||
const char *__assertion_desc = #val1 " == " #val2; \
|
||||
|
@ -27,20 +39,9 @@
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
#define YR_ASSERT_STRINGS_EQUAL(val1, val2, ...) do { \
|
||||
if ( strcmp((val1), (val2)) != 0 ) { \
|
||||
const char *__assertion_desc = "strcmp("#val1 ", " #val2 ") == 0"; \
|
||||
yr_fail_assertion(__assertion_desc, __FILE__, __LINE__, __FUNCTION__, "" __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define YR_ASSERT_STRINGS_NOT_EQUAL(val1, val2, ...) do { \
|
||||
if ( strcmp((val1), (val2)) == 0 ) { \
|
||||
const char *__assertion_desc = "strcmp("#val1 ", " #val2 ") != 0"; \
|
||||
yr_fail_assertion(__assertion_desc, __FILE__, __LINE__, __FUNCTION__, "" __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Assert that two values are not equal.
|
||||
*/
|
||||
#define YR_ASSERT_NOT_EQUAL(val1, val2, ...) do { \
|
||||
if ( (val1) == (val2) ) { \
|
||||
const char *__assertion_desc = #val1 " != " #val2; \
|
||||
|
@ -48,6 +49,9 @@
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Assert that one value is less than another (via the < operator).
|
||||
*/
|
||||
#define YR_ASSERT_LESS_THAN(val1, val2, ...) do { \
|
||||
if ( !((val1) < (val2)) ) { \
|
||||
const char *__assertion_desc = #val1 " < " #val2; \
|
||||
|
@ -55,6 +59,9 @@
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Assert that one value is greater than another (via the > operator).
|
||||
*/
|
||||
#define YR_ASSERT_GREATER_THAN(val1, val2, ...) do { \
|
||||
if ( !((val1) > (val2)) ) { \
|
||||
const char *__assertion_desc = #val1 " > " #val2; \
|
||||
|
@ -62,6 +69,9 @@
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Assert that one value is less than or equal to another (via the <= operator).
|
||||
*/
|
||||
#define YR_ASSERT_LESS_THAN_OR_EQUAL(val1, val2, ...) do { \
|
||||
if ( !((val1) <= (val2)) ) { \
|
||||
const char *__assertion_desc = #val1 " <= " #val2; \
|
||||
|
@ -69,6 +79,9 @@
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Assert that one value is greater than or equal to another (via the >= operator).
|
||||
*/
|
||||
#define YR_ASSERT_GREATER_THAN_OR_EQUAL(val1, val2, ...) do { \
|
||||
if ( !((val1) >= (val2)) ) { \
|
||||
const char *__assertion_desc = #val1 " >= " #val2; \
|
||||
|
@ -76,4 +89,24 @@
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Assert that two strings are equal.
|
||||
*/
|
||||
#define YR_ASSERT_STRINGS_EQUAL(val1, val2, ...) do { \
|
||||
if ( strcmp((val1), (val2)) != 0 ) { \
|
||||
const char *__assertion_desc = "strcmp("#val1 ", " #val2 ") == 0"; \
|
||||
yr_fail_assertion(__assertion_desc, __FILE__, __LINE__, __FUNCTION__, "" __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Assert that two strings are not equal.
|
||||
*/
|
||||
#define YR_ASSERT_STRINGS_NOT_EQUAL(val1, val2, ...) do { \
|
||||
if ( strcmp((val1), (val2)) == 0 ) { \
|
||||
const char *__assertion_desc = "strcmp("#val1 ", " #val2 ") != 0"; \
|
||||
yr_fail_assertion(__assertion_desc, __FILE__, __LINE__, __FUNCTION__, "" __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,6 +5,14 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* A testing result.
|
||||
*
|
||||
* YR_RESULT_UNSET: The result has not been set.
|
||||
* YR_RESULT_PASSED: A passing result.
|
||||
* YR_RESULT_FAILED: A failing result.
|
||||
* YR_RESULT_SKIPPED: The item was skipped.
|
||||
*/
|
||||
typedef enum yr_result {
|
||||
YR_RESULT_UNSET,
|
||||
YR_RESULT_PASSED,
|
||||
|
@ -12,11 +20,37 @@ typedef enum yr_result {
|
|||
YR_RESULT_SKIPPED
|
||||
} yr_result_t;
|
||||
|
||||
/**
|
||||
* Apply merging logic to a result, updating it with new information and returning the new result.
|
||||
*/
|
||||
YACHTROCK_EXTERN yr_result_t yr_merge_result(yr_result_t old_result, yr_result_t new_result);
|
||||
|
||||
typedef struct yr_result_store yr_result_store_s;
|
||||
|
||||
/**
|
||||
* Result store.
|
||||
*
|
||||
* A result store is a tree structure that organizes test results.
|
||||
*
|
||||
* Each node can record some test result, but the result state they actually contain is constrained
|
||||
* by the results of their children. For instance, a store that has a passing result will implicitly
|
||||
* and irrevocably move to a failing state if one of its children records a failing result. Thus
|
||||
* test results percolate up the store tree to yield an overall result at the root.
|
||||
*
|
||||
* Each node has a state (initially YR_RESULT_UNSET), a name, and zero or more children.
|
||||
*/
|
||||
typedef yr_result_store_s *yr_result_store_t;
|
||||
|
||||
/**
|
||||
* Hooks to invoke when interesting things happen to a result store hierarchy.
|
||||
*
|
||||
* context: an arbitrary pointer passed through to the hook functions.
|
||||
* store_opened: invoked when a store in the hierarchy is opened (including the root store).
|
||||
* store_closed: invoked when a store in the hierarchy is closed (including the root store).
|
||||
* store_result_changed: invoked when a store in the hierarchy has its result changed.
|
||||
*
|
||||
* A given hook may be set to NULL, in which case it will not be invoked.
|
||||
*/
|
||||
struct yr_result_hooks {
|
||||
void *context;
|
||||
void (*store_opened)(yr_result_store_t new_store, void *refcon);
|
||||
|
@ -24,27 +58,108 @@ struct yr_result_hooks {
|
|||
void (*store_result_changed)(yr_result_store_t store, void *refcon);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a new root store with the given name and no hooks.
|
||||
*/
|
||||
|
||||
YACHTROCK_EXTERN yr_result_store_t yr_result_store_create(const char *name);
|
||||
|
||||
/**
|
||||
* Create a new root store with the given name and the given hooks.
|
||||
*/
|
||||
YACHTROCK_EXTERN yr_result_store_t yr_result_store_create_with_hooks(const char *name,
|
||||
struct yr_result_hooks hooks);
|
||||
|
||||
/**
|
||||
* Destroy a root store and all of its subresults.
|
||||
*
|
||||
* The provided store *must* be a root store. You cannot remove a subresult once added.
|
||||
*/
|
||||
YACHTROCK_EXTERN void yr_result_store_destroy(yr_result_store_t store);
|
||||
|
||||
|
||||
/**
|
||||
* Close a store.
|
||||
*
|
||||
* Any remaining open subresult stores are closed. If the store's result is still unset, if any
|
||||
* subresult stores have failed, the store's result is set to failed; otherwise, no subresult stores
|
||||
* have failed, and the result is set to passed.
|
||||
*/
|
||||
YACHTROCK_EXTERN void yr_result_store_close(yr_result_store_t store);
|
||||
|
||||
/**
|
||||
* Test whether a store is closed.
|
||||
*/
|
||||
YACHTROCK_EXTERN bool yr_result_store_is_closed(yr_result_store_t store);
|
||||
|
||||
/**
|
||||
* Open a subresult of a store with the given name, returning the opened subresult store.
|
||||
*/
|
||||
YACHTROCK_EXTERN yr_result_store_t yr_result_store_open_subresult(yr_result_store_t store, const char *name);
|
||||
|
||||
/**
|
||||
* Record a result.
|
||||
*
|
||||
* The effective result is computed via merge_result with the old and provided results.
|
||||
*/
|
||||
YACHTROCK_EXTERN void yr_result_store_record_result(yr_result_store_t store, yr_result_t result);
|
||||
|
||||
/**
|
||||
* Extract the result from a store.
|
||||
*/
|
||||
YACHTROCK_EXTERN yr_result_t yr_result_store_get_result(yr_result_store_t store);
|
||||
|
||||
/**
|
||||
* Extract the name from a store.
|
||||
*
|
||||
* The lifetime of the string is the same as the lifetime of the store.
|
||||
*/
|
||||
YACHTROCK_EXTERN const char *yr_result_store_get_name(yr_result_store_t store);
|
||||
|
||||
/**
|
||||
* Look up the parent store for a given store.
|
||||
*
|
||||
* Returns NULL for a root store.
|
||||
*/
|
||||
YACHTROCK_EXTERN yr_result_store_t yr_result_store_get_parent(yr_result_store_t store);
|
||||
|
||||
typedef void (*yr_result_store_enumerator_t)(yr_result_store_t subresult, void *refcon);
|
||||
|
||||
/**
|
||||
* Enumerate the store's children with the given callback.
|
||||
*/
|
||||
YACHTROCK_EXTERN void yr_result_store_enumerate(yr_result_store_t store,
|
||||
yr_result_store_enumerator_t enumerator, void *refcon);
|
||||
|
||||
/**
|
||||
* Get the number of direct subresult stores of this store.
|
||||
*/
|
||||
YACHTROCK_EXTERN size_t yr_result_store_count_subresults(yr_result_store_t store);
|
||||
|
||||
/**
|
||||
* Get the subresult of this store with the given index.
|
||||
*
|
||||
* Indices are assigned sequentially in the obvious way.
|
||||
*/
|
||||
YACHTROCK_EXTERN yr_result_store_t yr_result_store_get_subresult(yr_result_store_t store,
|
||||
size_t i);
|
||||
|
||||
/**
|
||||
* Construct a string that describes the given store hierarchy.
|
||||
*
|
||||
* This fuction writes at most buf_size bytes into buf. The result is always NUL-terminated, unless
|
||||
* buf_size is zero.
|
||||
*
|
||||
* The return value is how many bytes would be written if given infinite space, even if the function
|
||||
* was actually forced to truncate the result written into buf.
|
||||
*/
|
||||
YACHTROCK_EXTERN size_t yr_result_store_get_description(yr_result_store_t store, char *buf, size_t buf_size);
|
||||
|
||||
/**
|
||||
* Construct a string on the heap that describes the given store hierarchy.
|
||||
*
|
||||
* The result must be passed to free by the caller.
|
||||
*/
|
||||
YACHTROCK_EXTERN char *yr_result_store_copy_description(yr_result_store_t store);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -10,7 +10,13 @@ typedef void (*yr_assertion_failure_callback)(const char *assertion, const char
|
|||
typedef void (*yr_test_skipped_callback)(const char *file, size_t line, const char *funname,
|
||||
const char *reason, va_list ap, void *refcon);
|
||||
|
||||
// callbacks
|
||||
/**
|
||||
* Runtime callbacks.
|
||||
*
|
||||
* refcon: Arbitrary pointer passed to the callbacks.
|
||||
* note_assertion_failed: called when an assertion fails.
|
||||
* note_skipped: called when a test is skipped.
|
||||
*/
|
||||
struct yr_runtime_callbacks
|
||||
{
|
||||
void *refcon;
|
||||
|
@ -18,14 +24,29 @@ struct yr_runtime_callbacks
|
|||
yr_test_skipped_callback note_skipped;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the runtime callbacks and return the previously set ones.
|
||||
*
|
||||
* Callbacks must be set before an assertion is failed or a test is skipped. Yachtrock functions
|
||||
* that invoke test cases do this; it's only necessary to call this function if you are implementing
|
||||
* your own test running routines.
|
||||
*/
|
||||
YACHTROCK_EXTERN struct yr_runtime_callbacks yr_set_runtime_callbacks(struct yr_runtime_callbacks callbacks);
|
||||
|
||||
|
||||
/**
|
||||
* Note that an assertion has failed, invoking the runtime callback.
|
||||
*/
|
||||
YACHTROCK_EXTERN void yr_fail_assertion(const char *assertion, const char *file, size_t line,
|
||||
const char *funname, const char *s, ...);
|
||||
/**
|
||||
* Note that a test has been marked as skipped, invoking the runtime callback.
|
||||
*/
|
||||
YACHTROCK_EXTERN void yr_skip_test(const char *file, size_t line, const char *funname,
|
||||
const char *reason, ...);
|
||||
|
||||
/**
|
||||
* Helper macros.
|
||||
*/
|
||||
#define YR_RECORD_SKIP(reason, ...) do { \
|
||||
yr_skip_test(__FILE__, __LINE__, __FUNCTION__, reason, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
|
|
@ -5,37 +5,109 @@
|
|||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/**
|
||||
* The vtable that defines selector behavior.
|
||||
*
|
||||
* match: returns true if the testcase matches the selector's criteria.
|
||||
* copy_context: copies and returns the selector-specific context.
|
||||
* destroy_context: releases resources held by the selector-specific context.
|
||||
*/
|
||||
struct yr_selector_vtable {
|
||||
bool (*match)(yr_test_case_t testcase, void *context);
|
||||
void *(*copy_context)(void *context);
|
||||
void (*destroy_context)(void *context);
|
||||
};
|
||||
|
||||
/**
|
||||
* A testcase selector.
|
||||
*/
|
||||
typedef struct yr_selector {
|
||||
struct yr_selector_vtable vtable;
|
||||
void *context;
|
||||
} *yr_selector_t;
|
||||
|
||||
/**
|
||||
* A set of testcase selectors.
|
||||
*/
|
||||
typedef struct yr_selector_set {
|
||||
size_t selector_count;
|
||||
struct yr_selector selectors[];
|
||||
} *yr_selector_set_t;
|
||||
|
||||
/**
|
||||
* Create a "glob" testcase selector.
|
||||
*
|
||||
* This takes a specifier of the form [<suite_glob>:]<case_glob>, with both globs having the meaning
|
||||
* ascribed by fnmatch(3).
|
||||
*/
|
||||
YACHTROCK_EXTERN yr_selector_t yr_selector_create_from_glob(const char *sel_specifier);
|
||||
|
||||
/**
|
||||
* Create a selector with the given vtable and context.
|
||||
*
|
||||
* The context is used directly, that is, it is not first copied.
|
||||
*/
|
||||
YACHTROCK_EXTERN yr_selector_t yr_selector_create(struct yr_selector_vtable vtable, void *context);
|
||||
|
||||
/**
|
||||
* Copy a selector.
|
||||
*
|
||||
* A new selector structure is allocated and its vtable and copied context are assigned.
|
||||
*/
|
||||
YACHTROCK_EXTERN yr_selector_t yr_selector_copy(yr_selector_t in);
|
||||
|
||||
/**
|
||||
* Destroy a selector.
|
||||
*
|
||||
* The selector is freed after the context destroy method is applied to its context.
|
||||
*/
|
||||
YACHTROCK_EXTERN void yr_selector_destroy(yr_selector_t selector);
|
||||
|
||||
/**
|
||||
* Returns true if the selector matches the testcase.
|
||||
*/
|
||||
YACHTROCK_EXTERN bool yr_selector_match_testcase(yr_selector_t selector,
|
||||
yr_test_case_t testcase);
|
||||
|
||||
|
||||
/**
|
||||
* Create a selector set from an array of selectors.
|
||||
*/
|
||||
YACHTROCK_EXTERN yr_selector_set_t yr_selector_set_create(size_t selector_count,
|
||||
yr_selector_t *selectors);
|
||||
yr_selector_t *selectors);
|
||||
|
||||
/**
|
||||
* Destroy a selector set.
|
||||
*/
|
||||
YACHTROCK_EXTERN void yr_selector_set_destroy(yr_selector_set_t set);
|
||||
|
||||
/**
|
||||
* Determine if a selector set matches a testcase.
|
||||
*
|
||||
* This is true if any one of the selectors in the set match the testcase.
|
||||
*/
|
||||
YACHTROCK_EXTERN bool yr_selector_set_match_testcase(yr_selector_set_t set,
|
||||
yr_test_case_t testcase);
|
||||
|
||||
/**
|
||||
* Filter a test suite with a selector set.
|
||||
*
|
||||
* The resulting test suite contains only cases that match the selector set. It is also a single
|
||||
* allocation, so all resources of the filtered set can and must be freed by the caller via a call
|
||||
* to free(3), providing the suite.
|
||||
*
|
||||
* This function returns NULL, rather than an empty suite, if all cases were filtered out.
|
||||
*/
|
||||
YACHTROCK_EXTERN yr_test_suite_t
|
||||
yr_test_suite_create_filtered(yr_test_suite_t suite, yr_selector_set_t filter);
|
||||
|
||||
/**
|
||||
* Create a test suite collection from the input collection subject to the selector set's filter.
|
||||
*
|
||||
* The resulting suite collection is a single allocation and must be freed by the caller.
|
||||
*
|
||||
* This function returns NULL, rather than an empty collection, if all cases were filtered out.
|
||||
*/
|
||||
YACHTROCK_EXTERN yr_test_suite_collection_t
|
||||
yr_test_suite_collection_create_filtered(yr_test_suite_collection_t collection,
|
||||
yr_selector_set_t filter);
|
||||
|
|
|
@ -22,14 +22,33 @@ typedef void (*yr_test_suite_setup_function)(yr_test_suite_t suite);
|
|||
typedef void (*yr_test_suite_teardown_function)(yr_test_suite_t suite);
|
||||
|
||||
#define __YR_DEVARIADICIFY_2(dummy, A, ...) A
|
||||
/**
|
||||
* Helper macro to define a testcase function.
|
||||
*/
|
||||
#define YR_TESTCASE(name, ...) void name(yr_test_case_t __YR_DEVARIADICIFY_2(dummy, ##__VA_ARGS__ , testcase) )
|
||||
|
||||
/**
|
||||
* A single test case.
|
||||
*
|
||||
* name: the name of the case.
|
||||
* testcase: the function that executes the test case.
|
||||
* suite: a pointer to the suite containing the test case.
|
||||
*/
|
||||
struct yr_test_case {
|
||||
const char *name;
|
||||
yr_test_case_function testcase;
|
||||
const struct yr_test_suite *suite;
|
||||
};
|
||||
|
||||
/**
|
||||
* Callbacks for suite lifecycle events.
|
||||
*
|
||||
* setup_case: called when a testcase is about to be invoked.
|
||||
* teardown_case: called after a testcase is invoked.
|
||||
* setup_suite: called when a test suite is about to be invoked, before any testcases or testcase setup
|
||||
* callbacks.
|
||||
* teardown_suite: called after a suite has been invoked.
|
||||
*/
|
||||
struct yr_suite_lifecycle_callbacks {
|
||||
yr_test_case_setup_function setup_case;
|
||||
yr_test_case_teardown_function teardown_case;
|
||||
|
@ -37,6 +56,15 @@ struct yr_suite_lifecycle_callbacks {
|
|||
yr_test_suite_teardown_function teardown_suite;
|
||||
};
|
||||
|
||||
/**
|
||||
* A test suite.
|
||||
*
|
||||
* name: the name of the suite.
|
||||
* refcon: arbitrary pointer passed to suite lifecyle callbacks.
|
||||
* lifecycle: suite lifecycle callbacks.
|
||||
* num_cases: the number of cases.
|
||||
* cases: the case structures themselves, allocated inline.
|
||||
*/
|
||||
struct yr_test_suite {
|
||||
const char *name;
|
||||
void *refcon;
|
||||
|
@ -45,6 +73,9 @@ struct yr_test_suite {
|
|||
yr_test_case_s cases[];
|
||||
};
|
||||
|
||||
/**
|
||||
* A set of callbacks that do nothing.
|
||||
*/
|
||||
YACHTROCK_EXTERN const struct yr_suite_lifecycle_callbacks YR_NO_CALLBACKS;
|
||||
|
||||
YACHTROCK_EXTERN yr_test_suite_t
|
||||
|
@ -53,17 +84,33 @@ _yr_create_suite_from_functions(const char *name,
|
|||
struct yr_suite_lifecycle_callbacks callbacks,
|
||||
const char *cs_names,
|
||||
yr_test_case_function first, ...);
|
||||
|
||||
/**
|
||||
* Create a suite from a static set of functions.
|
||||
*
|
||||
* The case names are taken from the function names. All storage consumed by the suite is in one
|
||||
* allocation and can and must be passed to free by the caller.
|
||||
*/
|
||||
#define yr_create_suite_from_functions(name, suite_refcon, lifecycle_callbacks, ...) \
|
||||
_yr_create_suite_from_functions(name, suite_refcon, lifecycle_callbacks, \
|
||||
# __VA_ARGS__, __VA_ARGS__)
|
||||
|
||||
/* Create a blank suite on the heap that you have to fill out.
|
||||
* It has the right number of cases that have the suite pointers in the cases set correctly.
|
||||
/**
|
||||
* Create a blank suite on the heap that you have to fill out.
|
||||
*
|
||||
* The suite has the right number of cases that have the suite pointers in the cases set correctly.
|
||||
* Everything else is zeroed/nulled out. This is the "escape hatch", really.
|
||||
*/
|
||||
YACHTROCK_EXTERN yr_test_suite_t
|
||||
yr_create_blank_suite(size_t num_cases);
|
||||
|
||||
/**
|
||||
* A collection of test suites.
|
||||
*
|
||||
* num_suites: the number of suites.
|
||||
* suites: the suites. When created by libyachtrock functions, all storage in the suites is in the
|
||||
* same allocation of the collection.
|
||||
*/
|
||||
struct yr_test_suite_collection {
|
||||
size_t num_suites;
|
||||
// note: storage in the same allocation when returned from libyachtrock functions
|
||||
|
@ -72,13 +119,32 @@ struct yr_test_suite_collection {
|
|||
typedef struct yr_test_suite_collection yr_test_suite_collection_s;
|
||||
typedef yr_test_suite_collection_s *yr_test_suite_collection_t;
|
||||
|
||||
/**
|
||||
* Create a collection from an array of suites, copying the suites.
|
||||
*
|
||||
* The resulting collection contains all suite storage as well and must be passed to free by the
|
||||
* caller.
|
||||
*/
|
||||
YACHTROCK_EXTERN yr_test_suite_collection_t
|
||||
yr_test_suite_collection_create_from_suites(size_t num_suites, yr_test_suite_t *suites);
|
||||
|
||||
/**
|
||||
* Create a collection from a set of collections, passed variadically.
|
||||
*
|
||||
* The resulting collection has copies of all suites in the input collections, containing all of
|
||||
* their storage, and must be passed to free by the caller.
|
||||
*/
|
||||
YACHTROCK_EXTERN yr_test_suite_collection_t
|
||||
yr_test_suite_collection_create_from_collections(size_t num_collections,
|
||||
yr_test_suite_collection_t collection1,
|
||||
...);
|
||||
|
||||
/**
|
||||
* Create a collection from a set of collections, passed as an array.
|
||||
*
|
||||
* The resulting collection has copies of all suites in the input collections, containing all of
|
||||
* their storage, and must be passed to free by the caller.
|
||||
*/
|
||||
YACHTROCK_EXTERN yr_test_suite_collection_t
|
||||
yr_test_suite_collection_create_from_collection_array(size_t num_collections,
|
||||
yr_test_suite_collection_t *collections);
|
||||
|
@ -86,6 +152,9 @@ yr_test_suite_collection_create_from_collection_array(size_t num_collections,
|
|||
|
||||
#if YACHTROCK_DLOPEN
|
||||
|
||||
/**
|
||||
* The name of the test suite collection discovery function that test dylibs must export.
|
||||
*/
|
||||
#define YACHTROCK_MODULE_DISCOVER_NAME yr_module_create_test_suite_collection
|
||||
|
||||
#define YACHTROCK_DISCOVER_VERSION 1
|
||||
|
@ -103,6 +172,9 @@ _yr_create_version_mismatch_error(unsigned discover_version,
|
|||
#define YACHTROCK_DISCOVERER_EXTERN extern
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Helper macro to define the test suite collection discovery function.
|
||||
*/
|
||||
#define YACHTROCK_DEFINE_TEST_SUITE_COLLECTION_DISCOVERER() \
|
||||
static yr_test_suite_collection_t \
|
||||
YACHTROCK_MODULE_DISCOVER_NAME ## __impl(unsigned discover_version, \
|
||||
|
@ -126,9 +198,19 @@ _yr_create_version_mismatch_error(unsigned discover_version,
|
|||
char **errmsg)
|
||||
|
||||
|
||||
/**
|
||||
* Discover a test suite collection provided by a dylib, by providing the path to the dylib.
|
||||
*
|
||||
* The resulting collection has all suite's storage and must be freed by the caller.
|
||||
*/
|
||||
YACHTROCK_EXTERN yr_test_suite_collection_t
|
||||
yr_test_suite_collection_create_from_dylib_path(const char *path, char **errmsg);
|
||||
|
||||
/**
|
||||
* Discover a test suite collection provided by a dylib, by providing a handle for the dylib.
|
||||
*
|
||||
* The resulting collection has all suite's storage and must be freed by the caller.
|
||||
*/
|
||||
YACHTROCK_EXTERN yr_test_suite_collection_t
|
||||
yr_test_suite_collection_create_from_handle(void *handle, char **errmsg);
|
||||
|
||||
|
|
|
@ -3,10 +3,16 @@
|
|||
|
||||
#include <yachtrock/base.h>
|
||||
|
||||
/**
|
||||
* Yachtrock version constants.
|
||||
*/
|
||||
YACHTROCK_EXTERN const unsigned yr_major;
|
||||
YACHTROCK_EXTERN const unsigned yr_minor;
|
||||
YACHTROCK_EXTERN const unsigned yr_patch;
|
||||
|
||||
/**
|
||||
* Precomposed Yachtrock version string.
|
||||
*/
|
||||
YACHTROCK_EXTERN const char *yr_version;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -10,17 +10,34 @@
|
|||
#include <yachtrock/results.h>
|
||||
#include <yachtrock/selector.h>
|
||||
|
||||
/**
|
||||
* Runtime callbacks and result hooks that print status to stderr.
|
||||
*/
|
||||
YACHTROCK_EXTERN const struct yr_runtime_callbacks YR_BASIC_STDERR_RUNTIME_CALLBACKS;
|
||||
YACHTROCK_EXTERN const struct yr_result_hooks YR_BASIC_STDERR_RESULT_HOOKS;
|
||||
|
||||
/**
|
||||
* Run a suite and print status and progress information to stderr. Returns true if all tests
|
||||
* passed.
|
||||
*/
|
||||
YACHTROCK_EXTERN bool yr_basic_run_suite(yr_test_suite_t suite);
|
||||
|
||||
/**
|
||||
* Run a suite with specified result hooks and runtime callbacks. Returns true if all tests passed.
|
||||
*/
|
||||
YACHTROCK_EXTERN bool yr_run_suite_with_result_hooks(yr_test_suite_t suite,
|
||||
struct yr_result_hooks hooks,
|
||||
struct yr_runtime_callbacks runtime_callbacks);
|
||||
|
||||
/**
|
||||
* Run a suite with runtime callbacks, recording results in the specified store.
|
||||
*/
|
||||
YACHTROCK_EXTERN void yr_run_suite_under_store(yr_test_suite_t suite,
|
||||
yr_result_store_t store,
|
||||
struct yr_runtime_callbacks runtime_callbacks);
|
||||
/**
|
||||
* Run a suite collection with runtime callbacks, recording results in the specified store.
|
||||
*/
|
||||
YACHTROCK_EXTERN void yr_run_suite_collection_under_store(yr_test_suite_collection_t collection,
|
||||
yr_result_store_t store,
|
||||
struct yr_runtime_callbacks runtime_callbacks);
|
||||
|
|
|
@ -115,9 +115,15 @@ yr_selector_t yr_selector_create_from_glob(const char *sel_specifier)
|
|||
testcase = NULL;
|
||||
}
|
||||
struct parsed_glob_specifier *parsed = create_parsed_glob_specifier(suite, testcase);
|
||||
yr_selector_t result = yr_selector_create(testname_glob_selector_vtable, parsed);
|
||||
return result;
|
||||
}
|
||||
|
||||
yr_selector_t yr_selector_create(struct yr_selector_vtable vtable, void *context)
|
||||
{
|
||||
yr_selector_t result = yr_malloc(sizeof(struct yr_selector));
|
||||
result->vtable = testname_glob_selector_vtable;
|
||||
result->context = parsed;
|
||||
result->vtable = vtable;
|
||||
result->context = context;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,11 +8,26 @@ cat <<EOF
|
|||
|
||||
/* This file is generated automatically when libyachtrock is built. */
|
||||
|
||||
/**
|
||||
* Whether this libyachtrock is targeting a "UNIX-y" environment.
|
||||
*/
|
||||
#define YACHTROCK_UNIXY $YACHTROCK_UNIXY
|
||||
|
||||
/**
|
||||
* Whether this libyachtrock is targeting a "POSIX-y" environment.
|
||||
*/
|
||||
#define YACHTROCK_POSIXY $YACHTROCK_POSIXY
|
||||
|
||||
/**
|
||||
* Whether this libyachtrock supports dynamic testcase discovery through the use of dlopen(3).
|
||||
*/
|
||||
#define YACHTROCK_DLOPEN $YACHTROCK_DLOPEN
|
||||
|
||||
/**
|
||||
* Whether this libyachtrock supports multi-process test execution.
|
||||
*/
|
||||
#define YACHTROCK_MULTIPROCESS $YACHTROCK_MULTIPROCESS
|
||||
|
||||
#endif
|
||||
|
||||
EOF
|
||||
EOF
|
||||
|
|
Loading…
Reference in New Issue