1 package types
2
3 import (
4 "fmt"
5 "reflect"
6 "strings"
7
8 "github.com/onsi/ginkgo/v2/formatter"
9 )
10
11 type GinkgoError struct {
12 Heading string
13 Message string
14 DocLink string
15 CodeLocation CodeLocation
16 }
17
18 func (g GinkgoError) Error() string {
19 out := formatter.F("{{bold}}{{red}}%s{{/}}\n", g.Heading)
20 if (g.CodeLocation != CodeLocation{}) {
21 contentsOfLine := strings.TrimLeft(g.CodeLocation.ContentsOfLine(), "\t ")
22 if contentsOfLine != "" {
23 out += formatter.F("{{light-gray}}%s{{/}}\n", contentsOfLine)
24 }
25 out += formatter.F("{{gray}}%s{{/}}\n", g.CodeLocation)
26 }
27 if g.Message != "" {
28 out += formatter.Fiw(1, formatter.COLS, g.Message)
29 out += "\n\n"
30 }
31 if g.DocLink != "" {
32 out += formatter.Fiw(1, formatter.COLS, "{{bold}}Learn more at:{{/}} {{cyan}}{{underline}}http://onsi.github.io/ginkgo/#%s{{/}}\n", g.DocLink)
33 }
34
35 return out
36 }
37
38 type ginkgoErrors struct{}
39
40 var GinkgoErrors = ginkgoErrors{}
41
42 func (g ginkgoErrors) UncaughtGinkgoPanic(cl CodeLocation) error {
43 return GinkgoError{
44 Heading: "Your Test Panicked",
45 Message: `When you, or your assertion library, calls Ginkgo's Fail(),
46 Ginkgo panics to prevent subsequent assertions from running.
47
48 Normally Ginkgo rescues this panic so you shouldn't see it.
49
50 However, if you make an assertion in a goroutine, Ginkgo can't capture the panic.
51 To circumvent this, you should call
52
53 defer GinkgoRecover()
54
55 at the top of the goroutine that caused this panic.
56
57 Alternatively, you may have made an assertion outside of a Ginkgo
58 leaf node (e.g. in a container node or some out-of-band function) - please move your assertion to
59 an appropriate Ginkgo node (e.g. a BeforeSuite, BeforeEach, It, etc...).`,
60 DocLink: "mental-model-how-ginkgo-handles-failure",
61 CodeLocation: cl,
62 }
63 }
64
65 func (g ginkgoErrors) RerunningSuite() error {
66 return GinkgoError{
67 Heading: "Rerunning Suite",
68 Message: formatter.F(`It looks like you are calling RunSpecs more than once. Ginkgo does not support rerunning suites. If you want to rerun a suite try {{bold}}ginkgo --repeat=N{{/}} or {{bold}}ginkgo --until-it-fails{{/}}`),
69 DocLink: "repeating-spec-runs-and-managing-flaky-specs",
70 }
71 }
72
73
74
75 func (g ginkgoErrors) PushingNodeInRunPhase(nodeType NodeType, cl CodeLocation) error {
76 return GinkgoError{
77 Heading: "Ginkgo detected an issue with your spec structure",
78 Message: formatter.F(
79 `It looks like you are trying to add a {{bold}}[%s]{{/}} node
80 to the Ginkgo spec tree in a leaf node {{bold}}after{{/}} the specs started running.
81
82 To enable randomization and parallelization Ginkgo requires the spec tree
83 to be fully constructed up front. In practice, this means that you can
84 only create nodes like {{bold}}[%s]{{/}} at the top-level or within the
85 body of a {{bold}}Describe{{/}}, {{bold}}Context{{/}}, or {{bold}}When{{/}}.`, nodeType, nodeType),
86 CodeLocation: cl,
87 DocLink: "mental-model-how-ginkgo-traverses-the-spec-hierarchy",
88 }
89 }
90
91 func (g ginkgoErrors) CaughtPanicDuringABuildPhase(caughtPanic interface{}, cl CodeLocation) error {
92 return GinkgoError{
93 Heading: "Assertion or Panic detected during tree construction",
94 Message: formatter.F(
95 `Ginkgo detected a panic while constructing the spec tree.
96 You may be trying to make an assertion in the body of a container node
97 (i.e. {{bold}}Describe{{/}}, {{bold}}Context{{/}}, or {{bold}}When{{/}}).
98
99 Please ensure all assertions are inside leaf nodes such as {{bold}}BeforeEach{{/}},
100 {{bold}}It{{/}}, etc.
101
102 {{bold}}Here's the content of the panic that was caught:{{/}}
103 %v`, caughtPanic),
104 CodeLocation: cl,
105 DocLink: "no-assertions-in-container-nodes",
106 }
107 }
108
109 func (g ginkgoErrors) SuiteNodeInNestedContext(nodeType NodeType, cl CodeLocation) error {
110 docLink := "suite-setup-and-cleanup-beforesuite-and-aftersuite"
111 if nodeType.Is(NodeTypeReportBeforeSuite | NodeTypeReportAfterSuite) {
112 docLink = "reporting-nodes---reportbeforesuite-and-reportaftersuite"
113 }
114
115 return GinkgoError{
116 Heading: "Ginkgo detected an issue with your spec structure",
117 Message: formatter.F(
118 `It looks like you are trying to add a {{bold}}[%s]{{/}} node within a container node.
119
120 {{bold}}%s{{/}} can only be called at the top level.`, nodeType, nodeType),
121 CodeLocation: cl,
122 DocLink: docLink,
123 }
124 }
125
126 func (g ginkgoErrors) SuiteNodeDuringRunPhase(nodeType NodeType, cl CodeLocation) error {
127 docLink := "suite-setup-and-cleanup-beforesuite-and-aftersuite"
128 if nodeType.Is(NodeTypeReportBeforeSuite | NodeTypeReportAfterSuite) {
129 docLink = "reporting-nodes---reportbeforesuite-and-reportaftersuite"
130 }
131
132 return GinkgoError{
133 Heading: "Ginkgo detected an issue with your spec structure",
134 Message: formatter.F(
135 `It looks like you are trying to add a {{bold}}[%s]{{/}} node within a leaf node after the spec started running.
136
137 {{bold}}%s{{/}} can only be called at the top level.`, nodeType, nodeType),
138 CodeLocation: cl,
139 DocLink: docLink,
140 }
141 }
142
143 func (g ginkgoErrors) MultipleBeforeSuiteNodes(nodeType NodeType, cl CodeLocation, earlierNodeType NodeType, earlierCodeLocation CodeLocation) error {
144 return ginkgoErrorMultipleSuiteNodes("setup", nodeType, cl, earlierNodeType, earlierCodeLocation)
145 }
146
147 func (g ginkgoErrors) MultipleAfterSuiteNodes(nodeType NodeType, cl CodeLocation, earlierNodeType NodeType, earlierCodeLocation CodeLocation) error {
148 return ginkgoErrorMultipleSuiteNodes("teardown", nodeType, cl, earlierNodeType, earlierCodeLocation)
149 }
150
151 func ginkgoErrorMultipleSuiteNodes(setupOrTeardown string, nodeType NodeType, cl CodeLocation, earlierNodeType NodeType, earlierCodeLocation CodeLocation) error {
152 return GinkgoError{
153 Heading: "Ginkgo detected an issue with your spec structure",
154 Message: formatter.F(
155 `It looks like you are trying to add a {{bold}}[%s]{{/}} node but
156 you already have a {{bold}}[%s]{{/}} node defined at: {{gray}}%s{{/}}.
157
158 Ginkgo only allows you to define one suite %s node.`, nodeType, earlierNodeType, earlierCodeLocation, setupOrTeardown),
159 CodeLocation: cl,
160 DocLink: "suite-setup-and-cleanup-beforesuite-and-aftersuite",
161 }
162 }
163
164
165 func (g ginkgoErrors) InvalidDecoratorForNodeType(cl CodeLocation, nodeType NodeType, decorator string) error {
166 return GinkgoError{
167 Heading: "Invalid Decorator",
168 Message: formatter.F(`[%s] node cannot be passed a(n) '%s' decorator`, nodeType, decorator),
169 CodeLocation: cl,
170 DocLink: "node-decorators-overview",
171 }
172 }
173
174 func (g ginkgoErrors) InvalidDeclarationOfFocusedAndPending(cl CodeLocation, nodeType NodeType) error {
175 return GinkgoError{
176 Heading: "Invalid Combination of Decorators: Focused and Pending",
177 Message: formatter.F(`[%s] node was decorated with both Focus and Pending. At most one is allowed.`, nodeType),
178 CodeLocation: cl,
179 DocLink: "node-decorators-overview",
180 }
181 }
182
183 func (g ginkgoErrors) InvalidDeclarationOfFlakeAttemptsAndMustPassRepeatedly(cl CodeLocation, nodeType NodeType) error {
184 return GinkgoError{
185 Heading: "Invalid Combination of Decorators: FlakeAttempts and MustPassRepeatedly",
186 Message: formatter.F(`[%s] node was decorated with both FlakeAttempts and MustPassRepeatedly. At most one is allowed.`, nodeType),
187 CodeLocation: cl,
188 DocLink: "node-decorators-overview",
189 }
190 }
191
192 func (g ginkgoErrors) UnknownDecorator(cl CodeLocation, nodeType NodeType, decorator interface{}) error {
193 return GinkgoError{
194 Heading: "Unknown Decorator",
195 Message: formatter.F(`[%s] node was passed an unknown decorator: '%#v'`, nodeType, decorator),
196 CodeLocation: cl,
197 DocLink: "node-decorators-overview",
198 }
199 }
200
201 func (g ginkgoErrors) InvalidBodyTypeForContainer(t reflect.Type, cl CodeLocation, nodeType NodeType) error {
202 return GinkgoError{
203 Heading: "Invalid Function",
204 Message: formatter.F(`[%s] node must be passed {{bold}}func(){{/}} - i.e. functions that take nothing and return nothing. You passed {{bold}}%s{{/}} instead.`, nodeType, t),
205 CodeLocation: cl,
206 DocLink: "node-decorators-overview",
207 }
208 }
209
210 func (g ginkgoErrors) InvalidBodyType(t reflect.Type, cl CodeLocation, nodeType NodeType) error {
211 mustGet := "{{bold}}func(){{/}}, {{bold}}func(ctx SpecContext){{/}}, or {{bold}}func(ctx context.Context){{/}}"
212 if nodeType.Is(NodeTypeContainer) {
213 mustGet = "{{bold}}func(){{/}}"
214 }
215 return GinkgoError{
216 Heading: "Invalid Function",
217 Message: formatter.F(`[%s] node must be passed `+mustGet+`.
218 You passed {{bold}}%s{{/}} instead.`, nodeType, t),
219 CodeLocation: cl,
220 DocLink: "node-decorators-overview",
221 }
222 }
223
224 func (g ginkgoErrors) InvalidBodyTypeForSynchronizedBeforeSuiteProc1(t reflect.Type, cl CodeLocation) error {
225 mustGet := "{{bold}}func() []byte{{/}}, {{bold}}func(ctx SpecContext) []byte{{/}}, or {{bold}}func(ctx context.Context) []byte{{/}}, {{bold}}func(){{/}}, {{bold}}func(ctx SpecContext){{/}}, or {{bold}}func(ctx context.Context){{/}}"
226 return GinkgoError{
227 Heading: "Invalid Function",
228 Message: formatter.F(`[SynchronizedBeforeSuite] node must be passed `+mustGet+` for its first function.
229 You passed {{bold}}%s{{/}} instead.`, t),
230 CodeLocation: cl,
231 DocLink: "node-decorators-overview",
232 }
233 }
234
235 func (g ginkgoErrors) InvalidBodyTypeForSynchronizedBeforeSuiteAllProcs(t reflect.Type, cl CodeLocation) error {
236 mustGet := "{{bold}}func(){{/}}, {{bold}}func(ctx SpecContext){{/}}, or {{bold}}func(ctx context.Context){{/}}, {{bold}}func([]byte){{/}}, {{bold}}func(ctx SpecContext, []byte){{/}}, or {{bold}}func(ctx context.Context, []byte){{/}}"
237 return GinkgoError{
238 Heading: "Invalid Function",
239 Message: formatter.F(`[SynchronizedBeforeSuite] node must be passed `+mustGet+` for its second function.
240 You passed {{bold}}%s{{/}} instead.`, t),
241 CodeLocation: cl,
242 DocLink: "node-decorators-overview",
243 }
244 }
245
246 func (g ginkgoErrors) MultipleBodyFunctions(cl CodeLocation, nodeType NodeType) error {
247 return GinkgoError{
248 Heading: "Multiple Functions",
249 Message: formatter.F(`[%s] node must be passed a single function - but more than one was passed in.`, nodeType),
250 CodeLocation: cl,
251 DocLink: "node-decorators-overview",
252 }
253 }
254
255 func (g ginkgoErrors) MissingBodyFunction(cl CodeLocation, nodeType NodeType) error {
256 return GinkgoError{
257 Heading: "Missing Functions",
258 Message: formatter.F(`[%s] node must be passed a single function - but none was passed in.`, nodeType),
259 CodeLocation: cl,
260 DocLink: "node-decorators-overview",
261 }
262 }
263
264 func (g ginkgoErrors) InvalidTimeoutOrGracePeriodForNonContextNode(cl CodeLocation, nodeType NodeType) error {
265 return GinkgoError{
266 Heading: "Invalid NodeTimeout SpecTimeout, or GracePeriod",
267 Message: formatter.F(`[%s] was passed NodeTimeout, SpecTimeout, or GracePeriod but does not have a callback that accepts a {{bold}}SpecContext{{/}} or {{bold}}context.Context{{/}}. You must accept a context to enable timeouts and grace periods`, nodeType),
268 CodeLocation: cl,
269 DocLink: "spec-timeouts-and-interruptible-nodes",
270 }
271 }
272
273 func (g ginkgoErrors) InvalidTimeoutOrGracePeriodForNonContextCleanupNode(cl CodeLocation) error {
274 return GinkgoError{
275 Heading: "Invalid NodeTimeout SpecTimeout, or GracePeriod",
276 Message: formatter.F(`[DeferCleanup] was passed NodeTimeout or GracePeriod but does not have a callback that accepts a {{bold}}SpecContext{{/}} or {{bold}}context.Context{{/}}. You must accept a context to enable timeouts and grace periods`),
277 CodeLocation: cl,
278 DocLink: "spec-timeouts-and-interruptible-nodes",
279 }
280 }
281
282
283 func (g ginkgoErrors) InvalidSerialNodeInNonSerialOrderedContainer(cl CodeLocation, nodeType NodeType) error {
284 return GinkgoError{
285 Heading: "Invalid Serial Node in Non-Serial Ordered Container",
286 Message: formatter.F(`[%s] node was decorated with Serial but occurs in an Ordered container that is not marked Serial. Move the Serial decorator to the outer-most Ordered container to mark all ordered specs within the container as serial.`, nodeType),
287 CodeLocation: cl,
288 DocLink: "node-decorators-overview",
289 }
290 }
291
292 func (g ginkgoErrors) SetupNodeNotInOrderedContainer(cl CodeLocation, nodeType NodeType) error {
293 return GinkgoError{
294 Heading: "Setup Node not in Ordered Container",
295 Message: fmt.Sprintf("[%s] setup nodes must appear inside an Ordered container. They cannot be nested within other containers, even containers in an ordered container.", nodeType),
296 CodeLocation: cl,
297 DocLink: "ordered-containers",
298 }
299 }
300
301 func (g ginkgoErrors) InvalidContinueOnFailureDecoration(cl CodeLocation) error {
302 return GinkgoError{
303 Heading: "ContinueOnFailure not decorating an outermost Ordered Container",
304 Message: "ContinueOnFailure can only decorate an Ordered container, and this Ordered container must be the outermost Ordered container.",
305 CodeLocation: cl,
306 DocLink: "ordered-containers",
307 }
308 }
309
310
311 func (g ginkgoErrors) DeferCleanupInvalidFunction(cl CodeLocation) error {
312 return GinkgoError{
313 Heading: "DeferCleanup requires a valid function",
314 Message: "You must pass DeferCleanup a function to invoke. This function must return zero or one values - if it does return, it must return an error. The function can take arbitrarily many arguments and you should provide these to DeferCleanup to pass along to the function.",
315 CodeLocation: cl,
316 DocLink: "cleaning-up-our-cleanup-code-defercleanup",
317 }
318 }
319
320 func (g ginkgoErrors) PushingCleanupNodeDuringTreeConstruction(cl CodeLocation) error {
321 return GinkgoError{
322 Heading: "DeferCleanup must be called inside a setup or subject node",
323 Message: "You must call DeferCleanup inside a setup node (e.g. BeforeEach, BeforeSuite, AfterAll...) or a subject node (i.e. It). You can't call DeferCleanup at the top-level or in a container node - use the After* family of setup nodes instead.",
324 CodeLocation: cl,
325 DocLink: "cleaning-up-our-cleanup-code-defercleanup",
326 }
327 }
328
329 func (g ginkgoErrors) PushingCleanupInReportingNode(cl CodeLocation, nodeType NodeType) error {
330 return GinkgoError{
331 Heading: fmt.Sprintf("DeferCleanup cannot be called in %s", nodeType),
332 Message: "Please inline your cleanup code - Ginkgo won't run cleanup code after a Reporting node.",
333 CodeLocation: cl,
334 DocLink: "cleaning-up-our-cleanup-code-defercleanup",
335 }
336 }
337
338 func (g ginkgoErrors) PushingCleanupInCleanupNode(cl CodeLocation) error {
339 return GinkgoError{
340 Heading: "DeferCleanup cannot be called in a DeferCleanup callback",
341 Message: "Please inline your cleanup code - Ginkgo doesn't let you call DeferCleanup from within DeferCleanup",
342 CodeLocation: cl,
343 DocLink: "cleaning-up-our-cleanup-code-defercleanup",
344 }
345 }
346
347
348 func (g ginkgoErrors) TooManyReportEntryValues(cl CodeLocation, arg interface{}) error {
349 return GinkgoError{
350 Heading: "Too Many ReportEntry Values",
351 Message: formatter.F(`{{bold}}AddGinkgoReport{{/}} can only be given one value. Got unexpected value: %#v`, arg),
352 CodeLocation: cl,
353 DocLink: "attaching-data-to-reports",
354 }
355 }
356
357 func (g ginkgoErrors) AddReportEntryNotDuringRunPhase(cl CodeLocation) error {
358 return GinkgoError{
359 Heading: "Ginkgo detected an issue with your spec structure",
360 Message: formatter.F(`It looks like you are calling {{bold}}AddGinkgoReport{{/}} outside of a running spec. Make sure you call {{bold}}AddGinkgoReport{{/}} inside a runnable node such as It or BeforeEach and not inside the body of a container such as Describe or Context.`),
361 CodeLocation: cl,
362 DocLink: "attaching-data-to-reports",
363 }
364 }
365
366
367 func (g ginkgoErrors) ByNotDuringRunPhase(cl CodeLocation) error {
368 return GinkgoError{
369 Heading: "Ginkgo detected an issue with your spec structure",
370 Message: formatter.F(`It looks like you are calling {{bold}}By{{/}} outside of a running spec. Make sure you call {{bold}}By{{/}} inside a runnable node such as It or BeforeEach and not inside the body of a container such as Describe or Context.`),
371 CodeLocation: cl,
372 DocLink: "documenting-complex-specs-by",
373 }
374 }
375
376
377 func (g ginkgoErrors) InvalidFileFilter(filter string) error {
378 return GinkgoError{
379 Heading: "Invalid File Filter",
380 Message: fmt.Sprintf(`The provided file filter: "%s" is invalid. File filters must have the format "file", "file:lines" where "file" is a regular expression that will match against the file path and lines is a comma-separated list of integers (e.g. file:1,5,7) or line-ranges (e.g. file:1-3,5-9) or both (e.g. file:1,5-9)`, filter),
381 DocLink: "filtering-specs",
382 }
383 }
384
385 func (g ginkgoErrors) InvalidFileFilterRegularExpression(filter string, err error) error {
386 return GinkgoError{
387 Heading: "Invalid File Filter Regular Expression",
388 Message: fmt.Sprintf(`The provided file filter: "%s" included an invalid regular expression. regexp.Compile error: %s`, filter, err),
389 DocLink: "filtering-specs",
390 }
391 }
392
393
394 func (g ginkgoErrors) SyntaxErrorParsingLabelFilter(input string, location int, error string) error {
395 var message string
396 if location >= 0 {
397 for i, r := range input {
398 if i == location {
399 message += "{{red}}{{bold}}{{underline}}"
400 }
401 message += string(r)
402 if i == location {
403 message += "{{/}}"
404 }
405 }
406 } else {
407 message = input
408 }
409 message += "\n" + error
410 return GinkgoError{
411 Heading: "Syntax Error Parsing Label Filter",
412 Message: message,
413 DocLink: "spec-labels",
414 }
415 }
416
417 func (g ginkgoErrors) InvalidLabel(label string, cl CodeLocation) error {
418 return GinkgoError{
419 Heading: "Invalid Label",
420 Message: fmt.Sprintf("'%s' is an invalid label. Labels cannot contain of the following characters: '&|!,()/'", label),
421 CodeLocation: cl,
422 DocLink: "spec-labels",
423 }
424 }
425
426 func (g ginkgoErrors) InvalidEmptyLabel(cl CodeLocation) error {
427 return GinkgoError{
428 Heading: "Invalid Empty Label",
429 Message: "Labels cannot be empty",
430 CodeLocation: cl,
431 DocLink: "spec-labels",
432 }
433 }
434
435
436 func (g ginkgoErrors) MultipleEntryBodyFunctionsForTable(cl CodeLocation) error {
437 return GinkgoError{
438 Heading: "DescribeTable passed multiple functions",
439 Message: "It looks like you are passing multiple functions into DescribeTable. Only one function can be passed in. This function will be called for each Entry in the table.",
440 CodeLocation: cl,
441 DocLink: "table-specs",
442 }
443 }
444
445 func (g ginkgoErrors) InvalidEntryDescription(cl CodeLocation) error {
446 return GinkgoError{
447 Heading: "Invalid Entry description",
448 Message: "Entry description functions must be a string, a function that accepts the entry parameters and returns a string, or nil.",
449 CodeLocation: cl,
450 DocLink: "table-specs",
451 }
452 }
453
454 func (g ginkgoErrors) MissingParametersForTableFunction(cl CodeLocation) error {
455 return GinkgoError{
456 Heading: "No parameters have been passed to the Table Function",
457 Message: "The Table Function expected at least 1 parameter",
458 CodeLocation: cl,
459 DocLink: "table-specs",
460 }
461 }
462
463 func (g ginkgoErrors) IncorrectParameterTypeForTable(i int, name string, cl CodeLocation) error {
464 return GinkgoError{
465 Heading: "DescribeTable passed incorrect parameter type",
466 Message: fmt.Sprintf("Parameter #%d passed to DescribeTable is of incorrect type <%s>", i, name),
467 CodeLocation: cl,
468 DocLink: "table-specs",
469 }
470 }
471
472 func (g ginkgoErrors) TooFewParametersToTableFunction(expected, actual int, kind string, cl CodeLocation) error {
473 return GinkgoError{
474 Heading: fmt.Sprintf("Too few parameters passed in to %s", kind),
475 Message: fmt.Sprintf("The %s expected %d parameters but you passed in %d", kind, expected, actual),
476 CodeLocation: cl,
477 DocLink: "table-specs",
478 }
479 }
480
481 func (g ginkgoErrors) TooManyParametersToTableFunction(expected, actual int, kind string, cl CodeLocation) error {
482 return GinkgoError{
483 Heading: fmt.Sprintf("Too many parameters passed in to %s", kind),
484 Message: fmt.Sprintf("The %s expected %d parameters but you passed in %d", kind, expected, actual),
485 CodeLocation: cl,
486 DocLink: "table-specs",
487 }
488 }
489
490 func (g ginkgoErrors) IncorrectParameterTypeToTableFunction(i int, expected, actual reflect.Type, kind string, cl CodeLocation) error {
491 return GinkgoError{
492 Heading: fmt.Sprintf("Incorrect parameters type passed to %s", kind),
493 Message: fmt.Sprintf("The %s expected parameter #%d to be of type <%s> but you passed in <%s>", kind, i, expected, actual),
494 CodeLocation: cl,
495 DocLink: "table-specs",
496 }
497 }
498
499 func (g ginkgoErrors) IncorrectVariadicParameterTypeToTableFunction(expected, actual reflect.Type, kind string, cl CodeLocation) error {
500 return GinkgoError{
501 Heading: fmt.Sprintf("Incorrect parameters type passed to %s", kind),
502 Message: fmt.Sprintf("The %s expected its variadic parameters to be of type <%s> but you passed in <%s>", kind, expected, actual),
503 CodeLocation: cl,
504 DocLink: "table-specs",
505 }
506 }
507
508 func (g ginkgoErrors) ContextsCannotBeUsedInSubtreeTables(cl CodeLocation) error {
509 return GinkgoError{
510 Heading: "Contexts cannot be used in subtree tables",
511 Message: "You''ve defined a subtree body function that accepts a context but did not provide one in the table entry. Ginkgo SpecContexts can only be passed in to subject and setup nodes - so if you are trying to implement a spec timeout you should request a context in the It function within your subtree body function, not in the subtree body function itself.",
512 CodeLocation: cl,
513 DocLink: "table-specs",
514 }
515 }
516
517
518
519 func (g ginkgoErrors) AggregatedReportUnavailableDueToNodeDisappearing() error {
520 return GinkgoError{
521 Heading: "Test Report unavailable because a Ginkgo parallel process disappeared",
522 Message: "The aggregated report could not be fetched for a ReportAfterSuite node. A Ginkgo parallel process disappeared before it could finish reporting.",
523 }
524 }
525
526 func (g ginkgoErrors) SynchronizedBeforeSuiteFailedOnProc1() error {
527 return GinkgoError{
528 Heading: "SynchronizedBeforeSuite failed on Ginkgo parallel process #1",
529 Message: "The first SynchronizedBeforeSuite function running on Ginkgo parallel process #1 failed. This suite will now abort.",
530 }
531 }
532
533 func (g ginkgoErrors) SynchronizedBeforeSuiteDisappearedOnProc1() error {
534 return GinkgoError{
535 Heading: "Process #1 disappeared before SynchronizedBeforeSuite could report back",
536 Message: "Ginkgo parallel process #1 disappeared before the first SynchronizedBeforeSuite function completed. This suite will now abort.",
537 }
538 }
539
540
541
542 func (g ginkgoErrors) UnknownTypePassedToRunSpecs(value interface{}) error {
543 return GinkgoError{
544 Heading: "Unknown Type passed to RunSpecs",
545 Message: fmt.Sprintf("RunSpecs() accepts labels, and configuration of type types.SuiteConfig and/or types.ReporterConfig.\n You passed in: %v", value),
546 }
547 }
548
549 var sharedParallelErrorMessage = "It looks like you are trying to run specs in parallel with go test.\nThis is unsupported and you should use the ginkgo CLI instead."
550
551 func (g ginkgoErrors) InvalidParallelTotalConfiguration() error {
552 return GinkgoError{
553 Heading: "-ginkgo.parallel.total must be >= 1",
554 Message: sharedParallelErrorMessage,
555 DocLink: "spec-parallelization",
556 }
557 }
558
559 func (g ginkgoErrors) InvalidParallelProcessConfiguration() error {
560 return GinkgoError{
561 Heading: "-ginkgo.parallel.process is one-indexed and must be <= ginkgo.parallel.total",
562 Message: sharedParallelErrorMessage,
563 DocLink: "spec-parallelization",
564 }
565 }
566
567 func (g ginkgoErrors) MissingParallelHostConfiguration() error {
568 return GinkgoError{
569 Heading: "-ginkgo.parallel.host is missing",
570 Message: sharedParallelErrorMessage,
571 DocLink: "spec-parallelization",
572 }
573 }
574
575 func (g ginkgoErrors) UnreachableParallelHost(host string) error {
576 return GinkgoError{
577 Heading: "Could not reach ginkgo.parallel.host:" + host,
578 Message: sharedParallelErrorMessage,
579 DocLink: "spec-parallelization",
580 }
581 }
582
583 func (g ginkgoErrors) DryRunInParallelConfiguration() error {
584 return GinkgoError{
585 Heading: "Ginkgo only performs -dryRun in serial mode.",
586 Message: "Please try running ginkgo -dryRun again, but without -p or -procs to ensure the suite is running in series.",
587 }
588 }
589
590 func (g ginkgoErrors) GracePeriodCannotBeZero() error {
591 return GinkgoError{
592 Heading: "Ginkgo requires a positive --grace-period.",
593 Message: "Please set --grace-period to a positive duration. The default is 30s.",
594 }
595 }
596
597 func (g ginkgoErrors) ConflictingVerbosityConfiguration() error {
598 return GinkgoError{
599 Heading: "Conflicting reporter verbosity settings.",
600 Message: "You can't set more than one of -v, -vv and --succinct. Please pick one!",
601 }
602 }
603
604 func (g ginkgoErrors) InvalidOutputInterceptorModeConfiguration(value string) error {
605 return GinkgoError{
606 Heading: fmt.Sprintf("Invalid value '%s' for --output-interceptor-mode.", value),
607 Message: "You must choose one of 'dup', 'swap', or 'none'.",
608 }
609 }
610
611 func (g ginkgoErrors) InvalidGoFlagCount() error {
612 return GinkgoError{
613 Heading: "Use of go test -count",
614 Message: "Ginkgo does not support using go test -count to rerun suites. Only -count=1 is allowed. To repeat suite runs, please use the ginkgo cli and `ginkgo -until-it-fails` or `ginkgo -repeat=N`.",
615 }
616 }
617
618 func (g ginkgoErrors) InvalidGoFlagParallel() error {
619 return GinkgoError{
620 Heading: "Use of go test -parallel",
621 Message: "Go test's implementation of parallelization does not actually parallelize Ginkgo specs. Please use the ginkgo cli and `ginkgo -p` or `ginkgo -procs=N` instead.",
622 }
623 }
624
625 func (g ginkgoErrors) BothRepeatAndUntilItFails() error {
626 return GinkgoError{
627 Heading: "--repeat and --until-it-fails are both set",
628 Message: "--until-it-fails directs Ginkgo to rerun specs indefinitely until they fail. --repeat directs Ginkgo to rerun specs a set number of times. You can't set both... which would you like?",
629 }
630 }
631
632
633
634 func (g ginkgoErrors) FailedToParseStackTrace(message string) error {
635 return GinkgoError{
636 Heading: "Failed to Parse Stack Trace",
637 Message: message,
638 }
639 }
640
View as plain text