Skip to content

Commit

Permalink
Added uppercase functionality (#15)
Browse files Browse the repository at this point in the history
* added uppercase arg in clap

* added uppercase to Config and ConfigFile structs.

* implemented uppercase functionality

* added uppercase ratio to CLAP args

* added uppercase ratio to Config, ConfigFile and related functions

* implemented uppercase ratio logic

* modified string vector in memory instead of cloning in function
  • Loading branch information
MercMayhem authored Oct 5, 2023
1 parent 649fb30 commit 024af7d
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 3 deletions.
9 changes: 9 additions & 0 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,13 @@ pub struct Args {
/// path to dictionary file
#[arg(long)]
pub dictionary_path: Option<String>,

/// indicates if test should include words beginning with uppercase letters
#[arg(short, long)]
pub uppercase: Option<bool>,

/// uppercase-ratio argument
#[arg(long)]
pub uppercase_ratio: Option<f64>,

}
34 changes: 34 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ pub struct Config {
pub numbers: bool,
pub numbers_ratio: f64,
pub dictionary_path: PathBuf,
pub uppercase: bool,
pub uppercase_ratio: f64,
}

/// Used by `serde` crate to parse config file into a rust struct
Expand All @@ -54,6 +56,8 @@ struct ConfigFile {
pub numbers: Option<bool>,
pub numbers_ratio: Option<f64>,
pub dictionary_path: Option<String>,
pub uppercase: Option<bool>,
pub uppercase_ratio: Option<f64>
}

#[automock]
Expand All @@ -65,6 +69,8 @@ impl Config {
numbers: false,
numbers_ratio: 0.05,
dictionary_path: PathBuf::from("src/dict/words.txt"),
uppercase: false,
uppercase_ratio: 0.45
}
}

Expand Down Expand Up @@ -120,6 +126,16 @@ fn augment_config_with_config_file(config: &mut Config, mut config_file: fs::Fil
if let Some(dictionary_path) = config_from_file.dictionary_path {
config.dictionary_path = PathBuf::from(dictionary_path);
}

if let Some(uppercase) = config_from_file.uppercase {
config.uppercase = uppercase;
}

if let Some(uppercase_ratio) = config_from_file.uppercase_ratio {
if uppercase_ratio >= 0.0 && uppercase_ratio <= 1.0 {
config.uppercase_ratio = uppercase_ratio
}
}
}

Ok(())
Expand Down Expand Up @@ -150,6 +166,16 @@ fn augment_config_with_args(config: &mut Config, args: Args) {
if let Some(dictionary_path) = args.dictionary_path {
config.dictionary_path = PathBuf::from(dictionary_path);
}

if let Some(uppercase_flag) = args.uppercase {
config.uppercase = uppercase_flag
}

if let Some(uppercase_ratio) = args.uppercase_ratio {
if uppercase_ratio >= 0.0 && uppercase_ratio <= 1.0 {
config.uppercase_ratio = uppercase_ratio
}
}
}

#[cfg(test)]
Expand All @@ -174,6 +200,8 @@ mod tests {
numbers: None,
numbers_ratio: None,
dictionary_path: None,
uppercase: None,
uppercase_ratio: None
};
let config = Config::new(args, PathBuf::new()).expect("Unable to create config");

Expand All @@ -194,6 +222,8 @@ mod tests {
numbers: None,
numbers_ratio: None,
dictionary_path: None,
uppercase: None,
uppercase_ratio: None
};
let config =
Config::new(args, config_file.path().to_path_buf()).expect("Unable to create config");
Expand All @@ -210,6 +240,8 @@ mod tests {
numbers: Some(true),
numbers_ratio: None,
dictionary_path: None,
uppercase: None,
uppercase_ratio: None
};
let config = Config::new(args, PathBuf::new()).expect("Unable to create config");

Expand All @@ -230,6 +262,8 @@ mod tests {
numbers: Some(false),
numbers_ratio: None,
dictionary_path: Some(String::from("/etc/dict/words")),
uppercase: None,
uppercase_ratio: None
};
let config =
Config::new(args, config_file.path().to_path_buf()).expect("Unable to create config");
Expand Down
32 changes: 29 additions & 3 deletions src/expected_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,22 @@ impl ExpectedInput {
let mut string_vec: Vec<String> = str_vec.iter().map(|s| s.to_string()).collect();
str_vec.shuffle(&mut rng);

// creating a pointer which points to where the words starts in the vector to help with uppercase words since we replace
// words in the beginning with numbers when numbers are enabled.
let mut words_start_pos:usize = 0;

if config.numbers == true {
replace_words_with_numbers(&mut string_vec, &mut rng, config.numbers_ratio);
words_start_pos = replace_words_with_numbers(&mut string_vec, &mut rng, config.numbers_ratio);
str_vec = string_vec.iter().map(|s| s.as_str()).collect();
}

if config.uppercase == true {
create_uppercase_words(&mut string_vec, words_start_pos, config.uppercase_ratio);
str_vec = string_vec.iter().map(|s| s.as_str()).collect();
str_vec.shuffle(&mut rng);
}

str_vec.shuffle(&mut rng);

let str = str_vec.join(" ").trim().to_string();

Ok(Self { str })
Expand All @@ -60,7 +69,7 @@ fn replace_words_with_numbers(
string_vec: &mut Vec<String>,
rng: &mut rand::rngs::ThreadRng,
numbers_ratio: f64,
) {
) -> usize {
let change_to_num_treshold = (numbers_ratio * string_vec.len() as f64).round() as usize;

*string_vec = string_vec
Expand All @@ -76,6 +85,21 @@ fn replace_words_with_numbers(
return word.to_string();
})
.collect();

return change_to_num_treshold - 1
}

fn create_uppercase_words (string_vec: &mut Vec<String>, pos: usize, uppercase_ratio: f64) {
// let mut string_vec2 = string_vec.clone();
let num_uppercase_words = (uppercase_ratio * string_vec[pos..].len() as f64).round() as usize;
for i in pos..pos+num_uppercase_words{
if string_vec[i] != ""{
let mut v: Vec<char> = string_vec[i].chars().collect();
v[0] = v[0].to_uppercase().nth(0).unwrap();
let s: String = v.into_iter().collect();
string_vec[i] = s;
}
}
}

/// extracted to trait to create mock with `mockall` crate
Expand Down Expand Up @@ -123,6 +147,8 @@ mod tests {
numbers: false,
numbers_ratio: 0.05,
dictionary_path: config_file.path().to_path_buf(),
uppercase: false,
uppercase_ratio: 0.45
};

let expected_input = ExpectedInput::new(&config).expect("unable to create expected input");
Expand Down

0 comments on commit 024af7d

Please sign in to comment.