Skip to content

Commit 186e61f

Browse files
committed
Add Binary Double datatype tests
1 parent 009eb56 commit 186e61f

File tree

1 file changed

+358
-0
lines changed

1 file changed

+358
-0
lines changed

tests/binary_double_test.go

Lines changed: 358 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,358 @@
1+
/*
2+
** Copyright (c) 2025 Oracle and/or its affiliates.
3+
**
4+
** The Universal Permissive License (UPL), Version 1.0
5+
**
6+
** Subject to the condition set forth below, permission is hereby granted to any
7+
** person obtaining a copy of this software, associated documentation and/or data
8+
** (collectively the "Software"), free of charge and under any and all copyright
9+
** rights in the Software, and any and all patent rights owned or freely
10+
** licensable by each licensor hereunder covering either (i) the unmodified
11+
** Software as contributed to or provided by such licensor, or (ii) the Larger
12+
** Works (as defined below), to deal in both
13+
**
14+
** (a) the Software, and
15+
** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
16+
** one is included with the Software (each a "Larger Work" to which the Software
17+
** is contributed by such licensors),
18+
**
19+
** without restriction, including without limitation the rights to copy, create
20+
** derivative works of, display, perform, and distribute the Software and make,
21+
** use, sell, offer for sale, import, export, have made, and have sold the
22+
** Software and the Larger Work(s), and to sublicense the foregoing rights on
23+
** either these or other terms.
24+
**
25+
** This license is subject to the following condition:
26+
** The above copyright notice and either this complete permission notice or at
27+
** a minimum a reference to the UPL must be included in all copies or
28+
** substantial portions of the Software.
29+
**
30+
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31+
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32+
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
33+
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34+
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
35+
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36+
** SOFTWARE.
37+
*/
38+
39+
package tests
40+
41+
import (
42+
"database/sql"
43+
"math"
44+
"testing"
45+
)
46+
47+
type BinaryDoubleTest struct {
48+
ID uint `gorm:"column:ID;primaryKey"`
49+
DoubleValue float64 `gorm:"column:DOUBLE_VALUE;type:BINARY_DOUBLE"`
50+
NullableDouble *float64 `gorm:"column:NULLABLE_DOUBLE;type:BINARY_DOUBLE"`
51+
SQLNullFloat sql.NullFloat64 `gorm:"column:SQL_NULL_FLOAT;type:BINARY_DOUBLE"`
52+
}
53+
54+
func (BinaryDoubleTest) TableName() string {
55+
return "BINARY_DOUBLE_TESTS"
56+
}
57+
58+
func TestBinaryDoubleBasicCRUD(t *testing.T) {
59+
DB.Migrator().DropTable(&BinaryDoubleTest{})
60+
if err := DB.AutoMigrate(&BinaryDoubleTest{}); err != nil {
61+
t.Fatalf("failed to migrate: %v", err)
62+
}
63+
64+
// CREATE - Insert basic double value
65+
testValue := 3.141592653589793
66+
bd1 := BinaryDoubleTest{DoubleValue: testValue}
67+
if err := DB.Create(&bd1).Error; err != nil {
68+
t.Fatalf("insert failed: %v", err)
69+
}
70+
71+
// READ - Fetch and verify
72+
var got BinaryDoubleTest
73+
if err := DB.First(&got, bd1.ID).Error; err != nil {
74+
t.Fatalf("fetch failed: %v", err)
75+
}
76+
77+
if math.Abs(got.DoubleValue - testValue) > 1e-15 {
78+
t.Errorf("expected %v, got %v", testValue, got.DoubleValue)
79+
}
80+
81+
// UPDATE - Modify the value
82+
newValue := 2.718281828459045
83+
if err := DB.Model(&got).Update("DoubleValue", newValue).Error; err != nil {
84+
t.Fatalf("update failed: %v", err)
85+
}
86+
87+
// Verify update
88+
var updated BinaryDoubleTest
89+
if err := DB.First(&updated, bd1.ID).Error; err != nil {
90+
t.Fatalf("fetch after update failed: %v", err)
91+
}
92+
if math.Abs(updated.DoubleValue - newValue) > 1e-15 {
93+
t.Errorf("expected %v after update, got %v", newValue, updated.DoubleValue)
94+
}
95+
96+
// DELETE
97+
if err := DB.Delete(&updated).Error; err != nil {
98+
t.Fatalf("delete failed: %v", err)
99+
}
100+
101+
// Verify deletion
102+
var deleted BinaryDoubleTest
103+
err := DB.First(&deleted, bd1.ID).Error
104+
if err == nil {
105+
t.Error("expected record to be deleted")
106+
}
107+
}
108+
109+
func TestBinaryDoubleSpecialValues(t *testing.T) {
110+
DB.Migrator().DropTable(&BinaryDoubleTest{})
111+
DB.AutoMigrate(&BinaryDoubleTest{})
112+
113+
testCases := []struct {
114+
name string
115+
value float64
116+
}{
117+
{"Positive Infinity", math.Inf(1)},
118+
{"Negative Infinity", math.Inf(-1)},
119+
{"NaN", math.NaN()},
120+
{"Max Float64", math.MaxFloat64},
121+
{"Min Float64", -math.MaxFloat64},
122+
{"Smallest Positive", math.SmallestNonzeroFloat64},
123+
{"Zero", 0.0},
124+
{"Negative Zero", -0.0},
125+
}
126+
127+
for _, tc := range testCases {
128+
t.Run(tc.name, func(t *testing.T) {
129+
bd := BinaryDoubleTest{DoubleValue: tc.value}
130+
if err := DB.Create(&bd).Error; err != nil {
131+
t.Fatalf("failed to insert %s: %v", tc.name, err)
132+
}
133+
134+
var got BinaryDoubleTest
135+
if err := DB.First(&got, bd.ID).Error; err != nil {
136+
t.Fatalf("failed to fetch %s: %v", tc.name, err)
137+
}
138+
139+
if math.IsNaN(tc.value) {
140+
if !math.IsNaN(got.DoubleValue) {
141+
t.Errorf("expected NaN, got %v", got.DoubleValue)
142+
}
143+
} else if math.IsInf(tc.value, 1) {
144+
if !math.IsInf(got.DoubleValue, 1) {
145+
t.Errorf("expected +Inf, got %v", got.DoubleValue)
146+
}
147+
} else if math.IsInf(tc.value, -1) {
148+
if !math.IsInf(got.DoubleValue, -1) {
149+
t.Errorf("expected -Inf, got %v", got.DoubleValue)
150+
}
151+
} else if tc.value == 0.0 || tc.value == -0.0 {
152+
if got.DoubleValue != 0.0 {
153+
t.Errorf("expected 0, got %v", got.DoubleValue)
154+
}
155+
} else {
156+
if math.Abs(got.DoubleValue - tc.value) > 1e-15 {
157+
t.Errorf("expected %v, got %v", tc.value, got.DoubleValue)
158+
}
159+
}
160+
})
161+
}
162+
}
163+
164+
func TestBinaryDoubleNullableColumn(t *testing.T) {
165+
DB.Migrator().DropTable(&BinaryDoubleTest{})
166+
DB.AutoMigrate(&BinaryDoubleTest{})
167+
168+
// Test NULL value
169+
bd1 := BinaryDoubleTest{
170+
DoubleValue: 1.23,
171+
NullableDouble: nil,
172+
}
173+
if err := DB.Create(&bd1).Error; err != nil {
174+
t.Fatalf("failed to insert with NULL: %v", err)
175+
}
176+
177+
var got1 BinaryDoubleTest
178+
if err := DB.First(&got1, bd1.ID).Error; err != nil {
179+
t.Fatal(err)
180+
}
181+
if got1.NullableDouble != nil {
182+
t.Errorf("expected NULL, got %v", *got1.NullableDouble)
183+
}
184+
185+
// Test with non-NULL value
186+
val := 456.789
187+
bd2 := BinaryDoubleTest{
188+
DoubleValue: 2.34,
189+
NullableDouble: &val,
190+
}
191+
if err := DB.Create(&bd2).Error; err != nil {
192+
t.Fatalf("failed to insert with value: %v", err)
193+
}
194+
195+
var got2 BinaryDoubleTest
196+
if err := DB.First(&got2, bd2.ID).Error; err != nil {
197+
t.Fatal(err)
198+
}
199+
if got2.NullableDouble == nil {
200+
t.Error("expected non-NULL value")
201+
} else if math.Abs(*got2.NullableDouble - val) > 1e-15 {
202+
t.Errorf("expected %v, got %v", val, *got2.NullableDouble)
203+
}
204+
205+
// Update to NULL
206+
if err := DB.Model(&got2).Update("NullableDouble", nil).Error; err != nil {
207+
t.Fatalf("failed to update to NULL: %v", err)
208+
}
209+
210+
var got3 BinaryDoubleTest
211+
if err := DB.First(&got3, bd2.ID).Error; err != nil {
212+
t.Fatal(err)
213+
}
214+
if got3.NullableDouble != nil {
215+
t.Errorf("expected NULL after update, got %v", *got3.NullableDouble)
216+
}
217+
}
218+
219+
func TestBinaryDoubleSQLNullFloat(t *testing.T) {
220+
DB.Migrator().DropTable(&BinaryDoubleTest{})
221+
DB.AutoMigrate(&BinaryDoubleTest{})
222+
223+
// Test with valid value
224+
bd1 := BinaryDoubleTest{
225+
DoubleValue: 1.0,
226+
SQLNullFloat: sql.NullFloat64{Float64: 123.456, Valid: true},
227+
}
228+
if err := DB.Create(&bd1).Error; err != nil {
229+
t.Fatalf("failed to create with sql.NullFloat64: %v", err)
230+
}
231+
232+
var got1 BinaryDoubleTest
233+
if err := DB.First(&got1, bd1.ID).Error; err != nil {
234+
t.Fatal(err)
235+
}
236+
if !got1.SQLNullFloat.Valid {
237+
t.Error("expected Valid to be true")
238+
}
239+
if math.Abs(got1.SQLNullFloat.Float64 - 123.456) > 1e-15 {
240+
t.Errorf("expected 123.456, got %v", got1.SQLNullFloat.Float64)
241+
}
242+
243+
// Test with invalid (NULL) value
244+
bd2 := BinaryDoubleTest{
245+
DoubleValue: 2.0,
246+
SQLNullFloat: sql.NullFloat64{Valid: false},
247+
}
248+
if err := DB.Create(&bd2).Error; err != nil {
249+
t.Fatalf("failed to create with NULL sql.NullFloat64: %v", err)
250+
}
251+
252+
var got2 BinaryDoubleTest
253+
if err := DB.First(&got2, bd2.ID).Error; err != nil {
254+
t.Fatal(err)
255+
}
256+
if got2.SQLNullFloat.Valid {
257+
t.Error("expected Valid to be false for NULL")
258+
}
259+
}
260+
261+
func TestBinaryDoubleArithmeticOperations(t *testing.T) {
262+
DB.Migrator().DropTable(&BinaryDoubleTest{})
263+
DB.AutoMigrate(&BinaryDoubleTest{})
264+
265+
// Insert test data
266+
values := []float64{10.5, 20.3, 30.7, 40.1, 50.9}
267+
for _, v := range values {
268+
bd := BinaryDoubleTest{DoubleValue: v}
269+
if err := DB.Create(&bd).Error; err != nil {
270+
t.Fatalf("failed to insert %v: %v", v, err)
271+
}
272+
}
273+
274+
// Test SUM
275+
var sum float64
276+
if err := DB.Model(&BinaryDoubleTest{}).Select("SUM(DOUBLE_VALUE)").Scan(&sum).Error; err != nil {
277+
t.Fatalf("failed to calculate SUM: %v", err)
278+
}
279+
expectedSum := 10.5 + 20.3 + 30.7 + 40.1 + 50.9
280+
if math.Abs(sum - expectedSum) > 1e-10 {
281+
t.Errorf("expected sum %v, got %v", expectedSum, sum)
282+
}
283+
284+
// Test AVG
285+
var avg float64
286+
if err := DB.Model(&BinaryDoubleTest{}).Select("AVG(DOUBLE_VALUE)").Scan(&avg).Error; err != nil {
287+
t.Fatalf("failed to calculate AVG: %v", err)
288+
}
289+
expectedAvg := expectedSum / 5
290+
if math.Abs(avg - expectedAvg) > 1e-10 {
291+
t.Errorf("expected avg %v, got %v", expectedAvg, avg)
292+
}
293+
294+
// Test MIN/MAX
295+
var min, max float64
296+
if err := DB.Model(&BinaryDoubleTest{}).Select("MIN(DOUBLE_VALUE)").Scan(&min).Error; err != nil {
297+
t.Fatalf("failed to calculate MIN: %v", err)
298+
}
299+
if err := DB.Model(&BinaryDoubleTest{}).Select("MAX(DOUBLE_VALUE)").Scan(&max).Error; err != nil {
300+
t.Fatalf("failed to calculate MAX: %v", err)
301+
}
302+
if math.Abs(min - 10.5) > 1e-10 {
303+
t.Errorf("expected min 10.5, got %v", min)
304+
}
305+
if math.Abs(max - 50.9) > 1e-10 {
306+
t.Errorf("expected max 50.9, got %v", max)
307+
}
308+
}
309+
310+
func TestBinaryDoubleRangeQueries(t *testing.T) {
311+
DB.Migrator().DropTable(&BinaryDoubleTest{})
312+
DB.AutoMigrate(&BinaryDoubleTest{})
313+
314+
// Insert test data with various ranges
315+
testData := []float64{-100.5, -50.0, 0.0, 25.5, 50.0, 75.75, 100.0, 150.25}
316+
for _, v := range testData {
317+
bd := BinaryDoubleTest{DoubleValue: v}
318+
if err := DB.Create(&bd).Error; err != nil {
319+
t.Fatalf("failed to insert %v: %v", v, err)
320+
}
321+
}
322+
323+
// Test BETWEEN query
324+
var results []BinaryDoubleTest
325+
if err := DB.Where("DOUBLE_VALUE BETWEEN ? AND ?", 0.0, 100.0).Find(&results).Error; err != nil {
326+
t.Fatalf("BETWEEN query failed: %v", err)
327+
}
328+
if len(results) != 5 {
329+
t.Errorf("expected 5 results, got %d", len(results))
330+
}
331+
332+
// Test greater than query
333+
var gtResults []BinaryDoubleTest
334+
if err := DB.Where("DOUBLE_VALUE > ?", 50.0).Find(&gtResults).Error; err != nil {
335+
t.Fatalf("> query failed: %v", err)
336+
}
337+
if len(gtResults) != 3 {
338+
t.Errorf("expected 3 results for > 50.0, got %d", len(gtResults))
339+
}
340+
341+
// Test less than or equal query
342+
var lteResults []BinaryDoubleTest
343+
if err := DB.Where("DOUBLE_VALUE <= ?", 0.0).Find(&lteResults).Error; err != nil {
344+
t.Fatalf("<= query failed: %v", err)
345+
}
346+
if len(lteResults) != 3 {
347+
t.Errorf("expected 3 results for <= 0.0, got %d", len(lteResults))
348+
}
349+
350+
// Test equality with floating point
351+
var eqResults []BinaryDoubleTest
352+
if err := DB.Where("DOUBLE_VALUE = ?", 25.5).Find(&eqResults).Error; err != nil {
353+
t.Fatalf("= query failed: %v", err)
354+
}
355+
if len(eqResults) != 1 {
356+
t.Errorf("expected 1 result for = 25.5, got %d", len(eqResults))
357+
}
358+
}

0 commit comments

Comments
 (0)