mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-06-01 21:21:15 -03:00
Port test_word_motion
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
use crate::redirection::RedirectionMode;
|
||||
use crate::tokenizer::{PipeOrRedir, TokFlags, TokenType, Tokenizer, TokenizerError};
|
||||
use crate::tokenizer::{
|
||||
MoveWordStateMachine, MoveWordStyle, PipeOrRedir, TokFlags, TokenType, Tokenizer,
|
||||
TokenizerError,
|
||||
};
|
||||
use crate::wchar::prelude::*;
|
||||
use libc::{STDERR_FILENO, STDOUT_FILENO};
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[test]
|
||||
fn test_tokenizer() {
|
||||
@@ -139,3 +143,166 @@ macro_rules! get_redir_mode {
|
||||
assert_eq!(get_redir_mode!("3<&0"), RedirectionMode::fd);
|
||||
assert_eq!(get_redir_mode!("3</tmp/filetxt"), RedirectionMode::input);
|
||||
}
|
||||
|
||||
/// Test word motion (forward-word, etc.). Carets represent cursor stops.
|
||||
#[test]
|
||||
fn test_word_motion() {
|
||||
#[derive(Eq, PartialEq)]
|
||||
pub enum Direction {
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
|
||||
macro_rules! validate {
|
||||
($direction:expr, $style:expr, $line:expr) => {
|
||||
let mut command = WString::new();
|
||||
let mut stops = HashSet::new();
|
||||
|
||||
// Carets represent stops and should be cut out of the command.
|
||||
for c in $line.chars() {
|
||||
if c == '^' {
|
||||
stops.insert(command.len());
|
||||
} else {
|
||||
command.push(c);
|
||||
}
|
||||
}
|
||||
|
||||
let (mut idx, end) = if $direction == Direction::Left {
|
||||
(stops.iter().max().unwrap().clone(), 0)
|
||||
} else {
|
||||
(stops.iter().min().unwrap().clone(), command.len())
|
||||
};
|
||||
stops.remove(&idx);
|
||||
|
||||
let mut sm = MoveWordStateMachine::new($style);
|
||||
while idx != end {
|
||||
let char_idx = if $direction == Direction::Left {
|
||||
idx - 1
|
||||
} else {
|
||||
idx
|
||||
};
|
||||
let c = command.as_char_slice()[char_idx];
|
||||
let will_stop = !sm.consume_char(c);
|
||||
let expected_stop = stops.contains(&idx);
|
||||
assert_eq!(will_stop, expected_stop);
|
||||
// We don't expect to stop here next time.
|
||||
if expected_stop {
|
||||
stops.remove(&idx);
|
||||
sm.reset();
|
||||
} else {
|
||||
if $direction == Direction::Left {
|
||||
idx -= 1;
|
||||
} else {
|
||||
idx += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
validate!(
|
||||
Direction::Left,
|
||||
MoveWordStyle::move_word_style_punctuation,
|
||||
"^echo ^hello_^world.^txt^"
|
||||
);
|
||||
validate!(
|
||||
Direction::Right,
|
||||
MoveWordStyle::move_word_style_punctuation,
|
||||
"^echo^ hello^_world^.txt^"
|
||||
);
|
||||
|
||||
validate!(
|
||||
Direction::Left,
|
||||
MoveWordStyle::move_word_style_punctuation,
|
||||
"echo ^foo_^foo_^foo/^/^/^/^/^ ^"
|
||||
);
|
||||
validate!(
|
||||
Direction::Right,
|
||||
MoveWordStyle::move_word_style_punctuation,
|
||||
"^echo^ foo^_foo^_foo^/^/^/^/^/ ^"
|
||||
);
|
||||
|
||||
validate!(
|
||||
Direction::Left,
|
||||
MoveWordStyle::move_word_style_path_components,
|
||||
"^/^foo/^bar/^baz/^"
|
||||
);
|
||||
validate!(
|
||||
Direction::Left,
|
||||
MoveWordStyle::move_word_style_path_components,
|
||||
"^echo ^--foo ^--bar^"
|
||||
);
|
||||
validate!(
|
||||
Direction::Left,
|
||||
MoveWordStyle::move_word_style_path_components,
|
||||
"^echo ^hi ^> ^/^dev/^null^"
|
||||
);
|
||||
|
||||
validate!(
|
||||
Direction::Left,
|
||||
MoveWordStyle::move_word_style_path_components,
|
||||
"^echo ^/^foo/^bar{^aaa,^bbb,^ccc}^bak/^"
|
||||
);
|
||||
validate!(
|
||||
Direction::Left,
|
||||
MoveWordStyle::move_word_style_path_components,
|
||||
"^echo ^bak ^///^"
|
||||
);
|
||||
validate!(
|
||||
Direction::Left,
|
||||
MoveWordStyle::move_word_style_path_components,
|
||||
"^aaa ^@ ^@^aaa^"
|
||||
);
|
||||
validate!(
|
||||
Direction::Left,
|
||||
MoveWordStyle::move_word_style_path_components,
|
||||
"^aaa ^a ^@^aaa^"
|
||||
);
|
||||
validate!(
|
||||
Direction::Left,
|
||||
MoveWordStyle::move_word_style_path_components,
|
||||
"^aaa ^@@@ ^@@^aa^"
|
||||
);
|
||||
validate!(
|
||||
Direction::Left,
|
||||
MoveWordStyle::move_word_style_path_components,
|
||||
"^aa^@@ ^aa@@^a^"
|
||||
);
|
||||
|
||||
validate!(
|
||||
Direction::Right,
|
||||
MoveWordStyle::move_word_style_punctuation,
|
||||
"^a^ bcd^"
|
||||
);
|
||||
validate!(
|
||||
Direction::Right,
|
||||
MoveWordStyle::move_word_style_punctuation,
|
||||
"a^b^ cde^"
|
||||
);
|
||||
validate!(
|
||||
Direction::Right,
|
||||
MoveWordStyle::move_word_style_punctuation,
|
||||
"^ab^ cde^"
|
||||
);
|
||||
validate!(
|
||||
Direction::Right,
|
||||
MoveWordStyle::move_word_style_punctuation,
|
||||
"^ab^&cd^ ^& ^e^ f^&"
|
||||
);
|
||||
|
||||
validate!(
|
||||
Direction::Right,
|
||||
MoveWordStyle::move_word_style_whitespace,
|
||||
"^^a-b-c^ d-e-f"
|
||||
);
|
||||
validate!(
|
||||
Direction::Right,
|
||||
MoveWordStyle::move_word_style_whitespace,
|
||||
"^a-b-c^\n d-e-f^ "
|
||||
);
|
||||
validate!(
|
||||
Direction::Right,
|
||||
MoveWordStyle::move_word_style_whitespace,
|
||||
"^a-b-c^\n\nd-e-f^ "
|
||||
);
|
||||
}
|
||||
|
||||
@@ -736,115 +736,6 @@ static void test_abbreviations() {
|
||||
}
|
||||
}
|
||||
|
||||
// todo!("port this")
|
||||
enum word_motion_t { word_motion_left, word_motion_right };
|
||||
static void test_1_word_motion(word_motion_t motion, move_word_style_t style,
|
||||
const wcstring &test) {
|
||||
wcstring command;
|
||||
std::set<size_t> stops;
|
||||
|
||||
// Carets represent stops and should be cut out of the command.
|
||||
for (wchar_t wc : test) {
|
||||
if (wc == L'^') {
|
||||
stops.insert(command.size());
|
||||
} else {
|
||||
command.push_back(wc);
|
||||
}
|
||||
}
|
||||
|
||||
size_t idx, end;
|
||||
if (motion == word_motion_left) {
|
||||
idx = *std::max_element(stops.begin(), stops.end());
|
||||
end = 0;
|
||||
} else {
|
||||
idx = *std::min_element(stops.begin(), stops.end());
|
||||
end = command.size();
|
||||
}
|
||||
stops.erase(idx);
|
||||
|
||||
auto sm = new_move_word_state_machine(style);
|
||||
while (idx != end) {
|
||||
size_t char_idx = (motion == word_motion_left ? idx - 1 : idx);
|
||||
wchar_t wc = command.at(char_idx);
|
||||
bool will_stop = !sm->consume_char(wc);
|
||||
// std::fwprintf(stdout, L"idx %lu, looking at %lu (%c): %d\n", idx, char_idx, (char)wc,
|
||||
// will_stop);
|
||||
bool expected_stop = (stops.count(idx) > 0);
|
||||
if (will_stop != expected_stop) {
|
||||
wcstring tmp = command;
|
||||
tmp.insert(idx, L"^");
|
||||
const char *dir = (motion == word_motion_left ? "left" : "right");
|
||||
if (will_stop) {
|
||||
err(L"Word motion: moving %s, unexpected stop at idx %lu: '%ls'", dir, idx,
|
||||
tmp.c_str());
|
||||
} else if (!will_stop && expected_stop) {
|
||||
err(L"Word motion: moving %s, should have stopped at idx %lu: '%ls'", dir, idx,
|
||||
tmp.c_str());
|
||||
}
|
||||
}
|
||||
// We don't expect to stop here next time.
|
||||
if (expected_stop) {
|
||||
stops.erase(idx);
|
||||
}
|
||||
if (will_stop) {
|
||||
sm->reset();
|
||||
} else {
|
||||
idx += (motion == word_motion_left ? -1 : 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// todo!("port this")
|
||||
/// Test word motion (forward-word, etc.). Carets represent cursor stops.
|
||||
static void test_word_motion() {
|
||||
say(L"Testing word motion");
|
||||
test_1_word_motion(word_motion_left, move_word_style_t::move_word_style_punctuation,
|
||||
L"^echo ^hello_^world.^txt^");
|
||||
test_1_word_motion(word_motion_right, move_word_style_t::move_word_style_punctuation,
|
||||
L"^echo^ hello^_world^.txt^");
|
||||
|
||||
test_1_word_motion(word_motion_left, move_word_style_t::move_word_style_punctuation,
|
||||
L"echo ^foo_^foo_^foo/^/^/^/^/^ ^");
|
||||
test_1_word_motion(word_motion_right, move_word_style_t::move_word_style_punctuation,
|
||||
L"^echo^ foo^_foo^_foo^/^/^/^/^/ ^");
|
||||
|
||||
test_1_word_motion(word_motion_left, move_word_style_t::move_word_style_path_components,
|
||||
L"^/^foo/^bar/^baz/^");
|
||||
test_1_word_motion(word_motion_left, move_word_style_t::move_word_style_path_components,
|
||||
L"^echo ^--foo ^--bar^");
|
||||
test_1_word_motion(word_motion_left, move_word_style_t::move_word_style_path_components,
|
||||
L"^echo ^hi ^> ^/^dev/^null^");
|
||||
|
||||
test_1_word_motion(word_motion_left, move_word_style_t::move_word_style_path_components,
|
||||
L"^echo ^/^foo/^bar{^aaa,^bbb,^ccc}^bak/^");
|
||||
test_1_word_motion(word_motion_left, move_word_style_t::move_word_style_path_components,
|
||||
L"^echo ^bak ^///^");
|
||||
test_1_word_motion(word_motion_left, move_word_style_t::move_word_style_path_components,
|
||||
L"^aaa ^@ ^@^aaa^");
|
||||
test_1_word_motion(word_motion_left, move_word_style_t::move_word_style_path_components,
|
||||
L"^aaa ^a ^@^aaa^");
|
||||
test_1_word_motion(word_motion_left, move_word_style_t::move_word_style_path_components,
|
||||
L"^aaa ^@@@ ^@@^aa^");
|
||||
test_1_word_motion(word_motion_left, move_word_style_t::move_word_style_path_components,
|
||||
L"^aa^@@ ^aa@@^a^");
|
||||
|
||||
test_1_word_motion(word_motion_right, move_word_style_t::move_word_style_punctuation,
|
||||
L"^a^ bcd^");
|
||||
test_1_word_motion(word_motion_right, move_word_style_t::move_word_style_punctuation,
|
||||
L"a^b^ cde^");
|
||||
test_1_word_motion(word_motion_right, move_word_style_t::move_word_style_punctuation,
|
||||
L"^ab^ cde^");
|
||||
test_1_word_motion(word_motion_right, move_word_style_t::move_word_style_punctuation,
|
||||
L"^ab^&cd^ ^& ^e^ f^&");
|
||||
|
||||
test_1_word_motion(word_motion_right, move_word_style_t::move_word_style_whitespace,
|
||||
L"^^a-b-c^ d-e-f");
|
||||
test_1_word_motion(word_motion_right, move_word_style_t::move_word_style_whitespace,
|
||||
L"^a-b-c^\n d-e-f^ ");
|
||||
test_1_word_motion(word_motion_right, move_word_style_t::move_word_style_whitespace,
|
||||
L"^a-b-c^\n\nd-e-f^ ");
|
||||
}
|
||||
|
||||
// todo!("already ported, delete this")
|
||||
/// Testing colors.
|
||||
static void test_colors() {
|
||||
@@ -1173,7 +1064,6 @@ static const test_t s_tests[]{
|
||||
{TEST_GROUP("convert_ascii"), test_convert_ascii},
|
||||
{TEST_GROUP("iothread"), test_iothread},
|
||||
{TEST_GROUP("lru"), test_lru},
|
||||
{TEST_GROUP("word_motion"), test_word_motion},
|
||||
{TEST_GROUP("colors"), test_colors},
|
||||
{TEST_GROUP("input"), test_input},
|
||||
{TEST_GROUP("completion_insertions"), test_completion_insertions},
|
||||
|
||||
Reference in New Issue
Block a user