Skip to content

Commit

Permalink
Fix transform to properly handle paths and maps.
Browse files Browse the repository at this point in the history
And add a test (that failed before this) to test returning paths. Sweet!
  • Loading branch information
aseemk committed Sep 11, 2012
1 parent 29c3da4 commit 0551fb2
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 12 deletions.
41 changes: 29 additions & 12 deletions lib/util.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand All @@ -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)
Expand Down
19 changes: 19 additions & 0 deletions test/cypher._coffee
Original file line number Diff line number Diff line change
Expand Up @@ -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.