Skip to main content
Glama
orneryd

M.I.M.I.R - Multi-agent Intelligent Memory & Insight Repository

by orneryd
case_expression_test.go10.1 kB
package cypher import ( "context" "testing" "github.com/orneryd/nornicdb/pkg/storage" ) func TestCaseExpressionSearched(t *testing.T) { store := storage.NewMemoryEngine() exec := NewStorageExecutor(store) ctx := context.Background() // Create test data for _, data := range []struct { name string age int64 }{ {"Alice", 15}, {"Bob", 30}, {"Charlie", 70}, {"Diana", 25}, } { _, err := exec.Execute(ctx, "CREATE (p:Person {name: $name, age: $age})", map[string]interface{}{ "name": data.name, "age": data.age, }) if err != nil { t.Fatalf("Failed to create node: %v", err) } } t.Run("BasicSearchedCase", func(t *testing.T) { result, err := exec.Execute(ctx, ` MATCH (p:Person) RETURN p.name, CASE WHEN p.age < 18 THEN 'minor' WHEN p.age < 65 THEN 'adult' ELSE 'senior' END AS ageGroup `, nil) if err != nil { t.Fatalf("Query failed: %v", err) } if len(result.Rows) != 4 { t.Errorf("Expected 4 rows, got %d", len(result.Rows)) } // Check specific cases expected := map[string]string{ "Alice": "minor", "Bob": "adult", "Charlie": "senior", "Diana": "adult", } for _, row := range result.Rows { name := row[0].(string) ageGroup := row[1] if ageGroup == nil { t.Errorf("Got NULL for %s, expected %s", name, expected[name]) continue } if expected[name] != ageGroup.(string) { t.Errorf("For %s: expected %s, got %v", name, expected[name], ageGroup) } } }) t.Run("CaseWithoutElse", func(t *testing.T) { result, err := exec.Execute(ctx, ` MATCH (p:Person) RETURN p.name, CASE WHEN p.age < 18 THEN 'minor' WHEN p.age >= 65 THEN 'senior' END AS category `, nil) if err != nil { t.Fatalf("Query failed: %v", err) } // Check that adults get NULL (no matching WHEN, no ELSE) for _, row := range result.Rows { name := row[0].(string) category := row[1] if name == "Bob" || name == "Diana" { // Adults should get NULL if category != nil { t.Errorf("Expected NULL for %s (adult), got %v", name, category) } } else { // Minor and senior should have values if category == nil { t.Errorf("Expected non-NULL for %s", name) } } } }) t.Run("CaseWithComparison", func(t *testing.T) { result, err := exec.Execute(ctx, ` MATCH (p:Person) WHERE p.name = 'Bob' RETURN CASE WHEN p.age > 50 THEN 'old' WHEN p.age > 25 THEN 'middle' WHEN p.age > 0 THEN 'young' END AS category `, nil) if err != nil { t.Fatalf("Query failed: %v", err) } if len(result.Rows) != 1 { t.Fatalf("Expected 1 row, got %d", len(result.Rows)) } if result.Rows[0][0] != "middle" { t.Errorf("Expected 'middle', got %v", result.Rows[0][0]) } }) t.Run("CaseWithLessEqual", func(t *testing.T) { result, err := exec.Execute(ctx, ` MATCH (p:Person) WHERE p.name = 'Diana' RETURN CASE WHEN p.age <= 20 THEN 'young' WHEN p.age <= 40 THEN 'adult' ELSE 'old' END AS category `, nil) if err != nil { t.Fatalf("Query failed: %v", err) } if result.Rows[0][0] != "adult" { t.Errorf("Expected 'adult', got %v", result.Rows[0][0]) } }) } func TestCaseExpressionSimple(t *testing.T) { store := storage.NewMemoryEngine() exec := NewStorageExecutor(store) ctx := context.Background() // Create test data with status for _, data := range []struct { name string status string }{ {"Task1", "pending"}, {"Task2", "active"}, {"Task3", "done"}, {"Task4", "cancelled"}, } { _, err := exec.Execute(ctx, "CREATE (t:Task {name: $name, status: $status})", map[string]interface{}{ "name": data.name, "status": data.status, }) if err != nil { t.Fatalf("Failed to create node: %v", err) } } t.Run("SimpleCaseExpression", func(t *testing.T) { result, err := exec.Execute(ctx, ` MATCH (t:Task) RETURN t.name, CASE t.status WHEN 'pending' THEN 'Not Started' WHEN 'active' THEN 'In Progress' WHEN 'done' THEN 'Completed' ELSE 'Unknown' END AS statusLabel `, nil) if err != nil { t.Fatalf("Query failed: %v", err) } if len(result.Rows) != 4 { t.Errorf("Expected 4 rows, got %d", len(result.Rows)) } expected := map[string]string{ "Task1": "Not Started", "Task2": "In Progress", "Task3": "Completed", "Task4": "Unknown", } for _, row := range result.Rows { name := row[0].(string) label := row[1].(string) if expected[name] != label { t.Errorf("For %s: expected %s, got %s", name, expected[name], label) } } }) t.Run("SimpleCaseWithNumbers", func(t *testing.T) { // Create numeric test data exec.Execute(ctx, "CREATE (n:Number {value: 1})", nil) exec.Execute(ctx, "CREATE (n:Number {value: 2})", nil) exec.Execute(ctx, "CREATE (n:Number {value: 3})", nil) result, err := exec.Execute(ctx, ` MATCH (n:Number) RETURN n.value, CASE n.value WHEN 1 THEN 'one' WHEN 2 THEN 'two' WHEN 3 THEN 'three' END AS word `, nil) if err != nil { t.Fatalf("Query failed: %v", err) } if len(result.Rows) != 3 { t.Errorf("Expected 3 rows, got %d", len(result.Rows)) } for _, row := range result.Rows { value := row[0].(int64) word := row[1].(string) expected := map[int64]string{1: "one", 2: "two", 3: "three"} if expected[value] != word { t.Errorf("For value %d: expected %s, got %s", value, expected[value], word) } } }) } func TestCaseExpressionNullHandling(t *testing.T) { store := storage.NewMemoryEngine() exec := NewStorageExecutor(store) ctx := context.Background() // Create data with NULL values exec.Execute(ctx, "CREATE (p:Person {name: 'Alice', age: 30})", nil) exec.Execute(ctx, "CREATE (p:Person {name: 'Bob'})", nil) // No age property t.Run("CaseWithNullValue", func(t *testing.T) { result, err := exec.Execute(ctx, ` MATCH (p:Person) RETURN p.name, CASE WHEN p.age IS NULL THEN 'unknown' WHEN p.age < 18 THEN 'minor' ELSE 'adult' END AS category `, nil) if err != nil { t.Fatalf("Query failed: %v", err) } for _, row := range result.Rows { name := row[0].(string) category := row[1].(string) if name == "Bob" && category != "unknown" { t.Errorf("Expected 'unknown' for Bob (NULL age), got %s", category) } if name == "Alice" && category != "adult" { t.Errorf("Expected 'adult' for Alice, got %s", category) } } }) t.Run("CaseReturningNull", func(t *testing.T) { result, err := exec.Execute(ctx, ` MATCH (p:Person) WHERE p.name = 'Bob' RETURN CASE WHEN p.age > 100 THEN 'very old' END AS category `, nil) if err != nil { t.Fatalf("Query failed: %v", err) } // Should return NULL (no matching WHEN, no ELSE) if result.Rows[0][0] != nil { t.Errorf("Expected NULL, got %v", result.Rows[0][0]) } }) } func TestCaseExpressionComplexConditions(t *testing.T) { store := storage.NewMemoryEngine() exec := NewStorageExecutor(store) ctx := context.Background() exec.Execute(ctx, "CREATE (p:Product {name: 'Widget', price: 100, stock: 5})", nil) exec.Execute(ctx, "CREATE (p:Product {name: 'Gadget', price: 50, stock: 0})", nil) exec.Execute(ctx, "CREATE (p:Product {name: 'Tool', price: 200, stock: 10})", nil) t.Run("CaseWithMultipleConditions", func(t *testing.T) { result, err := exec.Execute(ctx, ` MATCH (p:Product) RETURN p.name, CASE WHEN p.stock = 0 THEN 'Out of Stock' WHEN p.price >= 200 THEN 'Premium' WHEN p.price >= 100 THEN 'Standard' ELSE 'Budget' END AS category `, nil) if err != nil { t.Fatalf("Query failed: %v", err) } expected := map[string]string{ "Widget": "Standard", "Gadget": "Out of Stock", // stock = 0 comes first "Tool": "Premium", } for _, row := range result.Rows { name := row[0].(string) category := row[1].(string) if expected[name] != category { t.Errorf("For %s: expected %s, got %s", name, expected[name], category) } } }) t.Run("CaseWithNotEquals", func(t *testing.T) { result, err := exec.Execute(ctx, ` MATCH (p:Product) WHERE p.name = 'Widget' RETURN CASE WHEN p.stock <> 0 THEN 'available' ELSE 'unavailable' END AS availability `, nil) if err != nil { t.Fatalf("Query failed: %v", err) } if result.Rows[0][0] != "available" { t.Errorf("Expected 'available', got %v", result.Rows[0][0]) } }) } func TestCaseExpressionEdgeCases(t *testing.T) { store := storage.NewMemoryEngine() exec := NewStorageExecutor(store) ctx := context.Background() exec.Execute(ctx, "CREATE (n:Test {value: 0})", nil) exec.Execute(ctx, "CREATE (n:Test {value: -1})", nil) exec.Execute(ctx, "CREATE (n:Test {name: ''})", nil) t.Run("CaseWithZeroValue", func(t *testing.T) { result, err := exec.Execute(ctx, ` MATCH (n:Test) WHERE n.value = 0 RETURN CASE n.value WHEN 0 THEN 'zero' WHEN 1 THEN 'one' ELSE 'other' END AS label `, nil) if err != nil { t.Fatalf("Query failed: %v", err) } if result.Rows[0][0] != "zero" { t.Errorf("Expected 'zero', got %v", result.Rows[0][0]) } }) t.Run("CaseWithNegativeNumber", func(t *testing.T) { result, err := exec.Execute(ctx, ` MATCH (n:Test) WHERE n.value = -1 RETURN CASE WHEN n.value < 0 THEN 'negative' WHEN n.value > 0 THEN 'positive' ELSE 'zero' END AS sign `, nil) if err != nil { t.Fatalf("Query failed: %v", err) } if result.Rows[0][0] != "negative" { t.Errorf("Expected 'negative', got %v", result.Rows[0][0]) } }) t.Run("CaseWithEmptyString", func(t *testing.T) { result, err := exec.Execute(ctx, ` MATCH (n:Test) WHERE n.name IS NOT NULL RETURN CASE n.name WHEN '' THEN 'empty' ELSE 'not empty' END AS status `, nil) if err != nil { t.Fatalf("Query failed: %v", err) } if result.Rows[0][0] != "empty" { t.Errorf("Expected 'empty', got %v", result.Rows[0][0]) } }) }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/orneryd/Mimir'

If you have feedback or need assistance with the MCP directory API, please join our Discord server