package engine import ( "testing" "time" "git.kingecg.top/kingecg/gomog/pkg/types" ) // createTestCollection 创建测试集合的辅助函数 func createTestCollection(store *MemoryStore, name string, documents map[string]types.Document) { store.collections[name] = &Collection{ name: name, documents: documents, } } // TestMemoryStoreUpdateWithUpsert 测试 MemoryStore 的 upsert 功能 func TestMemoryStoreUpdateWithUpsert(t *testing.T) { store := NewMemoryStore(nil) // 创建测试集合 collection := "test.upsert_collection" createTestCollection(store, collection, map[string]types.Document{}) tests := []struct { name string filter types.Filter update types.Update upsert bool expectedMatch int expectedMod int expectUpsert bool checkField string expectedValue interface{} }{ { name: "upsert creates new document", filter: types.Filter{"_id": "new_doc"}, update: types.Update{ Set: map[string]interface{}{ "status": "active", }, SetOnInsert: map[string]interface{}{ "createdAt": "2024-01-01T00:00:00Z", }, }, upsert: true, expectedMatch: 1, expectedMod: 1, expectUpsert: true, checkField: "createdAt", expectedValue: "2024-01-01T00:00:00Z", }, { name: "update existing document without setOnInsert", filter: types.Filter{"name": "Alice"}, update: types.Update{ Set: map[string]interface{}{ "status": "updated", }, SetOnInsert: map[string]interface{}{ "shouldNotAppear": true, }, }, upsert: false, expectedMatch: 0, // No matching document initially expectedMod: 0, expectUpsert: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Clear collection before each test createTestCollection(store, collection, map[string]types.Document{}) matched, modified, upsertedIDs, err := store.Update(collection, tt.filter, tt.update, tt.upsert, nil) if err != nil { t.Fatalf("Update() error = %v", err) } if matched != tt.expectedMatch { t.Errorf("matched = %d, want %d", matched, tt.expectedMatch) } if modified != tt.expectedMod { t.Errorf("modified = %d, want %d", modified, tt.expectedMod) } if tt.expectUpsert && len(upsertedIDs) == 0 { t.Error("Expected upsert ID but got none") } if tt.checkField != "" { // Find the created/updated document found := false for _, d := range store.collections[collection].documents { if val, ok := d.Data[tt.checkField]; ok { if compareEq(val, tt.expectedValue) { found = true break } } } if tt.expectUpsert && !found { t.Errorf("Document with %s = %v not found", tt.checkField, tt.expectedValue) } } }) } } // TestMemoryStoreUpdateWithArrayFilters 测试 MemoryStore 的 arrayFilters 功能 func TestMemoryStoreUpdateWithArrayFilters(t *testing.T) { store := NewMemoryStore(nil) collection := "test.array_filters_collection" createTestCollection(store, collection, map[string]types.Document{ "doc1": { ID: "doc1", Data: map[string]interface{}{ "name": "Product A", "scores": []interface{}{ map[string]interface{}{"subject": "math", "score": float64(85)}, map[string]interface{}{"subject": "english", "score": float64(92)}, map[string]interface{}{"subject": "science", "score": float64(78)}, }, }, CreatedAt: time.Now(), UpdatedAt: time.Now(), }, }) arrayFilters := []types.Filter{ { "identifier": "elem", "score": map[string]interface{}{"$gte": float64(90)}, }, } update := types.Update{ Set: map[string]interface{}{ "scores.$[elem].grade": "A", }, } matched, modified, _, err := store.Update(collection, types.Filter{"name": "Product A"}, update, false, arrayFilters) if err != nil { t.Fatalf("Update() error = %v", err) } if matched != 1 { t.Errorf("matched = %d, want 1", matched) } if modified != 1 { t.Errorf("modified = %d, want 1", modified) } // Verify the update was applied correctly doc := store.collections[collection].documents["doc1"] scores, ok := doc.Data["scores"].([]interface{}) if !ok { t.Fatal("scores is not an array") } // Check that english score has grade "A" foundGradeA := false for _, score := range scores { scoreMap, ok := score.(map[string]interface{}) if !ok { continue } if subject, ok := scoreMap["subject"].(string); ok && subject == "english" { if grade, ok := scoreMap["grade"].(string); ok && grade == "A" { foundGradeA = true break } } } if !foundGradeA { t.Error("Expected to find grade A for english score >= 90") } } // TestMemoryStoreFindAll 测试获取所有文档 func TestMemoryStoreGetAllDocuments(t *testing.T) { store := NewMemoryStore(nil) collection := "test.get_all_collection" createTestCollection(store, collection, map[string]types.Document{ "doc1": {ID: "doc1", Data: map[string]interface{}{"name": "Alice"}, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "doc2": {ID: "doc2", Data: map[string]interface{}{"name": "Bob"}, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "doc3": {ID: "doc3", Data: map[string]interface{}{"name": "Charlie"}, CreatedAt: time.Now(), UpdatedAt: time.Now()}, }) docs, err := store.GetAllDocuments(collection) if err != nil { t.Fatalf("GetAllDocuments() error = %v", err) } if len(docs) != 3 { t.Errorf("GetAllDocuments() returned %d documents, want 3", len(docs)) } } // TestMemoryStoreCollectionNotFound 测试集合不存在的情况 func TestMemoryStoreCollectionNotFound(t *testing.T) { store := NewMemoryStore(nil) _, err := store.GetCollection("nonexistent.collection") if err == nil { t.Error("Expected error for non-existent collection") } } // TestMemoryStoreInsert 测试插入功能 func TestMemoryStoreInsert(t *testing.T) { store := NewMemoryStore(nil) collection := "test.insert_collection" createTestCollection(store, collection, make(map[string]types.Document)) doc := types.Document{ ID: "test_id", Data: map[string]interface{}{"name": "Test Document"}, CreatedAt: time.Now(), UpdatedAt: time.Now(), } err := store.Insert(collection, doc) if err != nil { t.Fatalf("Insert() error = %v", err) } // Verify insertion storedDoc, exists := store.collections[collection].documents["test_id"] if !exists { t.Error("Document was not inserted") } if storedDoc.Data["name"] != "Test Document" { t.Errorf("Document data mismatch: got %v", storedDoc.Data) } } // TestMemoryStoreDelete 测试删除功能 func TestMemoryStoreDelete(t *testing.T) { store := NewMemoryStore(nil) collection := "test.delete_collection" createTestCollection(store, collection, map[string]types.Document{ "doc1": {ID: "doc1", Data: map[string]interface{}{"status": "active"}, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "doc2": {ID: "doc2", Data: map[string]interface{}{"status": "inactive"}, CreatedAt: time.Now(), UpdatedAt: time.Now()}, }) deleted, err := store.Delete(collection, types.Filter{"status": "inactive"}) if err != nil { t.Fatalf("Delete() error = %v", err) } if deleted != 1 { t.Errorf("Delete() deleted %d documents, want 1", deleted) } // Verify only doc1 remains if _, exists := store.collections[collection].documents["doc2"]; exists { t.Error("Document should have been deleted") } if _, exists := store.collections[collection].documents["doc1"]; !exists { t.Error("Document should still exist") } }