Flag and aggregate commits by BotLike-ness
With this change it is possible to provide a new bot-like-regexps
parameter which allows to pass a comma separated list of regexps to be
used in recognizing bot-like commits.
When *all* files touched by a commit match those regexps, then the commit
is flagged as is_bot_like.
Change-Id: I0f3af74dc223e9f12c9e19592c226d784eceb6f7
diff --git a/README.md b/README.md
index 1b01f3e..e7eb7ab 100644
--- a/README.md
+++ b/README.md
@@ -71,22 +71,76 @@
- --aggregate -granularity -g one of email, email_year, email_month, email_day, email_hour defaulting to aggregation by email
- --extract-branches -r enables splitting of aggregation by branch name and expose branch name in the payload
- --extract-issues -i enables the extraction of issues from commentLink
+- --botlike-filename-regexps -n comma separated list of regexps that identify a bot-like commit, commits that modify only files whose name is a match will be flagged as bot-like
NOTE: Timestamp format is consistent with Gerrit's query syntax, see /Documentation/user-search.html for details.
-REST Example:
+### Examples
+
+- REST:
```
$ curl http://gerrit.mycompany.com/projects/myproject/analytics~contributors
- {"name":"John Doe","email":"john.doe@mycompany.com","num_commits":1, "num_files":4,"added_lines":9,"deleted_lines":1, "commits":[{"sha1":"6a1f73738071e299f600017d99f7252d41b96b4b","date":"Apr 28, 2011 5:13:14 AM","merge":false}]}
- {"name":"Matt Smith","email":"matt.smith@mycompany.com","num_commits":1, "num_files":1,"added_lines":90,"deleted_lines":10,"commits":[{"sha1":"54527e7e3086758a23e3b069f183db6415aca304","date":"Sep 8, 2015 3:11:23 AM","merge":true}],"branches":["master"]}
+ {"name":"John Doe","email":"john.doe@mycompany.com","num_commits":1, "num_files":4,"added_lines":9,"deleted_lines":1, "commits":[{"sha1":"6a1f73738071e299f600017d99f7252d41b96b4b","date":"Apr 28, 2011 5:13:14 AM","merge":false,"bot_like": false}],"is_bot_like": false}
+ {"name":"Matt Smith","email":"matt.smith@mycompany.com","num_commits":1, "num_files":1,"added_lines":90,"deleted_lines":10,"commits":[{"sha1":"54527e7e3086758a23e3b069f183db6415aca304","date":"Sep 8, 2015 3:11:23 AM","merge":true,"bot_like": false}],"branches":["master"],"is_bot_like": false}
```
-SSH Example:
+- SSH:
```
$ ssh -p 29418 admin@gerrit.mycompany.com analytics contributors myproject --since 2017-08-01 --until 2017-12-31 --extract-issues
- {"name":"John Doe","email":"john.doe@mycompany.com","num_commits":1, "num_files":4,"added_lines":9,"deleted_lines":1, "commits":[{"sha1":"6a1f73738071e299f600017d99f7252d41b96b4b","date":"Apr 28, 2011 5:13:14 AM","merge":false}], "issues_codes":["PRJ-001"],"issues_links":["https://jira.company.org/PRJ-001"]}
- {"name":"Matt Smith","email":"matt.smith@mycompany.com","num_commits":1, "num_files":1,"added_lines":90,"deleted_lines":10,"commits":[{"sha1":"54527e7e3086758a23e3b069f183db6415aca304","date":"Sep 8, 2015 3:11:23 AM","merge":true}],"branches":["branch1"],"issues_codes":["PRJ-002","PRJ-003"],"issues_links":["https://jira.company.org/PRJ-002","https://jira.company.org/PRJ-003"]}
+ {"name":"John Doe","email":"john.doe@mycompany.com","num_commits":1, "num_files":4,"added_lines":9,"deleted_lines":1, "commits":[{"sha1":"6a1f73738071e299f600017d99f7252d41b96b4b","date":"Apr 28, 2011 5:13:14 AM","merge":false,"bot_like": false}],"is_bot_like": false,"issues_codes":["PRJ-001"],"issues_links":["https://jira.company.org/PRJ-001"]}
+ {"name":"Matt Smith","email":"matt.smith@mycompany.com","num_commits":1, "num_files":1,"added_lines":90,"deleted_lines":10,"commits":[{"sha1":"54527e7e3086758a23e3b069f183db6415aca304","date":"Sep 8, 2015 3:11:23 AM","merge":true,"bot_like": false,}],"is_bot_like": false,"branches":["branch1"],"issues_codes":["PRJ-002","PRJ-003"],"issues_links":["https://jira.company.org/PRJ-002","https://jira.company.org/PRJ-003"]}
+```
+
+- BOT-like:
+Flags the commit as bot-like when *all* files in that commit match any of the following regular expressions:
+
+ * .+\\.xml
+ * .+\\.bzl
+ * BUILD
+ * WORKSPACE
+ * \\.gitignore
+ * plugins/
+ * \\.settings
+
+```
+curl 'http://gerrit.mycompany.com/projects/myproject/analytics~contributors?botlike-filename-regexps=.%2B%5C.xml%2C.%2B%5C.bzl%2CBUILD%2CWORKSPACE%2C%5C.gitignore%2Cplugins%2F%2C%5C.settings'
+
+{
+ "year": 2018,
+ "month": 3,
+ "day": 21,
+ "hour": 19,
+ "name": "Dave Borowitz",
+ "email": "dborowitz@google.com",
+ "num_commits": 1,
+ "num_files": 6,
+ "num_distinct_files": 6,
+ "added_lines": 6,
+ "deleted_lines": 6,
+ "commits": [
+ {
+ "sha1": "a3ab2e1d07e6745f50b1d9907f6580c6521fd035",
+ "date": 1521661246000,
+ "merge": false,
+ "bot_like": true,
+ "files": [
+ "version.bzl",
+ "gerrit-plugin-gwtui/pom.xml",
+ "gerrit-extension-api/pom.xml",
+ "gerrit-war/pom.xml",
+ "gerrit-plugin-api/pom.xml",
+ "gerrit-acceptance-framework/pom.xml"
+ ]
+ }
+ ],
+ "branches": [],
+ "issues_codes": [],
+ "issues_links": [],
+ "last_commit_date": 1521661246000,
+ "is_merge": false,
+ "is_bot_like": true
+}
```
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/analytics/Contributors.scala b/src/main/scala/com/googlesource/gerrit/plugins/analytics/Contributors.scala
index 4b6c5e7..c11da56 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/analytics/Contributors.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/Contributors.scala
@@ -34,6 +34,7 @@
private var beginDate: Option[Long] = None
private var endDate: Option[Long] = None
private var granularity: Option[AggregationStrategy] = None
+ private var botLikeRegexps: List[String] = List.empty[String]
@ArgOption(name = "--extract-branches", aliases = Array("-r"),
usage = "Do extra parsing to extract a list of all branches for each line")
@@ -73,9 +74,15 @@
usage = "Extract a list of issues and links using the Gerrit's commentLink configuration")
private var extractIssues: Boolean = false
+ @ArgOption(name = "--botlike-filename-regexps", aliases = Array("-n"),
+ usage = "comma separated list of regexps that identify a bot-like commit, commits that modify only files whose name is a match will be flagged as bot-like")
+ def setBotLikeRegexps(value: String): Unit = {
+ botLikeRegexps = value.split(",").toList
+ }
+
override protected def run =
gsonFmt.format(executor.get(projectRes, beginDate, endDate,
- granularity.getOrElse(AggregationStrategy.EMAIL), extractBranches, extractIssues), stdout)
+ granularity.getOrElse(AggregationStrategy.EMAIL), extractBranches, extractIssues, botLikeRegexps), stdout)
}
@@ -86,6 +93,7 @@
private var beginDate: Option[Long] = None
private var endDate: Option[Long] = None
private var granularity: Option[AggregationStrategy] = None
+ private var botLikeRegexps: List[String] = List.empty[String]
@ArgOption(name = "--since", aliases = Array("--after", "-b"), metaVar = "QUERY",
usage = "(included) begin timestamp. Must be in the format 2006-01-02[ 15:04:05[.890][ -0700]]")
@@ -125,11 +133,17 @@
usage = "Extract a list of issues and links using the Gerrit's commentLink configuration")
private var extractIssues: Boolean = false
+ @ArgOption(name = "--botlike-filename-regexps", aliases = Array("-n"),
+ usage = "comma separated list of regexps that identify a bot-like commit, commits that modify only files whose name is a match will be flagged as bot-like")
+ def setBotLikeRegexps(value: String): Unit = {
+ botLikeRegexps = value.split(",").toList
+ }
+
override def apply(projectRes: ProjectResource) =
Response.ok(
new GsonStreamedResult[UserActivitySummary](gson,
executor.get(projectRes, beginDate, endDate,
- granularity.getOrElse(AggregationStrategy.EMAIL), extractBranches, extractIssues)))
+ granularity.getOrElse(AggregationStrategy.EMAIL), extractBranches, extractIssues, botLikeRegexps)))
}
class ContributorsService @Inject()(repoManager: GitRepositoryManager,
@@ -141,7 +155,7 @@
import scala.collection.JavaConverters._
def get(projectRes: ProjectResource, startDate: Option[Long], stopDate: Option[Long],
- aggregationStrategy: AggregationStrategy, extractBranches: Boolean, extractIssues: Boolean)
+ aggregationStrategy: AggregationStrategy, extractBranches: Boolean, extractIssues: Boolean, botLikeIdentifiers: List[String])
: TraversableOnce[UserActivitySummary] = {
val nameKey = projectRes.getNameKey
val commentLinks: List[CommentLinkInfo] = extractIssues.option {
@@ -149,9 +163,8 @@
}.toList.flatten
-
ManagedResource.use(repoManager.openRepository(projectRes.getNameKey)) { repo =>
- val stats = new Statistics(repo, commentLinks.asJava)
+ val stats = new Statistics(repo, new BotLikeExtractorImpl(botLikeIdentifiers), commentLinks.asJava)
val branchesExtractor = extractBranches.option(new BranchesExtractor(repo))
histogram.get(repo, new AggregatedHistogramFilterByDates(startDate, stopDate, branchesExtractor, aggregationStrategy))
@@ -162,7 +175,7 @@
}
}
-case class CommitInfo(sha1: String, date: Long, merge: Boolean, files: java.util.Set[String])
+case class CommitInfo(sha1: String, date: Long, merge: Boolean, botLike: Boolean, files: java.util.Set[String])
case class IssueInfo(code: String, link: String)
@@ -182,7 +195,8 @@
issuesCodes: Array[String],
issuesLinks: Array[String],
lastCommitDate: Long,
- isMerge: Boolean
+ isMerge: Boolean,
+ isBotLike: Boolean
)
object UserActivitySummary {
@@ -202,7 +216,7 @@
stat.numFiles, stat.numDistinctFiles, stat.addedLines, stat.deletedLines,
stat.commits.toArray, maybeBranches, stat.issues.map(_.code)
.toArray, stat.issues.map(_.link).toArray, uca.getLatest, stat
- .isForMergeCommits
+ .isForMergeCommits,stat.isForBotLike
)
}
case _ => throw new Exception(s"invalid key format found ${uca.key}")
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/BotLikeExtractor.scala b/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/BotLikeExtractor.scala
new file mode 100644
index 0000000..16a8bf2
--- /dev/null
+++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/BotLikeExtractor.scala
@@ -0,0 +1,26 @@
+// Copyright (C) 2019 GerritForge Ltd
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+// http://www.apache.org/licenses/LICENSE-2.0
+
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.analytics.common
+
+import scala.util.matching.Regex
+
+trait BotLikeExtractor {
+ def isBotLike(files: Set[String]): Boolean
+}
+
+class BotLikeExtractorImpl(botLikeIdentifiers: List[String]) extends BotLikeExtractor {
+ private val botRegexps = new Regex(botLikeIdentifiers.mkString("|"))
+ override def isBotLike(files: Set[String]): Boolean = botLikeIdentifiers.nonEmpty && files.forall(botRegexps.findFirstIn(_).isDefined)
+}
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/CommitsStatistics.scala b/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/CommitsStatistics.scala
index bb5c0e2..e5f9723 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/CommitsStatistics.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/CommitsStatistics.scala
@@ -35,15 +35,18 @@
* @param isForMergeCommits true if the current instance is including stats for merge commits and false if
* calculated for NON merge commits. The current code is not generating stats objects for
* a mixture of merge and non-merge commits
+ * @param isForBotLike true if the current instance is including BOT-like commits, false otherwise
* @param commits list of commits the stats are calculated for
*/
case class CommitsStatistics(
addedLines: Int,
deletedLines: Int,
isForMergeCommits: Boolean,
+ isForBotLike: Boolean,
commits: List[CommitInfo],
issues: List[IssueInfo] = Nil
) {
+ require(commits.forall(_.botLike == isForBotLike), s"Creating a stats object with isForBotLike = $isForBotLike but containing commits of different type")
require(commits.forall(_.merge == isForMergeCommits), s"Creating a stats object with isMergeCommit = $isForMergeCommits but containing commits of different type")
/**
@@ -73,11 +76,13 @@
}
object CommitsStatistics {
- val Empty = CommitsStatistics(0, 0, false, List[CommitInfo](), List[IssueInfo]())
- val EmptyMerge = Empty.copy(isForMergeCommits = true)
+ val EmptyNonMerge = CommitsStatistics(0, 0, false, false, List[CommitInfo](), List[IssueInfo]())
+ val EmptyBotNonMerge = EmptyNonMerge.copy(isForBotLike = true)
+ val EmptyMerge = EmptyNonMerge.copy(isForMergeCommits = true)
+ val EmptyBotMerge = EmptyMerge.copy(isForBotLike = true)
}
-class Statistics(repo: Repository, commentInfoList: java.util.List[CommentLinkInfo] = Nil) {
+class Statistics(repo: Repository, botLikeExtractor: BotLikeExtractor, commentInfoList: java.util.List[CommentLinkInfo] = Nil) {
val log = LoggerFactory.getLogger(classOf[Statistics])
val replacers = commentInfoList.map(info =>
@@ -86,7 +91,11 @@
Option(info.link).getOrElse(info.html)))
/**
- * Returns up to two different CommitsStatistics object grouping the stats into merge and non-merge commits
+ * Returns up to four different CommitsStatistics object grouping the stats into:
+ * Non Merge - Non Bot
+ * Merge - Non Bot
+ * Non Merge - Bot
+ * Merge - Bot
*
* @param commits
* @return
@@ -97,10 +106,16 @@
val (mergeStatsSeq, nonMergeStatsSeq) = stats.partition(_.isForMergeCommits)
- val nonMergeStats = nonMergeStatsSeq.foldLeft(CommitsStatistics.Empty)(_ + _)
- val mergeStats = mergeStatsSeq.foldLeft(CommitsStatistics.EmptyMerge)(_ + _)
+ val (mergeBotStatsSeq, mergeNonBotStatsSeq) = mergeStatsSeq.partition(_.isForBotLike)
+ val (nonMergeBotStatsSeq, nonMergeNonBotStatsSeq) = nonMergeStatsSeq.partition(_.isForBotLike)
- List(nonMergeStats, mergeStats).filterNot(_.isEmpty)
+ List(
+ nonMergeNonBotStatsSeq.foldLeft(CommitsStatistics.EmptyNonMerge)(_ + _), // Non Merge - Non Bot
+ mergeNonBotStatsSeq.foldLeft(CommitsStatistics.EmptyMerge)(_ + _), // Merge - Non Bot
+ nonMergeBotStatsSeq.foldLeft(CommitsStatistics.EmptyBotNonMerge)(_ + _), // Non Merge - Bot
+ mergeBotStatsSeq.foldLeft(CommitsStatistics.EmptyBotMerge)(_ + _) // Merge - Bot
+ )
+ .filterNot(_.isEmpty)
}
protected def forSingleCommit(objectId: ObjectId): CommitsStatistics = {
@@ -138,9 +153,9 @@
val files: Set[String] = diffs.map(df.toFileHeader(_).getNewPath).toSet
- val commitInfo = CommitInfo(objectId.getName, commit.getAuthorIdent.getWhen.getTime, commit.isMerge, files)
+ val commitInfo = CommitInfo(objectId.getName, commit.getAuthorIdent.getWhen.getTime, commit.isMerge, botLikeExtractor.isBotLike(files), files)
- CommitsStatistics(lines.added, lines.deleted, commitInfo.merge, List(commitInfo), extractIssues(commitMessage))
+ CommitsStatistics(lines.added, lines.deleted, commitInfo.merge, commitInfo.botLike, List(commitInfo), extractIssues(commitMessage))
}
}
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/analytics/common/BotLikeExtractorImplSpec.scala b/src/test/scala/com/googlesource/gerrit/plugins/analytics/common/BotLikeExtractorImplSpec.scala
new file mode 100644
index 0000000..2893a31
--- /dev/null
+++ b/src/test/scala/com/googlesource/gerrit/plugins/analytics/common/BotLikeExtractorImplSpec.scala
@@ -0,0 +1,51 @@
+// Copyright (C) 2019 GerritForge Ltd
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+// http://www.apache.org/licenses/LICENSE-2.0
+
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.analytics.common
+
+import com.googlesource.gerrit.plugins.analytics.test.GitTestCase
+import org.scalatest.{FlatSpec, Matchers}
+
+class BotLikeExtractorImplSpec extends FlatSpec with Matchers with GitTestCase {
+
+ behavior of "isBotLike"
+
+ it should "return true when all files match bot-like identifiers" in {
+ val extractor = new BotLikeExtractorImpl(List(""".+\.xml"""))
+
+ extractor.isBotLike(Set(
+ "some/path/AFile.xml",
+ "some/path/AnotherFile.xml"
+ )).shouldBe(true)
+
+ }
+
+ it should "return false when at least one file does not match bot-like identifiers" in {
+ val extractor = new BotLikeExtractorImpl(List(""".+\.xml"""))
+
+ extractor.isBotLike(Set(
+ "some/path/AFile.xml",
+ "some/path/AnotherFile.someExtension"
+ )).shouldBe(false)
+
+ }
+
+ it should "return false when no bot-like identifiers have been provided" in {
+ val extractor = new BotLikeExtractorImpl(List.empty)
+
+ extractor.isBotLike(Set("some/path/anyFile")).shouldBe(false)
+
+ }
+
+}
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/CommitInfoSpec.scala b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/CommitInfoSpec.scala
index 7de2c03..c8aff83 100644
--- a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/CommitInfoSpec.scala
+++ b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/CommitInfoSpec.scala
@@ -8,14 +8,14 @@
class CommitInfoSpec extends FlatSpec with Matchers {
"CommitInfo" should "be serialised as JSON correctly" in {
- val commitInfo = CommitInfo(sha1 = "sha", date = 1000l, merge = false, files = newHashSet("file1", "file2"))
+ val commitInfo = CommitInfo(sha1 = "sha", date = 1000l, merge = false, botLike = false, files = newHashSet("file1", "file2"))
val gsonBuilder = OutputFormat.JSON_COMPACT.newGsonBuilder
val actual = gsonBuilder.create().toJson(commitInfo)
List(actual) should contain oneOf(
- "{\"sha1\":\"sha\",\"date\":1000,\"merge\":false,\"files\":[\"file1\",\"file2\"]}",
- "{\"sha1\":\"sha\",\"date\":1000,\"merge\":false,\"files\":[\"file2\",\"file1\"]}"
+ "{\"sha1\":\"sha\",\"date\":1000,\"merge\":false,\"bot_like\":false,\"files\":[\"file1\",\"file2\"]}",
+ "{\"sha1\":\"sha\",\"date\":1000,\"merge\":false,\"bot_like\":false,\"files\":[\"file2\",\"file1\"]}"
)
}
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/CommitStatisticsCommentLinkSpec.scala b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/CommitStatisticsCommentLinkSpec.scala
index 95784fd..c9031c6 100644
--- a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/CommitStatisticsCommentLinkSpec.scala
+++ b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/CommitStatisticsCommentLinkSpec.scala
@@ -39,7 +39,7 @@
createCommentLinkInfo(pattern = "([Bb]ug:\\s+)(\\d+)",
html = Some("$1<a href=\"http://trak.example.com/$2\">$2</a>"))).asJava) {
- lazy val stats = new Statistics(repo, commentLinks)
+ lazy val stats = new Statistics(repo, TestBotLikeExtractor, commentLinks)
}
it should "collect no commentslink if no matching" in new TestEnvironment {
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/CommitStatisticsSpec.scala b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/CommitStatisticsSpec.scala
index 6db1d00..d5257ef 100644
--- a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/CommitStatisticsSpec.scala
+++ b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/CommitStatisticsSpec.scala
@@ -25,7 +25,7 @@
class TestEnvironment {
val repo = new FileRepository(testRepo)
- val stats = new Statistics(repo)
+ val stats = new Statistics(repo, TestBotLikeExtractor)
}
"CommitStatistics" should "stats a single file added" in new TestEnvironment {
@@ -39,19 +39,19 @@
}
it should "sum to another compatible CommitStatistics generating an aggregated stat" in {
- val commit1 = CommitInfo("sha_1", 1000l, false, newHashSet("file1"))
- val commit2 = CommitInfo("sha_2", 2000l, false, newHashSet("file1"))
- val commit3 = CommitInfo("sha_3", 3000l, false, newHashSet("file2"))
- val commit4 = CommitInfo("sha_4", 1000l, false, newHashSet("file1"))
+ val commit1 = CommitInfo("sha_1", 1000l, false, botLike = false, newHashSet("file1"))
+ val commit2 = CommitInfo("sha_2", 2000l, false, botLike = false, newHashSet("file1"))
+ val commit3 = CommitInfo("sha_3", 3000l, false, botLike = false, newHashSet("file2"))
+ val commit4 = CommitInfo("sha_4", 1000l, false, botLike = false, newHashSet("file1"))
- val stat1 = CommitsStatistics(3, 4, false, List(commit1, commit2))
- val stat2 = CommitsStatistics(5, 7, false, List(commit3, commit4))
+ val stat1 = CommitsStatistics(3, 4, false, false, List(commit1, commit2))
+ val stat2 = CommitsStatistics(5, 7, false, false, List(commit3, commit4))
- (stat1 + stat2) shouldBe CommitsStatistics(8, 11, false, List(commit1, commit2, commit3, commit4))
+ (stat1 + stat2) shouldBe CommitsStatistics(8, 11, false, false, List(commit1, commit2, commit3, commit4))
}
it should "fail if trying to be added to a CommitStatistics object for a different isMerge value" in {
- an [IllegalArgumentException] should be thrownBy (CommitsStatistics.EmptyMerge + CommitsStatistics.Empty)
+ an [IllegalArgumentException] should be thrownBy (CommitsStatistics.EmptyMerge + CommitsStatistics.EmptyNonMerge)
}
it should "stats multiple files added" in new TestEnvironment {
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/TestBotLikeExtractor.scala b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/TestBotLikeExtractor.scala
new file mode 100644
index 0000000..3018436
--- /dev/null
+++ b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/TestBotLikeExtractor.scala
@@ -0,0 +1,21 @@
+// Copyright (C) 2019 GerritForge Ltd
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+// http://www.apache.org/licenses/LICENSE-2.0
+
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.analytics.test
+
+import com.googlesource.gerrit.plugins.analytics.common.BotLikeExtractor
+
+case object TestBotLikeExtractor extends BotLikeExtractor {
+ override def isBotLike(files: Set[String]): Boolean = false
+}
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/UserActivitySummarySpec.scala b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/UserActivitySummarySpec.scala
index 57417cd..de4d2f2 100644
--- a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/UserActivitySummarySpec.scala
+++ b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/UserActivitySummarySpec.scala
@@ -18,7 +18,7 @@
mergeCommit(personEmail, fileName = "anotherFile.txt", content="some other content")
val aggregatedCommits = aggregateBy(EMAIL)
- val List(nonMergeSummary, mergeSummary) = UserActivitySummary.apply(new Statistics(repo))(aggregatedCommits.head)
+ val List(nonMergeSummary, mergeSummary) = UserActivitySummary.apply(new Statistics(repo, TestBotLikeExtractor))(aggregatedCommits.head)
nonMergeSummary.numCommits should be(2)
mergeSummary.numCommits should be(1)