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+ }
0 commit comments