Skip to content

Commit

Permalink
Merge pull request #3 from bylee5/master
Browse files Browse the repository at this point in the history
test: Update test cases
  • Loading branch information
bylee5 authored Jan 15, 2018
2 parents 04b2a27 + 5b47364 commit b1db460
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 99 deletions.
10 changes: 0 additions & 10 deletions README

This file was deleted.

46 changes: 45 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,45 @@
# agens-graph-python
# AgensGraph Python driver

It is AgensGraph client for Python, supports the graph data types like Vertex, Edge and Path used in AgensGraph.

It is based on [psycopg2](https://github.com/psycopg/psycopg2).


## Install

```sh
$ pip install -U pip
$ pip install psycopg2

$ python /path/to/set.py install

```


## Example

```python
import psycopg2

connect = psycopg2.connect("dbname=agens user=bylee host=127.0.0.1")
cur = connect.cursor()
cur.execute("DROP GRAPH IF EXISTS g CASCADE")
cur.execute("CREATE GRAPH g")
cur.execute("SET graph_path = g")

cur.execute("CREATE p=(:v{name: 'agens'})-[:e]->() RETURN p")
cur.execute("MATCH ()-[r]->() RETURN count(*)")
print cur.fetchone()[0]

```



## Test

```sh
$ python test_agtype [-v]

```

The test cases must be executed in Python 2.x
154 changes: 66 additions & 88 deletions test_agtype.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

'''
Copyright (c) 2014-2016, Bitnine Inc.
Expand All @@ -11,60 +12,50 @@
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
'''

import unittest
import psycopg2
from psycopg2.extras import Json
import agtype

class BasicTest(unittest.TestCase):
def setUp(self):
self.conn = psycopg2.connect("dbname=test user=postgres")
self.conn = psycopg2.connect("dbname=agens user=bylee host=127.0.0.1")
self.cur = self.conn.cursor()
try:
self.cur.execute("drop graph p cascade")
self.cur.execute("DROP GRAPH p CASCADE")
except:
self.conn.commit()
self.cur.execute("create graph p")
self.cur.execute("set graph_path = p")
self.cur.execute("CREATE GRAPH p")
self.cur.execute("SET GRAPH_PATH = p")
self.conn.commit()
def tearDown(self):
self.conn.commit()
self.cur.execute("drop graph p cascade")
self.cur.execute("DROP GRAPH p CASCADE")
self.cur.close()
self.conn.close()

class CreateTest(BasicTest):
def setUp(self):
BasicTest.setUp(self)
self.cur.execute("create vlabel person")
self.cur.execute("create vlabel company")
self.cur.execute("create elabel employee")
self.cur.execute("CREATE VLABEL person")
self.cur.execute("CREATE VLABEL company")
self.cur.execute("CREATE ELABEL employee")
def test_CreateWithBind(self):
self.cur.execute(
"CREATE ( :person { 'name': 'XXX', 'from': 'Sweden', 'klout': %s } )", (99,))
self.cur.execute("MATCH (n:person {'name': %s}) return n", ('XXX',))
"CREATE ( :person { name: 'XXX', from: 'Sweden', klout: %s } )", (99,))
self.cur.execute("MATCH (n:person {name: %s}) RETURN n", ('XXX',))
n = self.cur.fetchone()[0]
self.assertEquals(99, n.props["klout"])
def test_CreateWithBindPrimitiveProp(self):
with self.assertRaises(psycopg2.ProgrammingError):
self.cur.execute("CREATE ( :person %s )", (Json(10),));
def test_CreateWithBindWholeProp(self):
self.cur.execute("CREATE ( :person %s )",
(Json({'name': 'ktlee', 'from': 'Korea', 'klout': 17}),))
self.cur.execute("MATCH (n:person {'name': %s}) return n", ('ktlee',))
n = self.cur.fetchone()[0]
self.assertEquals(17, n.props["klout"])

