Skip to content

Commit 4b5f883

Browse files
committed
Don't treat CARGO_BIN_EXE_renamify as screaming snake case - preserve the lowercase text during replacement
1 parent 5b264a7 commit 4b5f883

File tree

2 files changed

+124
-13
lines changed

2 files changed

+124
-13
lines changed

renamify-core/src/case_model.rs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -82,19 +82,10 @@ pub fn detect_style(s: &str) -> Option<Style> {
8282
// Mixed case with underscores - treat as screaming snake if it starts with
8383
// uppercase identifier followed by underscore
8484
(true, false, false, false, true, true) => {
85-
// Check if this looks like PREFIX_identifier pattern
86-
// e.g., PRODUCTION_old_name, DEBUG_old_name
87-
if let Some(first_underscore_pos) = s.find('_') {
88-
let prefix = &s[..first_underscore_pos];
89-
// If the prefix is all uppercase, treat as screaming snake
90-
if !prefix.is_empty() && prefix.bytes().all(|b| b.is_ascii_uppercase()) {
91-
Some(Style::ScreamingSnake)
92-
} else {
93-
Some(Style::Snake)
94-
}
95-
} else {
96-
Some(Style::Snake)
97-
}
85+
// Mixed case with underscores - this is NOT a standard style
86+
// Examples: CARGO_BIN_EXE_foobar, DEBUG_mode, PREFIX_camelCase
87+
// These should preserve the exact case of the matched portion
88+
None
9889
},
9990
(false, true, false, false, false, true) => Some(Style::Kebab),
10091
(false, true, false, false, true, false) => Some(Style::ScreamingTrain), // ALL-CAPS-WITH-HYPHENS
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
use renamify_core::{apply_plan, scan_repository, ApplyOptions, PlanOptions};
2+
use std::fs;
3+
use tempfile::TempDir;
4+
5+
#[test]
6+
fn test_mixed_case_prefix_replacement() {
7+
// Test that when replacing lowercase identifiers that appear after uppercase prefixes,
8+
// the replacement maintains the correct case (lowercase) rather than being coerced to uppercase
9+
10+
let temp_dir = TempDir::new().unwrap();
11+
let test_file = temp_dir.path().join("test.rs");
12+
13+
// Test content with CARGO_BIN_EXE_ prefix followed by lowercase identifier
14+
let content = r#"
15+
fn main() {
16+
// This tests the CARGO_BIN_EXE_ pattern where the suffix should remain lowercase
17+
let path = env!("CARGO_BIN_EXE_foobar");
18+
let another = env!("CARGO_BIN_EXE_foobar");
19+
20+
// Also test with other mixed patterns
21+
const PREFIX_foobar: &str = "test";
22+
let DEBUG_foobar_enabled = true;
23+
24+
// Regular lowercase should still work
25+
let foobar_config = "config";
26+
let simple_foobar = "test";
27+
}
28+
"#;
29+
30+
fs::write(&test_file, content).unwrap();
31+
32+
// Search for "foobar" and replace with "baz_qux"
33+
let mut plan = scan_repository(
34+
temp_dir.path(),
35+
"foobar",
36+
"baz_qux",
37+
&PlanOptions::default(),
38+
)
39+
.unwrap();
40+
41+
// Apply the plan
42+
apply_plan(&mut plan, &ApplyOptions::default()).unwrap();
43+
44+
// Read the modified content
45+
let result = fs::read_to_string(&test_file).unwrap();
46+
47+
// The key assertion: CARGO_BIN_EXE_foobar should become CARGO_BIN_EXE_baz_qux
48+
// NOT CARGO_BIN_EXE_BAZ_QUX
49+
assert!(
50+
result.contains(r#"env!("CARGO_BIN_EXE_baz_qux")"#),
51+
"Expected CARGO_BIN_EXE_baz_qux (lowercase), but got: {}",
52+
result
53+
);
54+
55+
// Other mixed patterns should also preserve the lowercase
56+
assert!(
57+
result.contains("PREFIX_baz_qux"),
58+
"Expected PREFIX_baz_qux (lowercase suffix)"
59+
);
60+
assert!(
61+
result.contains("DEBUG_baz_qux_enabled"),
62+
"Expected DEBUG_baz_qux_enabled (lowercase in middle)"
63+
);
64+
65+
// Regular lowercase replacements
66+
assert!(result.contains("baz_qux_config"));
67+
assert!(result.contains("simple_baz_qux"));
68+
}
69+
70+
#[test]
71+
fn test_screaming_snake_with_lowercase_suffix() {
72+
// More specific test for the SCREAMING_SNAKE_lowercase pattern
73+
let temp_dir = TempDir::new().unwrap();
74+
let test_file = temp_dir.path().join("build.rs");
75+
76+
let content = r#"
77+
// Build script with environment variables
78+
const CARGO_PKG_NAME_oldtool: &str = "oldtool";
79+
const CARGO_BIN_EXE_oldtool: &str = "/path/to/oldtool";
80+
const RUST_VERSION_oldtool: &str = "1.70.0";
81+
82+
// Should not change fully uppercase
83+
const CARGO_OLDTOOL_VERSION: &str = "1.0.0";
84+
"#;
85+
86+
fs::write(&test_file, content).unwrap();
87+
88+
// Replace "oldtool" with "new_tool"
89+
let mut plan = scan_repository(
90+
temp_dir.path(),
91+
"oldtool",
92+
"new_tool",
93+
&PlanOptions::default(),
94+
)
95+
.unwrap();
96+
97+
apply_plan(&mut plan, &ApplyOptions::default()).unwrap();
98+
99+
let result = fs::read_to_string(&test_file).unwrap();
100+
101+
// These should have lowercase replacements
102+
assert!(
103+
result.contains("CARGO_PKG_NAME_new_tool"),
104+
"Expected lowercase new_tool after CARGO_PKG_NAME_"
105+
);
106+
assert!(
107+
result.contains("CARGO_BIN_EXE_new_tool"),
108+
"Expected lowercase new_tool after CARGO_BIN_EXE_"
109+
);
110+
assert!(
111+
result.contains("RUST_VERSION_new_tool"),
112+
"Expected lowercase new_tool after RUST_VERSION_"
113+
);
114+
115+
// This should be fully uppercase since the original was fully uppercase
116+
assert!(
117+
result.contains("CARGO_NEW_TOOL_VERSION"),
118+
"Expected uppercase NEW_TOOL when replacing within fully uppercase context"
119+
);
120+
}

0 commit comments

Comments
 (0)