github.com/weaviate/weaviate@v1.24.6/adapters/repos/db/aggregator/numerical_test.go (about) 1 // _ _ 2 // __ _____ __ ___ ___ __ _| |_ ___ 3 // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ 4 // \ V V / __/ (_| |\ V /| | (_| | || __/ 5 // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| 6 // 7 // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. 8 // 9 // CONTACT: hello@weaviate.io 10 // 11 12 package aggregator 13 14 import ( 15 "testing" 16 17 "github.com/stretchr/testify/assert" 18 ) 19 20 func TestNumericalAggregator_MedianCalculation(t *testing.T) { 21 tests := []struct { 22 name string 23 numbers []float64 24 expectedMedian float64 25 }{ 26 { 27 name: "Uneven number of elements", 28 numbers: []float64{1, 2, 3, 4, 5, 6, 7}, 29 expectedMedian: 4, 30 }, 31 { 32 name: "Uneven number of elements with double elements", 33 numbers: []float64{2, 4, 4, 4, 5, 5, 7}, 34 expectedMedian: 4, 35 }, 36 { 37 name: "Even number of elements", 38 numbers: []float64{1, 2, 3, 5, 7, 7}, 39 expectedMedian: 4, 40 }, 41 { 42 name: "Even number of elements with double elements, median is within double entries", 43 numbers: []float64{1, 2, 3, 3, 6, 7}, 44 expectedMedian: 3, 45 }, 46 { 47 name: "Even number of elements with double elements, median is after double entries", 48 numbers: []float64{3, 3, 3, 5, 5, 7}, 49 expectedMedian: 4, 50 }, 51 { 52 name: "Single value", 53 numbers: []float64{42}, 54 expectedMedian: 42, 55 }, 56 } 57 for _, tt := range tests { 58 for i := 0; i < 2; i++ { // test two ways of adding the value to the aggregator 59 t.Run(tt.name, func(t *testing.T) { 60 agg := newNumericalAggregator() 61 for _, num := range tt.numbers { 62 if i == 0 { 63 agg.AddFloat64(num) 64 } else { 65 agg.AddNumberRow(num, 1) 66 } 67 } 68 agg.buildPairsFromCounts() // needed to populate all required info 69 assert.Equal(t, tt.expectedMedian, agg.Median()) 70 }) 71 } 72 } 73 } 74 75 func TestNumericalAggregator_ModeCalculation(t *testing.T) { 76 tests := []struct { 77 name string 78 numbers []float64 79 expectedMode float64 80 }{ 81 { 82 name: "Different elements (asc)", 83 numbers: []float64{1, 2, 3, 4, 5, 6, 7}, 84 expectedMode: 1, 85 }, 86 { 87 name: "Different elements (desc)", 88 numbers: []float64{7, 6, 5, 4, 3, 2, 1}, 89 expectedMode: 1, 90 }, 91 { 92 name: "Elements with different number of duplicates", 93 numbers: []float64{2, 4, 4, 5, 5, 5, 7}, 94 expectedMode: 5, 95 }, 96 { 97 name: "Elements with same number of duplicates (asc)", 98 numbers: []float64{1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7}, 99 expectedMode: 1, 100 }, 101 { 102 name: "Elements with same number of duplicates (desc)", 103 numbers: []float64{7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1}, 104 expectedMode: 1, 105 }, 106 { 107 name: "Elements with same number of duplicates (mixed oreder)", 108 numbers: []float64{5, 2, 6, 2, 1, 4, 7, 5, 7, 4, 3, 1, 6, 3}, 109 expectedMode: 1, 110 }, 111 { 112 name: "Single element", 113 numbers: []float64{42}, 114 expectedMode: 42, 115 }, 116 } 117 for _, tt := range tests { 118 t.Run(tt.name, func(t *testing.T) { 119 agg := newNumericalAggregator() 120 for _, num := range tt.numbers { 121 agg.AddFloat64(num) 122 } 123 agg.buildPairsFromCounts() // needed to populate all required info 124 125 assert.Equal(t, tt.expectedMode, agg.Mode()) 126 }) 127 128 t.Run(tt.name, func(t *testing.T) { 129 agg := newNumericalAggregator() 130 for _, num := range tt.numbers { 131 agg.AddNumberRow(num, 1) 132 } 133 agg.buildPairsFromCounts() // needed to populate all required info 134 135 assert.Equal(t, tt.expectedMode, agg.Mode()) 136 }) 137 } 138 } 139 140 func TestNumericalAggregator_MinMaxCalculation(t *testing.T) { 141 tests := []struct { 142 name string 143 numbers []float64 144 expectedMin float64 145 expectedMax float64 146 }{ 147 { 148 name: "Different positive elements (asc)", 149 numbers: []float64{0, 1, 2, 3, 4, 5, 6, 7}, 150 expectedMin: 0, 151 expectedMax: 7, 152 }, 153 { 154 name: "Different positive elements (desc)", 155 numbers: []float64{7, 6, 5, 4, 3, 2, 1, 0}, 156 expectedMin: 0, 157 expectedMax: 7, 158 }, 159 { 160 name: "Different negative elements (desc)", 161 numbers: []float64{-1, -2, -3, -4, -5, -6, -7}, 162 expectedMin: -7, 163 expectedMax: -1, 164 }, 165 { 166 name: "Different negative elements (asc)", 167 numbers: []float64{-7, -6, -5, -4, -3, -2, -1}, 168 expectedMin: -7, 169 expectedMax: -1, 170 }, 171 { 172 name: "Different elements (mixed order)", 173 numbers: []float64{-7, 6, -5, 4, -3, 2, -1, 0, 1, -2, 3, -4, 5, -6, 7}, 174 expectedMin: -7, 175 expectedMax: 7, 176 }, 177 { 178 name: "Single element", 179 numbers: []float64{-42}, 180 expectedMin: -42, 181 expectedMax: -42, 182 }, 183 } 184 185 for _, tt := range tests { 186 t.Run(tt.name, func(t *testing.T) { 187 agg := newNumericalAggregator() 188 for _, num := range tt.numbers { 189 agg.AddFloat64(num) 190 } 191 assert.Equal(t, tt.expectedMin, agg.Min()) 192 assert.Equal(t, tt.expectedMax, agg.Max()) 193 }) 194 195 t.Run(tt.name, func(t *testing.T) { 196 agg := newNumericalAggregator() 197 for _, num := range tt.numbers { 198 agg.AddNumberRow(num, 1) 199 } 200 assert.Equal(t, tt.expectedMin, agg.Min()) 201 assert.Equal(t, tt.expectedMax, agg.Max()) 202 }) 203 } 204 }