From 7209591e08e14ddda4c3ff1996d3d885de296950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20BENO=C3=8ET?= Date: Sat, 20 Jul 2024 18:42:18 +0200 Subject: [PATCH] feat(pkg): add `Range.Contains()` method --- pkg/perfdata/range.go | 24 ++++++++++++++++++ pkg/perfdata/range_test.go | 50 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/pkg/perfdata/range.go b/pkg/perfdata/range.go index f74ca2a..02face6 100644 --- a/pkg/perfdata/range.go +++ b/pkg/perfdata/range.go @@ -2,6 +2,7 @@ package perfdata // import nocternity.net/gomonop/pkg/perfdata import ( "fmt" + "strconv" "strings" ) @@ -66,6 +67,29 @@ func (r *Range) String() string { return inside + start + ":" + r.end } +// Contains checks whether a numeric value is within the range. +func (r *Range) Contains(value float64) bool { + var inStart, inEnd bool + + if r.start != "" { + startValue, err := strconv.ParseFloat(r.start, 64) + if err != nil { + panic(fmt.Sprintf("invalid performance data range start value: %v", err)) + } + inStart = value < startValue + } + + if r.end != "" { + endValue, err := strconv.ParseFloat(r.end, 64) + if err != nil { + panic(fmt.Sprintf("invalid performance data range end value: %v", err)) + } + inEnd = value > endValue + } + + return (inStart || inEnd) != r.inside +} + // A state of the range parser. type rangeParserState int diff --git a/pkg/perfdata/range_test.go b/pkg/perfdata/range_test.go index 8238026..2bcf56f 100644 --- a/pkg/perfdata/range_test.go +++ b/pkg/perfdata/range_test.go @@ -69,6 +69,56 @@ func TestRangeString(t *testing.T) { } } +func TestRangeContains(t *testing.T) { + type Test struct { + pdr Range + value float64 + result bool + } + + tests := []Test{ + {pdr: Range{start: "0", end: "10"}, value: 0, result: false}, + {pdr: Range{start: "0", end: "10"}, value: 10, result: false}, + {pdr: Range{start: "0", end: "10"}, value: -1, result: true}, + {pdr: Range{start: "0", end: "10"}, value: 11, result: true}, + {pdr: Range{start: "", end: "10"}, value: -1000, result: false}, + {pdr: Range{start: "", end: "10"}, value: 10, result: false}, + {pdr: Range{start: "", end: "10"}, value: 11, result: true}, + {pdr: Range{start: "10", end: ""}, value: -1000, result: true}, + {pdr: Range{start: "10", end: ""}, value: 9, result: true}, + {pdr: Range{start: "10", end: ""}, value: 10, result: false}, + {pdr: Range{start: "10", end: "20"}, value: 9, result: true}, + {pdr: Range{start: "10", end: "20"}, value: 10, result: false}, + {pdr: Range{start: "10", end: "20"}, value: 20, result: false}, + {pdr: Range{start: "10", end: "20"}, value: 21, result: true}, + } + + // Test cases with the inside flag set and the opposite result + n := len(tests) + for i := range n { + tests = append(tests, Test{ + pdr: Range{ + start: tests[i].pdr.start, + end: tests[i].pdr.end, + inside: !tests[i].pdr.inside, + }, + value: tests[i].value, + result: !tests[i].result, + }) + } + + for _, test := range tests { + t.Run(fmt.Sprintf("%v", test), func(t *testing.T) { + result := test.pdr.Contains(test.value) + assert.Equal( + t, test.result, result, + "Expected '%v', got '%v' for value '%f' and range '%s'", + test.result, result, test.value, test.pdr.String(), + ) + }) + } +} + func TestRangeParserOk(t *testing.T) { type Test struct { in string