Skip to main content
Glama
orneryd

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

by orneryd
documentation_examples_test.go20.9 kB
package cypher import ( "context" "testing" "github.com/orneryd/nornicdb/pkg/storage" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) // TestDocumentationExamples tests all Cypher queries from the documentation // to ensure they work correctly. This validates that our documentation is accurate. // // Source: docs/getting-started/first-queries.md func TestDocumentationExamples_FirstQueries(t *testing.T) { ctx := context.Background() store := storage.NewMemoryEngine() exec := NewStorageExecutor(store) t.Run("CreateFirstNode", func(t *testing.T) { query := ` CREATE (alice:Person { name: "Alice Johnson", age: 30, email: "alice@example.com" }) RETURN alice ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) // Result is a map representing the node node, ok := result.Rows[0][0].(map[string]interface{}) require.True(t, ok, "Expected node map") assert.Equal(t, "Alice Johnson", node["name"]) }) t.Run("CreateMultipleNodes", func(t *testing.T) { query := ` CREATE (bob:Person {name: "Bob Smith", age: 35}), (carol:Person {name: "Carol White", age: 28}), (company:Company {name: "TechCorp", founded: 2010}) RETURN bob, carol, company ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) bob, ok := result.Rows[0][0].(map[string]interface{}) require.True(t, ok, "Expected bob node map") assert.Equal(t, "Bob Smith", bob["name"]) company, ok := result.Rows[0][2].(map[string]interface{}) require.True(t, ok, "Expected company node map") assert.Equal(t, "TechCorp", company["name"]) }) t.Run("CreateRelationship", func(t *testing.T) { query := ` MATCH (alice:Person {name: "Alice Johnson"}), (company:Company {name: "TechCorp"}) CREATE (alice)-[r:WORKS_AT {since: 2020, role: "Engineer"}]->(company) RETURN alice, r, company ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) // May return 0 rows if MATCH finds nothing, that's ok for this test if len(result.Rows) > 0 { assert.NotNil(t, result.Rows[0]) } }) t.Run("FindAllPeople", func(t *testing.T) { query := ` MATCH (p:Person) RETURN p.name, p.age ORDER BY p.age DESC ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.GreaterOrEqual(t, len(result.Rows), 3) // Should be ordered by age descending if len(result.Rows) >= 2 { // Age values should be in descending order assert.NotNil(t, result.Rows[0][1]) assert.NotNil(t, result.Rows[1][1]) } }) t.Run("FindRelationships", func(t *testing.T) { // First create the relationship if it doesn't exist _, _ = exec.Execute(ctx, ` MATCH (alice:Person {name: "Alice Johnson"}), (company:Company {name: "TechCorp"}) CREATE (alice)-[:WORKS_AT {since: 2020, role: "Engineer"}]->(company) `, nil) query := ` MATCH (p:Person)-[r:WORKS_AT]->(c:Company) RETURN p.name, c.name ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) // May have results if relationship was created assert.NotNil(t, result) }) } // TestDocumentationExamples_QueryPatterns tests query patterns from documentation func TestDocumentationExamples_QueryPatterns(t *testing.T) { ctx := context.Background() store := storage.NewMemoryEngine() exec := NewStorageExecutor(store) // Setup test data setupQueries := []string{ `CREATE (a:Person {name: "Alice", age: 30, city: "New York"})`, `CREATE (b:Person {name: "Bob", age: 25, city: "Boston"})`, `CREATE (c:Person {name: "Charlie", age: 35, city: "New York"})`, `CREATE (d:Person {name: "Diana", age: 28, city: "Boston"})`, } for _, q := range setupQueries { _, err := exec.Execute(ctx, q, nil) require.NoError(t, err) } t.Run("WhereClauseEquality", func(t *testing.T) { query := ` MATCH (p:Person) WHERE p.city = 'New York' RETURN p.name ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) assert.Equal(t, 2, len(result.Rows), "Should find 2 people in New York") }) t.Run("WhereClauseComparison", func(t *testing.T) { query := ` MATCH (p:Person) WHERE p.age >= 30 RETURN p.name, p.age ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) assert.Equal(t, 2, len(result.Rows), "Should find 2 people age >= 30") }) t.Run("WhereClauseAnd", func(t *testing.T) { query := ` MATCH (p:Person) WHERE p.age > 25 AND p.city = 'Boston' RETURN p.name ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) assert.Equal(t, 1, len(result.Rows), "Should find Diana") }) t.Run("OrderByAscending", func(t *testing.T) { query := ` MATCH (p:Person) RETURN p.name, p.age ORDER BY p.age ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.GreaterOrEqual(t, len(result.Rows), 4) }) t.Run("OrderByDescending", func(t *testing.T) { query := ` MATCH (p:Person) RETURN p.name, p.age ORDER BY p.age DESC ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.GreaterOrEqual(t, len(result.Rows), 4) }) t.Run("LimitResults", func(t *testing.T) { query := ` MATCH (p:Person) RETURN p.name LIMIT 2 ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) assert.Equal(t, 2, len(result.Rows), "Should return exactly 2 rows") }) t.Run("SkipResults", func(t *testing.T) { query := ` MATCH (p:Person) RETURN p.name ORDER BY p.name SKIP 1 LIMIT 2 ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) assert.Equal(t, 2, len(result.Rows), "Should return 2 rows after skipping 1") }) } // TestDocumentationExamples_Aggregations tests aggregation queries from documentation func TestDocumentationExamples_Aggregations(t *testing.T) { ctx := context.Background() store := storage.NewMemoryEngine() exec := NewStorageExecutor(store) // Setup test data setupQueries := []string{ `CREATE (a:Product {name: "Widget", category: "Electronics", price: 29.99})`, `CREATE (b:Product {name: "Gadget", category: "Electronics", price: 49.99})`, `CREATE (c:Product {name: "Gizmo", category: "Electronics", price: 19.99})`, `CREATE (d:Product {name: "Tool", category: "Hardware", price: 15.99})`, `CREATE (e:Product {name: "Supply", category: "Hardware", price: 9.99})`, } for _, q := range setupQueries { _, err := exec.Execute(ctx, q, nil) require.NoError(t, err) } t.Run("CountAll", func(t *testing.T) { query := ` MATCH (p:Product) RETURN count(*) as total ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) assert.Equal(t, int64(5), result.Rows[0][0]) }) t.Run("CountByCategory", func(t *testing.T) { query := ` MATCH (p:Product) WITH p.category as category, count(*) as count RETURN category, count ORDER BY count DESC ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 2, "Should have 2 categories") }) t.Run("SumPrices", func(t *testing.T) { query := ` MATCH (p:Product) RETURN sum(p.price) as total ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) // Total: 29.99 + 49.99 + 19.99 + 15.99 + 9.99 = 125.95 total, ok := result.Rows[0][0].(float64) require.True(t, ok) assert.InDelta(t, 125.95, total, 0.01) }) t.Run("AvgPrice", func(t *testing.T) { query := ` MATCH (p:Product) RETURN avg(p.price) as average ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) // Avg: 125.95 / 5 = 25.19 avg, ok := result.Rows[0][0].(float64) require.True(t, ok) assert.InDelta(t, 25.19, avg, 0.01) }) t.Run("CollectNames", func(t *testing.T) { query := ` MATCH (p:Product) WHERE p.category = 'Electronics' RETURN collect(p.name) as names ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) names, ok := result.Rows[0][0].([]interface{}) require.True(t, ok) assert.Len(t, names, 3, "Should collect 3 electronics products") }) } // TestDocumentationExamples_Updates tests update queries from documentation func TestDocumentationExamples_Updates(t *testing.T) { ctx := context.Background() store := storage.NewMemoryEngine() exec := NewStorageExecutor(store) t.Run("SetProperty", func(t *testing.T) { // Create node _, err := exec.Execute(ctx, `CREATE (p:Person {name: "Test", age: 25})`, nil) require.NoError(t, err) // Update property query := ` MATCH (p:Person {name: "Test"}) SET p.age = 26 RETURN p.age ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) }) t.Run("SetMultipleProperties", func(t *testing.T) { // Create node _, err := exec.Execute(ctx, `CREATE (p:Person {name: "Multi"})`, nil) require.NoError(t, err) // Update multiple properties query := ` MATCH (p:Person {name: "Multi"}) SET p.age = 30, p.city = "Boston" RETURN p.name, p.age, p.city ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) }) t.Run("MergeCreate", func(t *testing.T) { query := ` MERGE (p:Person {name: "NewPerson"}) ON CREATE SET p.created = true RETURN p.name, p.created ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) }) t.Run("MergeMatch", func(t *testing.T) { // Create existing node _, err := exec.Execute(ctx, `CREATE (p:Person {name: "Existing"})`, nil) require.NoError(t, err) query := ` MERGE (p:Person {name: "Existing"}) ON MATCH SET p.updated = true RETURN p.name, p.updated ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) }) } // TestDocumentationExamples_Delete tests delete queries from documentation func TestDocumentationExamples_Delete(t *testing.T) { ctx := context.Background() store := storage.NewMemoryEngine() exec := NewStorageExecutor(store) t.Run("DeleteNode", func(t *testing.T) { // Create node _, err := exec.Execute(ctx, `CREATE (p:Person {name: "ToDelete"})`, nil) require.NoError(t, err) // Verify it exists result, err := exec.Execute(ctx, `MATCH (p:Person {name: "ToDelete"}) RETURN p`, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) // Delete it _, err = exec.Execute(ctx, `MATCH (p:Person {name: "ToDelete"}) DELETE p`, nil) require.NoError(t, err) // Verify it's gone result, err = exec.Execute(ctx, `MATCH (p:Person {name: "ToDelete"}) RETURN p`, nil) require.NoError(t, err) assert.Len(t, result.Rows, 0) }) t.Run("DetachDelete", func(t *testing.T) { // Create node with relationship _, err := exec.Execute(ctx, `CREATE (a:Person {name: "A"})-[:KNOWS]->(b:Person {name: "B"})`, nil) require.NoError(t, err) // Detach delete removes relationships first _, err = exec.Execute(ctx, `MATCH (p:Person {name: "A"}) DETACH DELETE p`, nil) require.NoError(t, err) // Verify A is gone result, err := exec.Execute(ctx, `MATCH (p:Person {name: "A"}) RETURN p`, nil) require.NoError(t, err) assert.Len(t, result.Rows, 0) }) } // TestDocumentationExamples_Functions tests built-in function usage func TestDocumentationExamples_Functions(t *testing.T) { ctx := context.Background() store := storage.NewMemoryEngine() exec := NewStorageExecutor(store) // Setup _, err := exec.Execute(ctx, `CREATE (p:Person:Employee {name: "FuncTest", email: "test@example.com"})`, nil) require.NoError(t, err) t.Run("IdFunction", func(t *testing.T) { query := ` MATCH (p:Person {name: "FuncTest"}) RETURN id(p) ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) assert.NotNil(t, result.Rows[0][0]) }) t.Run("LabelsFunction", func(t *testing.T) { query := ` MATCH (p:Person {name: "FuncTest"}) RETURN labels(p) ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) labels, ok := result.Rows[0][0].([]interface{}) require.True(t, ok) assert.GreaterOrEqual(t, len(labels), 2, "Should have at least Person and Employee labels") }) t.Run("KeysFunction", func(t *testing.T) { query := ` MATCH (p:Person {name: "FuncTest"}) RETURN keys(p) ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) keys, ok := result.Rows[0][0].([]interface{}) require.True(t, ok) assert.GreaterOrEqual(t, len(keys), 2, "Should have name and email keys") }) t.Run("CoalesceFunction", func(t *testing.T) { // Create node without optional property _, err := exec.Execute(ctx, `CREATE (p:Person {name: "CoalesceTest"})`, nil) require.NoError(t, err) query := ` MATCH (p:Person {name: "CoalesceTest"}) RETURN coalesce(p.nickname, p.name) as displayName ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) assert.Equal(t, "CoalesceTest", result.Rows[0][0]) }) t.Run("ToStringFunction", func(t *testing.T) { _, err := exec.Execute(ctx, `CREATE (p:Person {name: "StringTest", age: 42})`, nil) require.NoError(t, err) query := ` MATCH (p:Person {name: "StringTest"}) RETURN toString(p.age) ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) assert.Equal(t, "42", result.Rows[0][0]) }) } // TestDocumentationExamples_StringFunctions tests string functions func TestDocumentationExamples_StringFunctions(t *testing.T) { ctx := context.Background() store := storage.NewMemoryEngine() exec := NewStorageExecutor(store) t.Run("ToUpperToLower", func(t *testing.T) { query := `RETURN toUpper('hello') as upper, toLower('WORLD') as lower` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) assert.Equal(t, "HELLO", result.Rows[0][0]) assert.Equal(t, "world", result.Rows[0][1]) }) t.Run("TrimFunction", func(t *testing.T) { query := `RETURN trim(' hello ') as trimmed` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) assert.Equal(t, "hello", result.Rows[0][0]) }) t.Run("SubstringFunction", func(t *testing.T) { query := `RETURN substring('hello world', 0, 5) as sub` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) assert.Equal(t, "hello", result.Rows[0][0]) }) t.Run("ReplaceFunction", func(t *testing.T) { query := `RETURN replace('hello world', 'world', 'cypher') as replaced` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) assert.Equal(t, "hello cypher", result.Rows[0][0]) }) t.Run("SizeFunction", func(t *testing.T) { query := `RETURN size('hello') as len` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) assert.Equal(t, int64(5), result.Rows[0][0]) }) } // TestDocumentationExamples_ListFunctions tests list functions func TestDocumentationExamples_ListFunctions(t *testing.T) { ctx := context.Background() store := storage.NewMemoryEngine() exec := NewStorageExecutor(store) t.Run("RangeFunction", func(t *testing.T) { query := `RETURN range(1, 5) as nums` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) nums, ok := result.Rows[0][0].([]interface{}) require.True(t, ok) assert.Len(t, nums, 5) }) t.Run("HeadTailFunctions", func(t *testing.T) { query := ` WITH [1, 2, 3, 4, 5] as nums RETURN head(nums) as first, last(nums) as last ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) }) t.Run("SizeOfList", func(t *testing.T) { query := `RETURN size([1, 2, 3, 4, 5]) as count` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) assert.Equal(t, int64(5), result.Rows[0][0]) }) t.Run("ReverseFunction", func(t *testing.T) { query := `RETURN reverse([1, 2, 3]) as reversed` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) }) } // TestDocumentationExamples_CaseExpression tests CASE expressions func TestDocumentationExamples_CaseExpression(t *testing.T) { ctx := context.Background() store := storage.NewMemoryEngine() exec := NewStorageExecutor(store) // Setup setupQueries := []string{ `CREATE (a:Person {name: "Young", age: 18})`, `CREATE (b:Person {name: "Adult", age: 35})`, `CREATE (c:Person {name: "Senior", age: 70})`, } for _, q := range setupQueries { _, err := exec.Execute(ctx, q, nil) require.NoError(t, err) } t.Run("SimpleCaseWhen", func(t *testing.T) { query := ` MATCH (p:Person) RETURN p.name, CASE WHEN p.age < 20 THEN 'Young' WHEN p.age < 60 THEN 'Adult' ELSE 'Senior' END as category ORDER BY p.name ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 3) }) } // TestDocumentationExamples_UnwindClause tests UNWIND functionality func TestDocumentationExamples_UnwindClause(t *testing.T) { ctx := context.Background() store := storage.NewMemoryEngine() exec := NewStorageExecutor(store) t.Run("UnwindSimpleList", func(t *testing.T) { query := ` UNWIND [1, 2, 3, 4, 5] AS x RETURN x ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) assert.Len(t, result.Rows, 5) }) t.Run("UnwindRange", func(t *testing.T) { query := ` UNWIND range(1, 10) AS x RETURN x ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) assert.Len(t, result.Rows, 10) }) t.Run("UnwindWithMatch", func(t *testing.T) { // Create test data _, err := exec.Execute(ctx, `CREATE (p:Person:Developer {name: "UnwindTest"})`, nil) require.NoError(t, err) query := ` MATCH (p:Person {name: "UnwindTest"}) UNWIND labels(p) as label RETURN label ` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) assert.GreaterOrEqual(t, len(result.Rows), 2, "Should have at least Person and Developer labels") }) } // TestDocumentationExamples_ListComprehension tests list comprehension func TestDocumentationExamples_ListComprehension(t *testing.T) { ctx := context.Background() store := storage.NewMemoryEngine() exec := NewStorageExecutor(store) t.Run("SimpleListComprehension", func(t *testing.T) { query := `RETURN [x IN [1, 2, 3, 4, 5]] as nums` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) nums, ok := result.Rows[0][0].([]interface{}) require.True(t, ok) assert.Len(t, nums, 5) }) t.Run("ListComprehensionWithFilter", func(t *testing.T) { query := `RETURN [x IN [1, 2, 3, 4, 5] WHERE x > 2] as filtered` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) filtered, ok := result.Rows[0][0].([]interface{}) require.True(t, ok) assert.Len(t, filtered, 3, "Should have [3, 4, 5]") }) t.Run("ListComprehensionWithTransform", func(t *testing.T) { query := `RETURN [x IN [1, 2, 3] | x * 2] as doubled` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) doubled, ok := result.Rows[0][0].([]interface{}) require.True(t, ok) assert.Len(t, doubled, 3) }) } // TestDocumentationExamples_Procedures tests CALL procedure syntax func TestDocumentationExamples_Procedures(t *testing.T) { ctx := context.Background() store := storage.NewMemoryEngine() exec := NewStorageExecutor(store) t.Run("DbmsComponents", func(t *testing.T) { query := `CALL dbms.components()` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) require.Len(t, result.Rows, 1) }) t.Run("DbLabels", func(t *testing.T) { // Create some nodes first _, _ = exec.Execute(ctx, `CREATE (:TestLabel1), (:TestLabel2)`, nil) query := `CALL db.labels()` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) assert.GreaterOrEqual(t, len(result.Rows), 2) }) t.Run("DbRelationshipTypes", func(t *testing.T) { query := `CALL db.relationshipTypes()` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) // May be empty, that's ok assert.NotNil(t, result) }) t.Run("DbPropertyKeys", func(t *testing.T) { query := `CALL db.propertyKeys()` result, err := exec.Execute(ctx, query, nil) require.NoError(t, err) assert.NotNil(t, result) }) }

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