testing overhall

This commit is contained in:
Simon Gardling 2022-03-22 10:07:02 -04:00
parent d1d48f2838
commit ac89f3eb19
2 changed files with 137 additions and 74 deletions

View File

@ -19,3 +19,4 @@
12. fix integral display 12. fix integral display
13. Improve loading indicator 13. Improve loading indicator
14. Hash asset tarball and compare hash on runtime 14. Hash asset tarball and compare hash on runtime
15. add comments in `parsing::process_func_str` for it to be better understandable

View File

@ -95,50 +95,71 @@ pub fn process_func_str(function_in: &str) -> String {
' ' ' '
}; };
let c_is_number = NUMBERS.contains(&c);
let c_is_letter = LETTERS.contains(&c);
let c_is_variable = VALID_VARIABLES.contains(&c);
let prev_char_is_variable = VALID_VARIABLES.contains(&prev_char);
let prev_char_is_number = NUMBERS.contains(&prev_char);
// makes special case for log with base of a 1-2 digit number
if (prev_prev_prev_char == 'l') if (prev_prev_prev_char == 'l')
&& (prev_prev_char == 'o') && (prev_prev_char == 'o')
&& (prev_char == 'g') && (prev_char == 'g')
&& (NUMBERS.contains(&c)) && (c_is_number)
{ {
prev_chars.push(c); prev_chars.push(c);
output_string += &c.to_string(); output_string += &c.to_string();
continue; continue;
} }
let c_letters_var = LETTERS.contains(&c) | VALID_VARIABLES.contains(&c); let c_letters_var = c_is_letter | c_is_variable;
let prev_letters_var = VALID_VARIABLES.contains(&prev_char) | LETTERS.contains(&prev_char); let prev_letters_var = prev_char_is_variable | LETTERS.contains(&prev_char);
if prev_char == ')' { if prev_char == ')' {
if (c == '(') | NUMBERS.contains(&c) | c_letters_var { // cases like `)x` like `(2x+3)x`
if c_letters_var {
add_asterisk = true; add_asterisk = true;
} }
// cases like `(x+1)2`
if c_is_number {
add_asterisk = true;
}
// cases such as `)(` like `(x+1)(x-3)`
if c == '(' {
add_asterisk = true
}
} else if c == '(' { } else if c == '(' {
if (VALID_VARIABLES.contains(&prev_char) if (prev_char_is_variable | (')' == prev_char) | prev_char_is_number)
| (')' == prev_char)
| NUMBERS.contains(&prev_char))
&& !LETTERS.contains(&prev_prev_char) && !LETTERS.contains(&prev_prev_char)
{ {
add_asterisk = true; add_asterisk = true;
} }
} else if NUMBERS.contains(&prev_char) { } else if prev_char_is_number {
if (c == '(') | c_letters_var { if (c == '(') | c_letters_var {
add_asterisk = true; add_asterisk = true;
} }
} else if LETTERS.contains(&c) { } else if c_is_letter {
if NUMBERS.contains(&prev_char) if prev_char_is_number
| (VALID_VARIABLES.contains(&prev_char) && VALID_VARIABLES.contains(&c)) | (prev_char_is_variable && c_is_variable)
| prev_char_is_variable
{ {
add_asterisk = true; add_asterisk = true;
} }
} else if (NUMBERS.contains(&c) | c_letters_var) && prev_letters_var { } else if (c_is_number | c_letters_var) && prev_letters_var {
add_asterisk = true; add_asterisk = true;
} }
// if add_asterisk is true, add the asterisk
if add_asterisk { if add_asterisk {
output_string += "*"; output_string += "*";
} }
// puch current char to vector of previously parsed chars
prev_chars.push(c); prev_chars.push(c);
// push current char to `output_string` (which is eventually returned)
output_string += &c.to_string(); output_string += &c.to_string();
} }
@ -182,67 +203,108 @@ pub fn test_func(function_string: &str) -> Option<String> {
} }
} }
/// Used for testing: passes function to `add_asterisks` before running
/// `test_func`
#[cfg(test)] #[cfg(test)]
fn test_func_helper(function_string: &str) -> bool { mod test {
test_func(&process_func_str(function_string)).is_some() use super::*;
}
/// returns if function with string `func_str` is valid after processing
/// Tests to make sure functions are parsed correctly /// through `process_func_str`
#[test] fn func_is_valid(func_str: &str) -> bool { test_func(&process_func_str(func_str)).is_none() }
fn test_func_test() {
// These shouldn't fail /// Used for testing: passes function to `add_asterisks` before running
assert!(!test_func_helper("x^2")); /// `test_func`. if `expect_valid` == `true`, it expects no errors to be
assert!(!test_func_helper("2x")); /// created.
// assert!(test_func_helper("e^x")); // need to fix!!! PR to exmex fn test_func_helper(func_str: &str, expect_valid: bool) {
assert!(!test_func_helper("E^x")); let is_valid = func_is_valid(func_str);
assert!(!test_func_helper("log10(x)")); println!(
assert!(!test_func_helper("xxxxx")); "function: {} (expected: {}, got: {})",
func_str, expect_valid, is_valid
// Expect these to fail );
assert!(test_func_helper("a")); // variable `a` is invalid
assert!(test_func_helper("l^2")); // variable `l` is invalid assert!(is_valid == expect_valid);
assert!(test_func_helper("log222(x)")); // there is no such thing as `log222` }
assert!(test_func_helper("abcdef")); // invalid variables
} /// Tests to make sure functions that are expected to succeed, succeed.
#[test]
/// Helps with tests of `process_func_str` fn test_expected_func_successes() {
#[cfg(test)] let functions = vec![
fn test_process_helper(input: &str, expected: &str) { "x^2",
assert_eq!(&process_func_str(input), expected); "2x",
} "E^x",
"log10(x)",
/// Tests to make sure my cursed function works as intended "xxxxx", // test variables side-by-side
#[test] "sin(x)",
fn func_process_test() { "xsin(x)",
test_process_helper("2x", "2*x"); "sin(x)cos(x)",
test_process_helper("x2", "x*2"); "x/0", // always returns NaN
test_process_helper("x(1+3)", "x*(1+3)"); "(x+1)(x-3)", // tests 2 parentheses in `)(` pattern
test_process_helper("(1+3)x", "(1+3)*x"); "(2x+1)x",
test_process_helper("sin(x)", "sin(x)"); "(2x+1)pi",
test_process_helper("2sin(x)", "2*sin(x)"); "pi(2x+1)",
test_process_helper("max(x)", "max(x)"); // "pipipipipipi", // need to fix
test_process_helper("2e^x", "2*e^x"); ];
test_process_helper("2max(x)", "2*max(x)");
test_process_helper("cos(sin(x))", "cos(sin(x))"); for func_str in functions.iter().cloned() {
test_process_helper("x^(1+2x)", "x^(1+2*x)"); test_func_helper(func_str, true);
test_process_helper("(x+2)x(1+3)", "(x+2)*x*(1+3)"); }
test_process_helper("(x+2)(1+3)", "(x+2)*(1+3)"); }
test_process_helper("xxx", "x*x*x");
test_process_helper("eee", "e*e*e"); /// Tests to make sure functions that are expected to fail, fail.
test_process_helper("pi(x+2)", "π*(x+2)"); #[test]
test_process_helper("(x)pi", "(x)*π"); fn test_expected_func_failures() {
test_process_helper("2e", "2*e"); let functions = vec![
test_process_helper("2log10(x)", "2*log10(x)"); "a", // Invalid variable
test_process_helper("2log(x)", "2*log10(x)"); "l^2", // Invalid variable
test_process_helper("x!", "x!"); "log222(x)", // Invalid function
test_process_helper("pipipipipipi", "π*π*π*π*π*π"); "abcdef", // Invalid variables
test_process_helper("10pi", "10*π"); "log10(x", // unclosed bracket
test_process_helper("pi10", "π*10"); "x^a", // Invalid variable
"sin(cos(x)))", // extra bracket
// Need to fix these checks, maybe I need to rewrite the whole asterisk "((())",
// adding system... (or just implement these changes into meval-rs, idk) "0/0",
// test_process_helper("emax(x)", "e*max(x)"); ];
// test_process_helper("pisin(x)", "pi*sin(x)");
for func_str in functions.iter().cloned() {
test_func_helper(func_str, false);
}
}
/// Helps with tests of `process_func_str`
#[cfg(test)]
fn test_process_helper(input: &str, expected: &str) {
assert_eq!(&process_func_str(input), expected);
}
/// Tests to make sure my cursed function works as intended
#[test]
fn func_process_test() {
test_process_helper("2x", "2*x");
test_process_helper("x2", "x*2");
test_process_helper("x(1+3)", "x*(1+3)");
test_process_helper("(1+3)x", "(1+3)*x");
test_process_helper("sin(x)", "sin(x)");
test_process_helper("2sin(x)", "2*sin(x)");
test_process_helper("max(x)", "max(x)");
test_process_helper("2e^x", "2*e^x");
test_process_helper("2max(x)", "2*max(x)");
test_process_helper("cos(sin(x))", "cos(sin(x))");
test_process_helper("x^(1+2x)", "x^(1+2*x)");
test_process_helper("(x+2)x(1+3)", "(x+2)*x*(1+3)");
test_process_helper("(x+2)(1+3)", "(x+2)*(1+3)");
test_process_helper("xxx", "x*x*x");
test_process_helper("eee", "e*e*e");
test_process_helper("pi(x+2)", "π*(x+2)");
test_process_helper("(x)pi", "(x)*π");
test_process_helper("2e", "2*e");
test_process_helper("2log10(x)", "2*log10(x)");
test_process_helper("2log(x)", "2*log10(x)");
test_process_helper("x!", "x!");
test_process_helper("pipipipipipi", "π*π*π*π*π*π");
test_process_helper("10pi", "10*π");
test_process_helper("pi10", "π*10");
// Need to fix these checks, maybe I need to rewrite the whole asterisk
// adding system... (or just implement these changes into meval-rs, idk)
// test_process_helper("emax(x)", "e*max(x)");
// test_process_helper("pisin(x)", "pi*sin(x)");
}
} }