#[cfg(test)]
mod tests {
#[test]
fn test_variable_name_camel_to_snake() {
let c_code = r#"
int myVariable = 42;
int userId = 100;
"#;
let rust_expected = r#"
let my_variable = 42;
let user_id = 100;
"#;
assert!(c_code.contains("myVariable"));
assert!(c_code.contains("userId"));
assert!(rust_expected.contains("my_variable"));
assert!(rust_expected.contains("user_id"));
}
#[test]
fn test_function_name_snake_case() {
let c_code = r#"
void processData() { }
int calculateSum(int a, int b) { }
"#;
let rust_expected = r#"
fn process_data() { }
fn calculate_sum(a: i32, b: i32) -> i32 { }
"#;
assert!(c_code.contains("processData"));
assert!(c_code.contains("calculateSum"));
assert!(rust_expected.contains("process_data"));
assert!(rust_expected.contains("calculate_sum"));
}
#[test]
fn test_type_name_pascal_case() {
let c_code = r#"
struct point { int x; int y; };
typedef struct point Point;
typedef int my_int_t;
"#;
let rust_expected = r#"
struct Point { x: i32, y: i32 }
// typedef eliminated
type MyInt = i32;
"#;
assert!(c_code.contains("my_int_t"));
assert!(rust_expected.contains("MyInt"));
assert!(rust_expected.contains("Point"));
}
#[test]
fn test_constant_name_screaming_snake() {
let c_code = r#"
#define MAX_SIZE 100
#define BUFFER_LEN 256
const int DEFAULT_VALUE = 42;
"#;
let rust_expected = r#"
const MAX_SIZE: usize = 100;
const BUFFER_LEN: usize = 256;
const DEFAULT_VALUE: i32 = 42;
"#;
assert!(c_code.contains("MAX_SIZE"));
assert!(rust_expected.contains("MAX_SIZE"));
assert!(c_code.contains("DEFAULT_VALUE"));
assert!(rust_expected.contains("DEFAULT_VALUE"));
}
#[test]
fn test_static_name_screaming_snake() {
let c_code = r#"
static int counter = 0;
static const char* VERSION = "1.0";
"#;
let rust_expected = r#"
static COUNTER: i32 = 0;
static VERSION: &str = "1.0";
"#;
assert!(c_code.contains("counter"));
assert!(rust_expected.contains("COUNTER"));
assert!(rust_expected.contains("VERSION"));
}
#[test]
fn test_enum_variant_pascal_case() {
let c_code = r#"
enum Color {
RED,
GREEN,
BLUE
};
"#;
let rust_expected = r#"
enum Color {
Red,
Green,
Blue,
}
"#;
assert!(c_code.contains("RED"));
assert!(c_code.contains("GREEN"));
assert!(rust_expected.contains("Red"));
assert!(rust_expected.contains("Green"));
}
#[test]
fn test_module_name_snake_case() {
let c_code = r#"
// File: DataProcessor.h
// or: data_processor.h
"#;
let rust_expected = r#"
// File: data_processor.rs
// Module: mod data_processor;
"#;
assert!(c_code.contains("DataProcessor") || c_code.contains("data_processor"));
assert!(rust_expected.contains("data_processor"));
}
#[test]
fn test_macro_name_screaming_snake() {
let c_code = r#"
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define DEBUG_PRINT(x) printf("%d\n", x)
"#;
let rust_expected = r#"
macro_rules! min {
($a:expr, $b:expr) => {
if $a < $b { $a } else { $b }
}
}
// Or function: fn min(a: i32, b: i32) -> i32
"#;
assert!(c_code.contains("MIN"));
assert!(rust_expected.contains("min"));
}
#[test]
fn test_underscore_prefix() {
let c_code = r#"
static int _privateCounter = 0;
void _internalFunction() { }
"#;
let _rust_expected = r#"
static PRIVATE_COUNTER: i32 = 0;
fn internal_function() { }
// Or: fn _internal_function() { } (unused warning suppression)
"#;
assert!(c_code.contains("_privateCounter"));
assert!(c_code.contains("_internalFunction"));
}
#[test]
fn test_abbreviations_in_names() {
let c_code = r#"
int httpStatus;
int URLParser;
typedef struct HTTPRequest HTTPRequest;
"#;
let rust_expected = r#"
let http_status: i32;
let url_parser: i32;
struct HttpRequest { }
"#;
assert!(c_code.contains("httpStatus"));
assert!(c_code.contains("URLParser"));
assert!(rust_expected.contains("http_status"));
assert!(rust_expected.contains("url_parser"));
assert!(rust_expected.contains("HttpRequest"));
}
#[test]
fn test_numbers_in_identifiers() {
let c_code = r#"
int value1;
int value2;
struct Point2D { int x; int y; };
"#;
let rust_expected = r#"
let value1: i32;
let value2: i32;
struct Point2d { x: i32, y: i32 }
"#;
assert!(c_code.contains("value1"));
assert!(c_code.contains("Point2D"));
assert!(rust_expected.contains("value1"));
assert!(rust_expected.contains("Point2d"));
}
#[test]
fn test_reserved_keyword_conflicts() {
let c_code = r#"
int type = 42; // 'type' not reserved in C
int match = 10; // 'match' not reserved in C
int loop = 5; // 'loop' not reserved in C
"#;
let rust_expected = r#"
let r#type = 42; // 'type' is Rust keyword
let r#match = 10; // 'match' is Rust keyword
let r#loop = 5; // 'loop' is Rust keyword
"#;
assert!(c_code.contains("int type"));
assert!(c_code.contains("int match"));
assert!(rust_expected.contains("r#type"));
assert!(rust_expected.contains("r#match"));
}
#[test]
fn test_hungarian_notation() {
let c_code = r#"
int nCount;
char* pszName;
bool bEnabled;
"#;
let rust_expected = r#"
let count: i32; // Remove 'n' prefix
let name: &str; // Remove 'psz' prefix
let enabled: bool; // Remove 'b' prefix
"#;
assert!(c_code.contains("nCount"));
assert!(c_code.contains("pszName"));
assert!(rust_expected.contains("let count"));
assert!(rust_expected.contains("let name"));
}
#[test]
fn test_struct_member_names() {
let c_code = r#"
struct Person {
char firstName[50];
int userId;
bool isActive;
};
"#;
let rust_expected = r#"
struct Person {
first_name: [u8; 50],
user_id: i32,
is_active: bool,
}
"#;
assert!(c_code.contains("firstName"));
assert!(c_code.contains("userId"));
assert!(rust_expected.contains("first_name"));
assert!(rust_expected.contains("user_id"));
}
#[test]
fn test_function_parameter_names() {
let c_code = r#"
void setUserName(int userId, const char* userName) {
// ...
}
"#;
let rust_expected = r#"
fn set_user_name(user_id: i32, user_name: &str) {
// ...
}
"#;
assert!(c_code.contains("userId"));
assert!(c_code.contains("userName"));
assert!(rust_expected.contains("user_id"));
assert!(rust_expected.contains("user_name"));
}
#[test]
fn test_global_vs_local_naming() {
let c_code = r#"
int globalCounter = 0; // Global
static int fileCounter = 0; // File scope
void function() {
int localCounter = 0; // Local
}
"#;
let rust_expected = r#"
// Module-level (like C global)
static GLOBAL_COUNTER: i32 = 0;
static FILE_COUNTER: i32 = 0;
fn function() {
let local_counter = 0;
}
"#;
assert!(c_code.contains("globalCounter"));
assert!(c_code.contains("localCounter"));
assert!(rust_expected.contains("GLOBAL_COUNTER"));
assert!(rust_expected.contains("local_counter"));
}
#[test]
fn test_naming_transformation_summary() {
let c_code = r#"
// Rule 1: Variables → snake_case
int myVariable;
// Rule 2: Functions → snake_case
void processData() { }
// Rule 3: Types → PascalCase
typedef struct point Point;
// Rule 4: Constants → SCREAMING_SNAKE_CASE
#define MAX_SIZE 100
// Rule 5: Static → SCREAMING_SNAKE_CASE
static int counter;
// Rule 6: Enum variants → PascalCase
enum Color { RED, GREEN };
// Rule 7: Keyword conflicts → r#
int type;
"#;
let rust_expected = r#"
// Rule 1: Enforced snake_case
let my_variable: i32;
// Rule 2: Enforced snake_case
fn process_data() { }
// Rule 3: Required PascalCase
struct Point { }
// Rule 4: Required SCREAMING
const MAX_SIZE: i32 = 100;
// Rule 5: Required SCREAMING
static COUNTER: i32;
// Rule 6: PascalCase variants
enum Color { Red, Green }
// Rule 7: Raw identifier
let r#type: i32;
"#;
assert!(c_code.contains("myVariable"));
assert!(rust_expected.contains("my_variable"));
assert!(c_code.contains("processData"));
assert!(rust_expected.contains("process_data"));
assert!(c_code.contains("Point"));
assert!(c_code.contains("MAX_SIZE"));
assert!(c_code.contains("int type"));
assert!(rust_expected.contains("r#type"));
}
}