Skip to content

Commit

Permalink
Add unit tests which reproduce #1347
Browse files Browse the repository at this point in the history
### What's done:

 * Running `mvn diktat:fix` with `WRONG_INDENTATION` rule enabled injects
   whitespace into multiline string literals. Now, unit tests were added which
   reproduce this behaviour.
  • Loading branch information
0x6675636b796f75676974687562 committed Jun 16, 2022
1 parent bf8f624 commit f7a71d8
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import com.pinterest.ktlint.core.ast.ElementType.LONG_STRING_TEMPLATE_ENTRY
import com.pinterest.ktlint.core.ast.ElementType.LONG_TEMPLATE_ENTRY_END
import com.pinterest.ktlint.core.ast.ElementType.LONG_TEMPLATE_ENTRY_START
import com.pinterest.ktlint.core.ast.ElementType.LPAR
import com.pinterest.ktlint.core.ast.ElementType.OPEN_QUOTE
import com.pinterest.ktlint.core.ast.ElementType.RBRACE
import com.pinterest.ktlint.core.ast.ElementType.RBRACKET
import com.pinterest.ktlint.core.ast.ElementType.RPAR
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ import generated.WarningNames
import org.assertj.core.api.SoftAssertions.assertSoftly
import org.intellij.lang.annotations.Language
import org.junit.jupiter.api.Assumptions.assumeTrue
import org.junit.jupiter.api.MethodOrderer.MethodName
import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestMethodOrder
import org.junit.jupiter.api.io.TempDir

import java.nio.file.Path

