@@ -21,7 +21,9 @@ import org.assertj.core.api.Assertions
21
21
import org.assertj.core.api.ObjectAssert
22
22
import org.jetbrains.kotlin.config.LanguageVersion
23
23
import org.junit.jupiter.api.AfterEach
24
+ import org.junit.jupiter.api.DynamicTest
24
25
import org.junit.jupiter.api.Test
26
+ import org.junit.jupiter.api.TestFactory
25
27
import org.junit.jupiter.api.extension.RegisterExtension
26
28
import org.junit.jupiter.api.io.TempDir
27
29
import org.slf4j.event.Level
@@ -101,25 +103,24 @@ class CopyPasteDetectorTest {
101
103
.hasEndUnit(8 )
102
104
103
105
assertThat(cpdTokenLines[2 ])
104
- .hasValue(""" println(" LITERAL" )""" )
106
+ .hasValue(""" println(LITERAL)""" )
105
107
.hasStartLine(10 )
106
108
.hasStartUnit(9 )
107
- .hasEndUnit(14 )
109
+ .hasEndUnit(12 )
108
110
109
111
assertThat(cpdTokenLines[3 ])
110
112
.hasValue(" }" )
111
113
.hasStartLine(11 )
112
- .hasStartUnit(15 )
113
- .hasEndUnit(15 )
114
+ .hasStartUnit(13 )
115
+ .hasEndUnit(13 )
114
116
115
117
assertThat(cpdTokenLines[4 ])
116
118
.hasValue(" }" )
117
119
.hasStartLine(12 )
118
- .hasStartUnit(16 )
119
- .hasEndUnit(16 )
120
+ .hasStartUnit(14 )
121
+ .hasEndUnit(14 )
120
122
}
121
123
122
-
123
124
@Test
124
125
fun `cpd tokens are saved for the next analysis when the cache is enabled` () {
125
126
logTester.setLevel(Level .TRACE )
@@ -150,7 +151,7 @@ class CopyPasteDetectorTest {
150
151
151
152
Assertions .assertThat(logs)
152
153
.hasSize(1 )
153
- .containsExactly(" Caching 16 CPD tokens for next analysis of input file moduleKey:dummy.kt." )
154
+ .containsExactly(" Caching 14 CPD tokens for next analysis of input file moduleKey:dummy.kt." )
154
155
}
155
156
156
157
@Test
@@ -184,6 +185,53 @@ class CopyPasteDetectorTest {
184
185
.hasSize(1 )
185
186
.containsExactly(" No CPD tokens cached for next analysis of input file moduleKey:dummy.kt." )
186
187
}
188
+
189
+ private val d = " $"
190
+ private val tq = " \"\"\" "
191
+
192
+ @TestFactory
193
+ fun `cpd tokens` () = listOf (
194
+ Triple (" int literal" , """ val x = 42 """ , " valx=42" ),
195
+ Triple (" long literal" , """ val x = 42L """ , " valx=42L" ),
196
+ Triple (" float literal" , """ val x = 42.0f """ , " valx=42.0f" ),
197
+ Triple (" double literal" , """ val x = 42.0 """ , " valx=42.0" ),
198
+ Triple (" char literal" , """ val x = 'a' """ , " valx='a'" ),
199
+ Triple (" null literal" , """ val x = null """ , " valx=null" ),
200
+ Triple (" double-quote string literal" , """ val x = "a" """ , " valx=LITERAL" ),
201
+ Triple (" double-quote string literal concatenation" , """ val x = "a" + "b" """ , " valx=LITERAL+LITERAL" ),
202
+ Triple (" double-quote string template" , """ val x = "a $d {1}" """ , " valx=LITERAL" ),
203
+ Triple (" triple-quote string literal" , """ val x = ${tq} a${tq} """ , " valx=LITERAL" ),
204
+ Triple (" triple-quote string literal concatenation" , """ val x = ${tq} a${tq} + ${tq} b${tq} """ , " valx=LITERAL+LITERAL" ),
205
+ Triple (" triple-quote string template" , """ val x = ${tq} a $d {1}${tq} """ , " valx=LITERAL" ),
206
+ Triple (" mixed-quote string literal concatenation" , """ val x = "a" + ${tq} b${tq} """ , " valx=LITERAL+LITERAL" ),
207
+ Triple (
208
+ " triple-quote string template with interpolated vars" ,
209
+ """
210
+ val noInterpolations = "a literal"
211
+ val doubleQuoteTwoInterpolations = "$d {x} $d {x}"
212
+ val tripleQuoteTwoInterpolations = $tq$d {noInterpolations} $d {doubleQuoteTwoInterpolations}${tq}
213
+ var nestedInterpolations = $tq$d { "$d {1 + 1}" }${tq}
214
+ """ .trimIndent(),
215
+ """
216
+ valnoInterpolations=LITERAL
217
+ valdoubleQuoteTwoInterpolations=LITERAL
218
+ valtripleQuoteTwoInterpolations=LITERAL
219
+ varnestedInterpolations=LITERAL
220
+ """ .trimIndent()
221
+ )
222
+ ).map { (title, input, expected) ->
223
+ DynamicTest .dynamicTest(" with $title " ) {
224
+ val sensorContext: SensorContextTester = SensorContextTester .create(tmpFolder!! .root)
225
+ val inputFile = TestInputFileBuilder (" moduleKey" , " test.kt" ).setModuleBaseDir(Path .of(" ." )).setContents(input).build()
226
+ val root = kotlinTreeOf(input, Environment (disposable, emptyList(), LanguageVersion .LATEST_STABLE ), inputFile)
227
+ val ctx = InputFileContextImpl (sensorContext, inputFile, false )
228
+ CopyPasteDetector ().scan(ctx, root)
229
+
230
+ val cpdTokenLines = sensorContext.cpdTokens(inputFile.key())!!
231
+ val tokensStringified = cpdTokenLines.joinToString(separator = " \n " , transform = { it.value })
232
+ Assertions .assertThat(tokensStringified).isEqualTo(expected)
233
+ }
234
+ }
187
235
}
188
236
189
237
0 commit comments