Add shutdown dialog to start menu.
[helenos.git] / uspace / lib / pcut / src / report / tap.c
blob89c279604774882e37745672aa8c33264591d880
1 /*
2 * Copyright (c) 2013 Vojtech Horky
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 /** @file
31 * Test-anything-protocol reporting routines.
34 #include "../internal.h"
35 #include "report.h"
37 #ifdef __helenos__
38 #define _REALLY_WANT_STRING_H
39 #endif
41 #pragma warning(push, 0)
42 #include <string.h>
43 #include <stdio.h>
44 #pragma warning(pop)
47 /** Counter of all run tests. */
48 static int test_counter;
50 /** Counter of all failures. */
51 static int failed_test_counter;
53 /** Counter for tests in a current suite. */
54 static int tests_in_suite;
56 /** Counter of failed tests in current suite. */
57 static int failed_tests_in_suite;
59 /** Comma-separated list of failed test names. */
60 static char *failed_test_names;
62 /** Initialize the TAP output.
64 * @param all_items Start of the list with all items.
66 static void tap_init(pcut_item_t *all_items) {
67 int tests_total = pcut_count_tests(all_items);
68 test_counter = 0;
69 failed_test_counter = 0;
71 printf("1..%d\n", tests_total);
74 /** Report that a suite was started.
76 * @param suite Suite that just started.
78 static void tap_suite_start(pcut_item_t *suite) {
79 tests_in_suite = 0;
80 failed_tests_in_suite = 0;
82 printf("#> Starting suite %s.\n", suite->name);
85 /** Report that a suite was completed.
87 * @param suite Suite that just ended.
89 static void tap_suite_done(pcut_item_t *suite) {
90 if (failed_tests_in_suite == 0) {
91 printf("#> Finished suite %s (passed).\n",
92 suite->name);
93 } else {
94 printf("#> Finished suite %s (failed %d of %d).\n",
95 suite->name, failed_tests_in_suite, tests_in_suite);
99 /** Report that a test was started.
101 * We do nothing - all handling is done after the test completes.
103 * @param test Test that is started.
105 static void tap_test_start(pcut_item_t *test) {
106 PCUT_UNUSED(test);
108 tests_in_suite++;
109 test_counter++;
112 /** Print the buffer, prefix new line with a given string.
114 * @param message Message to print.
115 * @param prefix Prefix for each new line, such as comment character.
117 static void print_by_lines(const char *message, const char *prefix) {
118 char *next_line_start;
119 if ((message == NULL) || (message[0] == 0)) {
120 return;
122 next_line_start = pcut_str_find_char(message, '\n');
123 while (next_line_start != NULL) {
124 next_line_start[0] = 0;
125 printf("%s%s\n", prefix, message);
126 message = next_line_start + 1;
127 next_line_start = pcut_str_find_char(message, '\n');
129 if (message[0] != 0) {
130 printf("%s%s\n", prefix, message);
134 /** Report a completed test.
136 * @param test Test that just finished.
137 * @param outcome Outcome of the test.
138 * @param error_message Buffer with error message.
139 * @param teardown_error_message Buffer with error message from a tear-down function.
140 * @param extra_output Extra output from the test (stdout).
142 static void tap_test_done(pcut_item_t *test, int outcome,
143 const char *error_message, const char *teardown_error_message,
144 const char *extra_output) {
145 const char *test_name = test->name;
146 const char *status_str = NULL;
147 const char *fail_error_str = NULL;
149 if (outcome != PCUT_OUTCOME_PASS) {
150 failed_tests_in_suite++;
151 failed_test_counter++;
154 switch (outcome) {
155 case PCUT_OUTCOME_PASS:
156 status_str = "ok";
157 fail_error_str = "";
158 break;
159 case PCUT_OUTCOME_FAIL:
160 status_str = "not ok";
161 fail_error_str = " failed";
162 break;
163 default:
164 status_str = "not ok";
165 fail_error_str = " aborted";
166 break;
168 printf("%s %d %s%s\n", status_str, test_counter, test_name, fail_error_str);
170 print_by_lines(error_message, "# error: ");
171 print_by_lines(teardown_error_message, "# error: ");
173 print_by_lines(extra_output, "# stdio: ");
175 if (outcome != PCUT_OUTCOME_PASS) {
176 if (failed_test_names == NULL) {
177 failed_test_names = strdup(test_name);
178 } else {
179 char *fs = NULL;
180 if (asprintf(&fs, "%s, %s",
181 failed_test_names, test_name) >= 0) {
182 free(failed_test_names);
183 failed_test_names = fs;
189 /** Report testing done. */
190 static void tap_done(void) {
191 if (failed_test_counter == 0) {
192 printf("#> Done: all tests passed.\n");
193 } else {
194 printf("#> Done: %d of %d tests failed.\n", failed_test_counter, test_counter);
195 printf("#> Failed tests: %s\n", failed_test_names);
200 pcut_report_ops_t pcut_report_tap = {
201 tap_init, tap_done,
202 tap_suite_start, tap_suite_done,
203 tap_test_start, tap_test_done