@@ -41,15 +41,20 @@ package tests
4141import (
4242 "database/sql"
4343 "testing"
44+ "strings"
4445)
4546
4647type BooleanTest struct {
47- ID uint `gorm:"column:ID;primaryKey"`
48- Flag bool `gorm:"column:FLAG"`
49- Nullable * bool `gorm:"column:NULLABLE"`
48+ ID uint `gorm:"column:ID;primaryKey"`
49+ Flag bool `gorm:"column:FLAG"`
50+ Nullable * bool `gorm:"column:NULLABLE"`
5051 SQLBool sql.NullBool `gorm:"column:SQL_BOOL"`
5152}
5253
54+ func (BooleanTest ) TableName () string {
55+ return "BOOLEAN_TESTS"
56+ }
57+
5358func TestBooleanBasicInsert (t * testing.T ) {
5459 DB .Migrator ().DropTable (& BooleanTest {})
5560 if err := DB .AutoMigrate (& BooleanTest {}); err != nil {
@@ -95,7 +100,6 @@ func TestBooleanUpdate(t *testing.T) {
95100 bt := BooleanTest {Flag : false }
96101 DB .Create (& bt )
97102
98- // Update false → true
99103 if err := DB .Model (& bt ).Update ("Flag" , true ).Error ; err != nil {
100104 t .Fatalf ("update failed: %v" , err )
101105 }
@@ -118,6 +122,11 @@ func TestBooleanQueryFilters(t *testing.T) {
118122 if err := DB .Where ("FLAG = ?" , true ).Find (& trues ).Error ; err != nil {
119123 t .Fatal (err )
120124 }
125+
126+ if len (trues ) == 0 {
127+ t .Fatalf ("expected at least 1 row, got 0" )
128+ }
129+
121130 for _ , row := range trues {
122131 if ! row .Flag {
123132 t .Errorf ("expected only true rows, got false" )
@@ -126,15 +135,148 @@ func TestBooleanQueryFilters(t *testing.T) {
126135}
127136
128137func TestBooleanNegativeInvalidDBValue (t * testing.T ) {
129- // Insert invalid value directly (bypassing GORM)
130- if err := DB .Exec ("INSERT INTO BOOLEAN_TEST (ID, FLAG) VALUES (999, 2)" ).Error ; err != nil {
131- t .Logf ("expected insert error: %v" , err )
132- return
138+ DB .Migrator ().DropTable (& BooleanTest {})
139+ DB .AutoMigrate (& BooleanTest {})
140+
141+ if err := DB .Exec (`INSERT INTO "BOOLEAN_TESTS" ("ID","FLAG") VALUES (2001, 2)` ).Error ; err != nil {
142+ t .Fatalf ("failed to insert invalid bool: %v" , err )
143+ }
144+
145+ var got BooleanTest
146+ err := DB .First (& got , 2001 ).Error
147+ if err == nil {
148+ t .Fatal ("expected invalid boolean scan error, got nil" )
149+ }
150+
151+ if ! strings .Contains (err .Error (), "invalid" ) &&
152+ ! strings .Contains (err .Error (), "convert" ) {
153+ t .Fatalf ("expected boolean conversion error, got: %v" , err )
154+ }
155+ }
156+
157+ func TestBooleanInsertWithIntValues (t * testing.T ) {
158+ DB .Migrator ().DropTable (& BooleanTest {})
159+ DB .AutoMigrate (& BooleanTest {})
160+
161+ if err := DB .Exec ("INSERT INTO BOOLEAN_TESTS (ID, FLAG) VALUES (1001, 1)" ).Error ; err != nil {
162+ t .Fatalf ("failed to insert int 1 as boolean: %v" , err )
163+ }
164+ if err := DB .Exec ("INSERT INTO BOOLEAN_TESTS (ID, FLAG) VALUES (1002, 0)" ).Error ; err != nil {
165+ t .Fatalf ("failed to insert int 0 as boolean: %v" , err )
166+ }
167+
168+ var gotTrue , gotFalse BooleanTest
169+ if err := DB .First (& gotTrue , 1001 ).Error ; err != nil {
170+ t .Fatalf ("fetch failed: %v" , err )
171+ }
172+ if gotTrue .Flag != true {
173+ t .Errorf ("expected true for 1, got %v" , gotTrue .Flag )
174+ }
175+
176+ if err := DB .First (& gotFalse , 1002 ).Error ; err != nil {
177+ t .Fatalf ("fetch failed: %v" , err )
178+ }
179+ if gotFalse .Flag != false {
180+ t .Errorf ("expected false for 0, got %v" , gotFalse .Flag )
181+ }
182+ }
183+
184+ func TestBooleanSQLNullBool (t * testing.T ) {
185+ DB .Migrator ().DropTable (& BooleanTest {})
186+ DB .AutoMigrate (& BooleanTest {})
187+
188+ bt := BooleanTest {SQLBool : sql.NullBool {Bool : true , Valid : true }}
189+ DB .Create (& bt )
190+
191+ var got BooleanTest
192+ DB .First (& got , bt .ID )
193+ if ! got .SQLBool .Valid || got .SQLBool .Bool != true {
194+ t .Errorf ("expected sql.NullBool true/valid, got %+v" , got .SQLBool )
195+ }
196+ }
197+
198+ func TestBooleanDefaultValue (t * testing.T ) {
199+ DB .Migrator ().DropTable (& BooleanTest {})
200+ DB .AutoMigrate (& BooleanTest {})
201+
202+ bt := BooleanTest {}
203+ if err := DB .Create (& bt ).Error ; err != nil {
204+ t .Fatalf ("insert default failed: %v" , err )
133205 }
134206
135207 var got BooleanTest
136- err := DB .First (& got , 999 ).Error
137- if err == nil {
138- t .Errorf ("expected scan error for invalid boolean mapping, got %+v" , got )
208+ DB .First (& got , bt .ID )
209+
210+ // Expect default (false or NULL depending on DB)
211+ if got .Flag != false {
212+ t .Errorf ("expected default false, got %v" , got .Flag )
213+ }
214+ }
215+
216+ func TestBooleanQueryMixedComparisons (t * testing.T ) {
217+ DB .Migrator ().DropTable (& BooleanTest {})
218+ DB .AutoMigrate (& BooleanTest {})
219+
220+ DB .Create (& BooleanTest {Flag : true })
221+ DB .Create (& BooleanTest {Flag : false })
222+
223+ var gotNum []BooleanTest
224+
225+ // FILTER USING NUMBER
226+ if err := DB .Where ("FLAG = 1" ).Find (& gotNum ).Error ; err != nil {
227+ t .Fatal (err )
228+ }
229+ if len (gotNum ) == 0 {
230+ t .Errorf ("expected at least 1 row for FLAG=1" )
231+ }
232+
233+ // FILTER USING TEXT (invalid in Oracle)
234+ var gotStr []BooleanTest
235+ if err := DB .Where ("FLAG = 'true'" ).Find (& gotStr ).Error ; err == nil {
236+ t .Errorf ("expected ORA-01722 when comparing NUMBER to string literal" )
237+ }
238+ }
239+
240+ func TestBooleanStringCoercion (t * testing.T ) {
241+ DB .Migrator ().DropTable (& BooleanTest {})
242+ DB .AutoMigrate (& BooleanTest {})
243+
244+ // Insert using string literals
245+ if err := DB .Exec ("INSERT INTO BOOLEAN_TESTS (ID, FLAG) VALUES (2001, '1')" ).Error ; err != nil {
246+ t .Fatalf ("failed to insert '1': %v" , err )
247+ }
248+ if err := DB .Exec ("INSERT INTO BOOLEAN_TESTS (ID, FLAG) VALUES (2002, '0')" ).Error ; err != nil {
249+ t .Fatalf ("failed to insert '0': %v" , err )
250+ }
251+
252+ var got1 , got2 BooleanTest
253+ DB .First (& got1 , 2001 )
254+ DB .First (& got2 , 2002 )
255+
256+ if got1 .Flag != true {
257+ t .Errorf ("expected true for '1', got %v" , got1 .Flag )
258+ }
259+ if got2 .Flag != false {
260+ t .Errorf ("expected false for '0', got %v" , got2 .Flag )
261+ }
262+ }
263+
264+ func TestBooleanNullableColumn (t * testing.T ) {
265+ DB .Migrator ().DropTable (& BooleanTest {})
266+ DB .AutoMigrate (& BooleanTest {})
267+
268+ // Insert a row with NULL value for Nullable column
269+ bt := BooleanTest {Flag : true , Nullable : nil }
270+ if err := DB .Create (& bt ).Error ; err != nil {
271+ t .Fatalf ("failed to insert NULL bool: %v" , err )
272+ }
273+
274+ var got BooleanTest
275+ if err := DB .First (& got , bt .ID ).Error ; err != nil {
276+ t .Fatal (err )
277+ }
278+
279+ if got .Nullable != nil {
280+ t .Errorf ("expected NULL, got %v" , * got .Nullable )
139281 }
140282}
0 commit comments