Repository navigation
[review-factory test] textutil: keep acronyms together in CamelToSnakeCase #7633
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,11 +2,19 @@ package textutil | |
|
|
||
| import "unicode" | ||
|
|
||
| // CamelToSnakeCase converts camelCase or PascalCase to snake_case. A run of | ||
| // capitals is kept together as one word, so "HTTPServer" becomes "http_server" | ||
| // rather than "h_t_t_p_server". | ||
| func CamelToSnakeCase(name string) string { | ||
| out := make([]rune, 0, len(name)*2) | ||
| for i, r := range name { | ||
| runes := []rune(name) | ||
| out := make([]rune, 0, len(runes)*2) | ||
| for i, r := range runes { | ||
| if i > 0 && unicode.IsUpper(r) { | ||
| out = append(out, '_') | ||
| prev := runes[i-1] | ||
| nextIsLower := i+1 < len(runes) && unicode.IsLower(runes[i+1]) | ||
| if unicode.IsLower(prev) || unicode.IsDigit(prev) || (unicode.IsUpper(prev) && nextIsLower) { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. minor: Underscore is also dropped after any previous rune that is not lowercase, a digit, or an uppercase rune followed by lowercase; unannounced and untested The new condition
Evidence: Suggestion: decide which rule is intended and pin it with a test. At minimum add a Agreed by 2 reviewer model(s). |
||
| out = append(out, '_') | ||
| } | ||
| } | ||
| out = append(out, unicode.ToLower(r)) | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,6 +31,22 @@ func TestCamelToSnakeCase(t *testing.T) { | |
| input: "TestTestTest", | ||
| expected: "test_test_test", | ||
| }, | ||
| { | ||
| input: "HTTPServer", | ||
| expected: "http_server", | ||
| }, | ||
| { | ||
| input: "userID", | ||
| expected: "user_id", | ||
| }, | ||
| { | ||
| input: "getHTTPResponseCode", | ||
| expected: "get_http_response_code", | ||
| }, | ||
| { | ||
| input: "version2Beta", | ||
| expected: "version2_beta", | ||
| }, | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: Other behavior changes (all-caps input, non-letter before a capital, digit after an acronym) are not in the test table The new rule also changes outputs for inputs the table does not cover. Evidence: Agreed by 2 reviewer model(s). |
||
| } | ||
|
|
||
| for _, c := range cases { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: Doc comment overstates acronym handling: a run of capitals followed by a lowercase letter still splits (userIDs -> user_i_ds)
The doc comment says "A run of capitals is kept together as one word". That only holds when the run is followed by the end of the string, a digit, or another non-lowercase rune. When a lowercase rune follows the run, the last capital starts a new word (
unicode.IsUpper(prev) && nextIsLoweratcase.go:15). This is what givesHTTPServer->http_server, but it also splits plural acronyms and mixed-case names:userIDs->user_i_ds,IDs->i_ds,getURLs->get_ur_ls,MLflow->m_lflow,IPv4Address->i_pv4_address. The two-capital outputs are the same as before this PR, so this is not a regression, but a reader of the comment (and of the PR title) would expectuser_ids.Evidence: hand traces and a line-for-line Python port of the old and new bodies (no Go toolchain was available, so the Go test was not run). No entry in
case_test.go:14-49has an acronym followed by lowercase other than a full following word.Suggestion: state the rule as implemented (the last capital of a run begins the next word when a lowercase letter follows) and add a table entry such as
userIDsso the limitation is pinned deliberately. The reviewers do not think the algorithm needs to change, since plurals are ambiguous withHTTPServer.Agreed by 2 reviewer model(s).