Skip to content

Commit a9ab20d

Browse files
committed
introduce test code for git import phase
- test a few scenarios to exhibit interesting corner cases - utilities to perform git operations - utilities to query and introspect the codeq db
1 parent ed39dd2 commit a9ab20d

File tree

3 files changed

+662
-4
lines changed

3 files changed

+662
-4
lines changed

test/datomic/codeq/core_test.clj

Lines changed: 387 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,390 @@
11
(ns datomic.codeq.core-test
22
(:use clojure.test
3-
datomic.codeq.core))
3+
datomic.codeq.core
4+
datomic.codeq.util
5+
datomic.codeq.test-datomic-util
6+
datomic.codeq.test-git-util)
7+
(:require [datomic.codeq.git :as git]
8+
[datomic.api :as d]
9+
[clojure.java.io :as io]))
410

5-
(deftest a-test
6-
(testing "FIXME, I fail."
7-
(is (= 1 1))))
11+
12+
(def ^:dynamic *conn*
13+
"A dynamic var to hold the Datomic connection."
14+
nil)
15+
16+
(def ^:dynamic *git*
17+
"A dynamic var to hold the GitPorcelain API."
18+
nil)
19+
20+
(def ^:dynamic *repo*
21+
"A dynamic var to hold the Git repository."
22+
nil)
23+
24+
(def ^:dynamic *repo-dir*
25+
"A dynamic var to hold a File object to the repository directory."
26+
nil)
27+
28+
29+
(defn datomic-fixture
30+
[f]
31+
(let [uri (str "datomic:mem://" (d/squuid))]
32+
(d/create-database uri)
33+
(let [c (d/connect uri)]
34+
@(d/transact c schema)
35+
(binding [*conn* c]
36+
(f)))
37+
(d/delete-database uri)))
38+
39+
(defn git-fixture
40+
[f]
41+
(let [d (create-temp-dir)
42+
[g r] (init-repo d)]
43+
(binding [*git* g
44+
*repo* r
45+
*repo-dir* d]
46+
(f))))
47+
48+
(use-fixtures :each (compose-fixtures datomic-fixture git-fixture))
49+
50+
51+
(defmacro is-only
52+
[x coll]
53+
`(do
54+
(is (= 1 (count ~coll)))
55+
(is (= ~x (first ~coll)))))
56+
57+
(defmacro is-coll
58+
[coll-expected coll-found]
59+
`(let [c# ~coll-found]
60+
(do
61+
(is (= (count ~coll-expected)
62+
(count c#)))
63+
(are [e#]
64+
(some #(= e# %) c#)
65+
~@coll-expected))))
66+
67+
68+
(deftest test-extract-and-import-commit
69+
(testing "creating, extracting, and importing a commit:"
70+
(let [commit (do
71+
(spit (io/file *repo-dir* "a.txt") "contents of a\n")
72+
(add-file-to-index *git* "a.txt")
73+
(git/extract-commit-info
74+
(git-commit-all *git* "added a.txt\n")))]
75+
76+
(testing "extract the map of commit information"
77+
78+
(:author commit)))
79+
80+
(:committer commit)))
81+
(is (empty? (:parents commit)))
82+
(is (= "added a.txt\n"
83+
(:msg commit))))
84+
85+
(testing "importing the commit"
86+
(let [repoid (transact-repo-uri *conn* "test/.git")
87+
{db :db-after}
88+
@(d/transact *conn*
89+
(commit-tx-data (d/db *conn*) *repo* repoid "test" commit))
90+
root-tree-node
91+
(get-root-tree-node db (:sha commit))
92+
children
93+
(get-tree-node-children root-tree-node)]
94+
(is (= 1 (count children)))
95+
(let [node (first children)]
96+
(is (= "a.txt" (node-name node)))
97+
(is (= '("test/a.txt") (node-paths node)))))))))
98+
99+
100+
(deftest test-file-append
101+
(testing "a linear history of two commits, where a file is updated:"
102+
(let [f (io/file *repo-dir* "a.txt")
103+
c1 (do
104+
(spit f "line 1\n")
105+
(add-file-to-index *git* "a.txt")
106+
(git/extract-commit-info
107+
(git-commit-all *git* "added a.txt")))
108+
c2 (do
109+
(spit f "line 2\n" :append true)
110+
(git/extract-commit-info
111+
(git-commit-all *git* "updated a.txt")))
112+
repoid (transact-repo-uri *conn* "test/.git")
113+
_ (doseq [c [c1 c2]]
114+
@(d/transact *conn*
115+
(commit-tx-data (d/db *conn*) *repo* repoid "test" c)))
116+
db (d/db *conn*)]
117+
118+
(testing "examining first commit"
119+
(is-only "a.txt"
120+
(find-commit-filenames db (:sha c1)))
121+
(is-only "test/a.txt"
122+
(find-commit-filepaths db (:sha c1)))
123+
;;hardcoded sha corresponds to "line 1\n"
124+
(is-only (:sha c1)
125+
(find-blob-commits db "89b24ecec50c07aef0d6640a2a9f6dc354a33125")))
126+
127+
(testing "examining second commit"
128+
(is-only "a.txt"
129+
(find-commit-filenames db (:sha c2)))
130+
(is-only "test/a.txt"
131+
(find-commit-filepaths db (:sha c2)))
132+
;;hardcoded sha corresponds to "line 1\nline 2\n"
133+
(is-only (:sha c2)
134+
(find-blob-commits db "7bba8c8e64b598d317cdf1bb8a63278f9fc241b1")))
135+
136+
(testing "finding commits by file name and path"
137+
(is-coll [(:sha c1) (:sha c2)]
138+
(find-filename-commits db "a.txt"))
139+
(is-coll [(:sha c1) (:sha c2)]
140+
(find-filepath-commits db "test/a.txt"))))))
141+
142+
143+
(deftest test-rename-file
144+
(testing "a linear history of two commits, where a file is renamed:"
145+
(let [f1 (io/file *repo-dir* "a.txt")
146+
c1 (do
147+
(spit f1 "line 1\n")
148+
(add-file-to-index *git* "a.txt")
149+
(git/extract-commit-info
150+
(git-commit-all *git* "added a.txt")))
151+
f2 (io/file *repo-dir* "b.txt")
152+
c2 (do
153+
(io/copy f1 f2)
154+
(io/delete-file f1)
155+
(add-file-to-index *git* "b.txt")
156+
(git/extract-commit-info
157+
(git-commit-all *git* "renamed a.txt to b.txt")))
158+
repoid (transact-repo-uri *conn* "test/.git")
159+
_ (doseq [c [c1 c2]]
160+
@(d/transact *conn*
161+
(commit-tx-data (d/db *conn*) *repo* repoid "test" c)))
162+
db (d/db *conn*)]
163+
164+
(testing "examining first commit"
165+
(is-only "a.txt"
166+
(find-commit-filenames db (:sha c1))))
167+
168+
(testing "examining second commit"
169+
(is-only "b.txt"
170+
(find-commit-filenames db (:sha c2))))
171+
172+
(testing "finding commits by file contents"
173+
(is-coll [(:sha c1) (:sha c2)]
174+
(find-blob-commits db "89b24ecec50c07aef0d6640a2a9f6dc354a33125"))))))
175+
176+
177+
(deftest test-merge-commit
178+
(testing "a branch and recursive merge in one file:"
179+
(let [f (io/file *repo-dir* "a.txt")
180+
c1 (do
181+
(spit f "line 1\n")
182+
(add-file-to-index *git* "a.txt")
183+
(git/extract-commit-info
184+
(git-commit-all *git* "added a.txt\n")))
185+
c2 (do
186+
(checkout-branch *git* "branch" true)
187+
(spit f "line 0\nline 1\n")
188+
(git/extract-commit-info
189+
(git-commit-all *git* "prepended a line to a.txt\n")))
190+
c3 (do
191+
(checkout-branch *git* "master")
192+
(spit f "line 1\nline 2\n")
193+
(git/extract-commit-info
194+
(git-commit-all *git* "appended a line to a.txt\n")))
195+
c4 (do
196+
(merge-branch-no-commit *git* "branch")
197+
(git/extract-commit-info
198+
(git-commit-all *git* (str "Merged branch 'branch'\n"))))
199+
repoid (transact-repo-uri *conn* "test/.git")
200+
_ (doseq [c [c1 c2 c3 c4]]
201+
@(d/transact *conn*
202+
(commit-tx-data (d/db *conn*) *repo* repoid "test" c)))
203+
db (d/db *conn*)]
204+
205+
(testing "examining initial commit on master"
206+
(is-only (:sha c1)
207+
(find-blob-commits db "89b24ecec50c07aef0d6640a2a9f6dc354a33125")))
208+
209+
(testing "examining second commit on branch"
210+
(is-only (:sha c1)
211+
(:parents c2))
212+
(is-only (:sha c2)
213+
(find-blob-commits db "2bbfc232c2e71c62004c15806843df3ffc3688d0")))
214+
215+
(testing "examining third commit on master"
216+
(is-only (:sha c1)
217+
(:parents c3))
218+
(is-only (:sha c3)
219+
(find-blob-commits db "7bba8c8e64b598d317cdf1bb8a63278f9fc241b1")))
220+
221+
(testing "examining merge commit"
222+
(is-coll [(:sha c2) (:sha c3)]
223+
(:parents c4))
224+
(is-only (:sha c4)
225+
(find-blob-commits db "73fc08f0c8b6a87eaad8f5991df3a150b501462d")))
226+
227+
(testing "finding commits by file name and path"
228+
(is-coll [(:sha c1) (:sha c2) (:sha c3) (:sha c4)]
229+
(find-filename-commits db "a.txt"))
230+
(is-coll [(:sha c1) (:sha c2) (:sha c3) (:sha c4)]
231+
(find-filepath-commits db "test/a.txt"))))))
232+
233+
234+
(deftest test-mix-of-file-ops
235+
(testing "a linear history of five commits, involving add, update, delete, revert:"
236+
(let [f (io/file *repo-dir* "a.txt")
237+
;;start with initial commit of two files a.txt and b.txt
238+
c1 (do
239+
(spit f "line 1\n")
240+
(add-file-to-index *git* "a.txt")
241+
(spit (io/file *repo-dir* "b.txt")
242+
"contents of b.txt\n")
243+
(add-file-to-index *git* "b.txt")
244+
(git/extract-commit-info
245+
(git-commit-all *git* "added a.txt and b.txt\n")))
246+
;;then update a.txt by appending a line, and adding a new
247+
;;file c.txt
248+
c2 (do
249+
(spit f "line 2\n" :append true)
250+
(spit (io/file *repo-dir* "c.txt")
251+
"contents of c.txt\n")
252+
(add-file-to-index *git* "c.txt")
253+
(git/extract-commit-info
254+
(git-commit-all *git* "updated a.txt and added c.txt\n")))
255+
;;then add a new file d.txt
256+
g (io/file *repo-dir* "d.txt")
257+
c3 (do
258+
(spit g "contents of d.txt\n")
259+
(add-file-to-index *git* "d.txt")
260+
(git/extract-commit-info
261+
(git-commit-all *git* "added d.txt\n")))
262+
;;then only to delete that file -- this is equivalent to
263+
;;reverting commit c3
264+
c4 (do
265+
(io/delete-file g)
266+
(git/extract-commit-info
267+
(git-commit-all *git* "deleted d.txt\n")))
268+
;;finally, revert file a.txt to how it was after the
269+
;;first commit
270+
c5 (do
271+
(spit f "line 1\n")
272+
(git/extract-commit-info
273+
(git-commit-all *git* "revert a.txt\n")))
274+
repoid (transact-repo-uri *conn* "test/.git")
275+
_ (doseq [c [c1 c2 c3 c4 c5]]
276+
@(d/transact *conn*
277+
(commit-tx-data (d/db *conn*) *repo* repoid "test" c)))
278+
db (d/db *conn*)]
279+
280+
(testing "examining first commit"
281+
(is-coll ["a.txt" "b.txt"]
282+
(find-commit-filenames db (:sha c1))))
283+
284+
(testing "finding commits with blobs containing 'line 1\\n'"
285+
;;TODO might have expected c5 here?
286+
(is-only (:sha c1)
287+
(find-blob-commits db "89b24ecec50c07aef0d6640a2a9f6dc354a33125")))
288+
289+
(testing "examining second commit"
290+
(is-coll ["a.txt" "c.txt"]
291+
(find-commit-filenames db (:sha c2))))
292+
293+
(testing "finding commits with blobs containing 'line 1\\nline 2\\n'"
294+
;;TODO this is because c4 has the same root tree as c2 as
295+
;;it reverted c3
296+
(is-coll [(:sha c2) (:sha c4)]
297+
(find-blob-commits db "7bba8c8e64b598d317cdf1bb8a63278f9fc241b1")))
298+
299+
(testing "examining third commit"
300+
(is-only "d.txt"
301+
(find-commit-filenames db (:sha c3))))
302+
303+
(testing "examining fourth commit"
304+
;;TODO as said above, c2 and c4 share a root tree
305+
(is-coll ["a.txt" "c.txt"]
306+
(find-commit-filenames db (:sha c4))))
307+
308+
(testing "examining fifth commit"
309+
;;TODO maybe a tad surprising?
310+
(is (empty? (find-commit-filenames db (:sha c5)))))
311+
312+
(testing "find commits"
313+
;;TODO might have expected c5 here?
314+
(is-coll [(:sha c1) (:sha c2) (:sha c4)]
315+
(find-filename-commits db "a.txt"))))))
316+
317+
318+
(deftest test-path-trickery
319+
(testing "a linear history of four commits, to examine file path behavior:"
320+
(let [;;start with an initial commit of file a.txt in
321+
;;subdirectory d1
322+
dir1 (doto (io/file *repo-dir* "d1") (.mkdir))
323+
f1 (io/file dir1 "a.txt")
324+
c1 (do
325+
(spit f1 "line 1\n")
326+
(add-file-to-index *git* "d1/a.txt")
327+
(git/extract-commit-info
328+
(git-commit-all *git* "added d1/a.txt\n")))
329+
;;then add a file with the same name but distinct
330+
;;contents into subdirectory d2
331+
dir2 (doto (io/file *repo-dir* "d2") (.mkdir))
332+
f2 (io/file dir2 "a.txt")
333+
c2 (do
334+
(spit f2 "line 2\n")
335+
(add-file-to-index *git* "d2/a.txt")
336+
(git/extract-commit-info
337+
(git-commit-all *git* "added d2/a.txt\n")))
338+
;;then add a file with the same name and contents as the
339+
;;previous commit but in subdirectory d3
340+
dir3 (doto (io/file *repo-dir* "d3") (.mkdir))
341+
f3 (io/file dir3 "a.txt")
342+
c3 (do
343+
(spit f3 "line 2\n")
344+
(add-file-to-index *git* "d3/a.txt")
345+
(git/extract-commit-info
346+
(git-commit-all *git* "added d3/a.txt\n")))
347+
;;the repository is now is a state where there are three
348+
;;files, all of which have the same name, two of which
349+
;;have the same content, and all are in distinct
350+
;;subdirectories
351+
;;finally overwrite the contents of d2/a.txt with the
352+
;;contents of d1/a.txt
353+
c4 (do
354+
(spit f2 "line 1\n")
355+
(git/extract-commit-info
356+
(git-commit-all *git* "copied d1/a.txt to d2/a.txt\n")))
357+
;;before, two files contained 'line 2\\n'
358+
;;now, two files contain 'line 1\\n'
359+
repoid (transact-repo-uri *conn* "test/.git")
360+
_ (doseq [c [c1 c2 c3 c4]]
361+
@(d/transact *conn*
362+
(commit-tx-data (d/db *conn*) *repo* repoid "test" c)))
363+
db (d/db *conn*)]
364+
365+
(testing "find commits with file a.txt"
366+
(is-coll [(:sha c1) (:sha c2) (:sha c3) (:sha c4)]
367+
(find-filename-commits db "a.txt")))
368+
369+
(testing "find commits with path d1/a.txt"
370+
;;TODO might have expected just c1?
371+
(is-coll [(:sha c1) (:sha c4)]
372+
(find-filepath-commits db "test/d1/a.txt")))
373+
374+
(testing "find commits with path d2/a.txt"
375+
;;TODO might have expected just c2 and c4?
376+
(is-coll [(:sha c1) (:sha c2) (:sha c3) (:sha c4)]
377+
(find-filepath-commits db "test/d2/a.txt")))
378+
379+
(testing "find commits with path d3/a.txt"
380+
;;TODO might have expected just c3?
381+
(is-coll [(:sha c2) (:sha c3)]
382+
(find-filepath-commits db "test/d3/a.txt")))
383+
384+
(testing "find commits for blob with contents 'line 1\\n'"
385+
(is-coll [(:sha c1) (:sha c4)]
386+
(find-blob-commits db "89b24ecec50c07aef0d6640a2a9f6dc354a33125")))
387+
388+
(testing "find commits for blob with contents 'line 2\\n'"
389+
(is-coll [(:sha c2) (:sha c3)]
390+
(find-blob-commits db "b7e242c00cdad96cf88a626557eba4deab43b52f"))))))

0 commit comments

Comments
 (0)