...

Source file src/github.com/onsi/ginkgo/v2/types/errors.go

Documentation: github.com/onsi/ginkgo/v2/types

     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  /* Tree construction errors */
    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  /* Decorator errors */
   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  /* Ordered Container errors */
   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  /* DeferCleanup errors */
   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  /* ReportEntry errors */
   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  /* By errors */
   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  /* FileFilter and SkipFilter errors */
   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  /* Label Errors */
   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  /* Table errors */
   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  /* Parallel Synchronization errors */
   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  /* Configuration errors */
   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  /* Stack-Trace parsing errors */
   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