X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=tools%2Fccanlint%2Ftests%2Fhas_tests.c;h=bdfe49d56b8725389b279671052fd8356f499a06;hp=4237540011fed95d5a351d40246998ae9449ec17;hb=2926cafb52b9d95646d9dafa877d53f2368d8b2c;hpb=71c95e84ac622186f7e0ba0c0e7780c5acbc185e diff --git a/tools/ccanlint/tests/has_tests.c b/tools/ccanlint/tests/has_tests.c index 42375400..bdfe49d5 100644 --- a/tools/ccanlint/tests/has_tests.c +++ b/tools/ccanlint/tests/has_tests.c @@ -10,45 +10,22 @@ #include #include -static char test_is_not_dir[] = "test is not a directory"; +extern struct ccanlint tests_exist; -static void *check_has_tests(struct manifest *m, - bool keep, - unsigned int *timeleft) +static void handle_no_tests(struct manifest *m, struct score *score) { - struct stat st; + FILE *run; + struct ccan_file *i; char *test_dir = talloc_asprintf(m, "%s/test", m->dir); - if (lstat(test_dir, &st) != 0) { - if (errno != ENOENT) - err(1, "statting %s", test_dir); - return "You have no test directory"; - } - - if (!S_ISDIR(st.st_mode)) - return test_is_not_dir; - - if (list_empty(&m->api_tests) - && list_empty(&m->run_tests) - && list_empty(&m->compile_ok_tests)) { - if (list_empty(&m->compile_fail_tests)) - return "You have no tests in the test directory"; - else - return "You have no positive tests in the test directory"; - } - return NULL; -} - -static const char *describe_has_tests(struct manifest *m, void *check_result) -{ - return talloc_asprintf(m, "%s\n\n" - "CCAN modules have a directory called test/ which contains tests.\n" + printf( + "CCAN modules have a directory called test/ which contains tests.\n" "There are four kinds of tests: api, run, compile_ok and compile_fail:\n" "you can tell which type of test a C file is by its name, eg 'run.c'\n" "and 'run-simple.c' are both run tests.\n\n" "The simplest kind of test is a run test, which must compile with no\n" - "warnings, and then run: it is expected to use libtap to report its\n" + "warnings, and then run: it is expected to use ccan/tap to report its\n" "results in a simple and portable format. It should #include the C\n" "files from the module directly (so it can probe the internals): the\n" "module will not be linked in. The test will be run in a temporary\n" @@ -67,20 +44,8 @@ static const char *describe_has_tests(struct manifest *m, void *check_result) "when it's not defined: this helps ensure unrelated errors don't make\n" "compilation fail.\n\n" - "Note that the tests are not linked against the files in the\n" - "above: you should directly #include those C files you want. This\n" - "allows access to static functions and use special effects inside\n" - "test files\n", (char *)check_result); -} - -static void handle_no_tests(struct manifest *m, void *check_result) -{ - FILE *run; - struct ccan_file *i; - char *test_dir = talloc_asprintf(m, "%s/test", m->dir); - - if (check_result == test_is_not_dir) - return; + "Note that only API tests are linked against the files in the module!\n" + ); if (!ask("Should I create a template test/run.c file for you?")) return; @@ -101,41 +66,71 @@ static void handle_no_tests(struct manifest *m, void *check_result) fprintf(run, "#include \n", m->basename, i->name); } - fputs("#include \n", run); - fputs("\n", run); - - fputs("int main(void)\n", run); - fputs("{\n", run); - fputs("\t/* This is how many tests you plan to run */\n", run); - fputs("\tplan_tests(3);\n", run); - fputs("\n", run); - fputs("\t/* Simple thing we expect to succeed */\n", run); - fputs("\tok1(some_test())\n", run); - fputs("\t/* Same, with an explicit description of the test. */\n", run); - fputs("\tok(some_test(), \"%s with no args should return 1\", \"some_test\")\n", run); - fputs("\t/* How to print out messages for debugging. */\n", run); - fputs("\tdiag(\"Address of some_test is %p\", &some_test)\n", run); - fputs("\t/* Conditional tests must be explicitly skipped. */\n", run); - fputs("#if HAVE_SOME_FEATURE\n", run); - fputs("\tok1(test_some_feature())\n", run); - fputs("#else\n", run); - fputs("\tskip(1, \"Don\'t have SOME_FEATURE\")\n", run); - fputs("#endif\n", run); - fputs("\n", run); - fputs("\t/* This exits depending on whether all tests passed */\n", run); - fputs("\treturn exit_status();\n", run); - fputs("}\n", run); - + fprintf(run, "%s", + "#include \n\n" + "int main(void)\n" + "{\n" + " /* This is how many tests you plan to run */\n" + " plan_tests(3);\n" + "\n" + " /* Simple thing we expect to succeed */\n" + " ok1(some_test())\n" + " /* Same, with an explicit description of the test. */\n" + " ok(some_test(), \"%s with no args should return 1\", \"some_test\")\n" + " /* How to print out messages for debugging. */\n" + " diag(\"Address of some_test is %p\", &some_test)\n" + " /* Conditional tests must be explicitly skipped. */\n" + "#if HAVE_SOME_FEATURE\n" + " ok1(test_some_feature())\n" + "#else\n" + " skip(1, \"Don\'t have SOME_FEATURE\")\n" + "#endif\n" + "\n" + " /* This exits depending on whether all tests passed */\n" + " return exit_status();\n" + "}\n"); fclose(run); } -struct ccanlint has_tests = { - .key = "has-tests", - .name = "Module has tests", - .check = check_has_tests, - .describe = describe_has_tests, - .total_score = 1, - .handle = handle_no_tests, +static void check_tests_exist(struct manifest *m, + bool keep, + unsigned int *timeleft, struct score *score) +{ + struct stat st; + char *test_dir = talloc_asprintf(m, "%s/test", m->dir); + + if (lstat(test_dir, &st) != 0) { + score->error = "No test directory"; + if (errno != ENOENT) + err(1, "statting %s", test_dir); + tests_exist.handle = handle_no_tests; + return; + } + + if (!S_ISDIR(st.st_mode)) { + score->error = "test is not a directory"; + return; + } + + if (list_empty(&m->api_tests) + && list_empty(&m->run_tests) + && list_empty(&m->compile_ok_tests)) { + if (list_empty(&m->compile_fail_tests)) { + score->error = "No tests in test directory"; + tests_exist.handle = handle_no_tests; + } else + score->error = "No positive tests in test directory"; + return; + } + score->pass = true; + score->score = score->total; +} + +struct ccanlint tests_exist = { + .key = "tests_exist", + .name = "Module has test directory with tests in it", + .check = check_tests_exist, + .needs = "" }; -REGISTER_TEST(has_tests, NULL); +REGISTER_TEST(tests_exist);