Skip to content

Commit

Permalink
v1.4.2 release.
Browse files Browse the repository at this point in the history
Merge branch 'develop' -- see `CHANGELOG.md` for details.
  • Loading branch information
silentbicycle committed Mar 24, 2019
2 parents 39b9093 + cd57092 commit 7f89ba4
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 37 deletions.
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
# greatest Changes By Release

## v1.4.2 - 2019-03-24

### API Changes

None.


### Other Improvements

Fixed configuration parameters for the PRNG (used for shuffling).
Previously, certain rare combinations of test counts and input states
could prevent the linear congruential RNG from having its full period
before repeating values, which could cause tests to be run multiple
times or skipped during shuffling.

Fixed an assertion in the example code where the expected annd actual
parameters were swapped. (Reported by @shaohuasong.)

Updated a comment to reflect that `GREATEST_ASSERT_STR_EQm` compares
using `strncmp`, not `strcmp`. (Reported by @orangewait.)

Minor formatting improvements in the README.


## v1.4.1 - 2018-12-30

### API Changes
Expand Down
33 changes: 17 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ and print functions, use `ASSERT_EQUAL_T` instead.
### `ASSERT_EQ_FMT(EXPECTED, ACTUAL, FORMAT)`

Assert that `EXPECTED == ACTUAL`. If they are not equal, print their
values using FORMAT as the `printf` format string.
values using `FORMAT` as the `printf` format string.

For example: `ASSERT_EQ_FMT(123, result, "%d");` will call `printf`
like `printf("Expected: %d\nGot: %d\n", 123, result);` if its
Expand All @@ -204,8 +204,8 @@ captured in a local variable. `typeof` is a GCC extension.)

### `ASSERT_IN_RANGE(EXPECTED, ACTUAL, TOLERANCE)`

Assert that ACTUAL is within EXPECTED +/- TOLERANCE, once the values
have been converted to a configurable floating point type
Assert that `ACTUAL` is within `EXPECTED` +/- `TOLERANCE`, once the
values have been converted to a configurable floating point type
(`GREATEST_FLOAT`).

greatest does not depent on floating point math.
Expand All @@ -220,21 +220,22 @@ Assert that the strings are equal

### `ASSERT_STRN_EQ(EXPECTED, ACTUAL, SIZE)`

Assert that the first SIZE bytes of the strings are equal
Assert that the first `SIZE` bytes of the strings are equal
(i.e., `strncmp(EXPECTED, ACTUAL, SIZE) == 0`).


### `ASSERT_MEM_EQ(EXPECTED, ACTUAL, SIZE)`

Assert that the first SIZE bytes of memory pointed to by EXPECTED and
ACTUAL are equal. If their memory differs, print a hexdump and highlight
the lines and individual bytes which do not match.
Assert that the first `SIZE` bytes of memory pointed to by `EXPECTED`
and `ACTUAL` are equal. If their memory differs, print a hexdump and
highlight the lines and individual bytes which do not match.


### `ASSERT_ENUM_EQ(EXPECTED, ACTUAL, ENUM_STR_FUN)`

Assert that the enum value EXPECTED is equal to ACTUAL. If not, convert
each enum value to a string using `ENUM_STR_FUN` before printing them.
Assert that the enum value `EXPECTED` is equal to `ACTUAL`. If not,
convert each enum value to a string using `ENUM_STR_FUN` before printing
them.

`ENUM_STR_FUN` should have a type like:

Expand All @@ -243,12 +244,12 @@ each enum value to a string using `ENUM_STR_FUN` before printing them.

### `ASSERT_EQUAL_T(EXPECTED, ACTUAL, TYPE_INFO, UDATA)`

Assert that EXPECTED and ACTUAL are equal, using the `greatest_equal_cb`
function pointed to by `TYPE_INFO->equal` to compare them. The
assertion's `UDATA` argument can be used to pass in arbitrary user data
(or `NULL`). If the values are not equal and the `TYPE_INFO->print`
function is defined, it will be used to print an "Expected: X, Got: Y"
message.
Assert that `EXPECTED` and `ACTUAL` are equal, using the
`greatest_equal_cb` function pointed to by `TYPE_INFO->equal` to compare
them. The assertion's `UDATA` argument can be used to pass in arbitrary
user data (or `NULL`) to the callbacks. If the values are not equal and
the `TYPE_INFO->print` function is defined, it will be used to print an
"Expected: X, Got: Y" message.


### `ASSERT_OR_LONGJMP(COND)`
Expand All @@ -265,7 +266,7 @@ bytes, depending on the platform.

## Random Shuffling

Groups of suites or tests can be run in random order by using
Groups of suites or tests can be run in shuffled order by using
`GREATEST_SHUFFLE_SUITES` and `GREATEST_SHUFFLE_TESTS`, respectively.
This can help find and eliminate accidental coupling between tests.

Expand Down
2 changes: 1 addition & 1 deletion example.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ TEST expect_mem_equal(void) {
got[23] = 'X';
got[34] = 'X';

ASSERT_MEM_EQm("expected matching memory", got, exp, sizeof(got));
ASSERT_MEM_EQm("expected matching memory", exp, got, sizeof(got));
PASS();
}

