Skip to content

Commit 14b3e80

Browse files
Automated commit of generated code
1 parent 9927dbf commit 14b3e80

File tree

3 files changed

+101
-0
lines changed

3 files changed

+101
-0
lines changed

core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/codeGen/GeneratedField.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ public class ValidFieldName private constructor(private val identifier: String,
130130
.replace("`", "'")
131131
.replace(";", " ")
132132
.replace("\\", " ")
133+
.replace("\n", " ")
134+
.replace("\r", " ")
133135
}
134136

135137
return ValidFieldName(result, needsQuote)

core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/codeGen/CodeGeneratorImpl.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,8 @@ internal open class ExtensionsCodeGeneratorImpl(private val typeRendering: TypeR
247247
.replace("\\", "\\\\")
248248
.replace("$", "\\\$")
249249
.replace("\"", "\\\"")
250+
.replace("\n", "\\n")
251+
.replace("\r", "\\r")
250252

251253
private fun String.removeQuotes() = this.removeSurrounding("`")
252254

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package org.jetbrains.kotlinx.dataframe.codeGen
2+
3+
import io.kotest.matchers.shouldBe
4+
import org.junit.Test
5+
6+
class ValidFieldNameOfTest {
7+
8+
data class Case(val input: String, val expected: String, val needsQuote: Boolean)
9+
10+
@Test
11+
fun `ValidFieldName of covers diverse inputs`() {
12+
val cases = listOf(
13+
// simple valid identifiers (no quoting)
14+
Case("abc", "abc", false),
15+
Case("a_b9", "a_b9", false),
16+
Case("AbC123", "AbC123", false),
17+
Case("Привет", "Привет", false), // Cyrillic letters are letters
18+
Case("mañana", "mañana", false), // Latin letter with diacritic
19+
Case("Δelta", "Δelta", false), // Greek uppercase letter
20+
Case("__name", "__name", false),
21+
// needs quoting due to rules
22+
Case("_", "_", true), // all underscores
23+
Case("__", "__", true), // all underscores
24+
Case("1abc", "1abc", true), // starts with digit
25+
Case("", "", true), // empty
26+
Case(" ", " ", true), // blank (spaces)
27+
Case("fun", "fun", true), // modifier keyword
28+
Case("class", "class", true), // hard keyword
29+
Case("!in", "!in", true), // hard keyword (also special char)
30+
Case("hello world", "hello world", true), // contains space (special char per regex)
31+
Case("a-b", "a-b", true), // '-' is quoted char, not replaced
32+
Case("a|b", "a|b", true), // '|' is quoted char, not replaced
33+
Case("a?b", "a?b", true),
34+
Case("a!b", "a!b", true),
35+
Case("a@b", "a@b", true),
36+
Case("a#b", "a#b", true),
37+
Case("a\$b", "a\$b", true),
38+
Case("a%b", "a%b", true),
39+
Case("a^b", "a^b", true),
40+
Case("a&b", "a&b", true),
41+
Case("a*b", "a*b", true),
42+
Case("a(b)c", "a(b)c", true), // parentheses are quoted, not replaced
43+
Case("{x}", "{x}", true), // braces are quoted, not replaced
44+
// quoting due to non-letter symbol categories
45+
Case("😀", "😀", true), // emoji
46+
Case("你好", "你好", true), // CJK: category OTHER_LETTER -> quote
47+
Case("", "", true), // Devanagari OTHER_LETTER -> quote
48+
Case("a\tb", "a\tb", true), // tab (CONTROL) -> quote, not replaced
49+
Case("a\u200Bb", "a\u200Bb", true), // zero-width space (FORMAT) -> quote
50+
// precise replacement tests when quoting is needed
51+
Case("<name>", "{name}", true), // < > -> { }
52+
Case("a::b", "a - b", true), // :: -> -
53+
Case("a:b", "a - b", true), // : -> -
54+
Case("a: b", "a - b", true), // : -> -
55+
Case("a.b", "a b", true), // . -> space
56+
Case("a/b", "a-b", true), // / -> -
57+
Case("a[b]", "a{b}", true), // [ ] -> { }
58+
Case("a`b", "a'b", true), // backtick -> apostrophe
59+
Case("a;b", "a b", true), // ; -> space
60+
Case("a\\b", "a b", true), // backslash -> space
61+
Case("a\nb", "a b", true), // newline -> space
62+
Case("a\rb", "a b", true), // carriage return -> space
63+
Case(
64+
"a.b/c[d]`e;f\\g\nh\ri",
65+
"a b-c{d}'e f g h i",
66+
true,
67+
),
68+
Case(": leading colon", " - leading colon", true), // ": " -> " - "
69+
Case("a:bc", "a - bc", true), // ":" -> " - "
70+
Case("a: bc", "a - bc", true), // ": " -> " - "
71+
Case("<tag>", "{tag}", true),
72+
Case("name<generic>", "name{generic}", true),
73+
Case("x>y", "x}y", true),
74+
Case("a.b.c", "a b c", true),
75+
Case("a/b/c", "a-b-c", true),
76+
// extra heavy special-symbol cases
77+
Case("::", " - ", true),
78+
Case(":::", " - - ", true),
79+
Case("...---", " ---", true),
80+
Case("//\\", "-- ", true),
81+
Case("[[]]<>", "{{}}{}", true),
82+
Case("x`;;`y", "x' 'y", true),
83+
Case("a:::b", "a - - b", true),
84+
Case("..a..", " a ", true),
85+
// already quoted stays as-is and does not need quoting
86+
Case("`already quoted`", "`already quoted`", false),
87+
)
88+
89+
cases.forEach { (input, expected, needsQuote) ->
90+
val vf = ValidFieldName.of(input)
91+
vf.unquoted shouldBe expected
92+
vf.needsQuote shouldBe needsQuote
93+
val expectedQuotedIfNeeded = if (needsQuote) "`$expected`" else expected
94+
vf.quotedIfNeeded shouldBe expectedQuotedIfNeeded
95+
}
96+
}
97+
}

0 commit comments

Comments
 (0)