Skip to content

Commit 748914f

Browse files
committed
move to new tests
1 parent ec0af58 commit 748914f

File tree

2 files changed

+300
-21
lines changed

2 files changed

+300
-21
lines changed

tests/schema_simple.py

Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
"""
2+
A simple, abstract schema to test relational algebra
3+
"""
4+
import random
5+
import datajoint as dj
6+
import itertools
7+
import hashlib
8+
import uuid
9+
import faker
10+
from . import PREFIX, CONN_INFO_ROOT
11+
import numpy as np
12+
from datetime import date, timedelta
13+
14+
schema = dj.Schema(
15+
PREFIX + "_relational", locals(), connection=dj.conn(**CONN_INFO_ROOT)
16+
)
17+
18+
19+
@schema
20+
class IJ(dj.Lookup):
21+
definition = """ # tests restrictions
22+
i : int
23+
j : int
24+
"""
25+
contents = list(dict(i=i, j=j + 2) for i in range(3) for j in range(3))
26+
27+
28+
@schema
29+
class JI(dj.Lookup):
30+
definition = """ # tests restrictions by relations when attributes are reordered
31+
j : int
32+
i : int
33+
"""
34+
contents = list(dict(i=i + 1, j=j) for i in range(3) for j in range(3))
35+
36+
37+
@schema
38+
class A(dj.Lookup):
39+
definition = """
40+
id_a :int
41+
---
42+
cond_in_a :tinyint
43+
"""
44+
contents = [(i, i % 4 > i % 3) for i in range(10)]
45+
46+
47+
@schema
48+
class B(dj.Computed):
49+
definition = """
50+
-> A
51+
id_b :int
52+
---
53+
mu :float # mean value
54+
sigma :float # standard deviation
55+
n :smallint # number samples
56+
"""
57+
58+
class C(dj.Part):
59+
definition = """
60+
-> B
61+
id_c :int
62+
---
63+
value :float # normally distributed variables according to parameters in B
64+
"""
65+
66+
def make(self, key):
67+
random.seed(str(key))
68+
sub = B.C()
69+
for i in range(4):
70+
key["id_b"] = i
71+
mu = random.normalvariate(0, 10)
72+
sigma = random.lognormvariate(0, 4)
73+
n = random.randint(0, 10)
74+
self.insert1(dict(key, mu=mu, sigma=sigma, n=n))
75+
sub.insert(
76+
dict(key, id_c=j, value=random.normalvariate(mu, sigma))
77+
for j in range(n)
78+
)
79+
80+
81+
@schema
82+
class L(dj.Lookup):
83+
definition = """
84+
id_l: int
85+
---
86+
cond_in_l :tinyint
87+
"""
88+
contents = [(i, i % 3 >= i % 5) for i in range(30)]
89+
90+
91+
@schema
92+
class D(dj.Computed):
93+
definition = """
94+
-> A
95+
id_d :int
96+
---
97+
-> L
98+
"""
99+
100+
def _make_tuples(self, key):
101+
# make reference to a random tuple from L
102+
random.seed(str(key))
103+
lookup = list(L().fetch("KEY"))
104+
self.insert(dict(key, id_d=i, **random.choice(lookup)) for i in range(4))
105+
106+
107+
@schema
108+
class E(dj.Computed):
109+
definition = """
110+
-> B
111+
-> D
112+
---
113+
-> L
114+
"""
115+
116+
class F(dj.Part):
117+
definition = """
118+
-> E
119+
id_f :int
120+
---
121+
-> B.C
122+
"""
123+
124+
def make(self, key):
125+
random.seed(str(key))
126+
self.insert1(dict(key, **random.choice(list(L().fetch("KEY")))))
127+
sub = E.F()
128+
references = list((B.C() & key).fetch("KEY"))
129+
random.shuffle(references)
130+
sub.insert(
131+
dict(key, id_f=i, **ref)
132+
for i, ref in enumerate(references)
133+
if random.getrandbits(1)
134+
)
135+
136+
137+
@schema
138+
class F(dj.Manual):
139+
definition = """
140+
id: int
141+
----
142+
date=null: date
143+
"""
144+
145+
146+
@schema
147+
class DataA(dj.Lookup):
148+
definition = """
149+
idx : int
150+
---
151+
a : int
152+
"""
153+
contents = list(zip(range(5), range(5)))
154+
155+
156+
@schema
157+
class DataB(dj.Lookup):
158+
definition = """
159+
idx : int
160+
---
161+
a : int
162+
"""
163+
contents = list(zip(range(5), range(5, 10)))
164+
165+
166+
@schema
167+
class Website(dj.Lookup):
168+
definition = """
169+
url_hash : uuid
170+
---
171+
url : varchar(1000)
172+
"""
173+
174+
def insert1_url(self, url):
175+
hashed = hashlib.sha1()
176+
hashed.update(url.encode())
177+
url_hash = uuid.UUID(bytes=hashed.digest()[:16])
178+
self.insert1(dict(url=url, url_hash=url_hash), skip_duplicates=True)
179+
return url_hash
180+
181+
182+
@schema
183+
class Profile(dj.Manual):
184+
definition = """
185+
ssn : char(11)
186+
---
187+
name : varchar(70)
188+
residence : varchar(255)
189+
blood_group : enum('A+', 'A-', 'AB+', 'AB-', 'B+', 'B-', 'O+', 'O-')
190+
username : varchar(120)
191+
birthdate : date
192+
job : varchar(120)
193+
sex : enum('M', 'F')
194+
"""
195+
196+
class Website(dj.Part):
197+
definition = """
198+
-> master
199+
-> Website
200+
"""
201+
202+
def populate_random(self, n=10):
203+
fake = faker.Faker()
204+
faker.Faker.seed(0) # make test deterministic
205+
for _ in range(n):
206+
profile = fake.profile()
207+
with self.connection.transaction:
208+
self.insert1(profile, ignore_extra_fields=True)
209+
for url in profile["website"]:
210+
self.Website().insert1(
211+
dict(ssn=profile["ssn"], url_hash=Website().insert1_url(url))
212+
)
213+
214+
215+
@schema
216+
class TTestUpdate(dj.Lookup):
217+
definition = """
218+
primary_key : int
219+
---
220+
string_attr : varchar(255)
221+
num_attr=null : float
222+
blob_attr : longblob
223+
"""
224+
225+
contents = [
226+
(0, "my_string", 0.0, np.random.randn(10, 2)),
227+
(1, "my_other_string", 1.0, np.random.randn(20, 1)),
228+
]
229+
230+
231+
@schema
232+
class ArgmaxTest(dj.Lookup):
233+
definition = """
234+
primary_key : int
235+
---
236+
secondary_key : char(2)
237+
val : float
238+
"""
239+
240+
n = 10
241+
242+
@property
243+
def contents(self):
244+
n = self.n
245+
yield from zip(
246+
range(n**2),
247+
itertools.chain(*itertools.repeat(tuple(map(chr, range(100, 100 + n))), n)),
248+
np.random.rand(n**2),
249+
)
250+
251+
252+
@schema
253+
class ReservedWord(dj.Manual):
254+
definition = """
255+
# Test of SQL reserved words
256+
key : int
257+
---
258+
in : varchar(25)
259+
from : varchar(25)
260+
int : int
261+
select : varchar(25)
262+
"""
263+
264+
265+
@schema
266+
class OutfitLaunch(dj.Lookup):
267+
definition = """
268+
# Monthly released designer outfits
269+
release_id: int
270+
---
271+
day: date
272+
"""
273+
contents = [(0, date.today() - timedelta(days=15))]
274+
275+
class OutfitPiece(dj.Part, dj.Lookup):
276+
definition = """
277+
# Outfit piece associated with outfit
278+
-> OutfitLaunch
279+
piece: varchar(20)
280+
"""
281+
contents = [(0, "jeans"), (0, "sneakers"), (0, "polo")]