Expand Down
6 changes: 4 additions & 2 deletions example_shuffle.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ static void set_suffix(unsigned int i) {
SUITE(suite1) {
const unsigned int limit = TEST_COUNT;
volatile unsigned int count;
const unsigned int small_test_count = 10;
const unsigned int small_test_count = 11;
volatile unsigned int i = 0;

/* Check that all are run exactly once, for a small number of tests */
Expand All @@ -106,6 +106,8 @@ SUITE(suite1) {
COUNT_RUN(6);
COUNT_RUN(7);
COUNT_RUN(8);
COUNT_RUN(9);
COUNT_RUN(10);
});
#undef COUNT_RUN

Expand Down Expand Up @@ -169,9 +171,9 @@ int main(int argc, char **argv) {

/* PRNG internal state assumes uint32_t values */
assert(sizeof(greatest_info.prng[0].state) >= 4);
assert(sizeof(greatest_info.prng[0].mod) >= 4);
assert(sizeof(greatest_info.prng[0].a) >= 4);
assert(sizeof(greatest_info.prng[0].c) >= 4);
assert(sizeof(greatest_info.prng[0].m) >= 4);

SHUFFLE_SUITES(seed_of_time(), {
RUN_SUITE(suite1);
Expand Down
33 changes: 16 additions & 17 deletions greatest.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
extern "C" {
#endif

/* 1.4.1 */
/* 1.4.2 */
#define GREATEST_VERSION_MAJOR 1
#define GREATEST_VERSION_MINOR 4
#define GREATEST_VERSION_PATCH 1
#define GREATEST_VERSION_PATCH 2

/* A unit testing system for C, contained in 1 file.
* It doesn't use dynamic allocation or depend on anything
Expand Down Expand Up @@ -223,9 +223,9 @@ struct greatest_prng {
unsigned long count; /* how many tests, this pass */
unsigned long count_ceil; /* total number of tests */
unsigned long count_run; /* total tests run */
unsigned long mod; /* power-of-2 ceiling of count_ceil */
unsigned long a; /* LCG multiplier */
unsigned long c; /* LCG increment */
unsigned long m; /* LCG modulus, based on count_ceil */
};

/* Struct containing all test runner state. */
Expand Down Expand Up @@ -539,7 +539,7 @@ typedef enum greatest_test_res {
&greatest_type_info_string, NULL); \
} while (0) \

/* Fail if EXP is not equal to GOT, according to strcmp. */
/* Fail if EXP is not equal to GOT, according to strncmp. */
#define GREATEST_ASSERT_STRN_EQm(MSG, EXP, GOT, SIZE) \
do { \
size_t size = SIZE; \
Expand Down Expand Up @@ -1075,18 +1075,17 @@ void greatest_prng_init_first_pass(int id) { \
} \
\
int greatest_prng_init_second_pass(int id, unsigned long seed) { \
static unsigned long primes[] = { 11, 101, 1009, 10007, \
100003, 1000003, 10000019, 100000007, 1000000007, \
1538461, 1865471, 17471, 2147483647 /* 2**32 - 1 */, }; \
struct greatest_prng *prng = &greatest_info.prng[id]; \
if (prng->count == 0) { return 0; } \
prng->mod = 1; \
prng->count_ceil = prng->count; \
while (prng->mod < prng->count) { prng->mod <<= 1; } \
prng->state = seed & 0x1fffffff; /* only use lower 29 bits... */ \
prng->a = (4LU * prng->state) + 1; /* to avoid overflow */ \
prng->c = primes[(seed * 16451) % sizeof(primes)/sizeof(primes[0])];\
prng->initialized = 1; \
struct greatest_prng *p = &greatest_info.prng[id]; \
if (p->count == 0) { return 0; } \
p->count_ceil = p->count; \
for (p->m = 1; p->m < p->count; p->m <<= 1) {} \
p->state = seed & 0x1fffffff; /* only use lower 29 bits */ \
p->a = 4LU * p->state; /* to avoid overflow when */ \
p->a = (p->a ? p->a : 4) | 1; /* multiplied by 4 */ \
p->c = 2147483647; /* and so p->c ((2 ** 31) - 1) is */ \
p->initialized = 1; /* always relatively prime to p->a. */ \
fprintf(stderr, "init_second_pass: a %lu, c %lu, state %lu\n", \
p->a, p->c, p->state); \
return 1; \
} \
\
Expand All @@ -1103,7 +1102,7 @@ int greatest_prng_init_second_pass(int id, unsigned long seed) { \
void greatest_prng_step(int id) { \
struct greatest_prng *p = &greatest_info.prng[id]; \
do { \
p->state = ((p->a * p->state) + p->c) & (p->mod - 1); \
p->state = ((p->a * p->state) + p->c) & (p->m - 1); \
} while (p->state >= p->count_ceil); \
} \
\
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "greatest",
"version": "v1.4.1",
"version": "v1.4.2",
"repo": "silentbicycle/greatest",
"src": ["greatest.h"],
"description": "A C testing library in 1 file. No dependencies, no dynamic allocation.",
Expand Down

0 comments on commit 7f89ba4

Please sign in to comment.