384 lines
10 KiB
Go
384 lines
10 KiB
Go
package cassandra
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestCreateSAIIndex(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
keyspace string
|
|
table string
|
|
column string
|
|
indexName string
|
|
options *SAIIndexOptions
|
|
description string
|
|
wantErr bool
|
|
validate func(*testing.T, error)
|
|
}{
|
|
{
|
|
name: "create basic SAI index",
|
|
keyspace: "test_keyspace",
|
|
table: "test_table",
|
|
column: "name",
|
|
indexName: "test_name_idx",
|
|
options: nil,
|
|
description: "should create a basic SAI index",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "create SAI index with auto-generated name",
|
|
keyspace: "test_keyspace",
|
|
table: "test_table",
|
|
column: "email",
|
|
indexName: "",
|
|
options: nil,
|
|
description: "should auto-generate index name",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "create SAI index with case insensitive option",
|
|
keyspace: "test_keyspace",
|
|
table: "test_table",
|
|
column: "title",
|
|
indexName: "test_title_idx",
|
|
options: &SAIIndexOptions{CaseSensitive: boolPtr(false)},
|
|
description: "should create index with case insensitive option",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "create SAI index with normalize option",
|
|
keyspace: "test_keyspace",
|
|
table: "test_table",
|
|
column: "content",
|
|
indexName: "test_content_idx",
|
|
options: &SAIIndexOptions{Normalize: boolPtr(true)},
|
|
description: "should create index with normalize option",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "create SAI index with analyzer",
|
|
keyspace: "test_keyspace",
|
|
table: "test_table",
|
|
column: "description",
|
|
indexName: "test_desc_idx",
|
|
options: &SAIIndexOptions{Analyzer: "StandardAnalyzer"},
|
|
description: "should create index with analyzer",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "create SAI index with all options",
|
|
keyspace: "test_keyspace",
|
|
table: "test_table",
|
|
column: "text",
|
|
indexName: "test_text_idx",
|
|
options: &SAIIndexOptions{CaseSensitive: boolPtr(false), Normalize: boolPtr(true), Analyzer: "StandardAnalyzer"},
|
|
description: "should create index with all options",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "missing keyspace",
|
|
keyspace: "",
|
|
table: "test_table",
|
|
column: "name",
|
|
indexName: "test_idx",
|
|
options: nil,
|
|
description: "should return error when keyspace is empty and no default",
|
|
wantErr: true,
|
|
validate: func(t *testing.T, err error) {
|
|
assert.Error(t, err)
|
|
var e *Error
|
|
if assert.ErrorAs(t, err, &e) {
|
|
assert.Equal(t, ErrCodeInvalidInput, e.Code)
|
|
}
|
|
},
|
|
},
|
|
{
|
|
name: "missing table",
|
|
keyspace: "test_keyspace",
|
|
table: "",
|
|
column: "name",
|
|
indexName: "test_idx",
|
|
options: nil,
|
|
description: "should return error when table is empty",
|
|
wantErr: true,
|
|
validate: func(t *testing.T, err error) {
|
|
assert.Error(t, err)
|
|
var e *Error
|
|
if assert.ErrorAs(t, err, &e) {
|
|
assert.Equal(t, ErrCodeInvalidInput, e.Code)
|
|
}
|
|
},
|
|
},
|
|
{
|
|
name: "missing column",
|
|
keyspace: "test_keyspace",
|
|
table: "test_table",
|
|
column: "",
|
|
indexName: "test_idx",
|
|
options: nil,
|
|
description: "should return error when column is empty",
|
|
wantErr: true,
|
|
validate: func(t *testing.T, err error) {
|
|
assert.Error(t, err)
|
|
var e *Error
|
|
if assert.ErrorAs(t, err, &e) {
|
|
assert.Equal(t, ErrCodeInvalidInput, e.Code)
|
|
}
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// 注意:這需要一個有效的 DB 實例和 SAI 支援
|
|
// 在實際測試中,需要使用 testcontainers 或 mock
|
|
_ = tt
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDropSAIIndex(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
keyspace string
|
|
indexName string
|
|
description string
|
|
wantErr bool
|
|
validate func(*testing.T, error)
|
|
}{
|
|
{
|
|
name: "drop existing index",
|
|
keyspace: "test_keyspace",
|
|
indexName: "test_name_idx",
|
|
description: "should drop existing index",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "drop non-existent index",
|
|
keyspace: "test_keyspace",
|
|
indexName: "non_existent_idx",
|
|
description: "should not error when dropping non-existent index (IF EXISTS)",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "missing keyspace",
|
|
keyspace: "",
|
|
indexName: "test_idx",
|
|
description: "should return error when keyspace is empty and no default",
|
|
wantErr: true,
|
|
validate: func(t *testing.T, err error) {
|
|
assert.Error(t, err)
|
|
var e *Error
|
|
if assert.ErrorAs(t, err, &e) {
|
|
assert.Equal(t, ErrCodeInvalidInput, e.Code)
|
|
}
|
|
},
|
|
},
|
|
{
|
|
name: "missing index name",
|
|
keyspace: "test_keyspace",
|
|
indexName: "",
|
|
description: "should return error when index name is empty",
|
|
wantErr: true,
|
|
validate: func(t *testing.T, err error) {
|
|
assert.Error(t, err)
|
|
var e *Error
|
|
if assert.ErrorAs(t, err, &e) {
|
|
assert.Equal(t, ErrCodeInvalidInput, e.Code)
|
|
}
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// 注意:這需要一個有效的 DB 實例和 SAI 支援
|
|
// 在實際測試中,需要使用 testcontainers 或 mock
|
|
_ = tt
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestListSAIIndexes(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
keyspace string
|
|
table string
|
|
description string
|
|
wantErr bool
|
|
validate func(*testing.T, []SAIIndexInfo, error)
|
|
}{
|
|
{
|
|
name: "list all indexes in keyspace",
|
|
keyspace: "test_keyspace",
|
|
table: "",
|
|
description: "should list all SAI indexes in keyspace",
|
|
wantErr: false,
|
|
validate: func(t *testing.T, indexes []SAIIndexInfo, err error) {
|
|
require.NoError(t, err)
|
|
assert.NotNil(t, indexes)
|
|
},
|
|
},
|
|
{
|
|
name: "list indexes for specific table",
|
|
keyspace: "test_keyspace",
|
|
table: "test_table",
|
|
description: "should list SAI indexes for specific table",
|
|
wantErr: false,
|
|
validate: func(t *testing.T, indexes []SAIIndexInfo, err error) {
|
|
require.NoError(t, err)
|
|
assert.NotNil(t, indexes)
|
|
for _, idx := range indexes {
|
|
assert.Equal(t, "test_table", idx.TableName)
|
|
}
|
|
},
|
|
},
|
|
{
|
|
name: "missing keyspace",
|
|
keyspace: "",
|
|
table: "",
|
|
description: "should return error when keyspace is empty and no default",
|
|
wantErr: true,
|
|
validate: func(t *testing.T, indexes []SAIIndexInfo, err error) {
|
|
assert.Error(t, err)
|
|
assert.Nil(t, indexes)
|
|
var e *Error
|
|
if assert.ErrorAs(t, err, &e) {
|
|
assert.Equal(t, ErrCodeInvalidInput, e.Code)
|
|
}
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// 注意:這需要一個有效的 DB 實例和 SAI 支援
|
|
// 在實際測試中,需要使用 testcontainers 或 mock
|
|
_ = tt
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetSAIIndex(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
keyspace string
|
|
indexName string
|
|
description string
|
|
wantErr bool
|
|
validate func(*testing.T, *SAIIndexInfo, error)
|
|
}{
|
|
{
|
|
name: "get existing index",
|
|
keyspace: "test_keyspace",
|
|
indexName: "test_name_idx",
|
|
description: "should get existing SAI index",
|
|
wantErr: false,
|
|
validate: func(t *testing.T, index *SAIIndexInfo, err error) {
|
|
require.NoError(t, err)
|
|
assert.NotNil(t, index)
|
|
assert.Equal(t, "test_name_idx", index.IndexName)
|
|
},
|
|
},
|
|
{
|
|
name: "get non-existent index",
|
|
keyspace: "test_keyspace",
|
|
indexName: "non_existent_idx",
|
|
description: "should return ErrNotFound",
|
|
wantErr: true,
|
|
validate: func(t *testing.T, index *SAIIndexInfo, err error) {
|
|
assert.Error(t, err)
|
|
assert.Nil(t, index)
|
|
assert.True(t, IsNotFound(err))
|
|
},
|
|
},
|
|
{
|
|
name: "missing keyspace",
|
|
keyspace: "",
|
|
indexName: "test_idx",
|
|
description: "should return error when keyspace is empty and no default",
|
|
wantErr: true,
|
|
validate: func(t *testing.T, index *SAIIndexInfo, err error) {
|
|
assert.Error(t, err)
|
|
assert.Nil(t, index)
|
|
},
|
|
},
|
|
{
|
|
name: "missing index name",
|
|
keyspace: "test_keyspace",
|
|
indexName: "",
|
|
description: "should return error when index name is empty",
|
|
wantErr: true,
|
|
validate: func(t *testing.T, index *SAIIndexInfo, err error) {
|
|
assert.Error(t, err)
|
|
assert.Nil(t, index)
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// 注意:這需要一個有效的 DB 實例和 SAI 支援
|
|
// 在實際測試中,需要使用 testcontainers 或 mock
|
|
_ = tt
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSAIIndexOptions(t *testing.T) {
|
|
t.Run("default options", func(t *testing.T) {
|
|
opts := &SAIIndexOptions{}
|
|
assert.Nil(t, opts.CaseSensitive)
|
|
assert.Nil(t, opts.Normalize)
|
|
assert.Empty(t, opts.Analyzer)
|
|
})
|
|
|
|
t.Run("with case sensitive", func(t *testing.T) {
|
|
caseSensitive := false
|
|
opts := &SAIIndexOptions{CaseSensitive: &caseSensitive}
|
|
assert.NotNil(t, opts.CaseSensitive)
|
|
assert.False(t, *opts.CaseSensitive)
|
|
})
|
|
|
|
t.Run("with normalize", func(t *testing.T) {
|
|
normalize := true
|
|
opts := &SAIIndexOptions{Normalize: &normalize}
|
|
assert.NotNil(t, opts.Normalize)
|
|
assert.True(t, *opts.Normalize)
|
|
})
|
|
|
|
t.Run("with analyzer", func(t *testing.T) {
|
|
opts := &SAIIndexOptions{Analyzer: "StandardAnalyzer"}
|
|
assert.Equal(t, "StandardAnalyzer", opts.Analyzer)
|
|
})
|
|
}
|
|
|
|
func TestSAIIndexInfo(t *testing.T) {
|
|
t.Run("index info structure", func(t *testing.T) {
|
|
info := SAIIndexInfo{
|
|
KeyspaceName: "test_keyspace",
|
|
TableName: "test_table",
|
|
IndexName: "test_idx",
|
|
ColumnName: "name",
|
|
IndexType: "sai",
|
|
Options: map[string]string{"target": "name"},
|
|
}
|
|
|
|
assert.Equal(t, "test_keyspace", info.KeyspaceName)
|
|
assert.Equal(t, "test_table", info.TableName)
|
|
assert.Equal(t, "test_idx", info.IndexName)
|
|
assert.Equal(t, "name", info.ColumnName)
|
|
assert.Equal(t, "sai", info.IndexType)
|
|
assert.NotNil(t, info.Options)
|
|
})
|
|
}
|
|
|
|
// Helper function
|
|
func boolPtr(b bool) *bool {
|
|
return &b
|
|
}
|