typedef struct {
njs_bool_t disassemble;
+ njs_str_t filter;
njs_bool_t verbose;
- njs_bool_t unsafe;
+
+ njs_uint_t externals;
njs_bool_t module;
njs_uint_t repeat;
- njs_uint_t externals;
+ njs_bool_t unsafe;
} njs_opts_t;
static void
-njs_unit_test_report(const char *msg, njs_stat_t *prev, njs_stat_t *current)
+njs_unit_test_report(njs_str_t *name, njs_stat_t *prev, njs_stat_t *current)
{
njs_stat_t stat;
stat.failed = current->failed - prev->failed;
stat.passed = current->passed - prev->passed;
- njs_printf("%s: %s [%d/%d]\n", msg, stat.failed ? "FAILED" : "PASSED",
- stat.passed, stat.passed + stat.failed);
+ njs_printf("%V tests: %s [%d/%d]\n", name,
+ stat.failed ? "FAILED" : "PASSED", stat.passed,
+ stat.passed + stat.failed);
}
static njs_int_t
-njs_unit_test(njs_unit_test_t tests[], size_t num, const char *name,
+njs_unit_test(njs_unit_test_t tests[], size_t num, njs_str_t *name,
njs_opts_t *opts, njs_stat_t *stat)
{
u_char *start, *end;
static njs_int_t
-njs_interactive_test(njs_unit_test_t tests[], size_t num, const char *name,
+njs_interactive_test(njs_unit_test_t tests[], size_t num, njs_str_t *name,
njs_opts_t *opts, njs_stat_t *stat)
{
u_char *start, *last, *end;
}
start = tests[i].script.start;
- last = start + tests[i].script.length;
+ last = start + tests[i].script.length;
end = NULL;
for ( ;; ) {
ret = njs_vm_compile(vm, &start, end);
if (ret == NJS_OK) {
+ if (opts->disassemble) {
+ njs_disassembler(vm);
+ }
+
ret = njs_vm_start(vm);
}
}
static njs_int_t
-njs_timezone_optional_test(njs_opts_t *opts, njs_stat_t *stat)
+njs_timezone_optional_test(njs_unit_test_t tests[], size_t num, njs_str_t *name,
+ njs_opts_t *opts, njs_stat_t *stat)
{
size_t size;
u_char buf[16];
size = strftime((char *) buf, sizeof(buf), "%z", &tm);
if (memcmp(buf, "+1245", size) == 0) {
- ret = njs_unit_test(njs_tz_test, njs_nitems(njs_tz_test),
- "timezone tests", opts, stat);
+ ret = njs_unit_test(tests, num, name, opts, stat);
if (ret != NJS_OK) {
return ret;
}
static njs_int_t
-njs_regexp_optional_test(njs_opts_t *opts, njs_stat_t *stat)
+njs_regexp_optional_test(njs_unit_test_t tests[], size_t num, njs_str_t *name,
+ njs_opts_t *opts, njs_stat_t *stat)
{
int erroff;
pcre *re1, *re2;
&errstr, &erroff, NULL);
if (re1 == NULL && re2 != NULL) {
- ret = njs_unit_test(njs_regexp_test, njs_nitems(njs_regexp_test),
- "unicode regexp tests", opts, stat);
+ ret = njs_unit_test(tests, num, name, opts, stat);
if (ret != NJS_OK) {
return ret;
}
static njs_int_t
-njs_vm_json_test(njs_opts_t *opts, njs_stat_t *stat)
+njs_vm_json_test(njs_unit_test_t unused[], size_t num, njs_str_t *name,
+ njs_opts_t *opts, njs_stat_t *stat)
{
njs_vm_t *vm;
njs_int_t ret;
}
}
- njs_unit_test_report("VM json API tests", &prev, stat);
+ njs_unit_test_report(name, &prev, stat);
if (vm != NULL) {
njs_vm_destroy(vm);
static njs_int_t
-njs_vm_value_test(njs_opts_t *opts, njs_stat_t *stat)
+njs_vm_value_test(njs_unit_test_t unused[], size_t num, njs_str_t *name,
+ njs_opts_t *opts, njs_stat_t *stat)
{
njs_vm_t *vm;
njs_int_t ret;
}
}
- njs_unit_test_report("njs_vm_value() tests", &prev, stat);
+ njs_unit_test_report(name, &prev, stat);
if (vm != NULL) {
njs_vm_destroy(vm);
static njs_int_t
-njs_api_test(njs_opts_t *opts, njs_stat_t *stat)
+njs_vm_internal_api_test(njs_unit_test_t unused[], size_t num, njs_str_t *name,
+ njs_opts_t *opts, njs_stat_t *stat)
{
njs_vm_t *vm;
njs_int_t ret;
done:
- njs_unit_test_report("API tests", &prev, stat);
+ njs_unit_test_report(name, &prev, stat);
if (vm != NULL) {
njs_vm_destroy(vm);
}
-int njs_cdecl
-main(int argc, char **argv)
+static njs_int_t
+njs_get_options(njs_opts_t *opts, int argc, char **argv)
{
- njs_int_t ret;
- njs_opts_t opts;
- njs_stat_t stat;
+ char *p;
+ njs_int_t i;
- njs_memzero(&opts, sizeof(njs_opts_t));
+ static const char help[] =
+ "njs unit tests.\n"
+ "\n"
+ "njs_unit_test [options]"
+ "\n"
+ "Options:\n"
+ " -d print disassembled code.\n"
+ " -f PATTERN1[|PATTERN2..] filter test suites to run.\n"
+ " -v verbose mode.\n";
+
+ for (i = 1; i < argc; i++) {
+
+ p = argv[i];
+
+ if (p[0] != '-') {
+ goto help;
+ }
+
+ p++;
- if (argc > 1) {
- switch (argv[1][0]) {
+ switch (*p) {
+ case '?':
+ case 'h':
+ (void) write(STDOUT_FILENO, help, njs_length(help));
+ return NJS_DONE;
case 'd':
- opts.disassemble = 1;
+ opts->disassemble = 1;
break;
+ case 'f':
+ if (++i < argc) {
+ opts->filter.start = (u_char *) argv[i];
+ opts->filter.length = njs_strlen(argv[i]);
+ break;
+ }
+
+ njs_stderror("option \"-f\" requires argument\n");
+ return NJS_ERROR;
+
case 'v':
- opts.verbose = 1;
+ opts->verbose = 1;
break;
default:
- break;
+ goto help;
}
}
- (void) putenv((char *) "TZ=UTC");
- tzset();
+ return NJS_OK;
- njs_memzero(&stat, sizeof(njs_stat_t));
+help:
- opts.repeat = 1;
- opts.unsafe = 1;
+ njs_stderror("Unknown argument: \"%s\" "
+ "try \"%s -h\" for available options\n", argv[i],
+ argv[0]);
- njs_mm_denormals(1);
+ return NJS_ERROR;
+}
- ret = njs_unit_test(njs_test, njs_nitems(njs_test), "script tests",
- &opts, &stat);
- if (ret != NJS_OK) {
- return ret;
+
+static njs_int_t
+njs_match_test(njs_opts_t *opts, njs_str_t *name)
+{
+ u_char *p, *start, *end;
+ size_t len;
+
+ if (name->length == 0) {
+ return 0;
}
- ret = njs_unit_test(njs_denormals_test, njs_nitems(njs_denormals_test),
- "denormals tests", &opts, &stat);
- if (ret != NJS_OK) {
- return ret;
+ if (opts->filter.length == 0) {
+ return 1;
}
-#if (NJS_HAVE_DENORMALS_CONTROL)
+ start = opts->filter.start;
+ end = start + opts->filter.length;
- njs_mm_denormals(0);
+ for ( ;; ) {
+ p = njs_strlchr(start, end, '|');
+ len = ((p != NULL) ? p : end) - start;
+ len = njs_min(name->length, len);
- ret = njs_unit_test(njs_disabled_denormals_test,
- njs_nitems(njs_disabled_denormals_test),
- "disabled denormals tests", &opts, &stat);
- if (ret != NJS_OK) {
- return ret;
+ if (len != 0 && njs_strncmp(name->start, start, len) == 0) {
+ return 1;
+ }
+
+ if (p == NULL) {
+ break;
+ }
+
+ start = p + 1;
}
+ return 0;
+}
+
+
+typedef struct {
+ njs_str_t name;
+ njs_opts_t opts;
+ njs_unit_test_t *tests;
+ size_t n;
+ njs_int_t (*run)(njs_unit_test_t tests[], size_t num,
+ njs_str_t *name, njs_opts_t *opts,
+ njs_stat_t *stat);
+} njs_test_suite_t;
+
+
+static njs_int_t
+njs_disabled_denormals_tests(njs_unit_test_t tests[], size_t num,
+ njs_str_t *name, njs_opts_t *opts, njs_stat_t *stat)
+{
+ njs_int_t ret;
+
+ njs_mm_denormals(0);
+
+ ret = njs_unit_test(tests, num, name, opts, stat);
+
njs_mm_denormals(1);
-#else
+ return ret;
+}
- (void) njs_disabled_denormals_test;
+static njs_test_suite_t njs_suites[] =
+{
+ { njs_str("script"),
+ { .repeat = 1, .unsafe = 1 },
+ njs_test,
+ njs_nitems(njs_test),
+ njs_unit_test },
+
+ { njs_str("denormals"),
+ { .repeat = 1, .unsafe = 1 },
+ njs_denormals_test,
+ njs_nitems(njs_denormals_test),
+ njs_unit_test },
+
+ {
+#if (NJS_HAVE_DENORMALS_CONTROL)
+ njs_str("disabled denormals"),
+#else
+ njs_str(""),
#endif
+ { .repeat = 1, .unsafe = 1 },
+ njs_disabled_denormals_test,
+ njs_nitems(njs_disabled_denormals_test),
+ njs_disabled_denormals_tests },
+
+ { njs_str("module"),
+ { .repeat = 1, .module = 1, .unsafe = 1 },
+ njs_module_test,
+ njs_nitems(njs_module_test),
+ njs_unit_test },
+
+ { njs_str("externals"),
+ { .externals = 1, .repeat = 1, .unsafe = 1 },
+ njs_externals_test,
+ njs_nitems(njs_externals_test),
+ njs_unit_test },
+
+ { njs_str("shared"),
+ { .externals = 1, .repeat = 128, .unsafe = 1 },
+ njs_shared_test,
+ njs_nitems(njs_shared_test),
+ njs_unit_test },
+
+ { njs_str("interactive"),
+ { .externals = 1, .repeat = 1, .unsafe = 1 },
+ njs_shell_test,
+ njs_nitems(njs_shell_test),
+ njs_interactive_test },
+
+ { njs_str("timezone"),
+ { .repeat = 1, .unsafe = 1 },
+ njs_tz_test,
+ njs_nitems(njs_tz_test),
+ njs_timezone_optional_test },
+
+ { njs_str("regexp"),
+ { .repeat = 1, .unsafe = 1 },
+ njs_regexp_test,
+ njs_nitems(njs_regexp_test),
+ njs_regexp_optional_test },
+
+ { njs_str("vm_json"),
+ { .repeat = 1, .unsafe = 1 },
+ NULL,
+ 0,
+ njs_vm_json_test },
+
+ { njs_str("vm_value"),
+ { .repeat = 1, .unsafe = 1 },
+ NULL,
+ 0,
+ njs_vm_value_test },
+
+ { njs_str("vm_internal_api"),
+ { .repeat = 1, .unsafe = 1 },
+ NULL,
+ 0,
+ njs_vm_internal_api_test },
+};
- ret = njs_timezone_optional_test(&opts, &stat);
- if (ret != NJS_OK) {
- return ret;
- }
- ret = njs_regexp_optional_test(&opts, &stat);
- if (ret != NJS_OK) {
- return ret;
- }
+int njs_cdecl
+main(int argc, char **argv)
+{
+ njs_int_t ret;
+ njs_uint_t i;
+ njs_opts_t opts, op;
+ njs_stat_t stat;
+ njs_test_suite_t *suite;
- ret = njs_vm_json_test(&opts, &stat);
- if (ret != NJS_OK) {
- return ret;
- }
+ njs_memzero(&opts, sizeof(njs_opts_t));
- ret = njs_vm_value_test(&opts, &stat);
+ ret = njs_get_options(&opts, argc, argv);
if (ret != NJS_OK) {
- return ret;
+ return (ret == NJS_DONE) ? EXIT_SUCCESS: EXIT_FAILURE;
}
- ret = njs_api_test(&opts, &stat);
- if (ret != NJS_OK) {
- return ret;
- }
+ (void) putenv((char *) "TZ=UTC");
+ tzset();
- opts.module = 1;
+ njs_mm_denormals(1);
- ret = njs_unit_test(njs_module_test, njs_nitems(njs_module_test),
- "module tests", &opts, &stat);
- if (ret != NJS_OK) {
- return ret;
- }
+ njs_memzero(&stat, sizeof(njs_stat_t));
- opts.module = 0;
- opts.externals = 1;
+ for (i = 0; i < njs_nitems(njs_suites); i++) {
+ suite = &njs_suites[i];
- ret = njs_unit_test(njs_externals_test, njs_nitems(njs_externals_test),
- "externals tests", &opts, &stat);
- if (ret != NJS_OK) {
- return ret;
- }
+ if (!njs_match_test(&opts, &suite->name)) {
+ continue;
+ }
- ret = njs_interactive_test(njs_shell_test, njs_nitems(njs_shell_test),
- "interactive tests", &opts, &stat);
- if (ret != NJS_OK) {
- return ret;
- }
+ op = suite->opts;
- opts.repeat = 128;
+ op.verbose = opts.verbose;
+ op.disassemble = opts.disassemble;
- ret = njs_unit_test(njs_shared_test, njs_nitems(njs_shared_test),
- "shared tests", &opts, &stat);
- if (ret != NJS_OK) {
- return ret;
+ ret = suite->run(suite->tests, suite->n, &suite->name, &op, &stat);
+ if (ret != NJS_OK) {
+ return ret;
+ }
}
njs_printf("TOTAL: %s [%ui/%ui]\n", stat.failed ? "FAILED" : "PASSED",