GREATLY improve autocomplete tests + fix known autocomplete issues
This commit is contained in:
parent
e7d30e7213
commit
2e0569fe2e
@ -91,7 +91,7 @@ impl FunctionEntry {
|
|||||||
self.autocomplete.ui(ui, i);
|
self.autocomplete.ui(ui, i);
|
||||||
|
|
||||||
let output_string = self.autocomplete.string.clone();
|
let output_string = self.autocomplete.string.clone();
|
||||||
self.update_string(output_string.as_str());
|
self.update_string(&output_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get function's cached test result
|
/// Get function's cached test result
|
||||||
|
|||||||
@ -326,15 +326,11 @@ impl MathApp {
|
|||||||
#[cfg(not(threading))]
|
#[cfg(not(threading))]
|
||||||
tracing::info!("Threading: Disabled");
|
tracing::info!("Threading: Disabled");
|
||||||
|
|
||||||
tracing::info!(
|
tracing::info!("Integration name: {}", cc.integration_info.name);
|
||||||
"Integration name: {} Url: {:?}",
|
|
||||||
cc.integration_info.name,
|
if let Some(url) = &cc.integration_info.web_info {
|
||||||
if let Some(url) = &cc.integration_info.web_info {
|
tracing::info!("Url: {:?}", url);
|
||||||
&url.location.url
|
}
|
||||||
} else {
|
|
||||||
"N/A"
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
tracing::info!("egui app initialized.");
|
tracing::info!("egui app initialized.");
|
||||||
Self::default() // initialize `MathApp`
|
Self::default() // initialize `MathApp`
|
||||||
|
|||||||
@ -98,6 +98,7 @@ mod tests {
|
|||||||
("cos", HintEnum::Many(&["(", "h("])),
|
("cos", HintEnum::Many(&["(", "h("])),
|
||||||
("sin(", HintEnum::Single(")")),
|
("sin(", HintEnum::Single(")")),
|
||||||
("sqrt", HintEnum::Single("(")),
|
("sqrt", HintEnum::Single("(")),
|
||||||
|
("ln(x)", HintEnum::None),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
for (key, value) in values {
|
for (key, value) in values {
|
||||||
|
|||||||
200
src/widgets.rs
200
src/widgets.rs
@ -35,6 +35,7 @@ impl<'a> Default for AutoComplete<'a> {
|
|||||||
impl<'a> AutoComplete<'a> {
|
impl<'a> AutoComplete<'a> {
|
||||||
pub fn update(&mut self, string: &str) {
|
pub fn update(&mut self, string: &str) {
|
||||||
if &self.string != string {
|
if &self.string != string {
|
||||||
|
self.i = 0;
|
||||||
self.string = string.to_string();
|
self.string = string.to_string();
|
||||||
self.hint = generate_hint(string);
|
self.hint = generate_hint(string);
|
||||||
}
|
}
|
||||||
@ -48,7 +49,7 @@ impl<'a> AutoComplete<'a> {
|
|||||||
match self.hint {
|
match self.hint {
|
||||||
HintEnum::Many(hints) => {
|
HintEnum::Many(hints) => {
|
||||||
if movement == &Movement::Complete {
|
if movement == &Movement::Complete {
|
||||||
self.string += hints[self.i];
|
self.apply_hint(hints[self.i]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,24 +73,33 @@ impl<'a> AutoComplete<'a> {
|
|||||||
}
|
}
|
||||||
HintEnum::Single(hint) => {
|
HintEnum::Single(hint) => {
|
||||||
if movement == &Movement::Complete {
|
if movement == &Movement::Complete {
|
||||||
self.string += hint;
|
self.apply_hint(hint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HintEnum::None => {}
|
HintEnum::None => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn apply_hint(&mut self, hint: &str) {
|
||||||
|
let new_string = self.string.clone() + hint;
|
||||||
|
self.update(&new_string);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn ui(&mut self, ui: &mut egui::Ui, func_i: i32) {
|
pub fn ui(&mut self, ui: &mut egui::Ui, func_i: i32) {
|
||||||
let mut movement: Movement = Movement::default();
|
let mut movement: Movement = Movement::default();
|
||||||
|
|
||||||
let mut func_edit = egui::TextEdit::singleline(&mut self.string)
|
let mut new_string = self.string.clone();
|
||||||
.hint_forward(true) // Make the hint appear after the last text in the textbox
|
|
||||||
.lock_focus(true);
|
|
||||||
|
|
||||||
let te_id = ui.make_persistent_id(format!("text_edit_ac_{}", func_i));
|
let te_id = ui.make_persistent_id(format!("text_edit_ac_{}", func_i));
|
||||||
|
|
||||||
|
let mut func_edit = egui::TextEdit::singleline(&mut new_string)
|
||||||
|
.hint_forward(true) // Make the hint appear after the last text in the textbox
|
||||||
|
.lock_focus(true)
|
||||||
|
.id(te_id);
|
||||||
|
|
||||||
if self.hint.is_none() {
|
if self.hint.is_none() {
|
||||||
let _ = func_edit.id(te_id).ui(ui);
|
let _ = func_edit.ui(ui);
|
||||||
|
self.update(&new_string);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +114,9 @@ impl<'a> AutoComplete<'a> {
|
|||||||
func_edit = func_edit.hint_text(*single_hint);
|
func_edit = func_edit.hint_text(*single_hint);
|
||||||
}
|
}
|
||||||
|
|
||||||
let re = func_edit.id(te_id).ui(ui);
|
let re = func_edit.ui(ui);
|
||||||
|
|
||||||
|
self.update(&new_string);
|
||||||
|
|
||||||
if !self.hint.is_single() {
|
if !self.hint.is_single() {
|
||||||
if ui.input().key_pressed(Key::ArrowDown) {
|
if ui.input().key_pressed(Key::ArrowDown) {
|
||||||
@ -132,7 +144,7 @@ impl<'a> AutoComplete<'a> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if clicked {
|
if clicked {
|
||||||
self.string += hints[self.i];
|
self.apply_hint(hints[self.i]);
|
||||||
|
|
||||||
// don't need this here as it simply won't be display next frame
|
// don't need this here as it simply won't be display next frame
|
||||||
// ui.memory().close_popup();
|
// ui.memory().close_popup();
|
||||||
@ -164,67 +176,139 @@ impl<'a> AutoComplete<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod autocomplete_tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
fn auto_complete_helper(string: &str, movement: Movement) -> (AutoComplete, String) {
|
enum Action<'a> {
|
||||||
let mut auto_complete = AutoComplete::default();
|
AssertI(usize),
|
||||||
auto_complete.update(string);
|
AssertString(&'a str),
|
||||||
auto_complete.interact_back(&movement);
|
AssertHint(&'a str),
|
||||||
|
SetString(&'a str),
|
||||||
|
Move(Movement),
|
||||||
|
}
|
||||||
|
|
||||||
let output_string = auto_complete.clone().string;
|
fn ac_tester(actions: &[Action]) {
|
||||||
(auto_complete, output_string)
|
let mut ac = AutoComplete::default();
|
||||||
|
for action in actions.iter() {
|
||||||
|
match action {
|
||||||
|
Action::AssertI(target_i) => {
|
||||||
|
if &ac.i != target_i {
|
||||||
|
panic!(
|
||||||
|
"AssertI failed: Current: '{}' Expected: '{}'",
|
||||||
|
ac.i, target_i
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Action::AssertString(target_string) => {
|
||||||
|
if &ac.string != target_string {
|
||||||
|
panic!(
|
||||||
|
"AssertString failed: Current: '{}' Expected: '{}'",
|
||||||
|
ac.string, target_string
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Action::AssertHint(target_hint) => match ac.hint {
|
||||||
|
HintEnum::None => {
|
||||||
|
if !target_hint.is_empty() {
|
||||||
|
panic!(
|
||||||
|
"AssertHint failed on `HintEnum::None`: Expected: {}",
|
||||||
|
target_hint
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HintEnum::Many(hints) => {
|
||||||
|
let hint = hints[ac.i];
|
||||||
|
if &hint != target_hint {
|
||||||
|
panic!(
|
||||||
|
"AssertHint failed on `HintEnum::Many`: Current: '{}' (index: {}) Expected: '{}'",
|
||||||
|
hint, ac.i, target_hint
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HintEnum::Single(hint) => {
|
||||||
|
if hint != target_hint {
|
||||||
|
panic!(
|
||||||
|
"AssertHint failed on `HintEnum::Single`: Current: '{}' Expected: '{}'",
|
||||||
|
hint, target_hint
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Action::SetString(target_string) => {
|
||||||
|
ac.update(target_string);
|
||||||
|
}
|
||||||
|
Action::Move(target_movement) => {
|
||||||
|
ac.interact_back(target_movement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn auto_complete_single_still() {
|
fn single() {
|
||||||
let (_, string) = auto_complete_helper("", Movement::None);
|
ac_tester(&[
|
||||||
|
Action::SetString(""),
|
||||||
assert_eq!(&*string, "");
|
Action::AssertHint("x^2"),
|
||||||
|
Action::Move(Movement::Up),
|
||||||
|
Action::AssertI(0),
|
||||||
|
Action::AssertString(""),
|
||||||
|
Action::AssertHint("x^2"),
|
||||||
|
Action::Move(Movement::Down),
|
||||||
|
Action::AssertI(0),
|
||||||
|
Action::AssertString(""),
|
||||||
|
Action::AssertHint("x^2"),
|
||||||
|
Action::Move(Movement::Complete),
|
||||||
|
Action::AssertString("x^2"),
|
||||||
|
Action::AssertHint(""),
|
||||||
|
Action::AssertI(0),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn auto_complete_single_complete() {
|
fn multi() {
|
||||||
let (_, string) = auto_complete_helper("", Movement::Complete);
|
ac_tester(&[
|
||||||
|
Action::SetString("s"),
|
||||||
assert_eq!(&*string, "x^2");
|
Action::AssertHint("in("),
|
||||||
|
Action::Move(Movement::Up),
|
||||||
|
Action::AssertI(3),
|
||||||
|
Action::AssertString("s"),
|
||||||
|
Action::AssertHint("ignum("),
|
||||||
|
Action::Move(Movement::Down),
|
||||||
|
Action::AssertI(0),
|
||||||
|
Action::AssertString("s"),
|
||||||
|
Action::AssertHint("in("),
|
||||||
|
Action::Move(Movement::Down),
|
||||||
|
Action::AssertI(1),
|
||||||
|
Action::AssertString("s"),
|
||||||
|
Action::AssertHint("qrt("),
|
||||||
|
Action::Move(Movement::Up),
|
||||||
|
Action::AssertI(0),
|
||||||
|
Action::AssertString("s"),
|
||||||
|
Action::AssertHint("in("),
|
||||||
|
Action::Move(Movement::Complete),
|
||||||
|
Action::AssertString("sin("),
|
||||||
|
Action::AssertHint(")"),
|
||||||
|
Action::AssertI(0),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn auto_complete_single_down() {
|
fn parens() {
|
||||||
let (_, string) = auto_complete_helper("", Movement::Down);
|
ac_tester(&[
|
||||||
|
Action::SetString("sin(x"),
|
||||||
assert_eq!(&*string, "");
|
Action::AssertHint(")"),
|
||||||
}
|
Action::Move(Movement::Up),
|
||||||
|
Action::AssertI(0),
|
||||||
#[test]
|
Action::AssertString("sin(x"),
|
||||||
fn auto_complete_single_up() {
|
Action::AssertHint(")"),
|
||||||
let (_, string) = auto_complete_helper("", Movement::Up);
|
Action::Move(Movement::Down),
|
||||||
|
Action::AssertI(0),
|
||||||
assert_eq!(&*string, "");
|
Action::AssertString("sin(x"),
|
||||||
}
|
Action::AssertHint(")"),
|
||||||
|
Action::Move(Movement::Complete),
|
||||||
#[test]
|
Action::AssertString("sin(x)"),
|
||||||
fn auto_complete_multi_up() {
|
Action::AssertHint(""),
|
||||||
let (auto_complete, string) = auto_complete_helper("s", Movement::Up);
|
Action::AssertI(0),
|
||||||
|
]);
|
||||||
assert!(auto_complete.i > 0);
|
|
||||||
assert_eq!(&*string, "s");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn auto_complete_multi_down() {
|
|
||||||
let (auto_complete, string) = auto_complete_helper("s", Movement::Down);
|
|
||||||
|
|
||||||
assert_eq!(auto_complete.i, 1);
|
|
||||||
assert_eq!(&*string, "s");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn auto_complete_multi_complete() {
|
|
||||||
let (auto_complete, string) = auto_complete_helper("s", Movement::Complete);
|
|
||||||
|
|
||||||
assert_eq!(auto_complete.i, 0);
|
|
||||||
assert_eq!(&*string, "sin(");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user