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 }