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

     1  package internal_test
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"time"
     7  
     8  	. "github.com/onsi/ginkgo"
     9  	"github.com/onsi/ginkgo/internal"
    10  	"github.com/onsi/ginkgo/types"
    11  	. "github.com/onsi/gomega"
    12  )
    13  
    14  type SomeStruct struct {
    15  	Label string
    16  	Count int
    17  }
    18  
    19  type StringerStruct struct {
    20  	Label string
    21  	Count int
    22  }
    23  
    24  func (s StringerStruct) String() string {
    25  	return fmt.Sprintf("%s %d", s.Label, s.Count)
    26  }
    27  
    28  type ColorableStringerStruct struct {
    29  	Label string
    30  	Count int
    31  }
    32  
    33  func (s ColorableStringerStruct) String() string {
    34  	return fmt.Sprintf("%s %d", s.Label, s.Count)
    35  }
    36  
    37  func (s ColorableStringerStruct) ColorableString() string {
    38  	return fmt.Sprintf("{{red}}%s {{green}}%d{{/}}", s.Label, s.Count)
    39  }
    40  
    41  func reportEntryJSONRoundTrip(reportEntry internal.ReportEntry) internal.ReportEntry {
    42  	data, err := json.Marshal(reportEntry)
    43  	ExpectWithOffset(1, err).ShouldNot(HaveOccurred())
    44  	var out internal.ReportEntry
    45  	ExpectWithOffset(1, json.Unmarshal(data, &out)).Should(Succeed())
    46  	return out
    47  }
    48  
    49  var _ = Describe("ReportEntry and ReportEntries", func() {
    50  	var reportEntry internal.ReportEntry
    51  	var err error
    52  
    53  	Describe("ReportEntry with no passed-in value", func() {
    54  		BeforeEach(func() {
    55  			reportEntry, err = internal.NewReportEntry("name", cl)
    56  			Ω(err).ShouldNot(HaveOccurred())
    57  		})
    58  
    59  		It("returns a correctly configured ReportEntry", func() {
    60  			Ω(reportEntry.Visibility).Should(Equal(types.ReportEntryVisibilityAlways))
    61  			Ω(reportEntry.Name).Should(Equal("name"))
    62  			Ω(reportEntry.Time).Should(BeTemporally("~", time.Now(), time.Second))
    63  			Ω(reportEntry.Location).Should(Equal(cl))
    64  			Ω(reportEntry.GetRawValue()).Should(BeNil())
    65  		})
    66  
    67  		It("has an empty StringRepresentation", func() {
    68  			Ω(reportEntry.StringRepresentation()).Should(BeZero())
    69  		})
    70  
    71  		It("round-trips through JSON correctly", func() {
    72  			rtEntry := reportEntryJSONRoundTrip(reportEntry)
    73  			Ω(rtEntry.Visibility).Should(Equal(types.ReportEntryVisibilityAlways))
    74  			Ω(rtEntry.Name).Should(Equal("name"))
    75  			Ω(rtEntry.Time).Should(BeTemporally("~", time.Now(), time.Second))
    76  			Ω(rtEntry.Location).Should(Equal(cl))
    77  			Ω(rtEntry.GetRawValue()).Should(BeNil())
    78  			Ω(rtEntry.StringRepresentation()).Should(BeZero())
    79  		})
    80  	})
    81  
    82  	Context("with a string passed-in value", func() {
    83  		BeforeEach(func() {
    84  			reportEntry, err = internal.NewReportEntry("name", cl, "bob")
    85  			Ω(err).ShouldNot(HaveOccurred())
    86  		})
    87  
    88  		It("returns a correctly configured ReportEntry", func() {
    89  			Ω(reportEntry.GetRawValue()).Should(Equal("bob"))
    90  		})
    91  
    92  		It("has the correct StringRepresentation", func() {
    93  			Ω(reportEntry.StringRepresentation()).Should(Equal("bob"))
    94  		})
    95  
    96  		It("round-trips through JSON correctly", func() {
    97  			rtEntry := reportEntryJSONRoundTrip(reportEntry)
    98  			Ω(rtEntry.GetRawValue()).Should(Equal("bob"))
    99  			Ω(rtEntry.StringRepresentation()).Should(Equal("bob"))
   100  		})
   101  	})
   102  
   103  	Context("with a numerical passed-in value", func() {
   104  		BeforeEach(func() {
   105  			reportEntry, err = internal.NewReportEntry("name", cl, 17)
   106  			Ω(err).ShouldNot(HaveOccurred())
   107  		})
   108  
   109  		It("returns a correctly configured ReportEntry", func() {
   110  			Ω(reportEntry.GetRawValue()).Should(Equal(17))
   111  		})
   112  
   113  		It("has the correct StringRepresentation", func() {
   114  			Ω(reportEntry.StringRepresentation()).Should(Equal("17"))
   115  		})
   116  
   117  		It("round-trips through JSON correctly", func() {
   118  			rtEntry := reportEntryJSONRoundTrip(reportEntry)
   119  			Ω(rtEntry.GetRawValue()).Should(Equal(float64(17)))
   120  			Ω(rtEntry.StringRepresentation()).Should(Equal("17"))
   121  		})
   122  	})
   123  
   124  	Context("with a struct passed-in value", func() {
   125  		BeforeEach(func() {
   126  			reportEntry, err = internal.NewReportEntry("name", cl, SomeStruct{"bob", 17})
   127  			Ω(err).ShouldNot(HaveOccurred())
   128  		})
   129  
   130  		It("returns a correctly configured ReportEntry", func() {
   131  			Ω(reportEntry.GetRawValue()).Should(Equal(SomeStruct{"bob", 17}))
   132  		})
   133  
   134  		It("has the correct StringRepresentation", func() {
   135  			Ω(reportEntry.StringRepresentation()).Should(Equal("{Label:bob Count:17}"))
   136  		})
   137  
   138  		It("round-trips through JSON correctly", func() {
   139  			rtEntry := reportEntryJSONRoundTrip(reportEntry)
   140  			Ω(rtEntry.GetRawValue()).Should(Equal(map[string]interface{}{"Label": "bob", "Count": float64(17)}))
   141  			Ω(rtEntry.StringRepresentation()).Should(Equal("{Label:bob Count:17}"))
   142  		})
   143  
   144  		It("can be rehydrated into the correct struct, manually", func() {
   145  			rtEntry := reportEntryJSONRoundTrip(reportEntry)
   146  			var s SomeStruct
   147  			Ω(json.Unmarshal([]byte(rtEntry.Value.AsJSON), &s)).Should(Succeed())
   148  			Ω(s).Should(Equal(SomeStruct{"bob", 17}))
   149  		})
   150  	})
   151  
   152  	Context("with a stringer passed-in value", func() {
   153  		BeforeEach(func() {
   154  			reportEntry, err = internal.NewReportEntry("name", cl, StringerStruct{"bob", 17})
   155  			Ω(err).ShouldNot(HaveOccurred())
   156  		})
   157  
   158  		It("returns a correctly configured ReportEntry", func() {
   159  			Ω(reportEntry.GetRawValue()).Should(Equal(StringerStruct{"bob", 17}))
   160  		})
   161  
   162  		It("has the correct StringRepresentation", func() {
   163  			Ω(reportEntry.StringRepresentation()).Should(Equal("bob 17"))
   164  		})
   165  
   166  		It("round-trips through JSON correctly", func() {
   167  			rtEntry := reportEntryJSONRoundTrip(reportEntry)
   168  			Ω(rtEntry.GetRawValue()).Should(Equal(map[string]interface{}{"Label": "bob", "Count": float64(17)}))
   169  			Ω(rtEntry.StringRepresentation()).Should(Equal("bob 17"))
   170  		})
   171  	})
   172  
   173  	Context("with a ColorableStringer passed-in value", func() {
   174  		BeforeEach(func() {
   175  			reportEntry, err = internal.NewReportEntry("name", cl, ColorableStringerStruct{"bob", 17})
   176  			Ω(err).ShouldNot(HaveOccurred())
   177  		})
   178  
   179  		It("returns a correctly configured ReportEntry", func() {
   180  			Ω(reportEntry.GetRawValue()).Should(Equal(ColorableStringerStruct{"bob", 17}))
   181  		})
   182  
   183  		It("has the correct StringRepresentation", func() {
   184  			Ω(reportEntry.StringRepresentation()).Should(Equal("{{red}}bob {{green}}17{{/}}"))
   185  		})
   186  
   187  		It("round-trips through JSON correctly", func() {
   188  			rtEntry := reportEntryJSONRoundTrip(reportEntry)
   189  			Ω(rtEntry.GetRawValue()).Should(Equal(map[string]interface{}{"Label": "bob", "Count": float64(17)}))
   190  			Ω(rtEntry.StringRepresentation()).Should(Equal("{{red}}bob {{green}}17{{/}}"))
   191  		})
   192  	})
   193  
   194  	Context("with multiple passed-in values", func() {
   195  		It("errors", func() {
   196  			reportEntry, err = internal.NewReportEntry("name", cl, 1, "2")
   197  			Ω(err).Should(MatchError(types.GinkgoErrors.TooManyReportEntryValues(cl, "2")))
   198  		})
   199  	})
   200  
   201  	Context("with the Offset decoration", func() {
   202  		It("computes a new offset code location", func() {
   203  			reportEntry, err = internal.NewReportEntry("name", cl, Offset(1))
   204  			Ω(reportEntry.GetRawValue()).Should(BeNil())
   205  			expectedCL := types.NewCodeLocation(2) // NewReportEntry has a BaseOffset of 2
   206  			Ω(reportEntry.Location.FileName).Should(Equal(expectedCL.FileName))
   207  		})
   208  	})
   209  	Context("with a CodeLocation", func() {
   210  		It("uses the passed-in codelocation", func() {
   211  			customCl := types.NewCustomCodeLocation("foo")
   212  			reportEntry, err = internal.NewReportEntry("name", cl, customCl)
   213  			Ω(reportEntry.GetRawValue()).Should(BeNil())
   214  			Ω(reportEntry.Location).Should(Equal(customCl))
   215  		})
   216  	})
   217  	Context("with a ReportEntryVisibility", func() {
   218  		It("uses the passed in visibility", func() {
   219  			reportEntry, err = internal.NewReportEntry("name", cl, types.ReportEntryVisibilityFailureOrVerbose)
   220  			Ω(reportEntry.GetRawValue()).Should(BeNil())
   221  			Ω(reportEntry.Visibility).Should(Equal(types.ReportEntryVisibilityFailureOrVerbose))
   222  		})
   223  	})
   224  	Context("with a time", func() {
   225  		It("uses the passed in time", func() {
   226  			t := time.Date(1984, 3, 7, 0, 0, 0, 0, time.Local)
   227  			reportEntry, err = internal.NewReportEntry("name", cl, t)
   228  			Ω(reportEntry.GetRawValue()).Should(BeNil())
   229  			Ω(reportEntry.Time).Should(Equal(t))
   230  		})
   231  	})
   232  
   233  	Describe("ReportEntries.HasVisibility", func() {
   234  		It("is true when the ReportEntries have the requested visibilities", func() {
   235  			entries := types.ReportEntries{
   236  				types.ReportEntry{Visibility: types.ReportEntryVisibilityAlways},
   237  				types.ReportEntry{Visibility: types.ReportEntryVisibilityAlways},
   238  			}
   239  
   240  			Ω(entries.HasVisibility(types.ReportEntryVisibilityNever, types.ReportEntryVisibilityAlways)).Should(BeTrue())
   241  			Ω(entries.HasVisibility(types.ReportEntryVisibilityNever, types.ReportEntryVisibilityFailureOrVerbose)).Should(BeFalse())
   242  		})
   243  	})
   244  
   245  	Describe("ReportEntries.WithVisibility", func() {
   246  		It("returns the subset of report entries with the requested visibilities", func() {
   247  			entries := types.ReportEntries{
   248  				types.ReportEntry{Name: "A", Visibility: types.ReportEntryVisibilityAlways},
   249  				types.ReportEntry{Name: "B", Visibility: types.ReportEntryVisibilityFailureOrVerbose},
   250  				types.ReportEntry{Name: "C", Visibility: types.ReportEntryVisibilityNever},
   251  			}
   252  			Ω(entries.WithVisibility(types.ReportEntryVisibilityAlways, types.ReportEntryVisibilityFailureOrVerbose)).Should(Equal(
   253  				types.ReportEntries{
   254  					types.ReportEntry{Name: "A", Visibility: types.ReportEntryVisibilityAlways},
   255  					types.ReportEntry{Name: "B", Visibility: types.ReportEntryVisibilityFailureOrVerbose},
   256  				},
   257  			))
   258  
   259  		})
   260  	})
   261  
   262  	Describe("mini-integration test - validating that the DSL correctly wires into the suite", func() {
   263  		Context("when passed a value", func() {
   264  			It("works!", func() {
   265  				AddReportEntry("A Test ReportEntry", ColorableStringerStruct{"bob", 17}, types.ReportEntryVisibilityFailureOrVerbose)
   266  			})
   267  
   268  			ReportAfterEach(func(report SpecReport) {
   269  				if report.State.Is(types.SpecStatePassed) {
   270  					Ω(report.ReportEntries[0].StringRepresentation()).Should(Equal("{{red}}bob {{green}}17{{/}}"))
   271  				}
   272  			})
   273  		})
   274  
   275  		Context("when passed a pointer that subsequently changes", func() {
   276  			var obj *ColorableStringerStruct
   277  
   278  			BeforeEach(func() {
   279  				obj = &ColorableStringerStruct{"bob", 17}
   280  			})
   281  
   282  			It("works!", func() {
   283  				AddReportEntry("A Test ReportEntry", obj, types.ReportEntryVisibilityFailureOrVerbose)
   284  			})
   285  
   286  			AfterEach(func() {
   287  				obj.Label = "alice"
   288  				obj.Count = 42
   289  			})
   290  
   291  			ReportAfterEach(func(report SpecReport) {
   292  				if report.State.Is(types.SpecStatePassed) {
   293  					Ω(report.ReportEntries[0].StringRepresentation()).Should(Equal("{{red}}alice {{green}}42{{/}}"))
   294  				}
   295  			})
   296  		})
   297  	})
   298  })