@TestMethodOrder(MethodName::class)
class IndentationRuleFixTest : FixTestBase("test/paragraph3/indentation",
::IndentationRule,
listOf(
Expand Down Expand Up @@ -137,6 +140,76 @@ class IndentationRuleFixTest : FixTestBase("test/paragraph3/indentation",
rulesConfigList = customConfig.asRulesConfigList())
}

/**
* See [#1347](https://github.com/saveourtool/diktat/issues/1347).
*/
@Test
@Tag(WarningNames.WRONG_INDENTATION)
fun `no whitespace should be injected into multi-line string literals (code matches settings, extendedIndent = true)`(@TempDir tempDir: Path) {
val defaultConfig = IndentationConfig("newlineAtEnd" to false)
val customConfig = defaultConfig.withCustomParameters(*extendedIndent(enabled = true))

lintMultipleMethods(
whitespaceInStringLiteralsContinuationIndent,
tempDir = tempDir,
rulesConfigList = customConfig.asRulesConfigList())
}

/**
* See [#1347](https://github.com/saveourtool/diktat/issues/1347).
*/
@Test
@Tag(WarningNames.WRONG_INDENTATION)
fun `no whitespace should be injected into multi-line string literals (code matches settings, extendedIndent = false)`(@TempDir tempDir: Path) {
val defaultConfig = IndentationConfig("newlineAtEnd" to false)
val customConfig = defaultConfig.withCustomParameters(*extendedIndent(enabled = false))

lintMultipleMethods(
whitespaceInStringLiteralsSingleIndent,
tempDir = tempDir,
rulesConfigList = customConfig.asRulesConfigList())
}

/**
* See [#1347](https://github.com/saveourtool/diktat/issues/1347).
*/
@Test
@Tag(WarningNames.WRONG_INDENTATION)
fun `no whitespace should be injected into multi-line string literals (mis-indented code reformatted, extendedIndent = true)`(@TempDir tempDir: Path) {
assumeTrue(testsCanBeMuted()) {
"Skipping a known-to-fail test"
}

val defaultConfig = IndentationConfig("newlineAtEnd" to false)
val customConfig = defaultConfig.withCustomParameters(*extendedIndent(enabled = true))

lintMultipleMethods(
actualContent = whitespaceInStringLiteralsSingleIndent,
expectedContent = whitespaceInStringLiteralsContinuationIndent,
tempDir = tempDir,
rulesConfigList = customConfig.asRulesConfigList())
}

/**
* See [#1347](https://github.com/saveourtool/diktat/issues/1347).
*/
@Test
@Tag(WarningNames.WRONG_INDENTATION)
fun `no whitespace should be injected into multi-line string literals (mis-indented code reformatted, extendedIndent = false)`(@TempDir tempDir: Path) {
assumeTrue(testsCanBeMuted()) {
"Skipping a known-to-fail test"
}

val defaultConfig = IndentationConfig("newlineAtEnd" to false)
val customConfig = defaultConfig.withCustomParameters(*extendedIndent(enabled = false))

lintMultipleMethods(
actualContent = whitespaceInStringLiteralsContinuationIndent,
expectedContent = whitespaceInStringLiteralsSingleIndent,
tempDir = tempDir,
rulesConfigList = customConfig.asRulesConfigList())
}

/**
* @param actualContent the original file content (may well be modified as
* fixes are applied).
Expand All @@ -158,14 +231,8 @@ class IndentationRuleFixTest : FixTestBase("test/paragraph3/indentation",
}

assertSoftly { softly ->
sequence {
yieldAll(actualContent.asSequence() zip expectedContent.asSequence())

/*
* All fragments concatenated.
*/
yield(actualContent.concatenated() to expectedContent.concatenated())
}.forEach { (actual, expected) ->
(actualContent.asSequenceWithConcatenation() zip
expectedContent.asSequenceWithConcatenation()).forEach { (actual, expected) ->
val lintResult = fixAndCompareContent(
actual,
expected,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,12 @@ internal interface IndentationRuleTestMixin {
"""
|private fun lerp(start: Float, stop: Float, fraction: Float): Float =
| (1 - fraction) * start + fraction * stop
""".trimMargin()
""".trimMargin(),

"""
|fun foo() =
| println()
""".trimMargin(),
)

/**
Expand Down Expand Up @@ -120,6 +125,83 @@ internal interface IndentationRuleTestMixin {
|private fun lerp(start: Float, stop: Float, fraction: Float): Float =
| (1 - fraction) * start + fraction * stop
""".trimMargin(),

"""
|fun foo() =
| println()
""".trimMargin(),
)

/**
* See [#1347](https://github.com/saveourtool/diktat/issues/1347).
*
* @see whitespaceInStringLiteralsContinuationIndent
*/
@Suppress("CUSTOM_GETTERS_SETTERS")
val whitespaceInStringLiteralsSingleIndent: Array<String>
@Language("kotlin")
get() =
arrayOf(
"""
|@Test
|fun `test method name`() {
| @Language("kotlin")
| val code =
| ""${'"'}
| @Suppress("diktat")
| fun foo() {
| val a = 1
| }
| ""${'"'}.trimIndent()
| lintMethod(code)
|}
""".trimMargin(),

"""
|fun checkScript() {
| lintMethod(
| ""${'"'}
| |val A = "aa"
| ""${'"'}.trimMargin(),
| )
|}
""".trimMargin(),
)

/**
* See [#1347](https://github.com/saveourtool/diktat/issues/1347).
*
* @see whitespaceInStringLiteralsSingleIndent
*/
@Suppress("CUSTOM_GETTERS_SETTERS")
val whitespaceInStringLiteralsContinuationIndent: Array<String>
@Language("kotlin")
get() =
arrayOf(
"""
|@Test
|fun `test method name`() {
| @Language("kotlin")
| val code =
| ""${'"'}
| @Suppress("diktat")
| fun foo() {
| val a = 1
| }
| ""${'"'}.trimIndent()
| lintMethod(code)
|}
""".trimMargin(),

"""
|fun checkScript() {
| lintMethod(
| ""${'"'}
| |val A = "aa"
| ""${'"'}.trimMargin(),
| )
|}
""".trimMargin(),
)

/**
Expand Down Expand Up @@ -169,13 +251,39 @@ internal interface IndentationRuleTestMixin {
)
)

/**
* Allows to simultaneously enable or disable _all_ `extendedIndent*` flags.
*
* @param enabled whether the _continuation indent_ should be enabled or
* disabled.
* @return an array of map entries.
*/
fun extendedIndent(enabled: Boolean): Array<Pair<String, Any>> =
arrayOf(
"extendedIndentOfParameters" to enabled,
"extendedIndentAfterOperators" to enabled,
"extendedIndentBeforeDot" to enabled)

/**
* @return the concatenated content of this array (elements separated with
* blank lines).
*/
fun Array<String>.concatenated(): String =
private fun Array<String>.concatenated(): String =
joinToString(separator = "\n\n")

/**
* @return a sequence which returns the elements of this array and,
* additionally, the result of concatenation of all the elements.
*/
fun Array<String>.asSequenceWithConcatenation(): Sequence<String> =
sequence {
yieldAll(asSequence())

if (size > 1) {
yield(concatenated())
}
}

/**
* @return `true` if known-to-fail unit tests can be muted on the CI server.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@ import org.assertj.core.api.AbstractSoftAssertions
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.SoftAssertions.assertSoftly
import org.intellij.lang.annotations.Language
import org.junit.jupiter.api.MethodOrderer.MethodName
import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestMethodOrder
import org.opentest4j.MultipleFailuresError

import java.util.function.Consumer

@Suppress("LargeClass")
@TestMethodOrder(MethodName::class)
class IndentationRuleWarnTest : LintTestBase(::IndentationRule), IndentationRuleTestMixin {
private val ruleId = "$DIKTAT_RULE_SET_ID:${IndentationRule.NAME_ID}"
private val rulesConfigList = listOf(
Expand Down Expand Up @@ -864,14 +867,7 @@ class IndentationRuleWarnTest : LintTestBase(::IndentationRule), IndentationRule
}

assertSoftly { softly ->
sequence {
yieldAll(fragments.asSequence())

/*
* All fragments concatenated.
*/
yield(fragments.concatenated())
}.forEach { fragment ->
fragments.asSequenceWithConcatenation().forEach { fragment ->
softly.lintMethodSoftly(
fragment,
lintErrors = lintErrors,
Expand Down

0 comments on commit f7a71d8

Please sign in to comment.