@@ -4408,6 +4408,133 @@ async def test_order_by_with_where(self):
44084408 assert results [3 ] == {"x" : 4 }
44094409 assert results [4 ] == {"x" : 3 }
44104410
4411+ @pytest .mark .asyncio
4412+ async def test_order_by_with_property_access_expression (self ):
4413+ """Test ORDER BY with property access expression."""
4414+ runner = Runner (
4415+ "unwind [{name: 'Charlie', age: 30}, {name: 'Alice', age: 25}, {name: 'Bob', age: 35}] as person "
4416+ "return person.name as name, person.age as age "
4417+ "order by person.name asc"
4418+ )
4419+ await runner .run ()
4420+ results = runner .results
4421+ assert len (results ) == 3
4422+ assert results [0 ] == {"name" : "Alice" , "age" : 25 }
4423+ assert results [1 ] == {"name" : "Bob" , "age" : 35 }
4424+ assert results [2 ] == {"name" : "Charlie" , "age" : 30 }
4425+
4426+ @pytest .mark .asyncio
4427+ async def test_order_by_with_function_expression (self ):
4428+ """Test ORDER BY with function expression."""
4429+ runner = Runner (
4430+ "unwind ['BANANA', 'apple', 'Cherry'] as fruit "
4431+ "return fruit "
4432+ "order by toLower(fruit)"
4433+ )
4434+ await runner .run ()
4435+ results = runner .results
4436+ assert len (results ) == 3
4437+ assert results [0 ] == {"fruit" : "apple" }
4438+ assert results [1 ] == {"fruit" : "BANANA" }
4439+ assert results [2 ] == {"fruit" : "Cherry" }
4440+
4441+ @pytest .mark .asyncio
4442+ async def test_order_by_with_function_expression_descending (self ):
4443+ """Test ORDER BY with function expression descending."""
4444+ runner = Runner (
4445+ "unwind ['BANANA', 'apple', 'Cherry'] as fruit "
4446+ "return fruit "
4447+ "order by toLower(fruit) desc"
4448+ )
4449+ await runner .run ()
4450+ results = runner .results
4451+ assert len (results ) == 3
4452+ assert results [0 ] == {"fruit" : "Cherry" }
4453+ assert results [1 ] == {"fruit" : "BANANA" }
4454+ assert results [2 ] == {"fruit" : "apple" }
4455+
4456+ @pytest .mark .asyncio
4457+ async def test_order_by_with_nested_function_expression (self ):
4458+ """Test ORDER BY with nested function expression."""
4459+ runner = Runner (
4460+ "unwind ['Alice', 'Bob', 'ALICE', 'bob'] as name "
4461+ "return name "
4462+ "order by string_distance(toLower(name), toLower('alice')) asc"
4463+ )
4464+ await runner .run ()
4465+ results = runner .results
4466+ assert len (results ) == 4
4467+ # 'Alice' and 'ALICE' have distance 0 from 'alice', should come first
4468+ assert results [0 ]["name" ] == "Alice"
4469+ assert results [1 ]["name" ] == "ALICE"
4470+ # 'Bob' and 'bob' have higher distance from 'alice'
4471+ assert results [2 ]["name" ] == "Bob"
4472+ assert results [3 ]["name" ] == "bob"
4473+
4474+ @pytest .mark .asyncio
4475+ async def test_order_by_with_arithmetic_expression (self ):
4476+ """Test ORDER BY with arithmetic expression."""
4477+ runner = Runner (
4478+ "unwind [{a: 3, b: 1}, {a: 1, b: 5}, {a: 2, b: 2}] as item "
4479+ "return item.a as a, item.b as b "
4480+ "order by item.a + item.b asc"
4481+ )
4482+ await runner .run ()
4483+ results = runner .results
4484+ assert len (results ) == 3
4485+ assert results [0 ] == {"a" : 3 , "b" : 1 } # sum = 4
4486+ assert results [1 ] == {"a" : 2 , "b" : 2 } # sum = 4
4487+ assert results [2 ] == {"a" : 1 , "b" : 5 } # sum = 6
4488+
4489+ @pytest .mark .asyncio
4490+ async def test_order_by_expression_does_not_leak_synthetic_keys (self ):
4491+ """Test ORDER BY expression does not leak synthetic keys."""
4492+ runner = Runner (
4493+ "unwind ['B', 'a', 'C'] as x "
4494+ "return x "
4495+ "order by toLower(x) asc"
4496+ )
4497+ await runner .run ()
4498+ results = runner .results
4499+ assert len (results ) == 3
4500+ # Results should only contain 'x', no extra keys
4501+ for r in results :
4502+ assert list (r .keys ()) == ["x" ]
4503+ assert results [0 ] == {"x" : "a" }
4504+ assert results [1 ] == {"x" : "B" }
4505+ assert results [2 ] == {"x" : "C" }
4506+
4507+ @pytest .mark .asyncio
4508+ async def test_order_by_with_expression_and_limit (self ):
4509+ """Test ORDER BY with expression and limit."""
4510+ runner = Runner (
4511+ "unwind ['BANANA', 'apple', 'Cherry', 'date', 'ELDERBERRY'] as fruit "
4512+ "return fruit "
4513+ "order by toLower(fruit) asc "
4514+ "limit 3"
4515+ )
4516+ await runner .run ()
4517+ results = runner .results
4518+ assert len (results ) == 3
4519+ assert results [0 ] == {"fruit" : "apple" }
4520+ assert results [1 ] == {"fruit" : "BANANA" }
4521+ assert results [2 ] == {"fruit" : "Cherry" }
4522+
4523+ @pytest .mark .asyncio
4524+ async def test_order_by_with_mixed_simple_and_expression_fields (self ):
4525+ """Test ORDER BY with mixed simple and expression fields."""
4526+ runner = Runner (
4527+ "unwind [{name: 'Alice', score: 3}, {name: 'Alice', score: 1}, {name: 'Bob', score: 2}] as item "
4528+ "return item.name as name, item.score as score "
4529+ "order by name asc, item.score desc"
4530+ )
4531+ await runner .run ()
4532+ results = runner .results
4533+ assert len (results ) == 3
4534+ assert results [0 ] == {"name" : "Alice" , "score" : 3 } # Alice, score 3 desc
4535+ assert results [1 ] == {"name" : "Alice" , "score" : 1 } # Alice, score 1 desc
4536+ assert results [2 ] == {"name" : "Bob" , "score" : 2 } # Bob
4537+
44114538 @pytest .mark .asyncio
44124539 async def test_delete_virtual_node_operation (self ):
44134540 """Test delete virtual node operation."""
0 commit comments