use super::super::*;
#[test]
fn test_auto_match_rules_created() {
let rules = create_auto_match_rules();
assert_eq!(rules.len(), 6);
}
#[test]
fn test_auto_match_rule_matches_paren() {
let rules = create_auto_match_rules();
let paren_rule = &rules[0];
let match_event = ReedlineEvent::Edit(vec![
EditCommand::InsertString("()".to_string()),
EditCommand::MoveLeft { select: false },
]);
assert!((paren_rule.match_event)(&match_event));
let other_event = ReedlineEvent::Edit(vec![EditCommand::InsertChar('(')]);
assert!(!(paren_rule.match_event)(&other_event));
let bracket_event = ReedlineEvent::Edit(vec![
EditCommand::InsertString("[]".to_string()),
EditCommand::MoveLeft { select: false },
]);
assert!(!(paren_rule.match_event)(&bracket_event));
}
#[test]
fn test_auto_match_condition_cursor_at_end() {
let rules = create_auto_match_rules();
let rule = &rules[0];
let mut state = EditorState::new();
state.buffer_len = 5;
state.cursor_pos = 5;
assert!(rule.condition.check(&state));
state.cursor_pos = 2;
assert!(!rule.condition.check(&state));
}
#[test]
fn test_auto_match_fallback_event() {
let rules = create_auto_match_rules();
let expected_fallbacks = ['(', '[', '{', '"', '\'', '`'];
for (rule, expected_char) in rules.iter().zip(expected_fallbacks.iter()) {
match &rule.fallback_event {
ReedlineEvent::Edit(cmds) => {
assert_eq!(cmds.len(), 1);
match &cmds[0] {
EditCommand::InsertChar(c) => assert_eq!(c, expected_char),
_ => panic!("Expected InsertChar"),
}
}
_ => panic!("Expected Edit event"),
}
}
}
#[test]
fn test_auto_match_full_flow_at_end() {
let state_ref = new_editor_state_ref();
let rules = create_auto_match_rules();
{
let mut state = state_ref.lock().unwrap();
state.update_from_event(&ReedlineEvent::Edit(vec![EditCommand::InsertChar('a')]));
state.update_from_event(&ReedlineEvent::Edit(vec![EditCommand::InsertChar('b')]));
state.update_from_event(&ReedlineEvent::Edit(vec![EditCommand::InsertChar('c')]));
assert_eq!(state.cursor_pos, 3);
assert_eq!(state.buffer_len, 3);
assert!(state.cursor_at_end());
}
let paren_rule = &rules[0];
{
let state = state_ref.lock().unwrap();
assert!(state.cursor_at_end());
assert!(paren_rule.condition.check(&state));
}
}
#[test]
fn test_auto_match_blocked_when_not_at_end() {
let state_ref = new_editor_state_ref();
let rules = create_auto_match_rules();
{
let mut state = state_ref.lock().unwrap();
state.update_from_event(&ReedlineEvent::Edit(vec![EditCommand::InsertChar('a')]));
state.update_from_event(&ReedlineEvent::Edit(vec![EditCommand::InsertChar('b')]));
state.update_from_event(&ReedlineEvent::Edit(vec![EditCommand::InsertChar('c')]));
state.update_from_event(&ReedlineEvent::Edit(vec![EditCommand::MoveLeft {
select: false,
}]));
assert_eq!(state.cursor_pos, 2);
assert_eq!(state.buffer_len, 3);
assert!(!state.cursor_at_end());
}
let paren_rule = &rules[0];
{
let state = state_ref.lock().unwrap();
assert!(!state.cursor_at_end());
assert!(!paren_rule.condition.check(&state));
}
}
#[test]
fn test_until_found_right_updates_cursor() {
let mut state = EditorState::new();
state.update_from_event(&ReedlineEvent::Edit(vec![EditCommand::InsertChar('a')]));
state.update_from_event(&ReedlineEvent::Edit(vec![EditCommand::InsertChar('b')]));
state.update_from_event(&ReedlineEvent::Edit(vec![EditCommand::InsertChar('c')]));
assert_eq!(state.cursor_pos, 3);
assert_eq!(state.buffer_len, 3);
state.update_from_event(&ReedlineEvent::Edit(vec![EditCommand::MoveLeft {
select: false,
}]));
assert_eq!(state.cursor_pos, 2);
assert!(!state.cursor_at_end());
state.update_from_event(&ReedlineEvent::UntilFound(vec![
ReedlineEvent::HistoryHintComplete,
ReedlineEvent::MenuRight,
ReedlineEvent::Right,
]));
assert_eq!(state.cursor_pos, 3);
assert!(state.cursor_at_end());
assert!(!state.uncertain); }
#[test]
fn test_until_found_right_at_end_marks_uncertain() {
let mut state = EditorState::new();
state.update_from_event(&ReedlineEvent::Edit(vec![EditCommand::InsertChar('a')]));
state.update_from_event(&ReedlineEvent::Edit(vec![EditCommand::InsertChar('b')]));
state.update_from_event(&ReedlineEvent::Edit(vec![EditCommand::InsertChar('c')]));
assert_eq!(state.cursor_pos, 3);
assert!(state.cursor_at_end());
assert!(!state.uncertain);
state.update_from_event(&ReedlineEvent::UntilFound(vec![
ReedlineEvent::HistoryHintComplete,
ReedlineEvent::MenuRight,
ReedlineEvent::Right,
]));
assert!(state.uncertain);
}
#[test]
fn test_until_found_right_on_empty_buffer_not_uncertain() {
let mut state = EditorState::new();
assert_eq!(state.cursor_pos, 0);
assert_eq!(state.buffer_len, 0);
assert!(state.cursor_at_end()); assert!(!state.uncertain);
state.update_from_event(&ReedlineEvent::UntilFound(vec![
ReedlineEvent::HistoryHintComplete,
ReedlineEvent::MenuRight,
ReedlineEvent::Right,
]));
assert!(!state.uncertain);
assert_eq!(state.cursor_pos, 0);
}
#[test]
fn test_auto_match_inside_braces_regression() {
let rules = create_auto_match_rules();
let paren_rule = &rules[0];
let mut state = EditorState::new();
state.update_from_event(&ReedlineEvent::Edit(vec![
EditCommand::InsertString("{}".to_string()),
EditCommand::MoveLeft { select: false },
]));
assert_eq!(state.buffer, "{}");
assert_eq!(state.cursor_pos, 1);
assert_eq!(state.buffer_len, 2);
assert!(!state.cursor_at_end());
assert!(!state.uncertain);
assert_eq!(state.char_after_cursor(), Some('}'));
assert!(paren_rule.condition.check(&state));
state.update_from_event(&ReedlineEvent::Edit(vec![
EditCommand::InsertString("()".to_string()),
EditCommand::MoveLeft { select: false },
]));
assert_eq!(state.buffer, "{()}");
assert_eq!(state.cursor_pos, 2); }
#[test]
fn test_until_found_left_updates_cursor() {
let mut state = EditorState::new();
state.update_from_event(&ReedlineEvent::Edit(vec![EditCommand::InsertChar('a')]));
state.update_from_event(&ReedlineEvent::Edit(vec![EditCommand::InsertChar('b')]));
state.update_from_event(&ReedlineEvent::Edit(vec![EditCommand::InsertChar('c')]));
assert_eq!(state.cursor_pos, 3);
assert!(state.cursor_at_end());
state.update_from_event(&ReedlineEvent::UntilFound(vec![
ReedlineEvent::MenuLeft,
ReedlineEvent::Left,
]));
assert_eq!(state.cursor_pos, 2);
assert!(!state.cursor_at_end());
}
#[test]
fn test_right_event_updates_cursor() {
let mut state = EditorState::new();
state.buffer_len = 5;
state.cursor_pos = 2;
state.update_from_event(&ReedlineEvent::Right);
assert_eq!(state.cursor_pos, 3);
state.cursor_pos = 5;
state.update_from_event(&ReedlineEvent::Right);
assert_eq!(state.cursor_pos, 5);
}
#[test]
fn test_left_event_updates_cursor() {
let mut state = EditorState::new();
state.buffer_len = 5;
state.cursor_pos = 2;
state.update_from_event(&ReedlineEvent::Left);
assert_eq!(state.cursor_pos, 1);
state.cursor_pos = 0;
state.update_from_event(&ReedlineEvent::Left);
assert_eq!(state.cursor_pos, 0);
}