tests_old/test_cli.py renamed to tests/test_cli.py

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import subprocess
77
import pytest
88
import datajoint as dj
9-
from .schema_simple import *
9+
from .schema_simple import schema
1010

1111

1212
def test_cli_version(capsys):
@@ -93,40 +93,38 @@ def test_cli_args():
9393

9494
def test_cli_schemas():
9595
process = subprocess.Popen(
96-
["dj", "-s", "djtest_test1:test_schema1", "djtest_relational:test_schema2"],
96+
["dj", "-s", "djtest_relational:test_schema"],
9797
stdin=subprocess.PIPE,
9898
stdout=subprocess.PIPE,
9999
stderr=subprocess.PIPE,
100100
text=True,
101101
)
102102

103-
process.stdin.write("test_schema1.__dict__['__name__']\n")
104-
process.stdin.write("test_schema1.__dict__['schema']\n")
105-
process.stdin.write("test_schema1.TTest.fetch(as_dict=True)\n")
103+
process.stdin.write("test_schema.__dict__['__name__']\n")
104+
process.stdin.write("test_schema.__dict__['schema']\n")
105+
process.stdin.write("test_schema.IJ.fetch(as_dict=True)\n")
106106
process.stdin.flush()
107107

108108
stdout, stderr = process.communicate()
109109
fetch_res = [
110-
{"key": 0, "value": 0},
111-
{"key": 1, "value": 2},
112-
{"key": 2, "value": 4},
113-
{"key": 3, "value": 6},
114-
{"key": 4, "value": 8},
115-
{"key": 5, "value": 10},
116-
{"key": 6, "value": 12},
117-
{"key": 7, "value": 14},
118-
{"key": 8, "value": 16},
119-
{"key": 9, "value": 18},
110+
{"i": 0, "j": 2},
111+
{"i": 0, "j": 3},
112+
{"i": 0, "j": 4},
113+
{"i": 1, "j": 2},
114+
{"i": 1, "j": 3},
115+
{"i": 1, "j": 4},
116+
{"i": 2, "j": 2},
117+
{"i": 2, "j": 3},
118+
{"i": 2, "j": 4},
120119
]
121120
assert (
122121
"\
123122
dj repl\n\n\
124123
\
125124
schema modules:\n\n\
126-
- test_schema1\n\
127-
- test_schema2"
128-
== stderr[159:218]
125+
- test_schema"
126+
== stderr[159:200]
129127
)
130-
assert "'test_schema1'" == stdout[4:18]
131-
assert "Schema `djtest_test1`" == stdout[23:44]
132-
assert fetch_res == json.loads(stdout[50:295].replace("'", '"'))
128+
assert "'test_schema'" == stdout[4:17]
129+
assert "Schema `djtest_relational`" == stdout[22:48]
130+
assert fetch_res == json.loads(stdout[54:216].replace("'", '"'))

0 commit comments

Comments
 (0)