Reorganize

- Extracted functions to //lib:test for writing tests

- Extracted functions to lib/util.h if they are useful outside tests
This commit is contained in:
Dietrich Epp 2022-03-30 03:46:19 -04:00
parent d980169ec6
commit c4bf86786e
9 changed files with 173 additions and 99 deletions

View File

@ -48,5 +48,6 @@ cc_test(
deps = [
":convert",
"//lib",
"//lib:test",
],
)

View File

@ -1,12 +1,8 @@
/* Converter test. */
#define _XOPEN_SOURCE 500
#include "convert/convert.h"
#include "convert/data.h"
#include "lib/test.h"
#include "lib/util.h"
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -17,55 +13,6 @@ enum
kConvertBufferSize = 1024
};
static int gFailCount;
static char gTestName[128];
static void Failf(const char *msg, ...) __attribute__((format(printf, 1, 2)));
static void Failf(const char *msg, ...)
{
va_list ap;
gFailCount++;
fputs("Error: ", stderr);
fputs(gTestName, stderr);
fputs(": ", stderr);
va_start(ap, msg);
vfprintf(stderr, msg, ap);
va_end(ap);
fputc('\n', stderr);
if (gFailCount >= 10) {
exit(1);
}
}
static const char *const kErrorNames[] = {"ok", "no memory", "bad data"};
static const char *ErrorName(ErrorCode err)
{
if (err < 0 || (int)(sizeof(kErrorNames) / sizeof(*kErrorNames)) <= err) {
Dief("bad error code: %d", err);
}
return kErrorNames[err];
}
static void StringPrintf(char *dest, size_t destsz, const char *fmt, ...)
__attribute__((format(printf, 3, 4)));
static void StringPrintf(char *dest, size_t destsz, const char *fmt, ...)
{
va_list ap;
int n;
va_start(ap, fmt);
n = vsnprintf(dest, destsz, fmt, ap);
va_end(ap);
if (n < 0 || n >= (int)destsz) {
Dief("snprintf: overflow");
}
}
static UInt8 *gBuffer[3];
static void PrintQuotedString(const UInt8 *buf, int len)
@ -161,19 +108,19 @@ static void TestConverter(const char *name, struct CharmapData data)
cf.data = NULL;
cr.data = NULL;
StringPrintf(gTestName, sizeof(gTestName), "%s", name);
SetTestNamef(name);
/* Load the converter into memory and build the conversion table. */
datap = (void *)data.ptr;
datah = &datap;
err = ConverterBuild(&cf, datah, data.size, kToUTF8);
if (err != 0) {
Failf("ConverterBuild: to UTF-8: %s", ErrorName(err));
Failf("ConverterBuild: to UTF-8: %s", ErrorDescriptionOrDie(err));
goto done;
}
err = ConverterBuild(&cr, datah, data.size, kFromUTF8);
if (err != 0) {
Failf("ConverterBuild: from UTF-8: %s", ErrorName(err));
Failf("ConverterBuild: from UTF-8: %s", ErrorDescriptionOrDie(err));
goto done;
}
@ -206,8 +153,7 @@ static void TestConverter(const char *name, struct CharmapData data)
jmax = 4;
}
for (j = 1; j <= jmax; j++) {
StringPrintf(gTestName, sizeof(gTestName), "%s reverse i=%d j=%d",
name, i, j);
SetTestNamef("%s reverse i=%d j=%d", name, i, j);
st.data = 0;
iptr = gBuffer[1];
optr = gBuffer[2];
@ -237,8 +183,7 @@ static void TestConverter(const char *name, struct CharmapData data)
len1 = lblen[0]; /* Input data */
len0 = lblen[i]; /* Expected output */
for (j = 1; j < len1; j++) {
StringPrintf(gTestName, sizeof(gTestName),
"%s %s linebreak %s split=%d", name,
SetTestNamef("%s %s linebreak %s split=%d", name,
k == 0 ? "forward" : "backward", kLineBreakName[i],
j);
st.data = 0;
@ -282,7 +227,7 @@ int main(int argc, char **argv)
for (i = 0; i < 3; i++) {
buf = malloc(kConvertBufferSize);
if (buf == NULL) {
Dief("malloc failed");
Fatalf("malloc failed");
}
gBuffer[i] = buf;
}
@ -302,10 +247,5 @@ int main(int argc, char **argv)
free(gBuffer[i]);
}
if (gFailCount > 0) {
fputs("failed\n", stderr);
return 1;
}
fputs("ok\n", stderr);
return 0;
return TestsDone();
}

View File

@ -5,14 +5,31 @@ cc_library(
name = "lib",
srcs = [
"toolbox.c",
"util.c",
],
hdrs = [
"defs.h",
"endian.h",
"util.h",
],
copts = COPTS,
visibility = ["//visibility:public"],
)
cc_library(
name = "test",
testonly = True,
srcs = [
"test.c",
],
hdrs = [
"test.h",
],
copts = COPTS,
visibility = ["//visibility:public"],
deps = [
":lib",
],
)
cc_test(
@ -23,5 +40,6 @@ cc_test(
copts = COPTS,
deps = [
":lib",
":test",
],
)

View File

@ -1,22 +1,22 @@
#include "lib/endian.h"
#include "lib/test.h"
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
static int gDidFail;
static void Fail(const char *name, UInt32 got, UInt32 expect)
static void EndianFail(const char *name, UInt32 got, UInt32 expect)
{
fprintf(stderr, "%s = 0x%" PRIx32 ", expect 0x%" PRIx32 "\n", name, got,
expect);
gDidFail = 1;
gFailCount++;
}
#define CHECK(fn, expect) \
be = fn(u.i); \
if (be != expect) { \
Fail(#fn, be, expect); \
#define CHECK(fn, expect) \
be = fn(u.i); \
if (be != expect) { \
EndianFail(#fn, be, expect); \
}
static void Test16(void)
@ -58,5 +58,5 @@ int main(int argc, char **argv)
Test16();
Test32();
return gDidFail;
return TestsDone();
}

77
lib/test.c Normal file
View File

@ -0,0 +1,77 @@
/* Defined to get vsnprintf. */
#define _XOPEN_SOURCE 500
#include "lib/test.h"
#include "lib/util.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int gFailCount;
static char gTestName[256];
void SetTestName(const char *name)
{
size_t n;
n = strlen(name);
if (n >= sizeof(gTestName) - 1) {
Fatalf("SetTestName: overflow");
}
memcpy(gTestName, name, n + 1);
}
void SetTestNamef(const char *fmt, ...)
{
va_list ap;
int r;
va_start(ap, fmt);
r = vsnprintf(gTestName, sizeof(gTestName), fmt, ap);
va_end(ap);
if (r >= (int)sizeof(gTestName)) {
Fatalf("SetTestNamef: overflow");
}
}
void Failf(const char *msg, ...)
{
va_list ap;
gFailCount++;
fputs("Error: ", stderr);
fputs(gTestName, stderr);
fputs(": ", stderr);
va_start(ap, msg);
vfprintf(stderr, msg, ap);
va_end(ap);
fputc('\n', stderr);
if (gFailCount >= 10) {
exit(1);
}
}
const char *ErrorDescriptionOrDie(ErrorCode err)
{
const char *desc;
desc = ErrorDescription(err);
if (desc == NULL) {
Fatalf("invalid error code: %d", err);
}
return desc;
}
int TestsDone(void)
{
if (gFailCount > 0) {
fputs("failed\n", stderr);
return 1;
}
fputs("ok\n", stderr);
return 0;
}

View File

@ -4,11 +4,23 @@
#include "lib/defs.h"
/* Print an error message and exit. */
void Dief(const char *msg, ...) __attribute__((noreturn, format(printf, 1, 2)));
/* The number of test failures. */
extern int gFailCount;
/* Print an error message with an error code and exit. */
void DieErrorf(int errcode, const char *msg, ...)
__attribute__((noreturn, format(printf, 2, 3)));
/* Set the name of the current test. */
void SetTestName(const char *name);
/* Set the name of the current test. */
void SetTestNamef(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
/* Fail the current test. */
void Failf(const char *msg, ...) __attribute__((format(printf, 1, 2)));
/* Return the description of an error code. Fatal error if the error code is
invalid. */
const char *ErrorDescriptionOrDie(ErrorCode err);
/* Print information about completed tests and return the status code. */
int TestsDone(void );
#endif

View File

@ -4,31 +4,18 @@
development easier. These are not intended to make it possible to port the
converter to non-Mac OS systems. */
#include "lib/defs.h"
#include "lib/test.h"
#include "lib/util.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void Dief(const char *msg, ...)
{
va_list ap;
fputs("Error: ", stderr);
va_start(ap, msg);
vfprintf(stderr, msg, ap);
va_end(ap);
fputc('\n', stderr);
exit(1);
}
Handle NewHandle(Size byteCount)
{
Ptr p;
Handle h;
if (byteCount < 0) {
Dief("NewHandle: byteCount = %ld", byteCount);
Fatalf("NewHandle: byteCount = %ld", byteCount);
}
p = malloc(byteCount);
if (byteCount > 0 && p == NULL) {
@ -55,10 +42,10 @@ Boolean ResizeHandle(Handle h, Size newSize)
{
Ptr p;
if (h == NULL) {
Dief("ResizeHandle: h = NULL");
Fatalf("ResizeHandle: h = NULL");
}
if (newSize < 0) {
Dief("ResizeHandle: newSize = %ld", newSize);
Fatalf("ResizeHandle: newSize = %ld", newSize);
}
p = realloc(*h, newSize);
if (newSize > 0 && p == NULL) {

26
lib/util.c Normal file
View File

@ -0,0 +1,26 @@
#include "lib/util.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
void Fatalf(const char *msg, ...)
{
va_list ap;
fputs("Error: ", stderr);
va_start(ap, msg);
vfprintf(stderr, msg, ap);
va_end(ap);
fputc('\n', stderr);
exit(1);
}
static const char *const kErrorNames[] = {"ok", "no memory", "bad data"};
const char *ErrorDescription(ErrorCode err)
{
if (err < 0 || (int)(sizeof(kErrorNames) / sizeof(*kErrorNames)) <= err) {
return NULL;
}
return kErrorNames[err];
}

13
lib/util.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef lib_util_h
#define lib_util_h
#include "lib/defs.h"
/* Print an error message and exit. */
void Fatalf(const char *msg, ...)
__attribute__((noreturn, format(printf, 1, 2)));
/* Return a basic description of the given error code, or NULL if the error code
is unknown. */
const char *ErrorDescription(ErrorCode err);
#endif