github.com/onsi/ginkgo@v1.16.6-0.20211118180735-4e1925ba4c95/internal/test_helpers/fake_reporter.go (about)

     1  package test_helpers
     2  
     3  import (
     4  	"reflect"
     5  
     6  	. "github.com/onsi/gomega"
     7  	. "github.com/onsi/gomega/gstruct"
     8  
     9  	"github.com/onsi/ginkgo/internal/interrupt_handler"
    10  	"github.com/onsi/ginkgo/types"
    11  )
    12  
    13  /*
    14  
    15  A FakeReporter and collection of matchers to match against reported suite and spec summaries
    16  
    17  */
    18  
    19  type Reports []types.SpecReport
    20  
    21  func (s Reports) FindByLeafNodeType(nodeTypes types.NodeType) types.SpecReport {
    22  	for _, report := range s {
    23  		if report.LeafNodeType.Is(nodeTypes) {
    24  			return report
    25  		}
    26  	}
    27  
    28  	return types.SpecReport{}
    29  }
    30  
    31  func (s Reports) Find(name string) types.SpecReport {
    32  	for _, report := range s {
    33  		if report.LeafNodeText == name {
    34  			return report
    35  		}
    36  	}
    37  
    38  	return types.SpecReport{}
    39  }
    40  
    41  func (s Reports) FindByFullText(text string) types.SpecReport {
    42  	for _, report := range s {
    43  		if report.FullText() == text {
    44  			return report
    45  		}
    46  	}
    47  
    48  	return types.SpecReport{}
    49  }
    50  
    51  func (s Reports) Names() []string {
    52  	out := []string{}
    53  	for _, report := range s {
    54  		if report.LeafNodeText != "" {
    55  			out = append(out, report.LeafNodeText)
    56  		}
    57  	}
    58  	return out
    59  }
    60  
    61  func (s Reports) WithState(state types.SpecState) Reports {
    62  	out := Reports{}
    63  	for _, report := range s {
    64  		if report.State == state {
    65  			out = append(out, report)
    66  		}
    67  	}
    68  	return out
    69  }
    70  
    71  func (s Reports) WithLeafNodeType(nodeTypes types.NodeType) Reports {
    72  	out := Reports{}
    73  	for _, report := range s {
    74  		if report.LeafNodeType.Is(nodeTypes) {
    75  			out = append(out, report)
    76  		}
    77  	}
    78  	return out
    79  }
    80  
    81  type FakeReporter struct {
    82  	Begin types.Report
    83  	Will  Reports
    84  	Did   Reports
    85  	End   types.Report
    86  }
    87  
    88  func (r *FakeReporter) SuiteWillBegin(report types.Report) {
    89  	r.Begin = report
    90  }
    91  
    92  func (r *FakeReporter) WillRun(report types.SpecReport) {
    93  	r.Will = append(r.Will, report)
    94  }
    95  
    96  func (r *FakeReporter) DidRun(report types.SpecReport) {
    97  	r.Did = append(r.Did, report)
    98  }
    99  
   100  func (r *FakeReporter) SuiteDidEnd(report types.Report) {
   101  	r.End = report
   102  }
   103  
   104  type NSpecs int
   105  type NWillRun int
   106  type NPassed int
   107  type NSkipped int
   108  type NFailed int
   109  type NPending int
   110  type NFlaked int
   111  
   112  func BeASuiteSummary(options ...interface{}) OmegaMatcher {
   113  	type ReportStats struct {
   114  		Succeeded    bool
   115  		TotalSpecs   int
   116  		WillRunSpecs int
   117  		Passed       int
   118  		Skipped      int
   119  		Failed       int
   120  		Pending      int
   121  		Flaked       int
   122  	}
   123  	fields := Fields{
   124  		"Passed":     Equal(0),
   125  		"Skipped":    Equal(0),
   126  		"Failed":     Equal(0),
   127  		"Pending":    Equal(0),
   128  		"Flaked":     Equal(0),
   129  		"TotalSpecs": Equal(0),
   130  	}
   131  	for _, option := range options {
   132  		t := reflect.TypeOf(option)
   133  		if t.Kind() == reflect.Bool {
   134  			if option.(bool) {
   135  				fields["Succeeded"] = BeTrue()
   136  			} else {
   137  				fields["Succeeded"] = BeFalse()
   138  			}
   139  		} else if t == reflect.TypeOf(NSpecs(0)) {
   140  			fields["TotalSpecs"] = Equal(int(option.(NSpecs)))
   141  		} else if t == reflect.TypeOf(NWillRun(0)) {
   142  			fields["WillRunSpecs"] = Equal(int(option.(NWillRun)))
   143  		} else if t == reflect.TypeOf(NPassed(0)) {
   144  			fields["Passed"] = Equal(int(option.(NPassed)))
   145  		} else if t == reflect.TypeOf(NSkipped(0)) {
   146  			fields["Skipped"] = Equal(int(option.(NSkipped)))
   147  		} else if t == reflect.TypeOf(NFailed(0)) {
   148  			fields["Failed"] = Equal(int(option.(NFailed)))
   149  		} else if t == reflect.TypeOf(NPending(0)) {
   150  			fields["Pending"] = Equal(int(option.(NPending)))
   151  		} else if t == reflect.TypeOf(NFlaked(0)) {
   152  			fields["Flaked"] = Equal(int(option.(NFlaked)))
   153  		}
   154  	}
   155  	return WithTransform(func(report types.Report) ReportStats {
   156  		specs := report.SpecReports.WithLeafNodeType(types.NodeTypeIt)
   157  		return ReportStats{
   158  			Succeeded:    report.SuiteSucceeded,
   159  			TotalSpecs:   report.PreRunStats.TotalSpecs,
   160  			WillRunSpecs: report.PreRunStats.SpecsThatWillRun,
   161  			Passed:       specs.CountWithState(types.SpecStatePassed),
   162  			Skipped:      specs.CountWithState(types.SpecStateSkipped),
   163  			Failed:       specs.CountWithState(types.SpecStateFailureStates),
   164  			Pending:      specs.CountWithState(types.SpecStatePending),
   165  			Flaked:       specs.CountOfFlakedSpecs(),
   166  		}
   167  	}, MatchFields(IgnoreExtras, fields))
   168  }
   169  
   170  type CapturedGinkgoWriterOutput string
   171  type CapturedStdOutput string
   172  type NumAttempts int
   173  
   174  func HavePassed(options ...interface{}) OmegaMatcher {
   175  	matchers := []OmegaMatcher{
   176  		HaveField("State", types.SpecStatePassed),
   177  		HaveField("Failure", BeZero()),
   178  	}
   179  	for _, option := range options {
   180  		var matcher OmegaMatcher
   181  		switch v := option.(type) {
   182  		case CapturedGinkgoWriterOutput:
   183  			matcher = HaveField("CapturedGinkgoWriterOutput", string(v))
   184  		case CapturedStdOutput:
   185  			matcher = HaveField("CapturedStdOutErr", string(v))
   186  		case types.NodeType:
   187  			matcher = HaveField("LeafNodeType", v)
   188  		case NumAttempts:
   189  			matcher = HaveField("NumAttempts", int(v))
   190  		}
   191  		if matcher != nil {
   192  			matchers = append(matchers, matcher)
   193  		}
   194  	}
   195  
   196  	return And(matchers...)
   197  }
   198  
   199  func BePending() OmegaMatcher {
   200  	return And(
   201  		HaveField("State", types.SpecStatePending),
   202  		HaveField("Failure", BeZero()),
   203  	)
   204  }
   205  
   206  func HaveBeenSkipped() OmegaMatcher {
   207  	return And(
   208  		HaveField("State", types.SpecStateSkipped),
   209  		HaveField("Failure", BeZero()),
   210  	)
   211  }
   212  
   213  func HaveBeenSkippedWithMessage(message string, options ...interface{}) OmegaMatcher {
   214  	matchers := []OmegaMatcher{
   215  		HaveField("State", types.SpecStateSkipped),
   216  		HaveField("Failure.Message", Equal(message)),
   217  	}
   218  
   219  	for _, option := range options {
   220  		switch v := option.(type) {
   221  		case NumAttempts:
   222  			matchers = append(matchers, HaveField("NumAttempts", int(v)))
   223  		}
   224  	}
   225  	return And(matchers...)
   226  }
   227  
   228  func HaveBeenInterrupted(cause interrupt_handler.InterruptCause) OmegaMatcher {
   229  	return And(
   230  		HaveField("State", types.SpecStateInterrupted),
   231  		HaveField("Failure.Message", HavePrefix(cause.String())),
   232  	)
   233  }
   234  
   235  type FailureNodeType types.NodeType
   236  
   237  func failureMatcherForState(state types.SpecState, messageField string, options ...interface{}) OmegaMatcher {
   238  	matchers := []OmegaMatcher{
   239  		HaveField("State", state),
   240  	}
   241  	for _, option := range options {
   242  		var matcher OmegaMatcher
   243  		switch v := option.(type) {
   244  		case CapturedGinkgoWriterOutput:
   245  			matcher = HaveField("CapturedGinkgoWriterOutput", string(v))
   246  		case CapturedStdOutput:
   247  			matcher = HaveField("CapturedStdOutErr", string(v))
   248  		case types.NodeType:
   249  			matcher = HaveField("LeafNodeType", v)
   250  		case types.FailureNodeContext:
   251  			matcher = HaveField("Failure.FailureNodeContext", v)
   252  		case string:
   253  			matcher = HaveField(messageField, ContainSubstring(v))
   254  		case types.CodeLocation:
   255  			matcher = HaveField("Failure.Location", v)
   256  		case FailureNodeType:
   257  			matcher = HaveField("Failure.FailureNodeType", types.NodeType(v))
   258  		case NumAttempts:
   259  			matcher = HaveField("NumAttempts", int(v))
   260  		}
   261  		if matcher != nil {
   262  			matchers = append(matchers, matcher)
   263  		}
   264  	}
   265  
   266  	return And(matchers...)
   267  }
   268  
   269  func HaveFailed(options ...interface{}) OmegaMatcher {
   270  	return failureMatcherForState(types.SpecStateFailed, "Failure.Message", options...)
   271  }
   272  
   273  func HaveAborted(options ...interface{}) OmegaMatcher {
   274  	return failureMatcherForState(types.SpecStateAborted, "Failure.Message", options...)
   275  }
   276  
   277  func HavePanicked(options ...interface{}) OmegaMatcher {
   278  	return failureMatcherForState(types.SpecStatePanicked, "Failure.ForwardedPanic", options...)
   279  }