testing overhall
This commit is contained in:
parent
d1d48f2838
commit
ac89f3eb19
1
TODO.md
1
TODO.md
@ -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
|
||||||
|
|||||||
210
src/parsing.rs
210
src/parsing.rs
@ -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)");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user