class LabelInheritTest(BasicTest):
def setUp(self):
BasicTest.setUp(self)
self.cur.execute("create vlabel parent")
self.cur.execute("create vlabel child inherits (parent)")
self.cur.execute("create (:parent {'name': 'father'})")
self.cur.execute("create (:child {'name': 'son'})")
self.cur.execute("CREATE VLABEL parent")
self.cur.execute("CREATE VLABEL child INHERITS (parent)")
self.cur.execute("CREATE (:parent {name: 'father'})")
self.cur.execute("CREATE (:child {name: 'son'})")
pass
def test_MultiLable(self):
self.cur.execute("MATCH (x:parent) RETURN x ORDER BY x.name")
Expand All @@ -79,24 +70,24 @@ def test_MultiLable(self):
class MatchTest(BasicTest):
def setUp(self):
BasicTest.setUp(self)
self.cur.execute("create vlabel company")
self.cur.execute("create vlabel person")
self.cur.execute("create elabel employee")
self.cur.execute("create elabel manage")
self.cur.execute("create (:company {'name': 'bitnine'})"
+ "-[:employee]"
+ "->(:person {'name': 'kskim'})"
+ "-[:manage]"
+ "->(:person {'name': 'ktlee'})");
self.cur.execute("create (c:company {'name': 'bitnine'}) "
+ "create (c)-[:employee]"
+ "->(:person {'name': 'jsyang'})")
self.cur.execute("create (c:company {'name': 'bitnine'}) "
+ ", (p:person {'name': 'ktlee'}) "
+ "create (c)-[:employee]->(p)")
self.cur.execute("match (m:person {'name': 'kskim'})"
+ ", (p:person {'name': 'jsyang'}) "
+ "create (m)-[:manage]->(p)")
self.cur.execute("CREATE VLABEL company")
self.cur.execute("CREATE VLABEL person")
self.cur.execute("CREATE ELABEL employee")
self.cur.execute("CREATE ELABEL manage")
self.cur.execute("CREATE (:company {name: 'bitnine'})"
+ "-[:employee]"
+ "->(:person {name: 'kskim'})"
+ "-[:manage]"
+ "->(:person {name: 'ktlee'})");
self.cur.execute("CREATE (c:company {name: 'bitnine'}) "
+ "CREATE (c)-[:employee]"
+ "->(:person {name: 'jsyang'})")
self.cur.execute("CREATE (c:company {name: 'bitnine'}) "
+ ", (p:person {name: 'ktlee'}) "
+ "CREATE (c)-[:employee]->(p)")
self.cur.execute("MATCH (m:person {name: 'kskim'})"
+ ", (p:person {name: 'jsyang'}) "
+ "CREATE (m)-[:manage]->(p)")
def test_Match(self):
self.cur.execute("MATCH (c)-[e]->(p1)-[m]->(p2) RETURN p1, p2 ORDER BY p2.name")
row = self.cur.fetchone()
Expand All @@ -112,98 +103,85 @@ def test_Match(self):
member = row[1]
self.assertEquals("ktlee", member.props["name"])
def test_Path(self):
self.cur.execute("MATCH p=()-[]->()-[]->({'name':'ktlee'}) RETURN p")
self.cur.execute("MATCH p=()-[]->()-[]->({name:'ktlee'}) RETURN p")
p = self.cur.fetchone()[0]
self.assertEquals('company[3.1]{"name": "bitnine"},employee[5.1][3.1,4.1]{},'
+ 'person[4.1]{"name": "kskim"},manage[6.1][4.1,4.2]{},'
+ 'person[4.2]{"name": "ktlee"}',
+ 'person[4.1]{"name": "kskim"},manage[6.1][4.1,4.2]{},'
+ 'person[4.2]{"name": "ktlee"}',
str(p))

self.assertEquals(["bitnine","kskim","ktlee"],
[v.props["name"] for v in p.vertices])
[v.props["name"] for v in p.vertices])
self.assertEquals(["employee","manage"],
[e.label for e in p.edges])
[e.label for e in p.edges])
self.assertEquals(2, p.len())

class PropertyTest(BasicTest):
def setUp(self):
BasicTest.setUp(self)
self.cur.execute("create vlabel company")
self.cur.execute("create vlabel person")
self.cur.execute("create elabel employee")
self.cur.execute("create (:company {'name':'bitnine'})"
+ "-[:employee {'no':1}]"
+ "->(:person {'name':'jsyang', 'age':20, 'height':178.5, 'married':false})")
self.cur.execute("match (:company {'name':'bitnine'})"
+ "create (c)-[:employee {'no':2}]"
+ "->(:person '{\"name\":\"ktlee\", \"hobbies\":[\"reading\", \"climbing\"], \"age\":null}')")
self.cur.execute("create (:person {'name': 'Emil', 'from': 'Sweden', 'klout': 99})")
self.cur.execute("CREATE VLABEL company")
self.cur.execute("CREATE VLABEL person")
self.cur.execute("CREATE ELABEL employee")
self.cur.execute("CREATE (:company {name:'bitnine'})"
+ "-[:employee {no:1}]"
+ "->(:person {name:'jsyang', age:20, height:178.5, married:false})")
self.cur.execute("MATCH (:company {name:'bitnine'})"
+ "CREATE (c)-[:employee {no:2}]"
+ "->(:person {\"name\":\'ktlee\', \"hobbies\":[\'reading\', \'climbing\'], \"age\":null})")
self.cur.execute("CREATE (:person {name: 'Emil', from: 'Sweden', klout: 99})")
def test_Property(self):
self.cur.execute("match (n)-[:employee {'no':1}]->(m) RETURN n, m")
self.cur.execute("MATCH (n)-[:employee {no:1}]->(m) RETURN n, m")
row = self.cur.fetchone()
self.assertEquals(20, row[1].props["age"])
self.assertEquals(178.5, row[1].props["height"])
self.assertFalse(row[1].props["married"])
self.cur.execute("match (n)-[:employee {'no':2}]->(m) RETURN n, m")
self.cur.execute("MATCH (n)-[:employee {no:2}]->(m) RETURN n, m")
row = self.cur.fetchone()
self.assertEquals("climbing", row[1].props["hobbies"][1])
self.cur.execute("match (n)-[{'no':2}]->(m) return m.hobbies::jsonb as hobbies")
self.cur.execute("MATCH (n)-[{no:2}]->(m) return m.hobbies as hobbies")
hobbies = self.cur.fetchone()[0]
self.assertEquals("reading", hobbies[0])
self.cur.execute("match (ee:person) where ee.klout::int = 99 "
+ "return ee.name, to_jsonb(ee.name)")
self.cur.execute("MATCH (ee:person) WHERE ee.klout = 99 "
+ "RETURN ee.name, to_jsonb(ee.name)")
row = self.cur.fetchone()
self.assertIsInstance(row[0], str)
self.assertIsInstance(row[0], basestring) # if "str", error is occurred instead of "basestring"
self.assertEquals("Emil", row[0])
self.assertIsInstance(row[1], unicode)
self.assertEquals('Emil', row[1])

