mirror of
https://github.com/go-vikunja/vikunja.git
synced 2026-04-30 08:25:58 -05:00
test: call real MultiFieldSearch function and branch on db engine
Instead of manually constructing builder.Expr conditions to simulate the ParadeDB path, call MultiFieldSearchWithTableAlias() directly and use isParadeDB() to branch assertions. When ParadeDB is available, assert the ||| operator with ::pdb.fuzzy(1, t) syntax; otherwise assert the LIKE/ILIKE fallback. Tests skip when no database engine is initialized (x == nil).
This commit is contained in:
@@ -25,113 +25,97 @@ import (
|
|||||||
"xorm.io/builder"
|
"xorm.io/builder"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMultiFieldSearchParadeDB(t *testing.T) {
|
// isParadeDB returns true when the test engine is running with ParadeDB.
|
||||||
// Save and restore global state
|
// It is safe to call even when no database engine is initialized (x == nil),
|
||||||
originalParadeDB := paradedbInstalled
|
// in which case it returns false.
|
||||||
defer func() { paradedbInstalled = originalParadeDB }()
|
func isParadeDB() bool {
|
||||||
|
return x != nil && ParadeDBAvailable()
|
||||||
// These tests verify the SQL generation for the ParadeDB path.
|
|
||||||
// Since Type() requires an initialized engine, and the test engine is SQLite,
|
|
||||||
// we cannot call MultiFieldSearchWithTableAlias directly for the ParadeDB path.
|
|
||||||
// Instead, we verify the builder.Expr conditions that would be generated.
|
|
||||||
|
|
||||||
t.Run("single field generates fuzzy disjunction", func(t *testing.T) {
|
|
||||||
// Simulate what MultiFieldSearchWithTableAlias generates for ParadeDB single field
|
|
||||||
cond := builder.Expr("title ||| ?::pdb.fuzzy(1, t)", "landing")
|
|
||||||
|
|
||||||
w := builder.NewWriter()
|
|
||||||
err := cond.WriteTo(w)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
assert.Equal(t, "title ||| ?::pdb.fuzzy(1, t)", w.String())
|
|
||||||
assert.Equal(t, []interface{}{"landing"}, w.Args())
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("multi field generates OR of fuzzy disjunctions", func(t *testing.T) {
|
|
||||||
// Simulate what MultiFieldSearchWithTableAlias generates for ParadeDB multi field
|
|
||||||
cond := builder.Or(
|
|
||||||
builder.Expr("title ||| ?::pdb.fuzzy(1, t)", "landing"),
|
|
||||||
builder.Expr("description ||| ?::pdb.fuzzy(1, t)", "landing"),
|
|
||||||
)
|
|
||||||
|
|
||||||
w := builder.NewWriter()
|
|
||||||
err := cond.WriteTo(w)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
assert.Equal(t, "(title ||| ?::pdb.fuzzy(1, t)) OR (description ||| ?::pdb.fuzzy(1, t))", w.String())
|
|
||||||
assert.Equal(t, []interface{}{"landing", "landing"}, w.Args())
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("table alias prefixes field name", func(t *testing.T) {
|
|
||||||
// Simulate what MultiFieldSearchWithTableAlias generates with table alias
|
|
||||||
cond := builder.Expr("tasks.title ||| ?::pdb.fuzzy(1, t)", "test")
|
|
||||||
|
|
||||||
w := builder.NewWriter()
|
|
||||||
err := cond.WriteTo(w)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
assert.Equal(t, "tasks.title ||| ?::pdb.fuzzy(1, t)", w.String())
|
|
||||||
assert.Equal(t, []interface{}{"test"}, w.Args())
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("multi field with table alias", func(t *testing.T) {
|
|
||||||
cond := builder.Or(
|
|
||||||
builder.Expr("tasks.title ||| ?::pdb.fuzzy(1, t)", "test"),
|
|
||||||
builder.Expr("tasks.description ||| ?::pdb.fuzzy(1, t)", "test"),
|
|
||||||
)
|
|
||||||
|
|
||||||
w := builder.NewWriter()
|
|
||||||
err := cond.WriteTo(w)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
assert.Equal(t, "(tasks.title ||| ?::pdb.fuzzy(1, t)) OR (tasks.description ||| ?::pdb.fuzzy(1, t))", w.String())
|
|
||||||
assert.Equal(t, []interface{}{"test", "test"}, w.Args())
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMultiFieldSearchILIKEFallback(t *testing.T) {
|
func TestMultiFieldSearchSingleField(t *testing.T) {
|
||||||
// These tests verify the ILIKE fallback path (non-ParadeDB).
|
if x == nil {
|
||||||
// Since Type() requires an initialized engine, we test the builder.Like
|
t.Skip("requires initialized database engine")
|
||||||
// conditions directly — this is what ILIKE returns for non-Postgres databases.
|
}
|
||||||
|
|
||||||
t.Run("single field generates LIKE condition", func(t *testing.T) {
|
cond := MultiFieldSearchWithTableAlias([]string{"title"}, "landing", "")
|
||||||
// This is what ILIKE("title", "test") returns for SQLite/MySQL
|
|
||||||
cond := &builder.Like{"title", "%test%"}
|
|
||||||
|
|
||||||
w := builder.NewWriter()
|
w := builder.NewWriter()
|
||||||
err := cond.WriteTo(w)
|
err := cond.WriteTo(w)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, "title LIKE ?", w.String())
|
if isParadeDB() {
|
||||||
assert.Equal(t, []interface{}{"%test%"}, w.Args())
|
assert.Equal(t, "title ||| ?::pdb.fuzzy(1, t)", w.String())
|
||||||
})
|
assert.Equal(t, []interface{}{"landing"}, w.Args())
|
||||||
|
} else {
|
||||||
t.Run("ILIKE wraps search with wildcards", func(t *testing.T) {
|
assert.Contains(t, w.String(), "title")
|
||||||
// This is what ILIKE("description", "landing") returns for SQLite/MySQL
|
assert.Contains(t, w.String(), "LIKE")
|
||||||
cond := &builder.Like{"description", "%landing%"}
|
|
||||||
|
|
||||||
w := builder.NewWriter()
|
|
||||||
err := cond.WriteTo(w)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
assert.Equal(t, "description LIKE ?", w.String())
|
|
||||||
assert.Equal(t, []interface{}{"%landing%"}, w.Args())
|
assert.Equal(t, []interface{}{"%landing%"}, w.Args())
|
||||||
})
|
}
|
||||||
|
}
|
||||||
|
|
||||||
t.Run("multi field ILIKE generates OR of LIKE conditions", func(t *testing.T) {
|
func TestMultiFieldSearchMultiField(t *testing.T) {
|
||||||
// This is what MultiFieldSearch generates for non-ParadeDB databases
|
if x == nil {
|
||||||
cond := builder.Or(
|
t.Skip("requires initialized database engine")
|
||||||
&builder.Like{"title", "%landing%"},
|
}
|
||||||
&builder.Like{"description", "%landing%"},
|
|
||||||
)
|
|
||||||
|
|
||||||
w := builder.NewWriter()
|
cond := MultiFieldSearchWithTableAlias([]string{"title", "description"}, "landing", "")
|
||||||
err := cond.WriteTo(w)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
assert.Equal(t, "title LIKE ? OR description LIKE ?", w.String())
|
w := builder.NewWriter()
|
||||||
|
err := cond.WriteTo(w)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
if isParadeDB() {
|
||||||
|
assert.Equal(t, "(title ||| ?::pdb.fuzzy(1, t)) OR (description ||| ?::pdb.fuzzy(1, t))", w.String())
|
||||||
|
assert.Equal(t, []interface{}{"landing", "landing"}, w.Args())
|
||||||
|
} else {
|
||||||
|
assert.Contains(t, w.String(), "title")
|
||||||
|
assert.Contains(t, w.String(), "description")
|
||||||
|
assert.Contains(t, w.String(), "LIKE")
|
||||||
assert.Equal(t, []interface{}{"%landing%", "%landing%"}, w.Args())
|
assert.Equal(t, []interface{}{"%landing%", "%landing%"}, w.Args())
|
||||||
})
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMultiFieldSearchWithTableAlias(t *testing.T) {
|
||||||
|
if x == nil {
|
||||||
|
t.Skip("requires initialized database engine")
|
||||||
|
}
|
||||||
|
|
||||||
|
cond := MultiFieldSearchWithTableAlias([]string{"title"}, "test", "tasks")
|
||||||
|
|
||||||
|
w := builder.NewWriter()
|
||||||
|
err := cond.WriteTo(w)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
if isParadeDB() {
|
||||||
|
assert.Equal(t, "tasks.title ||| ?::pdb.fuzzy(1, t)", w.String())
|
||||||
|
assert.Equal(t, []interface{}{"test"}, w.Args())
|
||||||
|
} else {
|
||||||
|
assert.Contains(t, w.String(), "tasks.title")
|
||||||
|
assert.Contains(t, w.String(), "LIKE")
|
||||||
|
assert.Equal(t, []interface{}{"%test%"}, w.Args())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMultiFieldSearchMultiFieldWithTableAlias(t *testing.T) {
|
||||||
|
if x == nil {
|
||||||
|
t.Skip("requires initialized database engine")
|
||||||
|
}
|
||||||
|
|
||||||
|
cond := MultiFieldSearchWithTableAlias([]string{"title", "description"}, "test", "tasks")
|
||||||
|
|
||||||
|
w := builder.NewWriter()
|
||||||
|
err := cond.WriteTo(w)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
if isParadeDB() {
|
||||||
|
assert.Equal(t, "(tasks.title ||| ?::pdb.fuzzy(1, t)) OR (tasks.description ||| ?::pdb.fuzzy(1, t))", w.String())
|
||||||
|
assert.Equal(t, []interface{}{"test", "test"}, w.Args())
|
||||||
|
} else {
|
||||||
|
assert.Contains(t, w.String(), "tasks.title")
|
||||||
|
assert.Contains(t, w.String(), "tasks.description")
|
||||||
|
assert.Contains(t, w.String(), "LIKE")
|
||||||
|
assert.Equal(t, []interface{}{"%test%", "%test%"}, w.Args())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIsMySQLDuplicateEntryError(t *testing.T) {
|
func TestIsMySQLDuplicateEntryError(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user