Permalink
Browse files

Fix transform to properly handle paths and maps.

And add a test (that failed before this) to test returning paths. Sweet!
  • Loading branch information...
1 parent 29c3da4 commit 0551fb217f5f4c4c62acba8a8972c4fd56996fc9 @aseemk aseemk committed Sep 11, 2012
Showing with 48 additions and 12 deletions.
  1. +29 −12 lib/util.coffee
  2. +19 −0 test/cypher._coffee
View
@@ -105,28 +105,42 @@ exports.adjustError = (error) ->
# transforms it or its subvalues into the appropriate Node/Relationship/Path
# instances. returns the transformed value.
exports.transform = transform = (val, db) ->
+ # ignore non-objects:
+ if not val or typeof val isnt 'object'
+ return val
+
# arrays should be recursed:
if val instanceof Array
return val.map (val) ->
transform val, db
- # ignore non-neo4j objects:
- # (XXX this means we aren't recursing hash maps for now! fine for now.)
- if not val or typeof val isnt 'object' or not val.self
- return val
-
# inline requires to prevent circular dependencies:
Path = require './Path'
Node = require './Node'
Relationship = require './Relationship'
- # relationships have a type property:
- if typeof val.type is 'string'
+ # we want to transform neo4j objects but also recurse non-neo4j objects,
+ # since they may be maps/dictionaries. so we detect neo4j objects via
+ # duck typing, and assume all other objects are maps. helper:
+ hasProps = (props) ->
+ for type, keys of props
+ for key in keys.split '|'
+ if typeof val[key] isnt type
+ return false
+ return true
+
+ # nodes:
+ if hasProps {string: 'self|traverse', object:'data'}
+ return new Node db, val
+
+ # relationships:
+ if hasProps {string: 'self|type|start|end', object:'data'}
return new Relationship db, val
- # paths have nodes and relationships:
- # (XXX this doesn't handle fullpaths, but we don't return those yet.)
- if val.nodes and val.relationships
+ # paths:
+ # XXX this doesn't handle fullpaths for now, but we don't return those
+ # anywhere yet AFAIK. TODO detect and support fullpaths too?
+ if hasProps {string: 'start|end', number: 'length', object:'nodes|relationships'}
# XXX the path's nodes and relationships are just URLs for now!
start = new Node db, {self: val.start}
end = new Node db, {self: val.end}
@@ -138,9 +152,12 @@ exports.transform = transform = (val, db) ->
return new Path start, end, length, nodes, relationships
- # the only other type of neo4j object is a node:
+ # all other objects -- treat as maps:
else
- return new Node db, val
+ map = {}
+ for key, subval of val
+ map[key] = transform subval, db
+ return map
exports.serialize = (o, separator) ->
JSON.stringify flatten(o, separator)
View
@@ -120,5 +120,24 @@ assert.ok typeof results[0]['collect(n)'][0] 'object'
assert.equal results[0]['collect(n)'][0].id, user0.id
assert.equal results[0]['collect(n)'][0].data.name, user0.name
+# test: can return paths
+results = db.query """
+ START from=node({fromId}), to=node({toId})
+ MATCH path=shortestPath(from -[:follows*..3]-> to)
+ RETURN path
+""", {fromId: user0.id, toId: user6.id}, _
+assert.equal results.length, 1
+assert.ok typeof results[0]['path'], 'object'
+assert.ok typeof results[0]['path'].start, 'object'
+assert.ok typeof results[0]['path'].end, 'object'
+assert.ok results[0]['path'].nodes instanceof Array
+assert.ok results[0]['path'].relationships instanceof Array
+assert.equal results[0]['path'].length, 2
+assert.equal results[0]['path'].start.id, user0.id
+assert.equal results[0]['path'].end.id, user6.id
+assert.equal results[0]['path'].nodes.length, 3
+assert.equal results[0]['path'].nodes[1].id, user3.id
+assert.equal results[0]['path'].relationships.length, 2
+
# give some confidence that these tests actually passed ;)
console.log 'passed cypher tests'

0 comments on commit 0551fb2

Please sign in to comment.