Skip to content

Commit 129cb77

Browse files
committed
Added AndroidLintProcessorTest and updated code style.
1 parent efffc96 commit 129cb77

File tree

10 files changed

+733
-3
lines changed

10 files changed

+733
-3
lines changed

.idea/codeStyles/Project.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ buildscript {
55
versions.junit = '4.12'
66
versions.kotlin = '1.3.21'
77
versions.lint = '22.2.0'
8+
versions.mockito = '1.9.5'
89
versions.simplexml = '2.7.1'
910
versions.slf4j = '1.7.25'
1011
versions.sonar = '4.5.4'

sonar-android-plugin/build.gradle

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@ dependencies {
1616
implementation("org.codehaus.sonar-plugins.java:sonar-java-plugin:$versions.sonarJava") { transitive = false }
1717
implementation("org.codehaus.staxmate:staxmate:$versions.staxmate") { transitive = false }
1818
implementation "org.slf4j:slf4j-api:$versions.slf4j"
19-
19+
2020
testImplementation "junit:junit:$versions.junit"
21+
testImplementation "org.mockito:mockito-all:$versions.mockito"
22+
// Needed to get the dependencies that sonar has at runtime
23+
testImplementation("org.codehaus.sonar:sonar-plugin-api:$versions.sonar")
24+
testImplementation "org.slf4j:slf4j-simple:$versions.slf4j"
2125
}
2226

2327
compileKotlin {

sonar-android-plugin/src/main/kotlin/no/thorbear/sonar/plugins/android/lint/AndroidLintProcessor.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import org.simpleframework.xml.Root
66
import org.simpleframework.xml.core.Persister
77
import org.slf4j.LoggerFactory
88
import org.sonar.api.batch.fs.FileSystem
9-
import org.sonar.api.component.Component
109
import org.sonar.api.component.ResourcePerspectives
1110
import org.sonar.api.issue.Issuable
1211
import org.sonar.api.profiles.RulesProfile
@@ -50,7 +49,7 @@ class AndroidLintProcessor(
5049
val inputFile = fileSystem.inputFile(fileSystem.predicates().hasPath(lintLocation.file!!))
5150
if (inputFile != null) {
5251
logger.debug("Processing File {} for Issue {}", lintLocation.file, lintIssue.id)
53-
val issuable = perspectives.`as`(Issuable::class.java, inputFile as Component<*>)
52+
val issuable = perspectives.`as`(Issuable::class.java, inputFile)
5453
if (issuable != null) {
5554
val issue = issuable.newIssueBuilder()
5655
.ruleKey(rule.rule.ruleKey())
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
package no.thorbear.sonar.plugins.android.lint
2+
3+
import org.junit.Assert.fail
4+
import org.junit.Before
5+
import org.junit.Test
6+
import org.mockito.Matchers.anyString
7+
import org.mockito.Mockito.RETURNS_DEFAULTS
8+
import org.mockito.Mockito.`when`
9+
import org.mockito.Mockito.any
10+
import org.mockito.Mockito.mock
11+
import org.mockito.Mockito.never
12+
import org.mockito.Mockito.times
13+
import org.mockito.Mockito.verify
14+
import org.mockito.invocation.InvocationOnMock
15+
import org.mockito.stubbing.Answer
16+
import org.sonar.api.batch.fs.FilePredicate
17+
import org.sonar.api.batch.fs.InputFile
18+
import org.sonar.api.batch.fs.InputPath
19+
import org.sonar.api.batch.fs.internal.DefaultFileSystem
20+
import org.sonar.api.batch.fs.internal.DefaultInputFile
21+
import org.sonar.api.component.Perspective
22+
import org.sonar.api.component.ResourcePerspectives
23+
import org.sonar.api.issue.Issuable
24+
import org.sonar.api.issue.Issue
25+
import org.sonar.api.profiles.RulesProfile
26+
import org.sonar.api.rules.ActiveRule
27+
import org.sonar.api.rules.Rule
28+
import java.io.File
29+
30+
class AndroidLintProcessorTest {
31+
32+
private lateinit var perspectives: ResourcePerspectives
33+
private lateinit var fs: DefaultFileSystem
34+
private lateinit var rulesProfile: RulesProfile
35+
36+
@Before
37+
fun setUp() {
38+
// Setup mocks
39+
rulesProfile = mock(RulesProfile::class.java)
40+
val activeRule = mock(ActiveRule::class.java)
41+
`when`(activeRule.rule).thenReturn(Rule.create("repoKey", "ruleKey"))
42+
`when`(rulesProfile.getActiveRule(anyString(), anyString())).thenReturn(activeRule)
43+
44+
fs = object : DefaultFileSystem(File("")) {
45+
override fun inputFiles(predicate: FilePredicate): Iterable<InputFile> {
46+
return arrayListOf<InputFile>(DefaultInputFile("relativePath"))
47+
}
48+
}
49+
perspectives = mock(ResourcePerspectives::class.java)
50+
}
51+
52+
@Test
53+
fun process_empty_report() {
54+
// Process report
55+
try {
56+
AndroidLintProcessor(
57+
rulesProfile,
58+
perspectives,
59+
fs
60+
).process(File("src/test/resources/lint-report-empty.xml"))
61+
} catch (e: Exception) {
62+
fail()
63+
}
64+
65+
verify(rulesProfile, never())?.getActiveRule(anyString(), anyString())
66+
}
67+
68+
@Test
69+
fun process_report_with_relative_path() {
70+
// Process report
71+
AndroidLintProcessor(rulesProfile, perspectives, fs).process(File("src/test/resources/lint-report.xml"))
72+
73+
// Check we raise 30 issues on 21 different rules
74+
verify(rulesProfile, times(21))?.getActiveRule(anyString(), anyString())
75+
verify(perspectives, times(30))?.`as`(any<Class<out Perspective<*>>>(), any<InputPath>())
76+
}
77+
78+
@Test
79+
@Throws(Exception::class)
80+
fun process_report_with_absolute_path() {
81+
// Process report
82+
AndroidLintProcessor(
83+
rulesProfile,
84+
perspectives,
85+
fs
86+
).process(File("src/test/resources/lint-results_absolute_path.xml"))
87+
88+
// Check we raise 8 issues on 8 different rules
89+
verify(rulesProfile, times(8))?.getActiveRule(anyString(), anyString())
90+
verify(perspectives, times(8))?.`as`(any<Class<out Perspective<*>>>(), any<InputPath>())
91+
}
92+
93+
@Test
94+
@Throws(Exception::class)
95+
fun should_handle_bad_xml_results() {
96+
AndroidLintProcessor(
97+
rulesProfile,
98+
perspectives,
99+
fs
100+
).process(File("src/test/resources/lint-bad-report.xml"))
101+
verify(rulesProfile, never())?.getActiveRule(anyString(), anyString())
102+
verify(perspectives, never())?.`as`(any<Class<out Perspective<*>>>(), any<InputPath>())
103+
}
104+
105+
@Test
106+
fun issuable_call() {
107+
val issuable = mock(Issuable::class.java)
108+
`when`(perspectives.`as`(any<Class<out Perspective<*>>>(), any<InputPath>())).thenReturn(issuable)
109+
`when`(issuable.newIssueBuilder()).thenReturn(mock(Issuable.IssueBuilder::class.java, SelfReturningAnswer()))
110+
111+
AndroidLintProcessor(rulesProfile, perspectives, fs).process(File("src/test/resources/lint-report.xml"))
112+
113+
verify(perspectives, times(30))?.`as`(any<Class<out Perspective<*>>>(), any<InputPath>())
114+
verify(issuable, times(30)).addIssue(any(Issue::class.java))
115+
}
116+
117+
118+
@Test
119+
fun unknown_issue_should_not_be_reported() {
120+
`when`(rulesProfile.getActiveRule(anyString(), anyString())).thenReturn(null)
121+
AndroidLintProcessor(
122+
rulesProfile,
123+
perspectives,
124+
fs
125+
).process(File("src/test/resources/lint-unknown-rule-report.xml"))
126+
127+
verify(perspectives, never())?.`as`(any<Class<out Perspective<*>>>(), any<InputPath>())
128+
129+
}
130+
131+
inner class SelfReturningAnswer : Answer<Any> {
132+
@Throws(Throwable::class)
133+
override fun answer(invocation: InvocationOnMock?): Any? {
134+
val mock = invocation?.mock
135+
return if (invocation != null && invocation.method.returnType.isInstance(mock)) {
136+
mock
137+
} else {
138+
RETURNS_DEFAULTS.answer(invocation)
139+
}
140+
}
141+
}
142+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<issuesWithBadName format="3" by="lint 21.0.1">
3+
4+
<issueWithBadName
5+
id="MissingRegistered"
6+
severity="Error"
7+
message="Class referenced in the manifest, com.octo.appaloosasdk.async.AppaloosaSpiceService, was not found in the project or the libraries"
8+
category="Correctness"
9+
priority="8"
10+
summary="Ensures that classes referenced in the manifest are present in the project or libraries"
11+
explanation="If a class is referenced in the manifest, it must also exist in the project (or in one of the libraries included by the project. This check helps uncover typos in registration names, or attempts to rename or move classes without updating the manifest file properly."
12+
url="http://developer.android.com/guide/topics/manifest/manifest-intro.html"
13+
errorLine1=" &lt;service"
14+
errorLine2=" ^">
15+
<Badlocation
16+
file="AndroidManifest.xml"
17+
line="64"
18+
column="9"/>
19+
</issueWithBadName>
20+
</issuesWithBadName>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<issues format="4" by="lint 24.1.2">
3+
4+
</issues>

0 commit comments

Comments
 (0)