github.com/onsi/gomega@v1.32.0/gmeasure/measurement_test.go (about) 1 package gmeasure_test 2 3 import ( 4 "math" 5 "strings" 6 "time" 7 8 . "github.com/onsi/ginkgo/v2" 9 . "github.com/onsi/gomega" 10 "github.com/onsi/gomega/gmeasure" 11 ) 12 13 var _ = Describe("Measurement", func() { 14 var e *gmeasure.Experiment 15 var measurement gmeasure.Measurement 16 17 BeforeEach(func() { 18 e = gmeasure.NewExperiment("Test Experiment") 19 }) 20 21 Describe("Note Measurement", func() { 22 BeforeEach(func() { 23 e.RecordNote("I'm a red note", gmeasure.Style("{{red}}")) 24 measurement = e.Measurements[0] 25 }) 26 27 Describe("Generating Stats", func() { 28 It("returns an empty stats", func() { 29 Ω(measurement.Stats()).Should(BeZero()) 30 }) 31 }) 32 33 Describe("Emitting an unstyled report", func() { 34 It("does not include styling", func() { 35 Ω(measurement.String()).Should(Equal("Test Experiment - Note\nI'm a red note\n")) 36 }) 37 }) 38 39 Describe("Emitting a styled report", func() { 40 It("does include styling", func() { 41 Ω(measurement.ColorableString()).Should(Equal("{{red}}Test Experiment - Note\nI'm a red note\n{{/}}")) 42 }) 43 }) 44 }) 45 46 Describe("Value Measurement", func() { 47 var min, median, mean, stdDev, max float64 48 BeforeEach(func() { 49 e.RecordValue("flange widths", 7.128, gmeasure.Annotation("A"), gmeasure.Precision(2), gmeasure.Units("inches"), gmeasure.Style("{{blue}}")) 50 e.RecordValue("flange widths", 3.141, gmeasure.Annotation("B")) 51 e.RecordValue("flange widths", 9.28223, gmeasure.Annotation("C")) 52 e.RecordValue("flange widths", 14.249, gmeasure.Annotation("D")) 53 e.RecordValue("flange widths", 8.975, gmeasure.Annotation("E")) 54 measurement = e.Measurements[0] 55 min = 3.141 56 max = 14.249 57 median = 8.975 58 mean = (7.128 + 3.141 + 9.28223 + 14.249 + 8.975) / 5.0 59 stdDev = (7.128-mean)*(7.128-mean) + (3.141-mean)*(3.141-mean) + (9.28223-mean)*(9.28223-mean) + (14.249-mean)*(14.249-mean) + (8.975-mean)*(8.975-mean) 60 stdDev = math.Sqrt(stdDev / 5.0) 61 }) 62 63 Describe("Generating Stats", func() { 64 It("generates a correctly configured Stats with correct values", func() { 65 stats := measurement.Stats() 66 Ω(stats.ExperimentName).Should(Equal("Test Experiment")) 67 Ω(stats.MeasurementName).Should(Equal("flange widths")) 68 Ω(stats.Style).Should(Equal("{{blue}}")) 69 Ω(stats.Units).Should(Equal("inches")) 70 Ω(stats.PrecisionBundle.ValueFormat).Should(Equal("%.2f")) 71 72 Ω(stats.ValueBundle[gmeasure.StatMin]).Should(Equal(min)) 73 Ω(stats.AnnotationBundle[gmeasure.StatMin]).Should(Equal("B")) 74 Ω(stats.ValueBundle[gmeasure.StatMax]).Should(Equal(max)) 75 Ω(stats.AnnotationBundle[gmeasure.StatMax]).Should(Equal("D")) 76 Ω(stats.ValueBundle[gmeasure.StatMedian]).Should(Equal(median)) 77 Ω(stats.ValueBundle[gmeasure.StatMean]).Should(Equal(mean)) 78 Ω(stats.ValueBundle[gmeasure.StatStdDev]).Should(BeNumerically("~", stdDev)) 79 }) 80 }) 81 82 Describe("Emitting an unstyled report", func() { 83 It("does not include styling", func() { 84 expected := strings.Join([]string{ 85 "Test Experiment - flange widths [inches]", 86 "3.14 < [8.97] | <8.56> ±3.59 < 14.25", 87 "Value | Annotation", 88 "==================", 89 " 7.13 | A ", 90 "------------------", 91 " 3.14 | B ", 92 "------------------", 93 " 9.28 | C ", 94 "------------------", 95 "14.25 | D ", 96 "------------------", 97 " 8.97 | E ", 98 "", 99 }, "\n") 100 Ω(measurement.String()).Should(Equal(expected)) 101 }) 102 }) 103 104 Describe("Emitting a styled report", func() { 105 It("does include styling", func() { 106 expected := strings.Join([]string{ 107 "{{blue}}Test Experiment - flange widths [inches]{{/}}", 108 "3.14 < [8.97] | <8.56> ±3.59 < 14.25", 109 "{{blue}}Value{{/}} | {{blue}}Annotation{{/}}", 110 "==================", 111 " 7.13 | {{gray}}A {{/}}", 112 "------------------", 113 " 3.14 | {{gray}}B {{/}}", 114 "------------------", 115 " 9.28 | {{gray}}C {{/}}", 116 "------------------", 117 "14.25 | {{gray}}D {{/}}", 118 "------------------", 119 " 8.97 | {{gray}}E {{/}}", 120 "", 121 }, "\n") 122 Ω(measurement.ColorableString()).Should(Equal(expected)) 123 }) 124 }) 125 126 Describe("Computing medians", func() { 127 Context("with an odd number of values", func() { 128 It("returns the middle element", func() { 129 e.RecordValue("odd", 5) 130 e.RecordValue("odd", 1) 131 e.RecordValue("odd", 2) 132 e.RecordValue("odd", 4) 133 e.RecordValue("odd", 3) 134 135 Ω(e.GetStats("odd").ValueBundle[gmeasure.StatMedian]).Should(Equal(3.0)) 136 }) 137 }) 138 139 Context("when an even number of values", func() { 140 It("returns the mean of the two middle elements", func() { 141 e.RecordValue("even", 1) 142 e.RecordValue("even", 2) 143 e.RecordValue("even", 4) 144 e.RecordValue("even", 3) 145 146 Ω(e.GetStats("even").ValueBundle[gmeasure.StatMedian]).Should(Equal(2.5)) 147 }) 148 }) 149 }) 150 }) 151 152 Describe("Duration Measurement", func() { 153 var min, median, mean, stdDev, max time.Duration 154 BeforeEach(func() { 155 e.RecordDuration("runtime", 7128*time.Millisecond, gmeasure.Annotation("A"), gmeasure.Precision(time.Millisecond*100), gmeasure.Style("{{blue}}")) 156 e.RecordDuration("runtime", 3141*time.Millisecond, gmeasure.Annotation("B")) 157 e.RecordDuration("runtime", 9282*time.Millisecond, gmeasure.Annotation("C")) 158 e.RecordDuration("runtime", 14249*time.Millisecond, gmeasure.Annotation("D")) 159 e.RecordDuration("runtime", 8975*time.Millisecond, gmeasure.Annotation("E")) 160 measurement = e.Measurements[0] 161 min = 3141 * time.Millisecond 162 max = 14249 * time.Millisecond 163 median = 8975 * time.Millisecond 164 mean = ((7128 + 3141 + 9282 + 14249 + 8975) * time.Millisecond) / 5 165 stdDev = time.Duration(math.Sqrt((float64(7128*time.Millisecond-mean)*float64(7128*time.Millisecond-mean) + float64(3141*time.Millisecond-mean)*float64(3141*time.Millisecond-mean) + float64(9282*time.Millisecond-mean)*float64(9282*time.Millisecond-mean) + float64(14249*time.Millisecond-mean)*float64(14249*time.Millisecond-mean) + float64(8975*time.Millisecond-mean)*float64(8975*time.Millisecond-mean)) / 5.0)) 166 }) 167 168 Describe("Generating Stats", func() { 169 It("generates a correctly configured Stats with correct values", func() { 170 stats := measurement.Stats() 171 Ω(stats.ExperimentName).Should(Equal("Test Experiment")) 172 Ω(stats.MeasurementName).Should(Equal("runtime")) 173 Ω(stats.Style).Should(Equal("{{blue}}")) 174 Ω(stats.Units).Should(Equal("duration")) 175 Ω(stats.PrecisionBundle.Duration).Should(Equal(time.Millisecond * 100)) 176 177 Ω(stats.DurationBundle[gmeasure.StatMin]).Should(Equal(min)) 178 Ω(stats.AnnotationBundle[gmeasure.StatMin]).Should(Equal("B")) 179 Ω(stats.DurationBundle[gmeasure.StatMax]).Should(Equal(max)) 180 Ω(stats.AnnotationBundle[gmeasure.StatMax]).Should(Equal("D")) 181 Ω(stats.DurationBundle[gmeasure.StatMedian]).Should(Equal(median)) 182 Ω(stats.DurationBundle[gmeasure.StatMean]).Should(Equal(mean)) 183 Ω(stats.DurationBundle[gmeasure.StatStdDev]).Should(Equal(stdDev)) 184 }) 185 }) 186 187 Describe("Emitting an unstyled report", func() { 188 It("does not include styling", func() { 189 expected := strings.Join([]string{ 190 "Test Experiment - runtime [duration]", 191 "3.1s < [9s] | <8.6s> ±3.6s < 14.2s", 192 "Duration | Annotation", 193 "=====================", 194 " 7.1s | A ", 195 "---------------------", 196 " 3.1s | B ", 197 "---------------------", 198 " 9.3s | C ", 199 "---------------------", 200 " 14.2s | D ", 201 "---------------------", 202 " 9s | E ", 203 "", 204 }, "\n") 205 Ω(measurement.String()).Should(Equal(expected)) 206 }) 207 }) 208 209 Describe("Emitting a styled report", func() { 210 It("does include styling", func() { 211 expected := strings.Join([]string{ 212 "{{blue}}Test Experiment - runtime [duration]{{/}}", 213 "3.1s < [9s] | <8.6s> ±3.6s < 14.2s", 214 "{{blue}}Duration{{/}} | {{blue}}Annotation{{/}}", 215 "=====================", 216 "{{blue}} 7.1s{{/}} | {{gray}}A {{/}}", 217 "---------------------", 218 "{{blue}} 3.1s{{/}} | {{gray}}B {{/}}", 219 "---------------------", 220 "{{blue}} 9.3s{{/}} | {{gray}}C {{/}}", 221 "---------------------", 222 "{{blue}} 14.2s{{/}} | {{gray}}D {{/}}", 223 "---------------------", 224 "{{blue}} 9s{{/}} | {{gray}}E {{/}}", 225 "", 226 }, "\n") 227 Ω(measurement.ColorableString()).Should(Equal(expected)) 228 }) 229 }) 230 231 Describe("Computing medians", func() { 232 Context("with an odd number of values", func() { 233 It("returns the middle element", func() { 234 e.RecordDuration("odd", 5*time.Second) 235 e.RecordDuration("odd", 1*time.Second) 236 e.RecordDuration("odd", 2*time.Second) 237 e.RecordDuration("odd", 4*time.Second) 238 e.RecordDuration("odd", 3*time.Second) 239 240 Ω(e.GetStats("odd").DurationBundle[gmeasure.StatMedian]).Should(Equal(3 * time.Second)) 241 }) 242 }) 243 244 Context("when an even number of values", func() { 245 It("returns the mean of the two middle elements", func() { 246 e.RecordDuration("even", 1*time.Second) 247 e.RecordDuration("even", 2*time.Second) 248 e.RecordDuration("even", 4*time.Second) 249 e.RecordDuration("even", 3*time.Second) 250 251 Ω(e.GetStats("even").DurationBundle[gmeasure.StatMedian]).Should(Equal(2500 * time.Millisecond)) 252 }) 253 }) 254 }) 255 }) 256 })