Skip to content

Commit 342736b

Browse files
yaronskayaanatolystansler
authored andcommitted
feat: naming convention fact (APP-43) (#91)
* feat: naming convention fact (APP-43) * wip: fix pr
1 parent 9acccb2 commit 342736b

File tree

5 files changed

+110
-2
lines changed

5 files changed

+110
-2
lines changed

src/main/kotlin/app/FactCodes.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
// Copyright 2017 Sourcerer Inc. All Rights Reserved.
22
// Author: Anatoly Kislov ([email protected])
3+
// Author: Liubov Yaronskaya ([email protected])
34

45
package app
56

67
object FactCodes {
78
val COMMIT_DAY_WEEK = 1 // Day of week fun fact and graph.
89
val COMMIT_DAY_TIME = 2 // Day time fun fact.
10+
911
val COMMIT_LINE_NUM_AVG = 8 // Average number of lines per commit fun fact.
1012
val COMMIT_NUM = 9 // Used for averaging COMMIT_LINE_NUM_AVG between repos.
1113
// A map of line numbers to commits number. Used in a commit histogram.
@@ -17,4 +19,8 @@ object FactCodes {
1719
val REPO_DATE_START = 5 // Repo summary info. Date of first contribution.
1820
val REPO_DATE_END = 6 // Repo summary info. Date of last contribution.
1921
val REPO_TEAM_SIZE = 7 // Repo summary info. Number of contributors.
22+
val VARIABLE_NAMING = 13 // Variables naming fun fact.
23+
val VARIABLE_NAMING_SNAKE_CASE = 0
24+
val VARIABLE_NAMING_CAMEL_CASE = 1
25+
val VARIABLE_NAMING_OTHER = 2
2026
}

src/main/kotlin/app/extractors/GoExtractor.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,10 @@ class GoExtractor : ExtractorInterface {
3737
val contentJoined = fileContent.joinToString(separator = "")
3838
multipleImportRegex.findAll(contentJoined).forEach { matchResult ->
3939
imports.addAll(matchResult.groupValues.last()
40-
.split(Regex("""(\t+|\n+|\s+)"""))
40+
.split(Regex("""(\t+|\n+|\s+|")"""))
4141
.filter { it.isNotEmpty() }
42-
.map { it -> it.replace("\"", "") })
42+
.map { it -> it.replace("\"", "") }
43+
.map { it -> if (it.contains("github.com")) it.split("/")[2] else it})
4344
}
4445

4546
return imports.toList()

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
// Copyright 2017 Sourcerer Inc. All Rights Reserved.
22
// Author: Anatoly Kislov ([email protected])
3+
// Author: Liubov Yaronskaya ([email protected])
34

45
package app.hashers
56

67
import app.FactCodes
78
import app.Logger
89
import app.api.Api
10+
import app.extractors.Extractor
911
import app.model.Author
1012
import app.model.Commit
1113
import app.model.Fact
@@ -30,6 +32,7 @@ class FactHasher(private val serverRepo: Repo = Repo(),
3032
private val fsLineLenAvg = hashMapOf<String, Double>()
3133
private val fsLineNum = hashMapOf<String, Long>()
3234
private val fsLinesPerCommits = hashMapOf<String, Array<Int>>()
35+
private val fsVariableNaming = hashMapOf<String, Array<Int>>()
3336

3437
init {
3538
for (author in emails) {
@@ -43,6 +46,7 @@ class FactHasher(private val serverRepo: Repo = Repo(),
4346
fsLineNum.put(author, 0)
4447
// TODO(anatoly): Do the bin computations on the go.
4548
fsLinesPerCommits.put(author, Array(rehashes.size) {0})
49+
fsVariableNaming.put(author, Array(3) { 0 })
4650
}
4751
}
4852

@@ -102,6 +106,21 @@ class FactHasher(private val serverRepo: Repo = Repo(),
102106
fsLineNum[email] = fsLineNum[email]!! + lines.size
103107

104108
fsLinesPerCommits[email]!![numCommits - 1] += lines.size
109+
110+
lines.forEach { line ->
111+
val tokens = Extractor().tokenize(line)
112+
val underscores = tokens.count { it.contains('_') }
113+
val camelCases = tokens.count {
114+
!it.contains('_') && it.contains(Regex("[a-z][A-Z]"))
115+
}
116+
val others = tokens.size - underscores - camelCases
117+
fsVariableNaming[email]!![FactCodes.VARIABLE_NAMING_SNAKE_CASE] +=
118+
underscores
119+
fsVariableNaming[email]!![FactCodes.VARIABLE_NAMING_CAMEL_CASE] +=
120+
camelCases
121+
fsVariableNaming[email]!![FactCodes.VARIABLE_NAMING_OTHER] +=
122+
others
123+
}
105124
}
106125

107126
private fun createFacts(): List<Fact> {
@@ -116,6 +135,11 @@ class FactHasher(private val serverRepo: Repo = Repo(),
116135
fs.add(Fact(serverRepo, FactCodes.COMMIT_DAY_WEEK, day,
117136
count.toString(), author))
118137
}}
138+
fsVariableNaming[email]?.forEachIndexed { naming, count -> if (count > 0) {
139+
fs.add(Fact(serverRepo, FactCodes.VARIABLE_NAMING, naming,
140+
count.toString(), author))
141+
}}
142+
119143
fs.add(Fact(serverRepo, FactCodes.REPO_DATE_START, 0,
120144
fsRepoDateStart[email].toString(), author))
121145
fs.add(Fact(serverRepo, FactCodes.REPO_DATE_END, 0,

src/test/kotlin/test/tests/extractors/ExtractorTest.kt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,4 +188,36 @@ class ExtractorTest : Spek({
188188
assertExtractsImport(lib, line2, PythonExtractor())
189189
}
190190
}
191+
192+
given("one line import in go file") {
193+
it("extracts library name") {
194+
val lib = "macagon"
195+
val line = "import \"macagon\""
196+
assertExtractsImport(lib, line, GoExtractor())
197+
}
198+
}
199+
200+
given("multiline import in go file") {
201+
it("extracts library name") {
202+
val lib = "macagon"
203+
val lines = listOf("import (",
204+
"\"macagon\"",
205+
"\"github.com/astaxie/beego\"",
206+
")")
207+
val actualLineImports = GoExtractor().extractImports(lines)
208+
assertTrue(lib in actualLineImports)
209+
}
210+
}
211+
212+
given("github url as import in go file") {
213+
it("extracts library name") {
214+
val lib = "beego"
215+
val lines = listOf("import (",
216+
"\"macagon\"",
217+
"\"github.com/astaxie/beego\"",
218+
")")
219+
val actualLineImports = GoExtractor().extractImports(lines)
220+
assertTrue(lib in actualLineImports)
221+
}
222+
}
191223
})

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

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Copyright 2017 Sourcerer Inc. All Rights Reserved.
22
// Author: Anatoly Kislov ([email protected])
3+
// Author: Liubov Yaronskaya ([email protected])
34

45
package test.tests.hashers
56

@@ -282,4 +283,48 @@ class FactHasherTest : Spek({
282283
testRepo.destroy()
283284
}
284285
}
286+
287+
given("commits for naming convention facts") {
288+
val testRepo = TestRepo(repoPath + "file-facts")
289+
val emails = hashSetOf(authorEmail1)
290+
val mockApi = MockApi(mockRepo = repo)
291+
val facts = mockApi.receivedFacts
292+
293+
afterEachTest {
294+
facts.clear()
295+
}
296+
297+
val lines = listOf("camelCase1", "camelCase2", "snake_case", "fn()")
298+
299+
it("sends facts") {
300+
for (i in 0..lines.size - 1) {
301+
val line = lines[i]
302+
val fileName = "file$i.txt"
303+
testRepo.createFile(fileName, listOf(line))
304+
testRepo.commit(message = "$line in $fileName", author = author1)
305+
}
306+
307+
val errors = mutableListOf<Throwable>()
308+
val observable = CommitCrawler.getObservable(testRepo.git, repo)
309+
val rehashes = (0..lines.size - 1).map { "r$it" }
310+
311+
FactHasher(repo, mockApi, rehashes, emails)
312+
.updateFromObservable(observable, { e -> errors.add(e) })
313+
if (errors.size > 0) {
314+
println(errors[0].message)
315+
}
316+
assertEquals(0, errors.size)
317+
318+
assertFactInt(FactCodes.VARIABLE_NAMING,
319+
FactCodes.VARIABLE_NAMING_SNAKE_CASE, 1, author1, facts)
320+
assertFactInt(FactCodes.VARIABLE_NAMING,
321+
FactCodes.VARIABLE_NAMING_CAMEL_CASE, 2, author1, facts)
322+
assertFactInt(FactCodes.VARIABLE_NAMING,
323+
FactCodes.VARIABLE_NAMING_OTHER, 1, author1, facts)
324+
}
325+
326+
afterGroup {
327+
testRepo.destroy()
328+
}
329+
}
285330
})

0 commit comments

Comments
 (0)