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

Inconsistency: "1a".to_snake_case() == "1a", but "1aa".to_snake_case() == "1_aa". #86734

Closed
nathanfranke opened this issue Jan 3, 2024 · 3 comments · Fixed by #86639
Closed

Comments

@nathanfranke
Copy link
Contributor

Tested versions

Reproducible in:
3.5.3.stable using capitalize
4.2.1.stable using capitalize and to_snake_case.

System information

Linux on kernel 6.6.7-arch1-1

Issue description

extends Node

func _ready():
	print("1a".capitalize())
	print("1aa".capitalize())
	print("1a".to_snake_case())
	print("1aa".to_snake_case())

Output:

1a
1 Aa
1a
1_aa

Expected:

1 A
1 Aa
1_a
1_aa

Steps to reproduce

https://gd.tumeo.space/?KYDwLsB2AmDOAEA5A9tYAodAzArpAxvAPoBOwAhtAJ4AUAlAFzoCQADiQJaRg0BEAjOV4A6fOVYcw5ADYcAXsHp0W7LjwHkho8ZJnzFdZW07c+gkWGRFYkcgGtgRMbANHVpjVsvXbDp+RclIA

Minimal reproduction project (MRP)

to_snake_case_4.2.1.zip

@nathanfranke nathanfranke changed the title Inconsistency: "1a".to_snake_case() == "1a", but "1aa".to_snake_case() == "1_aa". Same problem with capitalize(). Inconsistency: "1a".to_snake_case() == "1a", but "1aa".to_snake_case() == "1_aa". Jan 3, 2024
@dalexeev
Copy link
Member

dalexeev commented Jan 3, 2024

This is made to handle "2D"/"3D" and "str2var", "var2bytes", etc. (replaced by _to_). See test cases.

godot/core/string/ustring.cpp

Lines 1060 to 1063 in 07b8860

const bool cond_a = is_prev_lower && is_curr_upper; // aA
const bool cond_b = (is_prev_upper || is_prev_digit) && is_curr_upper && is_next_lower; // AAa, 2Aa
const bool cond_c = is_prev_digit && is_curr_lower && is_next_lower; // 2aa
const bool cond_d = (is_prev_upper || is_prev_lower) && is_curr_digit; // A2, a2

TEST_CASE("[String] Checking case conversion methods") {
StringCasesTestCase test_cases[] = {
/* clang-format off */
{ "2D", "2d", "2d", "2d" },
{ "2d", "2d", "2d", "2d" },
{ "2db", "2Db", "2Db", "2_db" },
{ "Vector3", "vector3", "Vector3", "vector_3" },
{ "sha256", "sha256", "Sha256", "sha_256" },
{ "Node2D", "node2d", "Node2d", "node_2d" },
{ "RichTextLabel", "richTextLabel", "RichTextLabel", "rich_text_label" },
{ "HTML5", "html5", "Html5", "html_5" },
{ "Node2DPosition", "node2dPosition", "Node2dPosition", "node_2d_position" },
{ "Number2Digits", "number2Digits", "Number2Digits", "number_2_digits" },
{ "get_property_list", "getPropertyList", "GetPropertyList", "get_property_list" },
{ "get_camera_2d", "getCamera2d", "GetCamera2d", "get_camera_2d" },
{ "_physics_process", "physicsProcess", "PhysicsProcess", "_physics_process" },
{ "bytes2var", "bytes2Var", "Bytes2Var", "bytes_2_var" },
{ "linear2db", "linear2Db", "Linear2Db", "linear_2_db" },
{ "sha256sum", "sha256Sum", "Sha256Sum", "sha_256_sum" },
{ "camelCase", "camelCase", "CamelCase", "camel_case" },
{ "PascalCase", "pascalCase", "PascalCase", "pascal_case" },
{ "snake_case", "snakeCase", "SnakeCase", "snake_case" },
{ "Test TEST test", "testTestTest", "TestTestTest", "test_test_test" },
{ nullptr, nullptr, nullptr, nullptr },
/* clang-format on */
};

@Mickeon
Copy link
Contributor

Mickeon commented Jan 4, 2024

A few small examples for the casing may do the trick, like in capitalize()

@Mickeon
Copy link
Contributor

Mickeon commented Jan 4, 2024

I updated #86639 with some examples for this, as well. Feel free to suggest examples if necessary.

@AThousandShips AThousandShips added this to the 4.3 milestone Jan 4, 2024
YuriSizov pushed a commit to YuriSizov/godot that referenced this issue Jan 24, 2024
YuriSizov pushed a commit to YuriSizov/godot that referenced this issue Jan 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants