source: mainline/uspace/lib/pcut/src/report/tap.c

Last change on this file was 098e16a5, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 6 years ago

pcut: write out names of the failing tests

  • Property mode set to 100644
File size: 5.6 KB
Line 
1/*
2 * Copyright (c) 2013 Vojtech Horky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
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.
16 *
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.
27 */
28
29/** @file
30 *
31 * Test-anything-protocol reporting routines.
32 */
33
34#include "../internal.h"
35#include "report.h"
36
37#ifdef __helenos__
38#define _REALLY_WANT_STRING_H
39#endif
40
41#pragma warning(push, 0)
42#include <string.h>
43#include <stdio.h>
44#pragma warning(pop)
45
46
47/** Counter of all run tests. */
48static int test_counter;
49
50/** Counter of all failures. */
51static int failed_test_counter;
52
53/** Counter for tests in a current suite. */
54static int tests_in_suite;
55
56/** Counter of failed tests in current suite. */
57static int failed_tests_in_suite;
58
59/** Comma-separated list of failed test names. */
60static char *failed_test_names;
61
62/** Initialize the TAP output.
63 *
64 * @param all_items Start of the list with all items.
65 */
66static 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;
70
71 printf("1..%d\n", tests_total);
72}
73
74/** Report that a suite was started.
75 *
76 * @param suite Suite that just started.
77 */
78static void tap_suite_start(pcut_item_t *suite) {
79 tests_in_suite = 0;
80 failed_tests_in_suite = 0;
81
82 printf("#> Starting suite %s.\n", suite->name);
83}
84
85/** Report that a suite was completed.
86 *
87 * @param suite Suite that just ended.
88 */
89static 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);
96 }
97}
98
99/** Report that a test was started.
100 *
101 * We do nothing - all handling is done after the test completes.
102 *
103 * @param test Test that is started.
104 */
105static void tap_test_start(pcut_item_t *test) {
106 PCUT_UNUSED(test);
107
108 tests_in_suite++;
109 test_counter++;
110}
111
112/** Print the buffer, prefix new line with a given string.
113 *
114 * @param message Message to print.
115 * @param prefix Prefix for each new line, such as comment character.
116 */
117static void print_by_lines(const char *message, const char *prefix) {
118 char *next_line_start;
119 if ((message == NULL) || (message[0] == 0)) {
120 return;
121 }
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');
128 }
129 if (message[0] != 0) {
130 printf("%s%s\n", prefix, message);
131 }
132}
133
134/** Report a completed test.
135 *
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).
141 */
142static 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;
148
149 if (outcome != PCUT_OUTCOME_PASS) {
150 failed_tests_in_suite++;
151 failed_test_counter++;
152 }
153
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;
167 }
168 printf("%s %d %s%s\n", status_str, test_counter, test_name, fail_error_str);
169
170 print_by_lines(error_message, "# error: ");
171 print_by_lines(teardown_error_message, "# error: ");
172
173 print_by_lines(extra_output, "# stdio: ");
174
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;
184 }
185 }
186 }
187}
188
189/** Report testing done. */
190static 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);
196 }
197}
198
199
200pcut_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
204};
Note: See TracBrowser for help on using the repository browser.