@datadog/pprof 0.2.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/binding.gyp +130 -31
- package/bindings/binding.cc +13 -0
- package/bindings/code-event-record.cc +115 -0
- package/bindings/code-event-record.hh +67 -0
- package/bindings/code-map.cc +112 -0
- package/bindings/code-map.hh +47 -0
- package/bindings/cpu-time.cc +89 -0
- package/bindings/cpu-time.hh +35 -0
- package/bindings/location.cc +117 -0
- package/bindings/location.hh +43 -0
- package/bindings/per-isolate-data.cc +42 -0
- package/bindings/per-isolate-data.hh +26 -0
- package/bindings/profilers/cpu.cc +285 -0
- package/bindings/profilers/cpu.hh +78 -0
- package/bindings/profilers/heap.cc +112 -0
- package/bindings/profilers/heap.hh +40 -0
- package/bindings/profilers/wall.cc +306 -0
- package/bindings/profilers/wall.hh +28 -0
- package/bindings/sample.cc +160 -0
- package/bindings/sample.hh +48 -0
- package/bindings/test/binding.cc +59 -0
- package/bindings/test/code-event-record.test.cc +81 -0
- package/bindings/test/code-event-record.test.hh +5 -0
- package/bindings/test/code-map.test.cc +77 -0
- package/bindings/test/code-map.test.hh +5 -0
- package/bindings/test/cpu-time.test.cc +30 -0
- package/bindings/test/cpu-time.test.hh +5 -0
- package/bindings/test/location.test.cc +39 -0
- package/bindings/test/location.test.hh +5 -0
- package/bindings/test/profilers/cpu.test.cc +88 -0
- package/bindings/test/profilers/cpu.test.hh +5 -0
- package/bindings/test/sample.test.cc +128 -0
- package/bindings/test/sample.test.hh +5 -0
- package/bindings/test/tap.h +830 -0
- package/bindings/wrap.hh +20 -0
- package/out/src/cpu-profiler-bindings.d.ts +1 -0
- package/out/src/cpu-profiler-bindings.js +23 -0
- package/out/src/cpu-profiler-bindings.js.map +1 -0
- package/out/src/cpu-profiler.d.ts +19 -0
- package/out/src/cpu-profiler.js +94 -0
- package/out/src/cpu-profiler.js.map +1 -0
- package/out/src/index.d.ts +2 -0
- package/out/src/index.js +3 -1
- package/out/src/index.js.map +1 -1
- package/out/src/profile-encoder.js +3 -14
- package/out/src/profile-encoder.js.map +1 -1
- package/out/src/profile-serializer.d.ts +9 -1
- package/out/src/profile-serializer.js +73 -1
- package/out/src/profile-serializer.js.map +1 -1
- package/out/src/sourcemapper/sourcemapper.js +81 -88
- package/out/src/sourcemapper/sourcemapper.js.map +1 -1
- package/out/src/time-profiler.d.ts +1 -1
- package/out/src/time-profiler.js +40 -34
- package/out/src/time-profiler.js.map +1 -1
- package/out/src/v8-types.d.ts +38 -0
- package/out/third_party/cloud-debug-nodejs/src/agent/io/scanner.js +6 -17
- package/out/third_party/cloud-debug-nodejs/src/agent/io/scanner.js.map +1 -1
- package/package-lock.json +5627 -0
- package/package.json +12 -14
- package/prebuilds/darwin-arm64/node-102.node +0 -0
- package/prebuilds/darwin-arm64/node-108.node +0 -0
- package/prebuilds/darwin-arm64/node-72.node +0 -0
- package/prebuilds/darwin-arm64/node-79.node +0 -0
- package/prebuilds/darwin-arm64/node-83.node +0 -0
- package/prebuilds/darwin-arm64/node-88.node +0 -0
- package/prebuilds/darwin-arm64/node-93.node +0 -0
- package/prebuilds/darwin-ia32/node-102.node +0 -0
- package/prebuilds/darwin-ia32/node-108.node +0 -0
- package/prebuilds/darwin-ia32/node-72.node +0 -0
- package/prebuilds/darwin-ia32/node-79.node +0 -0
- package/prebuilds/darwin-ia32/node-83.node +0 -0
- package/prebuilds/darwin-ia32/node-88.node +0 -0
- package/prebuilds/darwin-ia32/node-93.node +0 -0
- package/prebuilds/darwin-x64/node-102.node +0 -0
- package/prebuilds/darwin-x64/node-108.node +0 -0
- package/prebuilds/darwin-x64/node-72.node +0 -0
- package/prebuilds/darwin-x64/node-79.node +0 -0
- package/prebuilds/darwin-x64/node-83.node +0 -0
- package/prebuilds/darwin-x64/node-88.node +0 -0
- package/prebuilds/darwin-x64/node-93.node +0 -0
- package/prebuilds/linux-ia32/node-72.node +0 -0
- package/prebuilds/linux-ia32/node-79.node +0 -0
- package/prebuilds/linux-x64/node-102.node +0 -0
- package/prebuilds/linux-x64/node-108.node +0 -0
- package/prebuilds/linux-x64/node-72.node +0 -0
- package/prebuilds/linux-x64/node-79.node +0 -0
- package/prebuilds/linux-x64/node-83.node +0 -0
- package/prebuilds/linux-x64/node-88.node +0 -0
- package/prebuilds/linux-x64/node-93.node +0 -0
- package/prebuilds/win32-ia32/node-102.node +0 -0
- package/prebuilds/win32-ia32/node-72.node +0 -0
- package/prebuilds/win32-ia32/node-79.node +0 -0
- package/prebuilds/win32-ia32/node-83.node +0 -0
- package/prebuilds/win32-ia32/node-88.node +0 -0
- package/prebuilds/win32-ia32/node-93.node +0 -0
- package/prebuilds/win32-x64/node-102.node +0 -0
- package/prebuilds/win32-x64/node-108.node +0 -0
- package/prebuilds/win32-x64/node-72.node +0 -0
- package/prebuilds/win32-x64/node-79.node +0 -0
- package/prebuilds/win32-x64/node-83.node +0 -0
- package/prebuilds/win32-x64/node-88.node +0 -0
- package/prebuilds/win32-x64/node-93.node +0 -0
- package/scripts/require-package-json.js +11 -11
- package/scripts/should_rebuild.js +3 -3
- package/bindings/profiler.cc +0 -384
- package/scripts/preinstall.js +0 -36
|
@@ -0,0 +1,830 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file tap.h
|
|
3
|
+
* @author Stephen Belanger
|
|
4
|
+
* @date Apr 13, 2022
|
|
5
|
+
* @brief C and C++ API for TAP testing
|
|
6
|
+
*
|
|
7
|
+
* @todo TODO directives
|
|
8
|
+
* @todo YAML blocks?
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#ifndef _INCLUDE_TAP_H_
|
|
12
|
+
#define _INCLUDE_TAP_H_
|
|
13
|
+
|
|
14
|
+
#include <stdio.h>
|
|
15
|
+
#include <string.h>
|
|
16
|
+
#include <stdlib.h>
|
|
17
|
+
#include <stdbool.h>
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @brief This is the TAP document every function will interact with
|
|
21
|
+
*/
|
|
22
|
+
typedef struct tap_s {
|
|
23
|
+
FILE* out; /**< FILE where TAP document will be written */
|
|
24
|
+
int plan_count; /**< Number of expected checks */
|
|
25
|
+
int count; /**< Number of checks made so far */
|
|
26
|
+
int failures; /**< Number of failures so far */
|
|
27
|
+
int skip_count; /**< Number of future checks to skip */
|
|
28
|
+
int skipped; /**< Number of checks skipped so far */
|
|
29
|
+
int indent; /**< Indentation level for sub-tests */
|
|
30
|
+
const char* skip_reason; /**< Reason to report for future skipped checks */
|
|
31
|
+
void* data; /**< Free pointer slot to pass data into sub-tests */
|
|
32
|
+
} tap_t;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @brief Sub-test function signature
|
|
36
|
+
*
|
|
37
|
+
* @param t TAP document
|
|
38
|
+
*/
|
|
39
|
+
typedef void (*tap_test_fn)(tap_t* t);
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @private
|
|
43
|
+
* @brief Print indentation level for sub-tests
|
|
44
|
+
* @note Internal use only!
|
|
45
|
+
*
|
|
46
|
+
* @param t TAP document
|
|
47
|
+
*/
|
|
48
|
+
static inline void _tap_print_indent(tap_t* t) {
|
|
49
|
+
for (int i = 0; i < t->indent; i++) {
|
|
50
|
+
fprintf(t->out, " ");
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @private
|
|
56
|
+
* @brief This is separated to prevent sub-tests from re-printing TAP version.
|
|
57
|
+
* @note Internal use only!
|
|
58
|
+
*
|
|
59
|
+
* @param t TAP document
|
|
60
|
+
*/
|
|
61
|
+
static inline tap_t _tap_init(FILE* out, int indent) {
|
|
62
|
+
return {
|
|
63
|
+
out, // out
|
|
64
|
+
0, // plan_count
|
|
65
|
+
0, // count
|
|
66
|
+
0, // failures
|
|
67
|
+
0, // skip_count
|
|
68
|
+
0, // skipped
|
|
69
|
+
indent,
|
|
70
|
+
NULL, // skip_reason
|
|
71
|
+
NULL // data
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @brief Creates a TAP document writing to the given FILE.
|
|
77
|
+
*
|
|
78
|
+
* ```c
|
|
79
|
+
* tap_t t = tap(stdout);
|
|
80
|
+
* // or...
|
|
81
|
+
* tap_t t = tap(fopen("out.tap", "w"));
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* ```tap
|
|
85
|
+
* TAP version 13
|
|
86
|
+
* ```
|
|
87
|
+
*
|
|
88
|
+
* @param out FILE to which the TAP document will be written
|
|
89
|
+
* @return tap_t
|
|
90
|
+
*/
|
|
91
|
+
static inline tap_t tap(FILE* out) {
|
|
92
|
+
fprintf(out, "TAP version 13\n");
|
|
93
|
+
return _tap_init(out, 0);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @brief Enable given pragma key
|
|
98
|
+
*
|
|
99
|
+
* ```c
|
|
100
|
+
* tap_on(&t, "strict");
|
|
101
|
+
* ```
|
|
102
|
+
*
|
|
103
|
+
* ```tap
|
|
104
|
+
* pragma +strict
|
|
105
|
+
* ```
|
|
106
|
+
*
|
|
107
|
+
* @param t TAP document
|
|
108
|
+
* @param pragma Key to enable
|
|
109
|
+
*/
|
|
110
|
+
static inline void tap_on(tap_t* t, const char* pragma) {
|
|
111
|
+
_tap_print_indent(t);
|
|
112
|
+
fprintf(t->out, "pragma +%s\n", pragma);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @brief Disable given pragma key
|
|
117
|
+
*
|
|
118
|
+
* ```c
|
|
119
|
+
* tap_off(&t, "strict");
|
|
120
|
+
* ```
|
|
121
|
+
*
|
|
122
|
+
* ```tap
|
|
123
|
+
* pragma -strict
|
|
124
|
+
* ```
|
|
125
|
+
*
|
|
126
|
+
* @param t TAP document
|
|
127
|
+
* @param pragma Key to disable
|
|
128
|
+
*/
|
|
129
|
+
static inline void tap_off(tap_t* t, const char* pragma) {
|
|
130
|
+
_tap_print_indent(t);
|
|
131
|
+
fprintf(t->out, "pragma -%s\n", pragma);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* @brief Bail out of the test
|
|
136
|
+
*
|
|
137
|
+
* ```c
|
|
138
|
+
* tap_bail_out(&t, "Oh no!");
|
|
139
|
+
* ```
|
|
140
|
+
*
|
|
141
|
+
* ```tap
|
|
142
|
+
* Bail out! Oh No!
|
|
143
|
+
* ```
|
|
144
|
+
*
|
|
145
|
+
* @param t TAP document
|
|
146
|
+
* @param reason Reason to record to TAP document for bailing out
|
|
147
|
+
*/
|
|
148
|
+
static inline void tap_bail_out(tap_t* t, const char* reason) {
|
|
149
|
+
fprintf(t->out, "Bail out! %s\n", reason);
|
|
150
|
+
exit(1);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* @brief Inform the TAP document to expect a set number of test completions
|
|
155
|
+
* when ended.
|
|
156
|
+
*
|
|
157
|
+
* Setting the plan multiple times is invalid. If not specified it will
|
|
158
|
+
* be set automatically from the total test count when the test is ended.
|
|
159
|
+
*
|
|
160
|
+
* ```c
|
|
161
|
+
* tap_plan(&t, 123);
|
|
162
|
+
* ```
|
|
163
|
+
*
|
|
164
|
+
* ```tap
|
|
165
|
+
* 1..123
|
|
166
|
+
* ```
|
|
167
|
+
*
|
|
168
|
+
* @param t TAP document
|
|
169
|
+
* @param n number of expected checks
|
|
170
|
+
*/
|
|
171
|
+
static inline void tap_plan(tap_t* t, int n) {
|
|
172
|
+
if (t->plan_count != 0) {
|
|
173
|
+
tap_bail_out(t, "setting the plan multiple times is invalid");
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
t->plan_count = n;
|
|
177
|
+
_tap_print_indent(t);
|
|
178
|
+
fprintf(t->out, "1..%d\n", n);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* @brief Add a comment line to the tap document. Useful for separating groups
|
|
183
|
+
* of tests too small to warrant splitting out to a fully separate test block.
|
|
184
|
+
*
|
|
185
|
+
* ```c
|
|
186
|
+
* tap_comment(&t, "my section");
|
|
187
|
+
* ```
|
|
188
|
+
*
|
|
189
|
+
* ```tap
|
|
190
|
+
* # my section
|
|
191
|
+
* ```
|
|
192
|
+
*
|
|
193
|
+
* @param t TAP document
|
|
194
|
+
* @param comment Comment to write to the TAP document
|
|
195
|
+
*/
|
|
196
|
+
static inline void tap_comment(tap_t* t, const char* comment) {
|
|
197
|
+
_tap_print_indent(t);
|
|
198
|
+
fprintf(t->out, "# %s\n", comment);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* @brief Skips the next n tests.
|
|
203
|
+
*
|
|
204
|
+
* ```c
|
|
205
|
+
* tap_skip_n(&t, 1, "unimplemented");
|
|
206
|
+
* tap_pass(&t, "not done yet");
|
|
207
|
+
* // or...
|
|
208
|
+
* tap_skip_n(&t, 2);
|
|
209
|
+
* tap_pass(&t, "just skipping");
|
|
210
|
+
* tap_pass(&t, "also skipping");
|
|
211
|
+
* ```
|
|
212
|
+
*
|
|
213
|
+
* ```tap
|
|
214
|
+
* ok 1 - not done yet # SKIP unimplemented
|
|
215
|
+
* ok 2 - just skipping # SKIP
|
|
216
|
+
* ok 3 - also skipping # SKIP
|
|
217
|
+
* ```
|
|
218
|
+
*
|
|
219
|
+
* @param t TAP document
|
|
220
|
+
* @param n Number of checks to skip
|
|
221
|
+
* @param reason Optional reason for skipping
|
|
222
|
+
*/
|
|
223
|
+
static inline void tap_skip_n(tap_t* t, int n, const char* reason) {
|
|
224
|
+
if (t->skip_count > 0) {
|
|
225
|
+
tap_bail_out(t, "only one skip task may be active");
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
t->skip_count = n;
|
|
229
|
+
t->skip_reason = reason;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* @brief Skips the next test.
|
|
234
|
+
*
|
|
235
|
+
* ```c
|
|
236
|
+
* tap_skip(&t, "unimplemented");
|
|
237
|
+
* tap_pass(&t, "not done yet");
|
|
238
|
+
* // or...
|
|
239
|
+
* tap_skip(&t);
|
|
240
|
+
* tap_pass(&t, "just skipping");
|
|
241
|
+
* ```
|
|
242
|
+
*
|
|
243
|
+
* ```tap
|
|
244
|
+
* ok 1 - not done yet # SKIP unimplemented
|
|
245
|
+
* ok 2 - just skipping # SKIP
|
|
246
|
+
* ```
|
|
247
|
+
*
|
|
248
|
+
* @param t TAP document
|
|
249
|
+
* @param reason Optional reason for skipping
|
|
250
|
+
*/
|
|
251
|
+
static inline void tap_skip(tap_t* t, const char* reason, ...) {
|
|
252
|
+
tap_skip_n(t, 1, reason);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* @internal
|
|
257
|
+
* Hack to make reason optional
|
|
258
|
+
*/
|
|
259
|
+
#define tap_skip(t, ...) \
|
|
260
|
+
tap_skip(t, ##__VA_ARGS__, NULL)
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* @brief Check if a given value is truthy.
|
|
264
|
+
*
|
|
265
|
+
* All other check types are sugar around this one.
|
|
266
|
+
*
|
|
267
|
+
* ```c
|
|
268
|
+
* tap_ok(&t, true, "it's true");
|
|
269
|
+
* // or...
|
|
270
|
+
* tap_ok(&t, false);
|
|
271
|
+
* ```
|
|
272
|
+
*
|
|
273
|
+
* ```tap
|
|
274
|
+
* ok 1 - it's true
|
|
275
|
+
* not ok 2
|
|
276
|
+
* ```
|
|
277
|
+
*
|
|
278
|
+
* @param t TAP document
|
|
279
|
+
* @param pass Mark if the checked value is truthy
|
|
280
|
+
* @param description Optional description of what was checked
|
|
281
|
+
*/
|
|
282
|
+
static inline void tap_ok(tap_t* t, bool pass, const char* description, ...) {
|
|
283
|
+
const char* skip_reason = t->skip_reason;
|
|
284
|
+
int skip_count = t->skip_count;
|
|
285
|
+
|
|
286
|
+
if (t->skip_count) {
|
|
287
|
+
t->skip_count--;
|
|
288
|
+
t->skipped++;
|
|
289
|
+
if (!t->skip_count) {
|
|
290
|
+
t->skip_reason = NULL;
|
|
291
|
+
}
|
|
292
|
+
} else {
|
|
293
|
+
t->count++;
|
|
294
|
+
if (!pass) {
|
|
295
|
+
t->failures++;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// Status information
|
|
299
|
+
_tap_print_indent(t);
|
|
300
|
+
if (!pass) fprintf(t->out, "not ");
|
|
301
|
+
fprintf(t->out, "ok %d", t->count);
|
|
302
|
+
// Optional message
|
|
303
|
+
if (description != NULL && strlen(description)) {
|
|
304
|
+
fprintf(t->out, " - %s", description);
|
|
305
|
+
}
|
|
306
|
+
// Directive
|
|
307
|
+
if (skip_reason != NULL && strlen(skip_reason)) {
|
|
308
|
+
fprintf(t->out, " # SKIP %s", skip_reason);
|
|
309
|
+
} else if (skip_count > 0) {
|
|
310
|
+
fprintf(t->out, " # SKIP");
|
|
311
|
+
}
|
|
312
|
+
fprintf(t->out, "\n");
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* @internal
|
|
317
|
+
* Hack to make descriptions optional
|
|
318
|
+
*/
|
|
319
|
+
#define tap_ok(t, value, ...) \
|
|
320
|
+
tap_ok(t, value, ##__VA_ARGS__, "")
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* @brief Check if the value is falsy.
|
|
324
|
+
*
|
|
325
|
+
* ```c
|
|
326
|
+
* tap_not_ok(&t, true, "it is falsy");
|
|
327
|
+
* // or...
|
|
328
|
+
* tap_not_ok(&t, false);
|
|
329
|
+
* ```
|
|
330
|
+
*
|
|
331
|
+
* ```tap
|
|
332
|
+
* not ok 1 - it is falsy
|
|
333
|
+
* ok 2
|
|
334
|
+
* ```
|
|
335
|
+
*
|
|
336
|
+
* @param t TAP document
|
|
337
|
+
* @param value Value to check if it is falsy
|
|
338
|
+
* @param description Optional description of what was checked
|
|
339
|
+
*/
|
|
340
|
+
#define tap_not_ok(t, value, ...) \
|
|
341
|
+
tap_ok(t, !((bool)value), __VA_ARGS__)
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* @brief Mark a passed check.
|
|
345
|
+
*
|
|
346
|
+
* ```c
|
|
347
|
+
* tap_pass(&t, "it passed");
|
|
348
|
+
* // or...
|
|
349
|
+
* tap_pass(&t);
|
|
350
|
+
* ```
|
|
351
|
+
*
|
|
352
|
+
* ```tap
|
|
353
|
+
* ok 1 - it passed
|
|
354
|
+
* ok 2
|
|
355
|
+
* ```
|
|
356
|
+
*
|
|
357
|
+
* @param t TAP document
|
|
358
|
+
* @param description Optional description of what was checked
|
|
359
|
+
*/
|
|
360
|
+
#define tap_pass(t, ...) \
|
|
361
|
+
tap_ok(t, true, __VA_ARGS__)
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* @brief Mark a failed check.
|
|
365
|
+
*
|
|
366
|
+
* ```c
|
|
367
|
+
* tap_fail(&t, "it failed");
|
|
368
|
+
* // or...
|
|
369
|
+
* tap_fail(&t);
|
|
370
|
+
* ```
|
|
371
|
+
*
|
|
372
|
+
* ```tap
|
|
373
|
+
* not ok 1 - it failed
|
|
374
|
+
* not ok 2
|
|
375
|
+
* ```
|
|
376
|
+
*
|
|
377
|
+
* @param t TAP document
|
|
378
|
+
* @param description Optional description of what was checked
|
|
379
|
+
*/
|
|
380
|
+
#define tap_fail(t, ...) \
|
|
381
|
+
tap_ok(t, false, __VA_ARGS__)
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* @brief Check if values are equal.
|
|
385
|
+
*
|
|
386
|
+
* ```c
|
|
387
|
+
* tap_equal(&t, a, b, "values are equal");
|
|
388
|
+
* // or...
|
|
389
|
+
* tap_equal(&t, a, b);
|
|
390
|
+
* ```
|
|
391
|
+
*
|
|
392
|
+
* ```tap
|
|
393
|
+
* ok 1 - values are equal
|
|
394
|
+
* ok 2
|
|
395
|
+
* ```
|
|
396
|
+
*
|
|
397
|
+
* @param t TAP document
|
|
398
|
+
* @param a First value to compare
|
|
399
|
+
* @param b Second balue to compare
|
|
400
|
+
* @param description Optional description of what was checked
|
|
401
|
+
*/
|
|
402
|
+
#define tap_equal(t, a, b, ...) \
|
|
403
|
+
tap_ok(t, a == b, __VA_ARGS__)
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* @brief Check if values are not equal.
|
|
407
|
+
*
|
|
408
|
+
* ```c
|
|
409
|
+
* tap_not_equal(&t, a, b, "values are not equal");
|
|
410
|
+
* // or...
|
|
411
|
+
* tap_not_equal(&t, a, b);
|
|
412
|
+
* ```
|
|
413
|
+
*
|
|
414
|
+
* ```tap
|
|
415
|
+
* ok 1 - values are equal
|
|
416
|
+
* ok 2
|
|
417
|
+
* ```
|
|
418
|
+
*
|
|
419
|
+
* @param t TAP document
|
|
420
|
+
* @param a First value to compare
|
|
421
|
+
* @param b Second balue to compare
|
|
422
|
+
* @param description Optional description of what was checked
|
|
423
|
+
*/
|
|
424
|
+
#define tap_not_equal(t, a, b, ...) \
|
|
425
|
+
tap_ok(t, a != b, __VA_ARGS__)
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* @brief End the test document. Will record the plan range if not already set.
|
|
429
|
+
*
|
|
430
|
+
* ```c
|
|
431
|
+
* tap_t t = tap(stdout);
|
|
432
|
+
* tap_pass(&t, "yay!");
|
|
433
|
+
* tap_end(&t);
|
|
434
|
+
* ```
|
|
435
|
+
*
|
|
436
|
+
* ```tap
|
|
437
|
+
* TAP version 13
|
|
438
|
+
* ok 1 - yay!
|
|
439
|
+
* 1..1
|
|
440
|
+
* ```
|
|
441
|
+
*
|
|
442
|
+
* @param t TAP document
|
|
443
|
+
* @return int Return 1 if unskipped failures or count does not match plan
|
|
444
|
+
*/
|
|
445
|
+
static inline int tap_end(tap_t* t) {
|
|
446
|
+
if (t->plan_count == 0) {
|
|
447
|
+
tap_plan(t, t->count + t->skipped);
|
|
448
|
+
}
|
|
449
|
+
if (t->failures > 0) return 1;
|
|
450
|
+
if ((t->count + t->skipped) != t->plan_count) return 1;
|
|
451
|
+
return 0;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* @brief Add a named sub-test
|
|
456
|
+
*
|
|
457
|
+
* ```c
|
|
458
|
+
* void sub_test(tap_t* t) {
|
|
459
|
+
* tap_pass(t, "it passed");
|
|
460
|
+
* }
|
|
461
|
+
*
|
|
462
|
+
* tap_test(&t, "sub-test", sub_test);
|
|
463
|
+
* ```
|
|
464
|
+
*
|
|
465
|
+
* ```tap
|
|
466
|
+
* # Subtest: sub-test
|
|
467
|
+
* ok 1 - it passed
|
|
468
|
+
* 1..1
|
|
469
|
+
* ok 1 - sub-test
|
|
470
|
+
* ```
|
|
471
|
+
*
|
|
472
|
+
* @param t TAP document
|
|
473
|
+
* @param name Test name
|
|
474
|
+
* @param fn Test function
|
|
475
|
+
* @param ptr Optional pointer to attach to tap_t given to test function
|
|
476
|
+
*/
|
|
477
|
+
static inline void tap_test(tap_t *t, const char *name, tap_test_fn fn, void *ptr, ...) {
|
|
478
|
+
_tap_print_indent(t);
|
|
479
|
+
fprintf(t->out, "# Subtest: %s\n", name);
|
|
480
|
+
tap_t t2 = _tap_init(t->out, t->indent + 4);
|
|
481
|
+
t2.data = ptr;
|
|
482
|
+
fn(&t2);
|
|
483
|
+
tap_ok(t, tap_end(&t2) == 0, name);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* @internal
|
|
488
|
+
* Hack to make ptr optional
|
|
489
|
+
*/
|
|
490
|
+
#define tap_test(t, name, fn, ...) \
|
|
491
|
+
tap_test(t, name, fn, ##__VA_ARGS__, NULL)
|
|
492
|
+
|
|
493
|
+
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
|
|
494
|
+
|
|
495
|
+
#include <string>
|
|
496
|
+
#include <functional>
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* @brief This is a TAP document
|
|
500
|
+
*/
|
|
501
|
+
class Tap : private tap_t {
|
|
502
|
+
public:
|
|
503
|
+
/**
|
|
504
|
+
* @brief Construct a new TAP document
|
|
505
|
+
*
|
|
506
|
+
* @param out FILE stream to write TAP document to. Defaults to stdout.
|
|
507
|
+
*/
|
|
508
|
+
Tap(FILE* out = stdout) : tap_t(tap(out)) {}
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* @brief Enable given pragma key
|
|
512
|
+
*
|
|
513
|
+
* ```cpp
|
|
514
|
+
* t.on(&t, "strict");
|
|
515
|
+
* ```
|
|
516
|
+
*
|
|
517
|
+
* ```tap
|
|
518
|
+
* pragma +strict
|
|
519
|
+
* ```
|
|
520
|
+
*
|
|
521
|
+
* @param pragma Key to enable
|
|
522
|
+
*/
|
|
523
|
+
void on(const std::string& pragma) {
|
|
524
|
+
tap_on(this, pragma.c_str());
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* @brief Disable given pragma key
|
|
529
|
+
*
|
|
530
|
+
* ```cpp
|
|
531
|
+
* t.off(&t, "strict");
|
|
532
|
+
* ```
|
|
533
|
+
*
|
|
534
|
+
* ```tap
|
|
535
|
+
* pragma -strict
|
|
536
|
+
* ```
|
|
537
|
+
*
|
|
538
|
+
* @param pragma Key to disable
|
|
539
|
+
*/
|
|
540
|
+
void off(const std::string& pragma) {
|
|
541
|
+
tap_off(this, pragma.c_str());
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* @brief Bail out of the test
|
|
546
|
+
*
|
|
547
|
+
* ```cpp
|
|
548
|
+
* t.bail_out("Oh no!");
|
|
549
|
+
* ```
|
|
550
|
+
*
|
|
551
|
+
* ```tap
|
|
552
|
+
* Bail out! Oh No!
|
|
553
|
+
* ```
|
|
554
|
+
*
|
|
555
|
+
* @param reason Reason to record to TAP document for bailing out
|
|
556
|
+
*/
|
|
557
|
+
void bail_out(const std::string& reason = "") {
|
|
558
|
+
tap_bail_out(this, reason.c_str());
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* @brief Expect a set number of test completions when ended.
|
|
563
|
+
*
|
|
564
|
+
* ```cpp
|
|
565
|
+
* t.plan(123);
|
|
566
|
+
* ```
|
|
567
|
+
*
|
|
568
|
+
* ```tap
|
|
569
|
+
* 1..123
|
|
570
|
+
* ```
|
|
571
|
+
*
|
|
572
|
+
* @param n number of expected checks
|
|
573
|
+
*/
|
|
574
|
+
void plan(int n) {
|
|
575
|
+
tap_plan(this, n);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* @brief Add a comment line to the tap document. Useful for separating
|
|
580
|
+
* groups of tests too small to warrant splitting out to a fully separate
|
|
581
|
+
* test block.
|
|
582
|
+
*
|
|
583
|
+
* ```cpp
|
|
584
|
+
* t.comment("my section");
|
|
585
|
+
* ```
|
|
586
|
+
*
|
|
587
|
+
* ```tap
|
|
588
|
+
* # my section
|
|
589
|
+
* ```
|
|
590
|
+
*
|
|
591
|
+
* @param comment Comment to write to the TAP document
|
|
592
|
+
*/
|
|
593
|
+
void comment(const std::string& comment) {
|
|
594
|
+
tap_comment(this, comment.c_str());
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* @brief Skips the next n tests.
|
|
599
|
+
*
|
|
600
|
+
* ```cpp
|
|
601
|
+
* t.skip(1, "unimplemented");
|
|
602
|
+
* t.pass("not done yet");
|
|
603
|
+
* // or...
|
|
604
|
+
* t.skip(2);
|
|
605
|
+
* t.pass("just skipping");
|
|
606
|
+
* t.pass("also skipping");
|
|
607
|
+
* ```
|
|
608
|
+
*
|
|
609
|
+
* ```tap
|
|
610
|
+
* ok 1 - not done yet # SKIP unimplemented
|
|
611
|
+
* ok 2 - just skipping # SKIP
|
|
612
|
+
* ok 3 - also skipping # SKIP
|
|
613
|
+
* ```
|
|
614
|
+
*
|
|
615
|
+
* @param n Number of checks to skip
|
|
616
|
+
* @param reason Optional reason for skipping
|
|
617
|
+
*/
|
|
618
|
+
void skip(int n, const std::string& reason = "") {
|
|
619
|
+
tap_skip_n(this, n, reason.c_str());
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
/**
|
|
623
|
+
* @brief Skips the next test.
|
|
624
|
+
*
|
|
625
|
+
* ```cpp
|
|
626
|
+
* t.skip("unimplemented");
|
|
627
|
+
* t.pass("not done yet");
|
|
628
|
+
* // or...
|
|
629
|
+
* t.skip();
|
|
630
|
+
* t.pass("just skipping");
|
|
631
|
+
* ```
|
|
632
|
+
*
|
|
633
|
+
* ```tap
|
|
634
|
+
* ok 1 - not done yet # SKIP unimplemented
|
|
635
|
+
* ok 2 - just skipping # SKIP
|
|
636
|
+
* ```
|
|
637
|
+
*
|
|
638
|
+
* @param reason Optional reason for skipping
|
|
639
|
+
*/
|
|
640
|
+
void skip(const std::string& reason = "") {
|
|
641
|
+
skip(1, reason);
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
* @brief Check if a given value is truthy.
|
|
646
|
+
*
|
|
647
|
+
* All other check types are sugar around this one.
|
|
648
|
+
*
|
|
649
|
+
* ```cpp
|
|
650
|
+
* t.ok(true, "it's true");
|
|
651
|
+
* // or...
|
|
652
|
+
* t.ok(false);
|
|
653
|
+
* ```
|
|
654
|
+
*
|
|
655
|
+
* ```tap
|
|
656
|
+
* ok 1 - it's true
|
|
657
|
+
* not ok 2
|
|
658
|
+
* ```
|
|
659
|
+
*
|
|
660
|
+
* @param pass Mark if the checked value is truthy
|
|
661
|
+
* @param description Optional description of what was checked
|
|
662
|
+
*/
|
|
663
|
+
template<typename T>
|
|
664
|
+
void ok(T pass, const std::string& description = "") {
|
|
665
|
+
tap_ok(this, pass, description.c_str());
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
/**
|
|
669
|
+
* @brief Check if the value is falsy.
|
|
670
|
+
*
|
|
671
|
+
* ```cpp
|
|
672
|
+
* t.not_ok(true, "it is falsy");
|
|
673
|
+
* // or...
|
|
674
|
+
* t.not_ok(false);
|
|
675
|
+
* ```
|
|
676
|
+
*
|
|
677
|
+
* ```tap
|
|
678
|
+
* not ok 1 - it is falsy
|
|
679
|
+
* ok 2
|
|
680
|
+
* ```
|
|
681
|
+
*
|
|
682
|
+
* @param value Value to check if it is falsy
|
|
683
|
+
* @param description Optional description of what was checked
|
|
684
|
+
*/
|
|
685
|
+
template<typename T>
|
|
686
|
+
void not_ok(T value, const std::string& description = "") {
|
|
687
|
+
ok(!value, description);
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
/**
|
|
691
|
+
* @brief Mark a passed check.
|
|
692
|
+
*
|
|
693
|
+
* ```cpp
|
|
694
|
+
* t.pass("it passed");
|
|
695
|
+
* // or...
|
|
696
|
+
* t.pass();
|
|
697
|
+
* ```
|
|
698
|
+
*
|
|
699
|
+
* ```tap
|
|
700
|
+
* ok 1 - it passed
|
|
701
|
+
* ok 2
|
|
702
|
+
* ```
|
|
703
|
+
*
|
|
704
|
+
* @param description Optional description of what was checked
|
|
705
|
+
*/
|
|
706
|
+
void pass(const std::string& description = "") {
|
|
707
|
+
ok(true, description);
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* @brief Mark a failed check.
|
|
712
|
+
*
|
|
713
|
+
* ```cpp
|
|
714
|
+
* t.fail("it failed");
|
|
715
|
+
* // or...
|
|
716
|
+
* t.fail();
|
|
717
|
+
* ```
|
|
718
|
+
*
|
|
719
|
+
* ```tap
|
|
720
|
+
* not ok 1 - it failed
|
|
721
|
+
* not ok 2
|
|
722
|
+
* ```
|
|
723
|
+
*
|
|
724
|
+
* @param description Optional description of what was checked
|
|
725
|
+
*/
|
|
726
|
+
void fail(const std::string& description = "") {
|
|
727
|
+
ok(false, description);
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
/**
|
|
731
|
+
* @brief Check if values are equal.
|
|
732
|
+
*
|
|
733
|
+
* ```cpp
|
|
734
|
+
* t.equal(a, b, "values are equal");
|
|
735
|
+
* // or...
|
|
736
|
+
* t.equal(a, b);
|
|
737
|
+
* ```
|
|
738
|
+
*
|
|
739
|
+
* ```tap
|
|
740
|
+
* ok 1 - values are equal
|
|
741
|
+
* ok 2
|
|
742
|
+
* ```
|
|
743
|
+
*
|
|
744
|
+
* @param a First value to compare
|
|
745
|
+
* @param b Second balue to compare
|
|
746
|
+
* @param description Optional description of what was checked
|
|
747
|
+
*/
|
|
748
|
+
template<typename A, typename B>
|
|
749
|
+
void equal(A a, B b, const std::string& description = "") {
|
|
750
|
+
ok(a == b, description);
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
/**
|
|
754
|
+
* @brief Check if values are not equal.
|
|
755
|
+
*
|
|
756
|
+
* ```cpp
|
|
757
|
+
* t.not_equal(a, b, "values are not equal");
|
|
758
|
+
* // or...
|
|
759
|
+
* t.not_equal(a, b);
|
|
760
|
+
* ```
|
|
761
|
+
*
|
|
762
|
+
* ```tap
|
|
763
|
+
* ok 1 - values are equal
|
|
764
|
+
* ok 2
|
|
765
|
+
* ```
|
|
766
|
+
*
|
|
767
|
+
* @param a First value to compare
|
|
768
|
+
* @param b Second balue to compare
|
|
769
|
+
* @param description Optional description of what was checked
|
|
770
|
+
*/
|
|
771
|
+
template<typename A, typename B>
|
|
772
|
+
void not_equal(A a, B b, const std::string& description = "") {
|
|
773
|
+
ok(a != b, description);
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
/**
|
|
777
|
+
* @brief End the test document. Will record the plan range if not already set.
|
|
778
|
+
*
|
|
779
|
+
* ```cpp
|
|
780
|
+
* Tap t;
|
|
781
|
+
* t.pass("yay!");
|
|
782
|
+
* t.end();
|
|
783
|
+
* ```
|
|
784
|
+
*
|
|
785
|
+
* ```tap
|
|
786
|
+
* TAP version 13
|
|
787
|
+
* ok 1 - yay!
|
|
788
|
+
* 1..1
|
|
789
|
+
* ```
|
|
790
|
+
*
|
|
791
|
+
* @return int Return 1 if unskipped failures or count does not match plan
|
|
792
|
+
*/
|
|
793
|
+
int end() {
|
|
794
|
+
return tap_end(this);
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
/**
|
|
798
|
+
* @brief Add a named sub-test
|
|
799
|
+
*
|
|
800
|
+
* ```cpp
|
|
801
|
+
* t.test("sub-test", [](Tap& t) {
|
|
802
|
+
* tap_pass(t, "it passed");
|
|
803
|
+
* });
|
|
804
|
+
* ```
|
|
805
|
+
*
|
|
806
|
+
* ```tap
|
|
807
|
+
* # Subtest: sub-test
|
|
808
|
+
* ok 1 - it passed
|
|
809
|
+
* 1..1
|
|
810
|
+
* ok 1 - sub-test
|
|
811
|
+
* ```
|
|
812
|
+
*
|
|
813
|
+
* @param name Test name
|
|
814
|
+
* @param fn Test function
|
|
815
|
+
*/
|
|
816
|
+
void test(const std::string& name, std::function<void(Tap&)> fn) {
|
|
817
|
+
struct callback {
|
|
818
|
+
std::function<void(Tap&)> fn;
|
|
819
|
+
};
|
|
820
|
+
callback wrap = {fn};
|
|
821
|
+
tap_test(this, name.c_str(), [](tap_t* t) {
|
|
822
|
+
callback* wrap = static_cast<callback*>(t->data);
|
|
823
|
+
wrap->fn(*static_cast<Tap*>(t));
|
|
824
|
+
}, &wrap);
|
|
825
|
+
}
|
|
826
|
+
};
|
|
827
|
+
|
|
828
|
+
#endif // __cplusplus >= 201103L
|
|
829
|
+
|
|
830
|
+
#endif // _INCLUDE_TAP_H_
|