Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding a test to validate line numbers and fix for multiline strings #217

Merged
merged 13 commits into from
May 7, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@ public class TomlMainDecoder(
is TomlKeyValuePrimitive -> node
is TomlKeyValueArray -> node
// empty nodes will be filtered by iterateUntilWillFindAnyKnownName() method, but in case we came into this
// branch, we should throw an exception as it is not expected at all and we should catch this in tests
// branch, we should throw an exception as it is not expected at all, and we should catch this in tests
else ->
throw InternalDecodingException(
"Node of type [${node::class}] should not be processed in TomlDecoder.decodeValue(): <${node.content}>."
"Node of type [${node::class}] should not be processed in TomlDecoder.decodeValue(): <${node}>."

Check failure

Code scanning / ktlint

[STRING_TEMPLATE_CURLY_BRACES] string template has redundant curly braces: ${node}

[STRING_TEMPLATE_CURLY_BRACES] string template has redundant curly braces: ${node}

Check failure

Code scanning / ktlint

[STRING_TEMPLATE_CURLY_BRACES] string template has redundant curly braces: ${node}

[STRING_TEMPLATE_CURLY_BRACES] string template has redundant curly braces: ${node}
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,6 @@ public sealed class TomlNode(
comments: List<String>,
public val inlineComment: String
) {
@Deprecated(
message = "content was replaced with toString; will be removed in future releases.",
replaceWith = ReplaceWith("toString()")
)
@Suppress("CUSTOM_GETTERS_SETTERS")
public val content: String get() = toString()

/**
* A list of comments prepended to the node.
*/
Expand Down Expand Up @@ -187,20 +180,22 @@ public sealed class TomlNode(

/**
* print the structure of parsed AST tree
* Important: as prettyPrint calls toString() of the node, and not just prints the value, but emits and reconstruct a source string,
* so in some cases (for example in case of multiline strings) it can work incorrectly.
*/
@Suppress("DEBUG_PRINT")
public fun prettyPrint() {
public fun prettyPrint(emitLine: Boolean = false) {
val sb = StringBuilder()
prettyPrint(this, sb)
prettyPrint(this, sb, emitLine)
println(sb.toString())
}

/**
* @return the string with AST tree visual representation
*/
public fun prettyStr(): String {
public fun prettyStr(emitLine: Boolean = false): String {
val sb = StringBuilder()
prettyPrint(this, sb)
prettyPrint(this, sb, emitLine)
return sb.toString()
}

Expand Down Expand Up @@ -233,37 +228,6 @@ public sealed class TomlNode(
}
}

@Deprecated(
message = "TomlConfig is deprecated; use TomlOutputConfig instead. Will be removed in next releases.",
replaceWith = ReplaceWith(
"write(emitter, config, multiline)",
"com.akuleshov7.ktoml.TomlOutputConfig"
)
)
public fun write(
emitter: TomlEmitter,
config: TomlConfig,
multiline: Boolean = false
): Unit = write(emitter, config.output, multiline)

/**
* Writes this node as text to [emitter].
*
* @param emitter The [TomlEmitter] instance to write to.
* @param config The [TomlConfig] instance. Defaults to the node's config.
* @param multiline Whether to write the node over multiple lines, if possible.
*/
@Deprecated(
message = "The multiline parameter overload is deprecated, use the multiline" +
" property on supported TomlValue types instead. Will be removed in next releases.",
replaceWith = ReplaceWith("write(emitter, config)")
)
public fun write(
emitter: TomlEmitter,
config: TomlOutputConfig = TomlOutputConfig(),
multiline: Boolean = false
): Unit = write(emitter, config)

/**
* Writes this node as text to [emitter].
*
Expand Down Expand Up @@ -328,6 +292,10 @@ public sealed class TomlNode(
.writeNode(this)
.replace(" = ", "=")

internal fun print(emitLine: Boolean = false): String =
"${this::class.simpleName} ($this)${if (emitLine) "[line:${this.lineNo}]" else ""}\n"

Check failure

Code scanning / ktlint

[TOO_MANY_BLANK_LINES] too many consecutive blank lines: do not use more than two consecutive blank lines

[TOO_MANY_BLANK_LINES] too many consecutive blank lines: do not use more than two consecutive blank lines

Check failure

Code scanning / ktlint

[TOO_MANY_BLANK_LINES] too many consecutive blank lines: do not use more than two consecutive blank lines

[TOO_MANY_BLANK_LINES] too many consecutive blank lines: do not use more than two consecutive blank lines


public companion object {
// number of spaces that is used to indent levels
internal const val INDENTING_LEVEL = 4
Expand All @@ -342,12 +310,14 @@ public sealed class TomlNode(
public fun prettyPrint(
node: TomlNode,
result: StringBuilder,
emitLine: Boolean = false,
level: Int = 0
) {
val spaces = " ".repeat(INDENTING_LEVEL * level)
result.append("$spaces - ${node::class.simpleName} ($node)\n")
// we are using print() method here instead of toString()
result.append("$spaces - ${node.print(emitLine)}")
node.children.forEach { child ->
prettyPrint(child, result, level + 1)
prettyPrint(child, result, emitLine, level + 1, )

Check failure

Code scanning / ktlint

[WRONG_WHITESPACE] incorrect usage of whitespaces for code separation: ) should have 0 space(s) before, but has 1 space(s) before

[WRONG_WHITESPACE] incorrect usage of whitespaces for code separation: ) should have 0 space(s) before, but has 1 space(s) before

Check failure

Code scanning / ktlint

[WRONG_WHITESPACE] incorrect usage of whitespaces for code separation: ) should have 0 space(s) before, but has 1 space(s) before

[WRONG_WHITESPACE] incorrect usage of whitespaces for code separation: ) should have 0 space(s) before, but has 1 space(s) before
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class TomlLiteralString internal constructor(
content: String,
lineNo: Int,
config: TomlInputConfig = TomlInputConfig()
) : this(content.verifyAndTrimQuotes(lineNo, config))
) : this(content.verifyAndTrimQuotes(lineNo, config), content.contains("\n"))

@Deprecated(
message = "TomlConfig is deprecated; use TomlInputConfig instead. Will be removed in next releases."
Expand All @@ -45,7 +45,7 @@ public class TomlLiteralString internal constructor(

override fun write(
emitter: TomlEmitter,
config: TomlOutputConfig
config: TomlOutputConfig,
) {
val content = content as String

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.akuleshov7.ktoml.parsers

import com.akuleshov7.ktoml.Toml
import com.akuleshov7.ktoml.tree.nodes.TomlKeyValuePrimitive
import kotlin.test.Test
import kotlin.test.assertContentEquals
import kotlin.test.assertEquals

class SetLineNoTest {
@Test
fun checkingLineNumbers() {
val string = """

# comment 1

[a] # comment 2
# comment 3
test = 1 # comment 4

# ====

[[a.b]] # comment 5
test = 1

mls = '''
1
2
3
'''

mla = [
"a",
"b",
"c"
orchestr7 marked this conversation as resolved.
Show resolved Hide resolved
]
""".trimIndent()
val parsedToml = Toml.tomlParser.parseString(string)

parsedToml.prettyPrint(true)
assertEquals(
"""
| - TomlFile (rootNode)[line:0]
| - TomlTablePrimitive ([a])[line:4]
| - TomlKeyValuePrimitive (test=1)[line:6]
| - TomlArrayOfTables ([[a.b]])[line:10]
| - TomlArrayOfTablesElement (technical_node)[line:10]
| - TomlKeyValuePrimitive (test=1)[line:11]
| - TomlKeyValuePrimitive (mls=''' 1
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's a little bit weird, cause it looks like we forget to put a newline after multiline string delimiters

Copy link
Owner Author

@orchestr7 orchestr7 May 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NightEule5 while we encode the string, I think it is necessary for the user to have a proper formatting of multiline strings. Now we have the following:

a = """1
2
3"""

I think (even the TOML spec is confusing here) that we should add a newline there (it will be more convenient):

a = """
1
2
3
"""

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, true

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And of course I have forgotten to trim spaces before the quotes ''' while decoding 😢
#221

| 2
| 3
| ''')[line:13]
| - TomlKeyValueArray (mla=[ "a", "b", "c" ])[line:18]
|
""".trimMargin(),
parsedToml.prettyStr(true)
)
}
}