Skip to content

Commit 99c4dc1

Browse files
authored
feat(colleagues) - send colleagues info to server (APP-174) (#162)
1 parent c1b6105 commit 99c4dc1

File tree

5 files changed

+188
-71
lines changed

5 files changed

+188
-71
lines changed

src/main/kotlin/app/FactCodes.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,6 @@ object FactCodes {
2626
val INDENTATION = 14
2727
val INDENTATION_TABS = 0
2828
val INDENTATION_SPACES = 1
29+
30+
val COLLEAGUES = 15
2931
}

src/main/kotlin/app/hashers/CodeLongevity.kt

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ class CodeLine(val repo: Repository,
131131
/**
132132
* Detects colleagues and their 'work vicinity' from commits.
133133
*/
134-
class Colleagues {
134+
class Colleagues(private val serverRepo: Repo) {
135135
// A map of <colleague_email1, colleague_email2> pairs to pairs of
136136
// <month, time>, which indicates to a minimum time in ms between all line
137137
// changes for these two colleagues in a given month (yyyy-mm).
@@ -145,9 +145,7 @@ class Colleagues {
145145
if (editorEmail == null || authorEmail == editorEmail) {
146146
return
147147
}
148-
val emails =
149-
if (editorEmail < authorEmail) Pair(editorEmail, authorEmail)
150-
else Pair(authorEmail, editorEmail)
148+
val emails = Pair(authorEmail, editorEmail)
151149

152150
val dates = map.getOrPut(emails, { hashMapOf() })
153151
val month = SimpleDateFormat("yyyy-MM").format(line.editDate)
@@ -159,15 +157,36 @@ class Colleagues {
159157
}
160158
}
161159

162-
fun updateStats() {
163-
// TODO(alex): report the stats to the server
164-
if (Logger.isDebug) {
165-
map.forEach( { (email1, email2), dates ->
166-
Logger.debug { "<$email1> <$email2>" }
167-
dates.forEach { month, vicinity ->
168-
Logger.debug { " $month: $vicinity ms" }
169-
}
170-
} )
160+
fun calculateAndSendFacts(api: Api) {
161+
// Expose colleagues iff colleague1 edited colleague2 code and
162+
// colleague2 edited colleauge1 code.
163+
val auxHash = hashSetOf<Pair<String, String>>()
164+
for ((pair, dates) in map) {
165+
val email1 = pair.first;
166+
val email2 = pair.second;
167+
if (auxHash.contains(Pair(email2, email1))) {
168+
continue;
169+
}
170+
171+
val min1 = dates.minBy { (_, vicinity) -> vicinity }!!
172+
val dates2 = map.get(Pair(email2, email1));
173+
if (dates2 != null) {
174+
auxHash.add(Pair(email1, email2))
175+
176+
val min2 = dates2.minBy { (_, vicinity) -> vicinity }!!
177+
val min: Long =
178+
if (min1.value < min2.value) { min1.value }
179+
else { min2.value }
180+
181+
val stats = mutableListOf<Fact>()
182+
stats.add(Fact(serverRepo,
183+
FactCodes.COLLEAGUES,
184+
value = email1,
185+
value2 = email2,
186+
value3 = min.toString()))
187+
188+
api.postFacts(stats).onErrorThrow()
189+
}
171190
}
172191
}
173192

@@ -243,7 +262,7 @@ class CodeLongevity(
243262
catch(e: Exception) { throw Exception("No branch") }
244263

245264
val dataPath = FileHelper.getPath(serverRepo.rehash, "longevity")
246-
val colleagues = Colleagues()
265+
val colleagues = Colleagues(serverRepo)
247266

248267
/**
249268
* Updates code line age statistics on the server.
@@ -296,7 +315,7 @@ class CodeLongevity(
296315
Logger.info { "Sent ${stats.size} facts to server" }
297316
}
298317

299-
colleagues.updateStats()
318+
colleagues.calculateAndSendFacts(api)
300319
}
301320

302321
/**

src/main/kotlin/app/model/Fact.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ data class Fact(
1515
var code: Int = 0,
1616
var key: Int = 0,
1717
var value: String = "",
18-
var author: Author = Author()
18+
var author: Author = Author(),
19+
var value2: String = "",
20+
var value3: String = ""
1921
) {
2022
@Throws(InvalidParameterException::class)
2123
constructor(proto: Protos.Fact) : this() {
@@ -38,6 +40,8 @@ data class Fact(
3840
.setCode(code)
3941
.setKey(key)
4042
.setValue1(value)
43+
.setValue2(value2)
44+
.setValue3(value3)
4145
.build()
4246
}
4347

src/test/kotlin/test/tests/hashers/CodeLongevityTest.kt

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -555,59 +555,4 @@ class CodeLongevityTest : Spek({
555555
testRepo.destroy()
556556
}
557557
}
558-
559-
given("'colleagues #1'") {
560-
val testRepoPath = "../CodeLongevity_colleagues1"
561-
val testRepo = TestRepo(testRepoPath)
562-
val testRehash = "rehash_colleagues1"
563-
val fileName = "test1.txt"
564-
val author1 = Author(testRepo.userName, testRepo.userEmail)
565-
val author2 = Author("Vasya Pupkin", "[email protected]")
566-
val emails = hashSetOf(author1.email, author2.email)
567-
568-
val serverRepo = Repo(rehash = testRehash)
569-
val mockApi = MockApi(mockRepo = serverRepo)
570-
571-
testRepo.createFile(fileName, listOf("line1", "line2"))
572-
testRepo.commit(message = "initial commit",
573-
author = author1,
574-
date = Calendar.Builder().setTimeOfDay(0, 0, 0)
575-
.build().time)
576-
577-
testRepo.deleteLines(fileName, 1, 1)
578-
testRepo.commit(message = "delete line",
579-
author = author1,
580-
date = Calendar.Builder().setTimeOfDay(0, 1, 0)
581-
.build().time)
582-
583-
testRepo.deleteLines(fileName, 0, 0)
584-
testRepo.commit(message = "delete line #2",
585-
author = author2,
586-
date = Calendar.Builder().setTimeOfDay(0, 1, 0)
587-
.build().time)
588-
589-
val cl = CodeLongevity(serverRepo, emails, testRepo.git)
590-
cl.updateFromObservable(onError = { _ -> fail("exception") },
591-
api = mockApi)
592-
593-
it("'t1'") {
594-
val triple1 = cl.colleagues.get(author1.email)[0]
595-
assertEquals(triple1.first, author2.email,
596-
"Wrong colleague email #1")
597-
assertEquals(triple1.second, "1970-01", "Wrong colleague month #1")
598-
assertEquals(triple1.third, 60, "Wrong colleague vicinity #1")
599-
600-
val triple2 = cl.colleagues.get(author2.email)[0]
601-
assertEquals(triple2.first, author1.email,
602-
"Wrong colleague email #1")
603-
assertEquals(triple2.second, "1970-01", "Wrong colleague month #1")
604-
assertEquals(triple2.third, 60, "Wrong colleague vicinity #1")
605-
}
606-
607-
afterGroup {
608-
CodeLongevity(Repo(rehash = testRehash), emails, testRepo.git)
609-
.dropSavedData()
610-
testRepo.destroy()
611-
}
612-
}
613558
})
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
// Copyright 2017 Sourcerer Inc. All Rights Reserved.
2+
// Author: Alexander Surkov ([email protected])
3+
4+
package test.tests.hashers
5+
6+
import app.api.MockApi
7+
import app.FactCodes
8+
import app.hashers.CodeLine
9+
import app.hashers.CodeLineAges
10+
import app.hashers.CodeLongevity
11+
import app.hashers.RevCommitLine
12+
import app.model.*
13+
14+
import test.utils.TestRepo
15+
16+
import kotlin.test.assertEquals
17+
import kotlin.test.assertTrue
18+
import kotlin.test.fail
19+
20+
import org.eclipse.jgit.revwalk.RevCommit
21+
22+
import org.jetbrains.spek.api.Spek
23+
import org.jetbrains.spek.api.dsl.given
24+
import org.jetbrains.spek.api.dsl.it
25+
26+
import java.util.Calendar
27+
import kotlin.test.assertNotNull
28+
29+
/**
30+
* Testing class.
31+
*/
32+
class ColleaguesTest : Spek({
33+
given("'colleagues #1'") {
34+
val testRepoPath = "../CodeLongevity_colleagues1"
35+
val testRepo = TestRepo(testRepoPath)
36+
val testRehash = "rehash_colleagues1"
37+
val fileName = "test1.txt"
38+
val author1 = Author(testRepo.userName, testRepo.userEmail)
39+
val author2 = Author("Vasya Pupkin", "[email protected]")
40+
val emails = hashSetOf(author1.email, author2.email)
41+
42+
val serverRepo = Repo(rehash = testRehash)
43+
val mockApi = MockApi(mockRepo = serverRepo)
44+
45+
testRepo.createFile(fileName, listOf("line1", "line2"))
46+
testRepo.commit(message = "initial commit",
47+
author = author1,
48+
date = Calendar.Builder().setTimeOfDay(0, 0, 0)
49+
.build().time)
50+
51+
testRepo.deleteLines(fileName, 1, 1)
52+
testRepo.commit(message = "delete line",
53+
author = author1,
54+
date = Calendar.Builder().setTimeOfDay(0, 1, 0)
55+
.build().time)
56+
57+
testRepo.deleteLines(fileName, 0, 0)
58+
testRepo.commit(message = "delete line #2",
59+
author = author2,
60+
date = Calendar.Builder().setTimeOfDay(0, 1, 0)
61+
.build().time)
62+
63+
val cl = CodeLongevity(serverRepo, emails, testRepo.git)
64+
cl.updateFromObservable(onError = { _ -> fail("exception") },
65+
api = mockApi)
66+
67+
it("'t1'") {
68+
val triple1 = cl.colleagues.get(author1.email)[0]
69+
assertEquals(triple1.first, author2.email,
70+
"Wrong colleague email #1")
71+
assertEquals(triple1.second, "1970-01", "Wrong colleague month #1")
72+
assertEquals(triple1.third, 60, "Wrong colleague vicinity #1")
73+
74+
val triple2 = cl.colleagues.get(author2.email)[0]
75+
assertEquals(triple2.first, author1.email,
76+
"Wrong colleague email #1")
77+
assertEquals(triple2.second, "1970-01", "Wrong colleague month #1")
78+
assertEquals(triple2.third, 60, "Wrong colleague vicinity #1")
79+
}
80+
81+
afterGroup {
82+
CodeLongevity(Repo(rehash = testRehash), emails, testRepo.git)
83+
.dropSavedData()
84+
testRepo.destroy()
85+
}
86+
}
87+
88+
given("'colleagues stats'") {
89+
val testRepoPath = "../CodeLongevity_colleagues_stats"
90+
val testRepo = TestRepo(testRepoPath)
91+
val testRehash = "rehash_lngstats2"
92+
val fileName = "test1.txt"
93+
val author1 = Author(testRepo.userName, testRepo.userEmail)
94+
val author2 = Author("Vasya Pupkin", "[email protected]")
95+
val emails = hashSetOf(author1.email, author2.email)
96+
97+
val serverRepo = Repo(rehash = testRehash)
98+
val mockApi = MockApi(mockRepo = serverRepo)
99+
100+
testRepo.createFile(fileName, listOf("line1", "line2"))
101+
testRepo.commit(message = "initial commit",
102+
author = author1,
103+
date = Calendar.Builder().setTimeOfDay(0, 0, 0)
104+
.build().time)
105+
106+
testRepo.deleteLines(fileName, 1, 1)
107+
testRepo.commit(message = "delete line",
108+
author = author2,
109+
date = Calendar.Builder().setTimeOfDay(0, 1, 0)
110+
.build().time)
111+
112+
testRepo.insertLines(fileName, 1, listOf("line in the end"))
113+
testRepo.commit(message = "insert line",
114+
author = author2,
115+
date = Calendar.Builder().setTimeOfDay(0, 10, 0)
116+
.build().time)
117+
118+
testRepo.deleteLines(fileName, 1, 1)
119+
testRepo.commit(message = "delete line #2",
120+
author = author1,
121+
date = Calendar.Builder().setTimeOfDay(0, 20, 0)
122+
.build().time)
123+
124+
CodeLongevity(serverRepo, emails, testRepo.git)
125+
.updateFromObservable(onError = { _ -> fail("exception") },
126+
api = mockApi)
127+
128+
it("'t1'") {
129+
for (f in mockApi.receivedFacts) {
130+
println(f)
131+
}
132+
assertTrue(mockApi.receivedFacts.contains(
133+
Fact(repo = serverRepo,
134+
code = FactCodes.COLLEAGUES,
135+
value = author2.email,
136+
value2 = author1.email,
137+
value3 = (60).toString())
138+
))
139+
}
140+
141+
afterGroup {
142+
CodeLongevity(Repo(rehash = testRehash), emails, testRepo.git)
143+
.dropSavedData()
144+
testRepo.destroy()
145+
}
146+
}
147+
})

0 commit comments

Comments
 (0)