-
Notifications
You must be signed in to change notification settings - Fork 0
/
tests.py
213 lines (192 loc) · 7.73 KB
/
tests.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
import json;
import pprint;
import pogodb;
import dotsi;
VERBOSE = False; # True/False;
pgUrl = json.load(open("tests.py.env.json"))["DATABASE_URL"];
dbful = pogodb.makeConnector(pgUrl, verbose=VERBOSE);
# Test shellConnect:
def test_shellConect ():
db = pogodb.shellConnect(pgUrl, verbose=VERBOSE);
assert db._ranSetup is True;
db.close();
db.reopen();
assert db._ranSetup is False;
db.close();
db.reopen();
assert db._ranSetup is False;
# Test context manager:
def test_contextManager ():
with pogodb.connect(pgUrl) as db:
assert db._ranSetup is True;
with pogodb.connect(pgUrl, skipSetup=True) as db:
assert db._ranSetup is False;
# ----------------------------------------------------------
# Hereon, use only the decorator (@dbful) format. ----------
# ----------------------------------------------------------
# Test decorator's auto-subsequent-skipping:
@dbful
def test_autoSkiping_a (db):
assert db._ranSetup is True; # 1st not skipped.
@dbful
def test_autoSkiping_b (db):
assert db._ranSetup is False; # Subsequent skipped.
@dbful
def test_autoSkiping_c (db):
assert db._ranSetup is False; # Subsequent skipped.
# Clear table:
@dbful
def test_clearing (db):
# Try .dropTable():
try: db.dropTable(); # Implicit `sure=False`.
except ValueError: assert True;
else: assert False;
#
# Try .clearTable();
try: db.clearTable(); # Implicit `sure=False`.
except ValueError: assert True;
else: assert False;
#
# Drop, ensure, assert empty, re-ensure.
db.dropTable(sure=True); # Expliit `sure=True`.
db.ensureTable();
assert db.find({}) == [];
db.ensureTable();
#
# Clear, assert empty:
db.clearTable(sure=True); # Expliit `sure=True`.
assert db.find({}) == [];
############################################################
# Blogging Example:
############################################################
# Sample data: :::::::::::::::::::::::::::::::::::::::::::::
userList = dotsi.fy([
{"_id": "00", "type":"user", "name": "Alice"},
{"_id": "01", "type":"user", "name": "Becci"},
{"_id": "02", "type":"user", "name": "Cathy"},
]);
postList = dotsi.fy([
{"_id": "03", "type":"post", "authorId": "00",
"hits": {"organic": 10, "promoted": 10, "tags": ["x"]},
"title": "Title X .. ", "body": "Body X .."},
{"_id": "04", "type":"post", "authorId": "01",
"hits": {"organic": 20, "promoted": 20, "tags": ["y"]},
"title": "Title Y .. ", "body": "Body Y .."},
{"_id": "05", "type":"post", "authorId": "02",
"hits": {"organic": 30, "promoted": 30, "tags": ["z"]},
"title": "Title Z .. ", "body": "Body Z .."},
{"_id": "06", "type":"post", "authorId": "00",
"hits": {"organic": 40, "promoted": 40, "tags": ["a"]},
"title": "Title A .. ", "body": "Body A .."},
]);
commentList = dotsi.fy([
{"_id": "07", "type":"comment", "authorId": "02",
"postId": "03", "text": "Comment P .."},
{"_id": "08", "type":"comment", "authorId": "01",
"postId": "04", "text": "Comment Q .."},
{"_id": "09", "type":"comment", "authorId": "00",
"postId": "05", "text": "Comment R .."},
]);
# Helper: `sorted` wrapper for sorting documents by `._id`.
sortid = lambda dl: sorted(dl, key=lambda d: d._id);
# Insert data: :::::::::::::::::::::::::::::::::::::::::::::
@dbful
def test_inserting__blogging_example (db):
# Insert users:
db.insertOne(userList[0]);
assert db.findOne({})._id == "00";
db.insertMany(userList[1:]);
assert len(db.find({})) == len(userList);
#
# Insert posts:
db.insertMany(postList);
assert db.findOne("03")._id == "03";
assert len(db.find({})) == len(userList + postList);
#
# Insert comments:
db.insertMany(commentList);
assert db.findOne("09")._id == "09";
assert len(db.find({})) == len(userList + postList + commentList);
#pprint.pprint(db.find({}));
# Finding data: ::::::::::::::::::::::::::::::::::::::::::::
@dbful
def test_finding__blogging_example (db):
# .findOne():
assert db.findOne("00") == userList[0];
assert db.findOne("_idNotFound") is None;
assert db.findOne({"name": "Alice"}) == userList[0];
assert db.findOne({"name": "NameNotFound"}) is None;
# .find():
assert sortid(db.find({"type": "user"})) == userList;
alicePosts = db.find({"type": "post", "authorId": "00"});
assert sortid(alicePosts) == [postList[0], postList[-1]]
assert sortid(db.find({})) == userList + postList + commentList;
# TODO: .findSql(), or .find(.., whereEtc, argsEtc)
# Updating data: :::::::::::::::::::::::::::::::::::::::::::
@dbful
def test_updating_blogging_example (db):
# .replaceOne():
post = postList[0];
post.body += "-- EDITED"; # In-memory update
assert not db.findOne(post._id).body.endswith("-- EDITED");
db.replaceOne(postList[0]); # Propagate to db.
assert db.findOne(post._id).body.endswith("-- EDITED");
# .incr():
post = postList[0];
assert post.hits.organic == 10; # Before
db.incr({"_id": post._id}, ["hits", "organic"], 1); # At db, w/ list keyPath.
r = db.findOne(post._id);
assert db.findOne(post._id).hits.organic == 11;
freshPost = db.findOne(post._id);
assert freshPost.hits.organic == 11;
assert post.hits.organic == 10; # Stale
postList[0] = freshPost; # In-memory update
assert db.findOne(freshPost._id) == postList[0];
# .decr():
post = postList[0];
assert post.hits.promoted == 10; # Before
db.decr({"_id": post._id}, "hits.promoted", 1); # At db, w/ dotted-str keyPath.
assert db.findOne(post._id).hits.promoted == 9;
freshPost = db.findOne(post._id);
assert freshPost.hits.promoted == 9;
assert post.hits.promoted == 10; # Stale
postList[0] = freshPost; # In-memory update
assert db.findOne(freshPost._id) == postList[0];
# .push():
post = postList[0];
assert post.hits.tags == ["x"]; # Before
db.push({"_id": post._id}, ["hits", "tags"], "p"); # At db, w/ list keyPath.
assert db.findOne(post._id).hits.tags == ["x", "p"];
db.push({"_id": post._id}, "hits.tags", "q"); # At db, w/ dotted-str keyPath.
assert db.findOne(post._id).hits.tags == ["x", "p", "q"];
freshPost = db.findOne(post._id);
assert freshPost.hits.tags == "x p q".split();
assert post.hits.tags == ["x"]; # Stale
postList[0] = freshPost; # In-memory update.
# Deleting data: :::::::::::::::::::::::::::::::::::::::::::
@dbful
def test_deleting__blogging_example (db):
for comment in commentList:
db.deleteOne(comment._id);
#r = db.find(comment._id); print("r = ", r);
assert db.findOne(comment._id) is None;
assert sortid(db.find({})) == userList + postList;
for doc in userList + postList:
db.deleteOne(doc._id);
assert db.findOne(doc._id) is None;
assert db.find({}) == [];
############################################################
# Run All Tests: ###########################################
############################################################
if __name__ == "__main__":
for (name, val) in dict(**locals()).items():
if name.startswith("test_") and callable(val):
print("\nRunning %s() ..." % name)
val();
print("Passed.")
if VERBOSE:
print("\n" + ("=" * 80) + "\n");
print("\nGreat! All tests passed.\n");
else:
getdb = lambda: pogodb.shellConnect(pgUrl);
# End ######################################################