class ReturnTest(BasicTest):
def test_Return(self):
self.cur.execute("RETURN 'be' || ' happy!', 1+1")
self.cur.execute("RETURN 'be happy!', 1+1")
row = self.cur.fetchone()
self.assertEquals("be happy!", row[0])
self.assertEquals(2, row[1])
self.cur.execute("RETURN %s", (Json({'name': 'Emil'}),))
row = self.cur.fetchone()[0]
#self.assertEquals("\"Emil\"", row["name"])

class WhereTest(BasicTest):
def setUp(self):
BasicTest.setUp(self)
self.cur.execute("create vlabel person")
self.cur.execute("create (:person { 'name': 'Emil', 'from': 'Sweden', 'klout': 99})")
self.cur.execute("CREATE VLABEL person")
self.cur.execute("CREATE (:person { name: 'Emil', from: 'Sweden', klout: 99})")
def test_Where(self):
self.cur.execute("match (ee:person) where ee.name = 'Emil' return ee")
self.cur.execute("MATCH (ee:person) WHERE ee.name = 'Emil' RETURN ee")
row = self.cur.fetchone()[0]
self.assertEquals(99, row.props["klout"])
#self.cur.execute("match (ee:person) where ee.klout = to_jsonb(99::int) return ee")
self.cur.execute("match (ee:person) where ee.klout::int = %s return ee", (99,))
self.cur.execute("MATCH (ee:person) WHERE ee.klout = 99 RETURN ee")
self.cur.execute("MATCH (ee:person) WHERE ee.klout = %s RETURN ee", (99,))
row = self.cur.fetchone()[0]
self.assertEquals(99, row.props["klout"])
def test_WhereBind(self):
self.cur.execute("match (ee:person) where ee.from = %s return ee", ('Sweden',))
self.cur.execute("MATCH (ee:person) WHERE ee.from = %s RETURN ee", ('Sweden',))
row = self.cur.fetchone()[0]
self.assertEquals(99, row.props["klout"])
self.cur.execute("match (ee:person {'klout': %s}) return ee.name", (99,))
self.cur.execute("MATCH (ee:person {'klout': %s}) RETURN ee.name", (99,))
row = self.cur.fetchone()[0]
self.assertIsInstance(row, str)
self.assertIsInstance(row, basestring)
self.assertEquals("Emil", row)
def test_WhereBindJson(self):
self.cur.execute("match (ee:person) where ee.name = %s return ee", ("Emil",))
self.cur.execute("MATCH (ee:person) WHERE ee.name = %s RETURN ee", ("Emil",))
row = self.cur.fetchone()[0]
self.assertIsInstance(row, agtype.Vertex)
self.assertEquals("Emil", row.props["name"])
def test_MatchBindStr(self):
self.cur.execute("match (ee:person %s) return ee",
("{\"name\": \"Emil\"}",))
row = self.cur.fetchone()[0]
self.assertEquals(99, row.props["klout"])
def test_MatchBindJson(self):
self.cur.execute("match (ee:person %s) return ee",
(Json({'name': 'Emil'}),))
row = self.cur.fetchone()[0]
self.assertEquals(99, row.props["klout"])

if __name__ == '__main__':
unittest.main()
unittest.main()

0 comments on commit b1db460

Please sign in to comment.