Skip to content

Commit e9bf64c

Browse files
committed
Tests for Oracle DATE type covering edge, null, range, update, and invalid scenarios
1 parent 924c878 commit e9bf64c

File tree

1 file changed

+214
-0
lines changed

1 file changed

+214
-0
lines changed

tests/date_type_test.go

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
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+
"testing"
43+
"time"
44+
45+
"gorm.io/gorm"
46+
)
47+
48+
type DateModel struct {
49+
ID uint `gorm:"primaryKey;autoIncrement"`
50+
EventName string `gorm:"size:100"`
51+
EventDate time.Time `gorm:"column:EVENT_DATE;type:DATE"`
52+
OptionalCol *time.Time `gorm:"column:OPTIONAL_DATE"`
53+
}
54+
55+
func setupDateTests(t *testing.T) {
56+
t.Log("Setting up DATE test table")
57+
58+
// Drop the table safely
59+
dropSQL := `
60+
BEGIN
61+
EXECUTE IMMEDIATE 'DROP TABLE "date_models" CASCADE CONSTRAINTS';
62+
EXCEPTION
63+
WHEN OTHERS THEN
64+
IF SQLCODE != -942 THEN RAISE; END IF;
65+
END;`
66+
if err := DB.Exec(dropSQL).Error; err != nil {
67+
t.Fatalf("Failed to drop table: %v", err)
68+
}
69+
70+
// migrate
71+
if err := DB.AutoMigrate(&DateModel{}); err != nil {
72+
t.Fatalf("Failed to migrate date_models: %v", err)
73+
}
74+
75+
t.Log("DATE test table created successfully")
76+
}
77+
78+
func TestDate_InsertAndRetrieve(t *testing.T) {
79+
setupDateTests(t)
80+
81+
now := time.Now().Truncate(time.Second)
82+
record := DateModel{
83+
EventName: "Launch",
84+
EventDate: now,
85+
}
86+
if err := DB.Create(&record).Error; err != nil {
87+
t.Fatalf("Insert failed: %v", err)
88+
}
89+
90+
var out DateModel
91+
err := DB.First(&out, record.ID).Error
92+
if err != nil {
93+
t.Fatalf("Fetch failed: %v", err)
94+
}
95+
96+
if !out.EventDate.Equal(now) {
97+
t.Errorf("Expected %v, got %v", now, out.EventDate)
98+
}
99+
}
100+
101+
func TestDate_NullAndOptionalColumns(t *testing.T) {
102+
setupDateTests(t)
103+
104+
record := DateModel{
105+
EventName: "NullDate",
106+
}
107+
if err := DB.Create(&record).Error; err != nil {
108+
t.Fatalf("Insert with null date failed: %v", err)
109+
}
110+
111+
var fetched DateModel
112+
err := DB.First(&fetched, record.ID).Error
113+
if err != nil {
114+
t.Fatalf("Fetch failed: %v", err)
115+
}
116+
117+
if fetched.OptionalCol != nil {
118+
t.Errorf("Expected OptionalCol to be nil, got %v", fetched.OptionalCol)
119+
}
120+
}
121+
122+
func TestDate_UpdateAndCompare(t *testing.T) {
123+
setupDateTests(t)
124+
125+
initial := DateModel{
126+
EventName: "CompareTest",
127+
EventDate: time.Date(2025, 10, 30, 10, 10, 10, 0, time.UTC),
128+
}
129+
if err := DB.Create(&initial).Error; err != nil {
130+
t.Fatalf("Create failed: %v", err)
131+
}
132+
133+
updateTime := initial.EventDate.Add(2 * time.Hour)
134+
if err := DB.Model(&initial).Update("EVENT_DATE", updateTime).Error; err != nil {
135+
t.Fatalf("Update failed: %v", err)
136+
}
137+
138+
var fetched DateModel
139+
err := DB.First(&fetched, initial.ID).Error
140+
if err != nil {
141+
t.Fatalf("Fetch failed: %v", err)
142+
}
143+
144+
if !fetched.EventDate.Equal(updateTime) {
145+
t.Errorf("Expected %v, got %v", updateTime, fetched.EventDate)
146+
}
147+
}
148+
149+
func TestDate_QueryByDateRange(t *testing.T) {
150+
setupDateTests(t)
151+
152+
base := time.Now().Truncate(time.Second)
153+
records := []DateModel{
154+
{EventName: "Day1", EventDate: base.Add(-24 * time.Hour)},
155+
{EventName: "Day2", EventDate: base},
156+
{EventName: "Day3", EventDate: base.Add(24 * time.Hour)},
157+
}
158+
if err := DB.Create(&records).Error; err != nil {
159+
t.Fatalf("Bulk insert failed: %v", err)
160+
}
161+
162+
var results []DateModel
163+
err := DB.Where("\"EVENT_DATE\" BETWEEN ? AND ?", base.Add(-12*time.Hour), base.Add(12*time.Hour)).Find(&results).Error
164+
if err != nil {
165+
t.Fatalf("Range query failed: %v", err)
166+
}
167+
168+
if len(results) != 1 {
169+
t.Errorf("Expected 1 record, got %d", len(results))
170+
}
171+
}
172+
173+
func TestDate_InvalidDateHandling(t *testing.T) {
174+
setupDateTests(t)
175+
176+
// insert invalid date
177+
err := DB.Exec(`INSERT INTO "DATE_MODELS" ("EVENT_NAME","EVENT_DATE") VALUES ('BadDate', TO_DATE('2025-13-40','YYYY-MM-DD'))`).Error
178+
if err == nil {
179+
t.Error("Expected error inserting invalid date, got nil")
180+
}
181+
}
182+
183+
func TestDate_TimePrecisionLoss(t *testing.T) {
184+
setupDateTests(t)
185+
186+
withMillis := time.Now().Truncate(time.Millisecond)
187+
record := DateModel{
188+
EventName: "PrecisionLoss",
189+
EventDate: withMillis,
190+
}
191+
if err := DB.Create(&record).Error; err != nil {
192+
t.Fatalf("Insert failed: %v", err)
193+
}
194+
195+
var fetched DateModel
196+
_ = DB.First(&fetched, record.ID).Error
197+
if !fetched.EventDate.Truncate(time.Second).Equal(withMillis.Truncate(time.Second)) {
198+
t.Errorf("Expected time match up to seconds precision, got %v", fetched.EventDate)
199+
}
200+
}
201+
202+
func TestDate_ZeroDateHandling(t *testing.T) {
203+
setupDateTests(t)
204+
205+
zeroTime := time.Time{}
206+
record := DateModel{
207+
EventName: "ZeroDate",
208+
EventDate: zeroTime,
209+
}
210+
err := DB.Create(&record).Error
211+
if err != nil && err != gorm.ErrInvalidData {
212+
t.Errorf("Unexpected error inserting zero date: %v", err)
213+
}
214+
}

0 commit comments

Comments
 (0)