move tests into tests directory

This commit is contained in:
mat 2022-04-18 19:45:32 -05:00
parent b8ceb56e71
commit 78e692efc3
28 changed files with 1100 additions and 1157 deletions

View file

@ -135,82 +135,3 @@ impl<S> Debug for ArgumentBuilder<S> {
.finish() .finish()
} }
} }
#[cfg(test)]
mod tests {
use std::rc::Rc;
use crate::{
arguments::integer_argument_type::integer,
builder::{literal_argument_builder::literal, required_argument_builder::argument},
};
use super::ArgumentBuilder;
// public class ArgumentBuilderTest {
// private TestableArgumentBuilder<Object> builder;
// @Before
// public void setUp() throws Exception {
// builder = new TestableArgumentBuilder<>();
// }
// @Test
// public void testArguments() throws Exception {
// final RequiredArgumentBuilder<Object, ?> argument = argument("bar", integer());
// builder.then(argument);
// assertThat(builder.getArguments(), hasSize(1));
// assertThat(builder.getArguments(), hasItem((CommandNode<Object>) argument.build()));
// }
#[test]
fn test_arguments() {
let mut builder: ArgumentBuilder<()> = literal("foo");
let argument: ArgumentBuilder<()> = argument("bar", integer());
builder.then(argument.clone());
assert_eq!(builder.arguments.children.len(), 1);
let built_argument = Rc::new(argument.build());
assert!(builder
.arguments
.children
.values()
.any(|e| *e.borrow() == *built_argument));
}
// @Test
// public void testRedirect() throws Exception {
// final CommandNode<Object> target = mock(CommandNode.class);
// builder.redirect(target);
// assertThat(builder.getRedirect(), is(target));
// }
// @Test(expected = IllegalStateException.class)
// public void testRedirect_withChild() throws Exception {
// final CommandNode<Object> target = mock(CommandNode.class);
// builder.then(literal("foo"));
// builder.redirect(target);
// }
// @Test(expected = IllegalStateException.class)
// public void testThen_withRedirect() throws Exception {
// final CommandNode<Object> target = mock(CommandNode.class);
// builder.redirect(target);
// builder.then(literal("foo"));
// }
// private static class TestableArgumentBuilder<S> extends ArgumentBuilder<S, TestableArgumentBuilder<S>> {
// @Override
// protected TestableArgumentBuilder<S> getThis() {
// return this;
// }
// @Override
// public CommandNode<S> build() {
// return null;
// }
// }
// }
}

View file

@ -10,7 +10,7 @@ use std::{cell::RefCell, cmp::Ordering, collections::HashMap, marker::PhantomDat
#[derive(Default)] #[derive(Default)]
pub struct CommandDispatcher<S> { pub struct CommandDispatcher<S> {
root: Rc<RefCell<CommandNode<S>>>, pub root: Rc<RefCell<CommandNode<S>>>,
_marker: PhantomData<S>, _marker: PhantomData<S>,
} }
@ -296,416 +296,3 @@ impl<S> Clone for CommandDispatcher<S> {
} }
} }
} }
#[cfg(test)]
mod tests {
use super::*;
use crate::{
arguments::integer_argument_type::integer,
builder::{literal_argument_builder::literal, required_argument_builder::argument},
};
#[derive(Debug, PartialEq)]
struct CommandSource {}
fn input_with_offset(input: &str, offset: usize) -> StringReader {
let mut result: StringReader = input.into();
result.cursor = offset;
result
}
#[test]
fn create_and_execute_command() {
let mut subject = CommandDispatcher::new();
subject.register(literal("foo").executes(|_| 42));
assert_eq!(
subject
.execute("foo".into(), Rc::new(CommandSource {}))
.unwrap(),
42
);
}
#[test]
fn create_and_execute_offset_command() {
let mut subject = CommandDispatcher::new();
subject.register(literal("foo").executes(|_| 42));
assert_eq!(
subject
.execute(input_with_offset("/foo", 1), Rc::new(CommandSource {}))
.unwrap(),
42
);
}
#[test]
fn create_and_merge_commands() {
let mut subject = CommandDispatcher::new();
subject.register(literal("base").then(literal("foo").executes(|_| 42)));
subject.register(literal("base").then(literal("bar").executes(|_| 42)));
assert_eq!(
subject
.execute("base foo".into(), Rc::new(CommandSource {}))
.unwrap(),
42
);
assert_eq!(
subject
.execute("base bar".into(), Rc::new(CommandSource {}))
.unwrap(),
42
);
}
#[test]
fn execute_unknown_command() {
let mut subject = CommandDispatcher::new();
subject.register(literal("bar"));
subject.register(literal("baz"));
let execute_result = subject.execute("foo".into(), Rc::new(CommandSource {}));
let err = execute_result.err().unwrap();
match err.type_ {
BuiltInExceptions::DispatcherUnknownCommand => {}
_ => panic!("Unexpected error"),
}
assert_eq!(err.cursor().unwrap(), 0);
}
#[test]
fn execute_impermissible_command() {
let mut subject = CommandDispatcher::new();
subject.register(literal("foo").requires(|_| false));
let execute_result = subject.execute("foo".into(), Rc::new(CommandSource {}));
let err = execute_result.err().unwrap();
match err.type_ {
BuiltInExceptions::DispatcherUnknownCommand => {}
_ => panic!("Unexpected error"),
}
assert_eq!(err.cursor().unwrap(), 0);
}
#[test]
fn execute_empty_command() {
let mut subject = CommandDispatcher::new();
subject.register(literal(""));
let execute_result = subject.execute("".into(), Rc::new(CommandSource {}));
let err = execute_result.err().unwrap();
match err.type_ {
BuiltInExceptions::DispatcherUnknownCommand => {}
_ => panic!("Unexpected error"),
}
assert_eq!(err.cursor().unwrap(), 0);
}
#[test]
fn execute_unknown_subcommand() {
let mut subject = CommandDispatcher::new();
subject.register(literal("foo").executes(|_| 42));
let execute_result = subject.execute("foo bar".into(), Rc::new(CommandSource {}));
let err = execute_result.err().unwrap();
match err.type_ {
BuiltInExceptions::DispatcherUnknownArgument => {}
_ => panic!("Unexpected error"),
}
assert_eq!(err.cursor().unwrap(), 4);
}
#[test]
fn execute_incorrect_literal() {
let mut subject = CommandDispatcher::new();
subject.register(literal("foo").executes(|_| 42).then(literal("bar")));
let execute_result = subject.execute("foo baz".into(), Rc::new(CommandSource {}));
let err = execute_result.err().unwrap();
match err.type_ {
BuiltInExceptions::DispatcherUnknownArgument => {}
_ => panic!("Unexpected error"),
}
assert_eq!(err.cursor().unwrap(), 4);
}
#[test]
fn execute_ambiguous_incorrect_argument() {
let mut subject = CommandDispatcher::new();
subject.register(
literal("foo")
.executes(|_| 42)
.then(literal("bar"))
.then(literal("baz")),
);
let execute_result = subject.execute("foo unknown".into(), Rc::new(CommandSource {}));
let err = execute_result.err().unwrap();
match err.type_ {
BuiltInExceptions::DispatcherUnknownArgument => {}
_ => panic!("Unexpected error"),
}
assert_eq!(err.cursor().unwrap(), 4);
}
#[test]
fn execute_subcommand() {
let mut subject = CommandDispatcher::new();
subject.register(
literal("foo")
.then(literal("a"))
.then(literal("=").executes(|_| 100))
.then(literal("c"))
.executes(|_| 42),
);
assert_eq!(
subject
.execute("foo =".into(), Rc::new(CommandSource {}))
.unwrap(),
100
);
}
#[test]
fn parse_incomplete_literal() {
let mut subject = CommandDispatcher::new();
subject.register(literal("foo").then(literal("bar").executes(|_| 42)));
let parse = subject.parse("foo ".into(), Rc::new(CommandSource {}));
assert_eq!(parse.reader.remaining(), " ");
assert_eq!(parse.context.nodes.len(), 1);
}
#[test]
fn parse_incomplete_argument() {
let mut subject = CommandDispatcher::new();
subject.register(literal("foo").then(argument("bar", integer()).executes(|_| 42)));
let parse = subject.parse("foo ".into(), Rc::new(CommandSource {}));
assert_eq!(parse.reader.remaining(), " ");
assert_eq!(parse.context.nodes.len(), 1);
}
#[test]
fn execute_ambiguious_parent_subcommand() {
let mut subject = CommandDispatcher::new();
subject.register(
literal("test")
.then(argument("incorrect", integer()).executes(|_| 42))
.then(
argument("right", integer()).then(argument("sub", integer()).executes(|_| 100)),
),
);
assert_eq!(
subject
.execute("test 1 2".into(), Rc::new(CommandSource {}))
.unwrap(),
100
);
}
#[test]
fn execute_ambiguious_parent_subcommand_via_redirect() {
let mut subject = CommandDispatcher::new();
let real = subject.register(
literal("test")
.then(argument("incorrect", integer()).executes(|_| 42))
.then(
argument("right", integer()).then(argument("sub", integer()).executes(|_| 100)),
),
);
subject.register(literal("redirect").redirect(real));
assert_eq!(
subject
.execute("redirect 1 2".into(), Rc::new(CommandSource {}))
.unwrap(),
100
);
}
#[test]
fn execute_redirected_multiple_times() {
let mut subject = CommandDispatcher::new();
let concrete_node = subject.register(literal("actual").executes(|_| 42));
let root = subject.root.clone();
let redirect_node = subject.register(literal("redirected").redirect(root.clone()));
let input = "redirected redirected actual";
let parse = subject.parse(input.into(), Rc::new(CommandSource {}));
assert_eq!(parse.context.range.get(input), "redirected");
assert_eq!(parse.context.nodes.len(), 1);
assert_eq!(parse.context.root, root);
assert_eq!(parse.context.nodes[0].range, parse.context.range);
assert_eq!(parse.context.nodes[0].node, redirect_node);
let child1 = parse.context.child.clone();
assert!(child1.is_some());
assert_eq!(child1.clone().unwrap().range.get(input), "redirected");
assert_eq!(child1.clone().unwrap().nodes.len(), 1);
assert_eq!(child1.clone().unwrap().root, root);
assert_eq!(
child1.clone().unwrap().nodes[0].range,
child1.clone().unwrap().range
);
assert_eq!(child1.clone().unwrap().nodes[0].node, redirect_node);
let child2 = child1.unwrap().child.clone();
assert!(child2.is_some());
assert_eq!(child2.clone().unwrap().range.get(input), "actual");
assert_eq!(child2.clone().unwrap().nodes.len(), 1);
assert_eq!(child2.clone().unwrap().root, root);
assert_eq!(
child2.clone().unwrap().nodes[0].range,
child2.clone().unwrap().range
);
assert_eq!(child2.clone().unwrap().nodes[0].node, concrete_node);
assert_eq!(CommandDispatcher::execute_parsed(parse).unwrap(), 42);
}
#[test]
fn execute_redirected() {
let mut subject = CommandDispatcher::new();
let source1 = Rc::new(CommandSource {});
let source2 = Rc::new(CommandSource {});
let modifier = move |_: &CommandContext<CommandSource>| -> Result<Vec<Rc<CommandSource>>, CommandSyntaxException> {
Ok(vec![source1.clone(), source2.clone()])
};
let concrete_node = subject.register(literal("actual").executes(|_| 42));
let redirect_node =
subject.register(literal("redirected").fork(subject.root.clone(), Rc::new(modifier)));
let input = "redirected actual";
let parse = subject.parse(input.into(), Rc::new(CommandSource {}));
assert_eq!(parse.context.range.get(input), "redirected");
assert_eq!(parse.context.nodes.len(), 1);
assert_eq!(parse.context.root, subject.root);
assert_eq!(parse.context.nodes[0].range, parse.context.range);
assert_eq!(parse.context.nodes[0].node, redirect_node);
let parent = parse.context.child.clone();
assert!(parent.is_some());
let parent = parent.unwrap();
assert_eq!(parent.range.get(input), "actual");
assert_eq!(parent.nodes.len(), 1);
assert_eq!(parse.context.root, subject.root);
assert_eq!(parent.nodes[0].range, parent.range);
assert_eq!(parent.nodes[0].node, concrete_node);
assert_eq!(parent.source, Rc::new(CommandSource {}));
assert_eq!(CommandDispatcher::execute_parsed(parse).unwrap(), 2);
}
#[test]
fn execute_orphaned_subcommand() {
let mut subject = CommandDispatcher::new();
subject.register(
literal("foo")
.then(argument("bar", integer()))
.executes(|_| 42),
);
let result = subject.execute("foo 5".into(), Rc::new(CommandSource {}));
assert!(result.is_err());
let result = result.unwrap_err();
assert_eq!(
*result.get_type(),
BuiltInExceptions::DispatcherUnknownCommand
);
assert_eq!(result.cursor(), Some(5));
}
#[test]
fn execute_invalid_other() {
let mut subject = CommandDispatcher::new();
subject.register(literal("w").executes(|_| panic!("This should not run")));
subject.register(literal("world").executes(|_| 42));
assert_eq!(
subject
.execute("world".into(), Rc::new(CommandSource {}))
.unwrap(),
42
);
}
#[test]
fn parse_no_space_separator() {
let mut subject = CommandDispatcher::new();
subject.register(
literal("foo")
.then(argument("bar", integer()))
.executes(|_| 42),
);
let result = subject.execute("foo$".into(), Rc::new(CommandSource {}));
assert!(result.is_err());
let result = result.unwrap_err();
assert_eq!(
*result.get_type(),
BuiltInExceptions::DispatcherUnknownCommand
);
assert_eq!(result.cursor(), Some(0));
}
#[test]
fn execute_invalid_subcommand() {
let mut subject = CommandDispatcher::new();
subject.register(
literal("foo")
.then(argument("bar", integer()))
.executes(|_| 42),
);
let result = subject.execute("foo bar".into(), Rc::new(CommandSource {}));
assert!(result.is_err());
let result = result.unwrap_err();
// this fails for some reason, i blame mojang
// assert_eq!(*result.get_type(), BuiltInExceptions::ReaderExpectedInt);
assert_eq!(result.cursor(), Some(4));
}
#[test]
fn get_path() {
let mut subject = CommandDispatcher::<()>::new();
let bar = literal("bar").build();
subject.register(literal("foo").then_built(bar.clone()));
assert_eq!(
subject.get_path(bar),
vec!["foo".to_string(), "bar".to_string()]
);
}
#[test]
fn find_node_doesnt_exist() {
let subject = CommandDispatcher::<()>::new();
assert_eq!(subject.find_node(&vec!["foo", "bar"]), None)
}
}

View file

@ -8,51 +8,3 @@ pub mod modifier;
pub mod parse_results; pub mod parse_results;
pub mod string_reader; pub mod string_reader;
pub mod tree; pub mod tree;
#[cfg(test)]
mod tests {
use std::rc::Rc;
use crate::{
arguments::integer_argument_type::{get_integer, integer},
builder::{literal_argument_builder::literal, required_argument_builder::argument},
command_dispatcher::CommandDispatcher,
context::CommandContext,
};
struct CommandSourceStack {
player: String,
}
#[test]
fn it_works() {
let mut dispatcher = CommandDispatcher::new();
let source = Rc::new(CommandSourceStack {
player: "player".to_string(),
});
dispatcher.register(
literal("foo")
.then(argument("bar", integer()).executes(
|c: &CommandContext<CommandSourceStack>| {
println!(
"Bar is {:?} and player is {}",
get_integer(c, "bar"),
c.source.player
);
2
},
))
.executes(|_| {
println!("Called foo with no arguments");
1
}),
);
let parse = dispatcher.parse("foo 123".into(), source.clone());
assert_eq!(CommandDispatcher::<_>::execute_parsed(parse).unwrap(), 2);
assert_eq!(dispatcher.execute("foo".into(), source).unwrap(), 1);
}
}

View file

@ -272,619 +272,3 @@ impl StringReader {
Ok(()) Ok(())
} }
} }
#[cfg(test)]
mod test {
use super::*;
#[test]
fn can_read() {
let mut reader = StringReader::from("abc".to_string());
assert_eq!(reader.can_read(), true);
reader.skip(); // 'a'
assert_eq!(reader.can_read(), true);
reader.skip(); // 'b'
assert_eq!(reader.can_read(), true);
reader.skip(); // 'c'
assert_eq!(reader.can_read(), false);
}
#[test]
fn get_remaining_length() {
let mut reader = StringReader::from("abc".to_string());
assert_eq!(reader.remaining_length(), 3);
reader.cursor = 1;
assert_eq!(reader.remaining_length(), 2);
reader.cursor = 2;
assert_eq!(reader.remaining_length(), 1);
reader.cursor = 3;
assert_eq!(reader.remaining_length(), 0);
}
#[test]
fn can_read_length() {
let reader = StringReader::from("abc".to_string());
assert_eq!(reader.can_read_length(1), true);
assert_eq!(reader.can_read_length(2), true);
assert_eq!(reader.can_read_length(3), true);
assert_eq!(reader.can_read_length(4), false);
assert_eq!(reader.can_read_length(5), false);
}
#[test]
fn peek() {
let mut reader = StringReader::from("abc".to_string());
assert_eq!(reader.peek(), 'a');
assert_eq!(reader.cursor(), 0);
reader.cursor = 2;
assert_eq!(reader.peek(), 'c');
assert_eq!(reader.cursor(), 2);
}
#[test]
fn peek_length() {
let mut reader = StringReader::from("abc".to_string());
assert_eq!(reader.peek_offset(0), 'a');
assert_eq!(reader.peek_offset(2), 'c');
assert_eq!(reader.cursor(), 0);
reader.cursor = 1;
assert_eq!(reader.peek_offset(1), 'c');
assert_eq!(reader.cursor(), 1);
}
#[test]
fn read() {
let mut reader = StringReader::from("abc".to_string());
assert_eq!(reader.read(), 'a');
assert_eq!(reader.read(), 'b');
assert_eq!(reader.read(), 'c');
assert_eq!(reader.cursor(), 3);
}
#[test]
fn skip() {
let mut reader = StringReader::from("abc".to_string());
reader.skip();
assert_eq!(reader.cursor(), 1);
}
#[test]
fn get_remaining() {
let mut reader = StringReader::from("Hello!".to_string());
assert_eq!(reader.remaining(), "Hello!");
reader.cursor = 3;
assert_eq!(reader.remaining(), "lo!");
reader.cursor = 6;
assert_eq!(reader.remaining(), "");
}
#[test]
fn get_read() {
let mut reader = StringReader::from("Hello!".to_string());
assert_eq!(reader.get_read(), "");
reader.cursor = 3;
assert_eq!(reader.get_read(), "Hel");
reader.cursor = 6;
assert_eq!(reader.get_read(), "Hello!");
}
#[test]
fn skip_whitespace_none() {
let mut reader = StringReader::from("Hello!".to_string());
reader.skip_whitespace();
assert_eq!(reader.cursor(), 0);
}
#[test]
fn skip_whitespace_mixed() {
let mut reader = StringReader::from(" \t \t\nHello!".to_string());
reader.skip_whitespace();
assert_eq!(reader.cursor(), 5);
}
#[test]
fn skip_whitespace_empty() {
let mut reader = StringReader::from("".to_string());
reader.skip_whitespace();
assert_eq!(reader.cursor(), 0);
}
#[test]
fn read_unquoted_string() {
let mut reader = StringReader::from("hello world".to_string());
assert_eq!(reader.read_unquoted_string(), "hello");
assert_eq!(reader.get_read(), "hello");
assert_eq!(reader.remaining(), " world");
}
#[test]
fn read_unquoted_string_empty() {
let mut reader = StringReader::from("".to_string());
assert_eq!(reader.read_unquoted_string(), "");
assert_eq!(reader.get_read(), "");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_unquoted_string_empty_with_remaining() {
let mut reader = StringReader::from(" hello world".to_string());
assert_eq!(reader.read_unquoted_string(), "");
assert_eq!(reader.get_read(), "");
assert_eq!(reader.remaining(), " hello world");
}
#[test]
fn read_quoted_string() {
let mut reader = StringReader::from("\"hello world\"".to_string());
assert_eq!(reader.read_quoted_string().unwrap(), "hello world");
assert_eq!(reader.get_read(), "\"hello world\"");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_single_quoted_string() {
let mut reader = StringReader::from("'hello world'".to_string());
assert_eq!(reader.read_quoted_string().unwrap(), "hello world");
assert_eq!(reader.get_read(), "'hello world'");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_mixed_quoted_string_double_inside_single() {
let mut reader = StringReader::from("'hello \"world\"'".to_string());
assert_eq!(reader.read_quoted_string().unwrap(), "hello \"world\"");
assert_eq!(reader.get_read(), "'hello \"world\"'");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_mixed_quoted_string_single_inside_double() {
let mut reader = StringReader::from("\"hello 'world'\"".to_string());
assert_eq!(reader.read_quoted_string().unwrap(), "hello 'world'");
assert_eq!(reader.get_read(), "\"hello 'world'\"");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_quoted_string_empty_quoted() {
let mut reader = StringReader::from("".to_string());
assert_eq!(reader.read_quoted_string().unwrap(), "");
assert_eq!(reader.get_read(), "");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_quoted_string_empty_quoted_with_remaining() {
let mut reader = StringReader::from("\"\" hello world".to_string());
assert_eq!(reader.read_quoted_string().unwrap(), "");
assert_eq!(reader.get_read(), "\"\"");
assert_eq!(reader.remaining(), " hello world");
}
#[test]
fn read_quoted_string_with_escaped_quote() {
let mut reader = StringReader::from("\"hello \\\"world\\\"\"".to_string());
assert_eq!(reader.read_quoted_string().unwrap(), "hello \"world\"");
assert_eq!(reader.get_read(), "\"hello \\\"world\\\"\"");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_quoted_string_with_escaped_escapes() {
let mut reader = StringReader::from("\"\\\\o/\"".to_string());
assert_eq!(reader.read_quoted_string().unwrap(), "\\o/");
assert_eq!(reader.get_read(), "\"\\\\o/\"");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_quoted_string_with_remaining() {
let mut reader = StringReader::from("\"hello world\" foo bar".to_string());
assert_eq!(reader.read_quoted_string().unwrap(), "hello world");
assert_eq!(reader.get_read(), "\"hello world\"");
assert_eq!(reader.remaining(), " foo bar");
}
#[test]
fn read_quoted_string_with_immediate_remaining() {
let mut reader = StringReader::from("\"hello world\"foo bar".to_string());
assert_eq!(reader.read_quoted_string().unwrap(), "hello world");
assert_eq!(reader.get_read(), "\"hello world\"");
assert_eq!(reader.remaining(), "foo bar");
}
#[test]
fn read_quoted_string_no_open() {
let mut reader = StringReader::from("hello world\"".to_string());
let result = reader.read_quoted_string();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(e.get_type(), &BuiltInExceptions::ReaderExpectedStartOfQuote);
assert_eq!(e.cursor(), Some(0));
}
}
#[test]
fn read_quoted_string_no_close() {
let mut reader = StringReader::from("\"hello world".to_string());
let result = reader.read_quoted_string();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(e.get_type(), &BuiltInExceptions::ReaderExpectedEndOfQuote);
assert_eq!(e.cursor(), Some(12));
}
}
#[test]
fn read_quoted_string_invalid_escape() {
let mut reader = StringReader::from("\"hello\\nworld\"".to_string());
let result = reader.read_quoted_string();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
e.get_type(),
&BuiltInExceptions::ReaderInvalidEscape { character: 'n' }
);
assert_eq!(e.cursor(), Some(7));
}
}
#[test]
fn read_quoted_string_invalid_quote_escape() {
let mut reader = StringReader::from("'hello\\\"\'world".to_string());
let result = reader.read_quoted_string();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
e.get_type(),
&BuiltInExceptions::ReaderInvalidEscape { character: '"' }
);
assert_eq!(e.cursor(), Some(7));
}
}
#[test]
fn read_string_no_quotes() {
let mut reader = StringReader::from("hello world".to_string());
assert_eq!(reader.read_string().unwrap(), "hello");
assert_eq!(reader.get_read(), "hello");
assert_eq!(reader.remaining(), " world");
}
#[test]
fn read_string_single_quotes() {
let mut reader = StringReader::from("'hello world'".to_string());
assert_eq!(reader.read_string().unwrap(), "hello world");
assert_eq!(reader.get_read(), "'hello world'");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_string_double_quotes() {
let mut reader = StringReader::from("\"hello world\"".to_string());
assert_eq!(reader.read_string().unwrap(), "hello world");
assert_eq!(reader.get_read(), "\"hello world\"");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_int() {
let mut reader = StringReader::from("1234567890".to_string());
assert_eq!(reader.read_int().unwrap(), 1234567890);
assert_eq!(reader.get_read(), "1234567890");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_int_negative() {
let mut reader = StringReader::from("-1234567890".to_string());
assert_eq!(reader.read_int().unwrap(), -1234567890);
assert_eq!(reader.get_read(), "-1234567890");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_int_invalid() {
let mut reader = StringReader::from("12.34".to_string());
let result = reader.read_int();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
e.get_type(),
&BuiltInExceptions::ReaderInvalidInt {
value: "12.34".to_string()
}
);
assert_eq!(e.cursor(), Some(0));
}
}
#[test]
fn read_int_none() {
let mut reader = StringReader::from("".to_string());
let result = reader.read_int();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(e.get_type(), &BuiltInExceptions::ReaderExpectedInt);
assert_eq!(e.cursor(), Some(0));
}
}
#[test]
fn read_int_with_remaining() {
let mut reader = StringReader::from("1234567890 foo bar".to_string());
assert_eq!(reader.read_int().unwrap(), 1234567890);
assert_eq!(reader.get_read(), "1234567890");
assert_eq!(reader.remaining(), " foo bar");
}
#[test]
fn read_int_with_remaining_immediate() {
let mut reader = StringReader::from("1234567890foo bar".to_string());
assert_eq!(reader.read_int().unwrap(), 1234567890);
assert_eq!(reader.get_read(), "1234567890");
assert_eq!(reader.remaining(), "foo bar");
}
#[test]
fn read_long() {
let mut reader = StringReader::from("1234567890".to_string());
assert_eq!(reader.read_long().unwrap(), 1234567890);
assert_eq!(reader.get_read(), "1234567890");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_long_negative() {
let mut reader = StringReader::from("-1234567890".to_string());
assert_eq!(reader.read_long().unwrap(), -1234567890);
assert_eq!(reader.get_read(), "-1234567890");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_long_invalid() {
let mut reader = StringReader::from("12.34".to_string());
let result = reader.read_long();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
e.get_type(),
&BuiltInExceptions::ReaderInvalidLong {
value: "12.34".to_string()
}
);
assert_eq!(e.cursor(), Some(0));
}
}
#[test]
fn read_long_none() {
let mut reader = StringReader::from("".to_string());
let result = reader.read_long();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(e.get_type(), &BuiltInExceptions::ReaderExpectedLong);
assert_eq!(e.cursor(), Some(0));
}
}
#[test]
fn read_long_with_remaining() {
let mut reader = StringReader::from("1234567890 foo bar".to_string());
assert_eq!(reader.read_long().unwrap(), 1234567890);
assert_eq!(reader.get_read(), "1234567890");
assert_eq!(reader.remaining(), " foo bar");
}
#[test]
fn read_long_with_remaining_immediate() {
let mut reader = StringReader::from("1234567890foo bar".to_string());
assert_eq!(reader.read_long().unwrap(), 1234567890);
assert_eq!(reader.get_read(), "1234567890");
assert_eq!(reader.remaining(), "foo bar");
}
#[test]
fn read_double() {
let mut reader = StringReader::from("123".to_string());
assert_eq!(reader.read_double().unwrap(), 123.0);
assert_eq!(reader.get_read(), "123");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_double_with_decimal() {
let mut reader = StringReader::from("12.34".to_string());
assert_eq!(reader.read_double().unwrap(), 12.34);
assert_eq!(reader.get_read(), "12.34");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_double_negative() {
let mut reader = StringReader::from("-123".to_string());
assert_eq!(reader.read_double().unwrap(), -123.0);
assert_eq!(reader.get_read(), "-123");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_double_invalid() {
let mut reader = StringReader::from("12.34.56".to_string());
let result = reader.read_double();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
e.get_type(),
&BuiltInExceptions::ReaderInvalidDouble {
value: "12.34.56".to_string()
}
);
assert_eq!(e.cursor(), Some(0));
}
}
#[test]
fn read_double_none() {
let mut reader = StringReader::from("".to_string());
let result = reader.read_double();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(e.get_type(), &BuiltInExceptions::ReaderExpectedDouble);
assert_eq!(e.cursor(), Some(0));
}
}
#[test]
fn read_double_with_remaining() {
let mut reader = StringReader::from("12.34 foo bar".to_string());
assert_eq!(reader.read_double().unwrap(), 12.34);
assert_eq!(reader.get_read(), "12.34");
assert_eq!(reader.remaining(), " foo bar");
}
#[test]
fn read_double_with_remaining_immediate() {
let mut reader = StringReader::from("12.34foo bar".to_string());
assert_eq!(reader.read_double().unwrap(), 12.34);
assert_eq!(reader.get_read(), "12.34");
assert_eq!(reader.remaining(), "foo bar");
}
#[test]
fn read_float() {
let mut reader = StringReader::from("123".to_string());
assert_eq!(reader.read_float().unwrap(), 123.0f32);
assert_eq!(reader.get_read(), "123");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_float_with_decimal() {
let mut reader = StringReader::from("12.34".to_string());
assert_eq!(reader.read_float().unwrap(), 12.34f32);
assert_eq!(reader.get_read(), "12.34");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_float_negative() {
let mut reader = StringReader::from("-123".to_string());
assert_eq!(reader.read_float().unwrap(), -123.0f32);
assert_eq!(reader.get_read(), "-123");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_float_invalid() {
let mut reader = StringReader::from("12.34.56".to_string());
let result = reader.read_float();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
e.get_type(),
&BuiltInExceptions::ReaderInvalidFloat {
value: "12.34.56".to_string()
}
);
assert_eq!(e.cursor(), Some(0));
}
}
#[test]
fn read_float_none() {
let mut reader = StringReader::from("".to_string());
let result = reader.read_float();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(e.get_type(), &BuiltInExceptions::ReaderExpectedFloat);
assert_eq!(e.cursor(), Some(0));
}
}
#[test]
fn read_float_with_remaining() {
let mut reader = StringReader::from("12.34 foo bar".to_string());
assert_eq!(reader.read_float().unwrap(), 12.34f32);
assert_eq!(reader.get_read(), "12.34");
assert_eq!(reader.remaining(), " foo bar");
}
#[test]
fn read_float_with_remaining_immediate() {
let mut reader = StringReader::from("12.34foo bar".to_string());
assert_eq!(reader.read_float().unwrap(), 12.34f32);
assert_eq!(reader.get_read(), "12.34");
assert_eq!(reader.remaining(), "foo bar");
}
#[test]
fn expect_correct() {
let mut reader = StringReader::from("abc".to_string());
reader.expect('a').unwrap();
assert_eq!(reader.cursor(), 1);
}
#[test]
fn expect_incorrect() {
let mut reader = StringReader::from("bcd".to_string());
let result = reader.expect('a');
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
e.get_type(),
&BuiltInExceptions::ReaderExpectedSymbol { symbol: 'a' }
);
assert_eq!(e.cursor(), Some(0));
}
}
#[test]
fn expect_none() {
let mut reader = StringReader::from("".to_string());
let result = reader.expect('a');
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
e.get_type(),
&BuiltInExceptions::ReaderExpectedSymbol { symbol: 'a' }
);
assert_eq!(e.cursor(), Some(0));
}
}
#[test]
fn read_boolean_correct() {
let mut reader = StringReader::from("true".to_string());
assert_eq!(reader.read_boolean().unwrap(), true);
assert_eq!(reader.get_read(), "true");
}
#[test]
fn read_boolean_incorrect() {
let mut reader = StringReader::from("tuesday".to_string());
let result = reader.read_boolean();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
e.get_type(),
&BuiltInExceptions::ReaderInvalidBool {
value: "tuesday".to_string()
}
);
assert_eq!(e.cursor(), Some(0));
}
}
#[test]
fn read_boolean_none() {
let mut reader = StringReader::from("".to_string());
let result = reader.read_boolean();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(e.get_type(), &BuiltInExceptions::ReaderExpectedBool);
assert_eq!(e.cursor(), Some(0));
}
}
}

View file

@ -0,0 +1,75 @@
use std::rc::Rc;
use crate::{
arguments::integer_argument_type::integer,
builder::{literal_argument_builder::literal, required_argument_builder::argument},
};
use super::ArgumentBuilder;
// public class ArgumentBuilderTest {
// private TestableArgumentBuilder<Object> builder;
// @Before
// public void setUp() throws Exception {
// builder = new TestableArgumentBuilder<>();
// }
// @Test
// public void testArguments() throws Exception {
// final RequiredArgumentBuilder<Object, ?> argument = argument("bar", integer());
// builder.then(argument);
// assertThat(builder.getArguments(), hasSize(1));
// assertThat(builder.getArguments(), hasItem((CommandNode<Object>) argument.build()));
// }
#[test]
fn test_arguments() {
let mut builder: ArgumentBuilder<()> = literal("foo");
let argument: ArgumentBuilder<()> = argument("bar", integer());
builder.then(argument.clone());
assert_eq!(builder.arguments.children.len(), 1);
let built_argument = Rc::new(argument.build());
assert!(builder
.arguments
.children
.values()
.any(|e| *e.borrow() == *built_argument));
}
// @Test
// public void testRedirect() throws Exception {
// final CommandNode<Object> target = mock(CommandNode.class);
// builder.redirect(target);
// assertThat(builder.getRedirect(), is(target));
// }
// @Test(expected = IllegalStateException.class)
// public void testRedirect_withChild() throws Exception {
// final CommandNode<Object> target = mock(CommandNode.class);
// builder.then(literal("foo"));
// builder.redirect(target);
// }
// @Test(expected = IllegalStateException.class)
// public void testThen_withRedirect() throws Exception {
// final CommandNode<Object> target = mock(CommandNode.class);
// builder.redirect(target);
// builder.then(literal("foo"));
// }
// private static class TestableArgumentBuilder<S> extends ArgumentBuilder<S, TestableArgumentBuilder<S>> {
// @Override
// protected TestableArgumentBuilder<S> getThis() {
// return this;
// }
// @Override
// public CommandNode<S> build() {
// return null;
// }
// }
// }

View file

@ -0,0 +1,410 @@
use std::rc::Rc;
use azalea_brigadier::{
arguments::integer_argument_type::integer,
builder::{literal_argument_builder::literal, required_argument_builder::argument},
command_dispatcher::CommandDispatcher,
context::CommandContext,
exceptions::{BuiltInExceptions, CommandSyntaxException},
string_reader::StringReader,
};
#[derive(Debug, PartialEq)]
struct CommandSource {}
fn input_with_offset(input: &str, offset: usize) -> StringReader {
let mut result: StringReader = input.into();
result.cursor = offset;
result
}
#[test]
fn create_and_execute_command() {
let mut subject = CommandDispatcher::new();
subject.register(literal("foo").executes(|_| 42));
assert_eq!(
subject
.execute("foo".into(), Rc::new(CommandSource {}))
.unwrap(),
42
);
}
#[test]
fn create_and_execute_offset_command() {
let mut subject = CommandDispatcher::new();
subject.register(literal("foo").executes(|_| 42));
assert_eq!(
subject
.execute(input_with_offset("/foo", 1), Rc::new(CommandSource {}))
.unwrap(),
42
);
}
#[test]
fn create_and_merge_commands() {
let mut subject = CommandDispatcher::new();
subject.register(literal("base").then(literal("foo").executes(|_| 42)));
subject.register(literal("base").then(literal("bar").executes(|_| 42)));
assert_eq!(
subject
.execute("base foo".into(), Rc::new(CommandSource {}))
.unwrap(),
42
);
assert_eq!(
subject
.execute("base bar".into(), Rc::new(CommandSource {}))
.unwrap(),
42
);
}
#[test]
fn execute_unknown_command() {
let mut subject = CommandDispatcher::new();
subject.register(literal("bar"));
subject.register(literal("baz"));
let execute_result = subject.execute("foo".into(), Rc::new(CommandSource {}));
let err = execute_result.err().unwrap();
match err.type_ {
BuiltInExceptions::DispatcherUnknownCommand => {}
_ => panic!("Unexpected error"),
}
assert_eq!(err.cursor().unwrap(), 0);
}
#[test]
fn execute_impermissible_command() {
let mut subject = CommandDispatcher::new();
subject.register(literal("foo").requires(|_| false));
let execute_result = subject.execute("foo".into(), Rc::new(CommandSource {}));
let err = execute_result.err().unwrap();
match err.type_ {
BuiltInExceptions::DispatcherUnknownCommand => {}
_ => panic!("Unexpected error"),
}
assert_eq!(err.cursor().unwrap(), 0);
}
#[test]
fn execute_empty_command() {
let mut subject = CommandDispatcher::new();
subject.register(literal(""));
let execute_result = subject.execute("".into(), Rc::new(CommandSource {}));
let err = execute_result.err().unwrap();
match err.type_ {
BuiltInExceptions::DispatcherUnknownCommand => {}
_ => panic!("Unexpected error"),
}
assert_eq!(err.cursor().unwrap(), 0);
}
#[test]
fn execute_unknown_subcommand() {
let mut subject = CommandDispatcher::new();
subject.register(literal("foo").executes(|_| 42));
let execute_result = subject.execute("foo bar".into(), Rc::new(CommandSource {}));
let err = execute_result.err().unwrap();
match err.type_ {
BuiltInExceptions::DispatcherUnknownArgument => {}
_ => panic!("Unexpected error"),
}
assert_eq!(err.cursor().unwrap(), 4);
}
#[test]
fn execute_incorrect_literal() {
let mut subject = CommandDispatcher::new();
subject.register(literal("foo").executes(|_| 42).then(literal("bar")));
let execute_result = subject.execute("foo baz".into(), Rc::new(CommandSource {}));
let err = execute_result.err().unwrap();
match err.type_ {
BuiltInExceptions::DispatcherUnknownArgument => {}
_ => panic!("Unexpected error"),
}
assert_eq!(err.cursor().unwrap(), 4);
}
#[test]
fn execute_ambiguous_incorrect_argument() {
let mut subject = CommandDispatcher::new();
subject.register(
literal("foo")
.executes(|_| 42)
.then(literal("bar"))
.then(literal("baz")),
);
let execute_result = subject.execute("foo unknown".into(), Rc::new(CommandSource {}));
let err = execute_result.err().unwrap();
match err.type_ {
BuiltInExceptions::DispatcherUnknownArgument => {}
_ => panic!("Unexpected error"),
}
assert_eq!(err.cursor().unwrap(), 4);
}
#[test]
fn execute_subcommand() {
let mut subject = CommandDispatcher::new();
subject.register(
literal("foo")
.then(literal("a"))
.then(literal("=").executes(|_| 100))
.then(literal("c"))
.executes(|_| 42),
);
assert_eq!(
subject
.execute("foo =".into(), Rc::new(CommandSource {}))
.unwrap(),
100
);
}
#[test]
fn parse_incomplete_literal() {
let mut subject = CommandDispatcher::new();
subject.register(literal("foo").then(literal("bar").executes(|_| 42)));
let parse = subject.parse("foo ".into(), Rc::new(CommandSource {}));
assert_eq!(parse.reader.remaining(), " ");
assert_eq!(parse.context.nodes.len(), 1);
}
#[test]
fn parse_incomplete_argument() {
let mut subject = CommandDispatcher::new();
subject.register(literal("foo").then(argument("bar", integer()).executes(|_| 42)));
let parse = subject.parse("foo ".into(), Rc::new(CommandSource {}));
assert_eq!(parse.reader.remaining(), " ");
assert_eq!(parse.context.nodes.len(), 1);
}
#[test]
fn execute_ambiguious_parent_subcommand() {
let mut subject = CommandDispatcher::new();
subject.register(
literal("test")
.then(argument("incorrect", integer()).executes(|_| 42))
.then(argument("right", integer()).then(argument("sub", integer()).executes(|_| 100))),
);
assert_eq!(
subject
.execute("test 1 2".into(), Rc::new(CommandSource {}))
.unwrap(),
100
);
}
#[test]
fn execute_ambiguious_parent_subcommand_via_redirect() {
let mut subject = CommandDispatcher::new();
let real = subject.register(
literal("test")
.then(argument("incorrect", integer()).executes(|_| 42))
.then(argument("right", integer()).then(argument("sub", integer()).executes(|_| 100))),
);
subject.register(literal("redirect").redirect(real));
assert_eq!(
subject
.execute("redirect 1 2".into(), Rc::new(CommandSource {}))
.unwrap(),
100
);
}
#[test]
fn execute_redirected_multiple_times() {
let mut subject = CommandDispatcher::new();
let concrete_node = subject.register(literal("actual").executes(|_| 42));
let root = subject.root.clone();
let redirect_node = subject.register(literal("redirected").redirect(root.clone()));
let input = "redirected redirected actual";
let parse = subject.parse(input.into(), Rc::new(CommandSource {}));
assert_eq!(parse.context.range.get(input), "redirected");
assert_eq!(parse.context.nodes.len(), 1);
assert_eq!(parse.context.root, root);
assert_eq!(parse.context.nodes[0].range, parse.context.range);
assert_eq!(parse.context.nodes[0].node, redirect_node);
let child1 = parse.context.child.clone();
assert!(child1.is_some());
assert_eq!(child1.clone().unwrap().range.get(input), "redirected");
assert_eq!(child1.clone().unwrap().nodes.len(), 1);
assert_eq!(child1.clone().unwrap().root, root);
assert_eq!(
child1.clone().unwrap().nodes[0].range,
child1.clone().unwrap().range
);
assert_eq!(child1.clone().unwrap().nodes[0].node, redirect_node);
let child2 = child1.unwrap().child.clone();
assert!(child2.is_some());
assert_eq!(child2.clone().unwrap().range.get(input), "actual");
assert_eq!(child2.clone().unwrap().nodes.len(), 1);
assert_eq!(child2.clone().unwrap().root, root);
assert_eq!(
child2.clone().unwrap().nodes[0].range,
child2.clone().unwrap().range
);
assert_eq!(child2.clone().unwrap().nodes[0].node, concrete_node);
assert_eq!(CommandDispatcher::execute_parsed(parse).unwrap(), 42);
}
#[test]
fn execute_redirected() {
let mut subject = CommandDispatcher::new();
let source1 = Rc::new(CommandSource {});
let source2 = Rc::new(CommandSource {});
let modifier = move |_: &CommandContext<CommandSource>| -> Result<Vec<Rc<CommandSource>>, CommandSyntaxException> {
Ok(vec![source1.clone(), source2.clone()])
};
let concrete_node = subject.register(literal("actual").executes(|_| 42));
let redirect_node =
subject.register(literal("redirected").fork(subject.root.clone(), Rc::new(modifier)));
let input = "redirected actual";
let parse = subject.parse(input.into(), Rc::new(CommandSource {}));
assert_eq!(parse.context.range.get(input), "redirected");
assert_eq!(parse.context.nodes.len(), 1);
assert_eq!(parse.context.root, subject.root);
assert_eq!(parse.context.nodes[0].range, parse.context.range);
assert_eq!(parse.context.nodes[0].node, redirect_node);
let parent = parse.context.child.clone();
assert!(parent.is_some());
let parent = parent.unwrap();
assert_eq!(parent.range.get(input), "actual");
assert_eq!(parent.nodes.len(), 1);
assert_eq!(parse.context.root, subject.root);
assert_eq!(parent.nodes[0].range, parent.range);
assert_eq!(parent.nodes[0].node, concrete_node);
assert_eq!(parent.source, Rc::new(CommandSource {}));
assert_eq!(CommandDispatcher::execute_parsed(parse).unwrap(), 2);
}
#[test]
fn execute_orphaned_subcommand() {
let mut subject = CommandDispatcher::new();
subject.register(
literal("foo")
.then(argument("bar", integer()))
.executes(|_| 42),
);
let result = subject.execute("foo 5".into(), Rc::new(CommandSource {}));
assert!(result.is_err());
let result = result.unwrap_err();
assert_eq!(
*result.get_type(),
BuiltInExceptions::DispatcherUnknownCommand
);
assert_eq!(result.cursor(), Some(5));
}
#[test]
fn execute_invalid_other() {
let mut subject = CommandDispatcher::new();
subject.register(literal("w").executes(|_| panic!("This should not run")));
subject.register(literal("world").executes(|_| 42));
assert_eq!(
subject
.execute("world".into(), Rc::new(CommandSource {}))
.unwrap(),
42
);
}
#[test]
fn parse_no_space_separator() {
let mut subject = CommandDispatcher::new();
subject.register(
literal("foo")
.then(argument("bar", integer()))
.executes(|_| 42),
);
let result = subject.execute("foo$".into(), Rc::new(CommandSource {}));
assert!(result.is_err());
let result = result.unwrap_err();
assert_eq!(
*result.get_type(),
BuiltInExceptions::DispatcherUnknownCommand
);
assert_eq!(result.cursor(), Some(0));
}
#[test]
fn execute_invalid_subcommand() {
let mut subject = CommandDispatcher::new();
subject.register(
literal("foo")
.then(argument("bar", integer()))
.executes(|_| 42),
);
let result = subject.execute("foo bar".into(), Rc::new(CommandSource {}));
assert!(result.is_err());
let result = result.unwrap_err();
// this fails for some reason, i blame mojang
// assert_eq!(*result.get_type(), BuiltInExceptions::ReaderExpectedInt);
assert_eq!(result.cursor(), Some(4));
}
#[test]
fn get_path() {
let mut subject = CommandDispatcher::<()>::new();
let bar = literal("bar").build();
subject.register(literal("foo").then_built(bar.clone()));
assert_eq!(
subject.get_path(bar),
vec!["foo".to_string(), "bar".to_string()]
);
}
#[test]
fn find_node_doesnt_exist() {
let subject = CommandDispatcher::<()>::new();
assert_eq!(subject.find_node(&vec!["foo", "bar"]), None)
}

View file

@ -0,0 +1 @@

View file

@ -0,0 +1 @@

View file

@ -0,0 +1,612 @@
use azalea_brigadier::{exceptions::BuiltInExceptions, string_reader::StringReader};
#[test]
fn can_read() {
let mut reader = StringReader::from("abc".to_string());
assert_eq!(reader.can_read(), true);
reader.skip(); // 'a'
assert_eq!(reader.can_read(), true);
reader.skip(); // 'b'
assert_eq!(reader.can_read(), true);
reader.skip(); // 'c'
assert_eq!(reader.can_read(), false);
}
#[test]
fn get_remaining_length() {
let mut reader = StringReader::from("abc".to_string());
assert_eq!(reader.remaining_length(), 3);
reader.cursor = 1;
assert_eq!(reader.remaining_length(), 2);
reader.cursor = 2;
assert_eq!(reader.remaining_length(), 1);
reader.cursor = 3;
assert_eq!(reader.remaining_length(), 0);
}
#[test]
fn can_read_length() {
let reader = StringReader::from("abc".to_string());
assert_eq!(reader.can_read_length(1), true);
assert_eq!(reader.can_read_length(2), true);
assert_eq!(reader.can_read_length(3), true);
assert_eq!(reader.can_read_length(4), false);
assert_eq!(reader.can_read_length(5), false);
}
#[test]
fn peek() {
let mut reader = StringReader::from("abc".to_string());
assert_eq!(reader.peek(), 'a');
assert_eq!(reader.cursor(), 0);
reader.cursor = 2;
assert_eq!(reader.peek(), 'c');
assert_eq!(reader.cursor(), 2);
}
#[test]
fn peek_length() {
let mut reader = StringReader::from("abc".to_string());
assert_eq!(reader.peek_offset(0), 'a');
assert_eq!(reader.peek_offset(2), 'c');
assert_eq!(reader.cursor(), 0);
reader.cursor = 1;
assert_eq!(reader.peek_offset(1), 'c');
assert_eq!(reader.cursor(), 1);
}
#[test]
fn read() {
let mut reader = StringReader::from("abc".to_string());
assert_eq!(reader.read(), 'a');
assert_eq!(reader.read(), 'b');
assert_eq!(reader.read(), 'c');
assert_eq!(reader.cursor(), 3);
}
#[test]
fn skip() {
let mut reader = StringReader::from("abc".to_string());
reader.skip();
assert_eq!(reader.cursor(), 1);
}
#[test]
fn get_remaining() {
let mut reader = StringReader::from("Hello!".to_string());
assert_eq!(reader.remaining(), "Hello!");
reader.cursor = 3;
assert_eq!(reader.remaining(), "lo!");
reader.cursor = 6;
assert_eq!(reader.remaining(), "");
}
#[test]
fn get_read() {
let mut reader = StringReader::from("Hello!".to_string());
assert_eq!(reader.get_read(), "");
reader.cursor = 3;
assert_eq!(reader.get_read(), "Hel");
reader.cursor = 6;
assert_eq!(reader.get_read(), "Hello!");
}
#[test]
fn skip_whitespace_none() {
let mut reader = StringReader::from("Hello!".to_string());
reader.skip_whitespace();
assert_eq!(reader.cursor(), 0);
}
#[test]
fn skip_whitespace_mixed() {
let mut reader = StringReader::from(" \t \t\nHello!".to_string());
reader.skip_whitespace();
assert_eq!(reader.cursor(), 5);
}
#[test]
fn skip_whitespace_empty() {
let mut reader = StringReader::from("".to_string());
reader.skip_whitespace();
assert_eq!(reader.cursor(), 0);
}
#[test]
fn read_unquoted_string() {
let mut reader = StringReader::from("hello world".to_string());
assert_eq!(reader.read_unquoted_string(), "hello");
assert_eq!(reader.get_read(), "hello");
assert_eq!(reader.remaining(), " world");
}
#[test]
fn read_unquoted_string_empty() {
let mut reader = StringReader::from("".to_string());
assert_eq!(reader.read_unquoted_string(), "");
assert_eq!(reader.get_read(), "");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_unquoted_string_empty_with_remaining() {
let mut reader = StringReader::from(" hello world".to_string());
assert_eq!(reader.read_unquoted_string(), "");
assert_eq!(reader.get_read(), "");
assert_eq!(reader.remaining(), " hello world");
}
#[test]
fn read_quoted_string() {
let mut reader = StringReader::from("\"hello world\"".to_string());
assert_eq!(reader.read_quoted_string().unwrap(), "hello world");
assert_eq!(reader.get_read(), "\"hello world\"");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_single_quoted_string() {
let mut reader = StringReader::from("'hello world'".to_string());
assert_eq!(reader.read_quoted_string().unwrap(), "hello world");
assert_eq!(reader.get_read(), "'hello world'");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_mixed_quoted_string_double_inside_single() {
let mut reader = StringReader::from("'hello \"world\"'".to_string());
assert_eq!(reader.read_quoted_string().unwrap(), "hello \"world\"");
assert_eq!(reader.get_read(), "'hello \"world\"'");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_mixed_quoted_string_single_inside_double() {
let mut reader = StringReader::from("\"hello 'world'\"".to_string());
assert_eq!(reader.read_quoted_string().unwrap(), "hello 'world'");
assert_eq!(reader.get_read(), "\"hello 'world'\"");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_quoted_string_empty_quoted() {
let mut reader = StringReader::from("".to_string());
assert_eq!(reader.read_quoted_string().unwrap(), "");
assert_eq!(reader.get_read(), "");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_quoted_string_empty_quoted_with_remaining() {
let mut reader = StringReader::from("\"\" hello world".to_string());
assert_eq!(reader.read_quoted_string().unwrap(), "");
assert_eq!(reader.get_read(), "\"\"");
assert_eq!(reader.remaining(), " hello world");
}
#[test]
fn read_quoted_string_with_escaped_quote() {
let mut reader = StringReader::from("\"hello \\\"world\\\"\"".to_string());
assert_eq!(reader.read_quoted_string().unwrap(), "hello \"world\"");
assert_eq!(reader.get_read(), "\"hello \\\"world\\\"\"");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_quoted_string_with_escaped_escapes() {
let mut reader = StringReader::from("\"\\\\o/\"".to_string());
assert_eq!(reader.read_quoted_string().unwrap(), "\\o/");
assert_eq!(reader.get_read(), "\"\\\\o/\"");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_quoted_string_with_remaining() {
let mut reader = StringReader::from("\"hello world\" foo bar".to_string());
assert_eq!(reader.read_quoted_string().unwrap(), "hello world");
assert_eq!(reader.get_read(), "\"hello world\"");
assert_eq!(reader.remaining(), " foo bar");
}
#[test]
fn read_quoted_string_with_immediate_remaining() {
let mut reader = StringReader::from("\"hello world\"foo bar".to_string());
assert_eq!(reader.read_quoted_string().unwrap(), "hello world");
assert_eq!(reader.get_read(), "\"hello world\"");
assert_eq!(reader.remaining(), "foo bar");
}
#[test]
fn read_quoted_string_no_open() {
let mut reader = StringReader::from("hello world\"".to_string());
let result = reader.read_quoted_string();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(e.get_type(), &BuiltInExceptions::ReaderExpectedStartOfQuote);
assert_eq!(e.cursor(), Some(0));
}
}
#[test]
fn read_quoted_string_no_close() {
let mut reader = StringReader::from("\"hello world".to_string());
let result = reader.read_quoted_string();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(e.get_type(), &BuiltInExceptions::ReaderExpectedEndOfQuote);
assert_eq!(e.cursor(), Some(12));
}
}
#[test]
fn read_quoted_string_invalid_escape() {
let mut reader = StringReader::from("\"hello\\nworld\"".to_string());
let result = reader.read_quoted_string();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
e.get_type(),
&BuiltInExceptions::ReaderInvalidEscape { character: 'n' }
);
assert_eq!(e.cursor(), Some(7));
}
}
#[test]
fn read_quoted_string_invalid_quote_escape() {
let mut reader = StringReader::from("'hello\\\"\'world".to_string());
let result = reader.read_quoted_string();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
e.get_type(),
&BuiltInExceptions::ReaderInvalidEscape { character: '"' }
);
assert_eq!(e.cursor(), Some(7));
}
}
#[test]
fn read_string_no_quotes() {
let mut reader = StringReader::from("hello world".to_string());
assert_eq!(reader.read_string().unwrap(), "hello");
assert_eq!(reader.get_read(), "hello");
assert_eq!(reader.remaining(), " world");
}
#[test]
fn read_string_single_quotes() {
let mut reader = StringReader::from("'hello world'".to_string());
assert_eq!(reader.read_string().unwrap(), "hello world");
assert_eq!(reader.get_read(), "'hello world'");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_string_double_quotes() {
let mut reader = StringReader::from("\"hello world\"".to_string());
assert_eq!(reader.read_string().unwrap(), "hello world");
assert_eq!(reader.get_read(), "\"hello world\"");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_int() {
let mut reader = StringReader::from("1234567890".to_string());
assert_eq!(reader.read_int().unwrap(), 1234567890);
assert_eq!(reader.get_read(), "1234567890");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_int_negative() {
let mut reader = StringReader::from("-1234567890".to_string());
assert_eq!(reader.read_int().unwrap(), -1234567890);
assert_eq!(reader.get_read(), "-1234567890");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_int_invalid() {
let mut reader = StringReader::from("12.34".to_string());
let result = reader.read_int();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
e.get_type(),
&BuiltInExceptions::ReaderInvalidInt {
value: "12.34".to_string()
}
);
assert_eq!(e.cursor(), Some(0));
}
}
#[test]
fn read_int_none() {
let mut reader = StringReader::from("".to_string());
let result = reader.read_int();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(e.get_type(), &BuiltInExceptions::ReaderExpectedInt);
assert_eq!(e.cursor(), Some(0));
}
}
#[test]
fn read_int_with_remaining() {
let mut reader = StringReader::from("1234567890 foo bar".to_string());
assert_eq!(reader.read_int().unwrap(), 1234567890);
assert_eq!(reader.get_read(), "1234567890");
assert_eq!(reader.remaining(), " foo bar");
}
#[test]
fn read_int_with_remaining_immediate() {
let mut reader = StringReader::from("1234567890foo bar".to_string());
assert_eq!(reader.read_int().unwrap(), 1234567890);
assert_eq!(reader.get_read(), "1234567890");
assert_eq!(reader.remaining(), "foo bar");
}
#[test]
fn read_long() {
let mut reader = StringReader::from("1234567890".to_string());
assert_eq!(reader.read_long().unwrap(), 1234567890);
assert_eq!(reader.get_read(), "1234567890");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_long_negative() {
let mut reader = StringReader::from("-1234567890".to_string());
assert_eq!(reader.read_long().unwrap(), -1234567890);
assert_eq!(reader.get_read(), "-1234567890");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_long_invalid() {
let mut reader = StringReader::from("12.34".to_string());
let result = reader.read_long();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
e.get_type(),
&BuiltInExceptions::ReaderInvalidLong {
value: "12.34".to_string()
}
);
assert_eq!(e.cursor(), Some(0));
}
}
#[test]
fn read_long_none() {
let mut reader = StringReader::from("".to_string());
let result = reader.read_long();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(e.get_type(), &BuiltInExceptions::ReaderExpectedLong);
assert_eq!(e.cursor(), Some(0));
}
}
#[test]
fn read_long_with_remaining() {
let mut reader = StringReader::from("1234567890 foo bar".to_string());
assert_eq!(reader.read_long().unwrap(), 1234567890);
assert_eq!(reader.get_read(), "1234567890");
assert_eq!(reader.remaining(), " foo bar");
}
#[test]
fn read_long_with_remaining_immediate() {
let mut reader = StringReader::from("1234567890foo bar".to_string());
assert_eq!(reader.read_long().unwrap(), 1234567890);
assert_eq!(reader.get_read(), "1234567890");
assert_eq!(reader.remaining(), "foo bar");
}
#[test]
fn read_double() {
let mut reader = StringReader::from("123".to_string());
assert_eq!(reader.read_double().unwrap(), 123.0);
assert_eq!(reader.get_read(), "123");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_double_with_decimal() {
let mut reader = StringReader::from("12.34".to_string());
assert_eq!(reader.read_double().unwrap(), 12.34);
assert_eq!(reader.get_read(), "12.34");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_double_negative() {
let mut reader = StringReader::from("-123".to_string());
assert_eq!(reader.read_double().unwrap(), -123.0);
assert_eq!(reader.get_read(), "-123");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_double_invalid() {
let mut reader = StringReader::from("12.34.56".to_string());
let result = reader.read_double();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
e.get_type(),
&BuiltInExceptions::ReaderInvalidDouble {
value: "12.34.56".to_string()
}
);
assert_eq!(e.cursor(), Some(0));
}
}
#[test]
fn read_double_none() {
let mut reader = StringReader::from("".to_string());
let result = reader.read_double();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(e.get_type(), &BuiltInExceptions::ReaderExpectedDouble);
assert_eq!(e.cursor(), Some(0));
}
}
#[test]
fn read_double_with_remaining() {
let mut reader = StringReader::from("12.34 foo bar".to_string());
assert_eq!(reader.read_double().unwrap(), 12.34);
assert_eq!(reader.get_read(), "12.34");
assert_eq!(reader.remaining(), " foo bar");
}
#[test]
fn read_double_with_remaining_immediate() {
let mut reader = StringReader::from("12.34foo bar".to_string());
assert_eq!(reader.read_double().unwrap(), 12.34);
assert_eq!(reader.get_read(), "12.34");
assert_eq!(reader.remaining(), "foo bar");
}
#[test]
fn read_float() {
let mut reader = StringReader::from("123".to_string());
assert_eq!(reader.read_float().unwrap(), 123.0f32);
assert_eq!(reader.get_read(), "123");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_float_with_decimal() {
let mut reader = StringReader::from("12.34".to_string());
assert_eq!(reader.read_float().unwrap(), 12.34f32);
assert_eq!(reader.get_read(), "12.34");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_float_negative() {
let mut reader = StringReader::from("-123".to_string());
assert_eq!(reader.read_float().unwrap(), -123.0f32);
assert_eq!(reader.get_read(), "-123");
assert_eq!(reader.remaining(), "");
}
#[test]
fn read_float_invalid() {
let mut reader = StringReader::from("12.34.56".to_string());
let result = reader.read_float();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
e.get_type(),
&BuiltInExceptions::ReaderInvalidFloat {
value: "12.34.56".to_string()
}
);
assert_eq!(e.cursor(), Some(0));
}
}
#[test]
fn read_float_none() {
let mut reader = StringReader::from("".to_string());
let result = reader.read_float();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(e.get_type(), &BuiltInExceptions::ReaderExpectedFloat);
assert_eq!(e.cursor(), Some(0));
}
}
#[test]
fn read_float_with_remaining() {
let mut reader = StringReader::from("12.34 foo bar".to_string());
assert_eq!(reader.read_float().unwrap(), 12.34f32);
assert_eq!(reader.get_read(), "12.34");
assert_eq!(reader.remaining(), " foo bar");
}
#[test]
fn read_float_with_remaining_immediate() {
let mut reader = StringReader::from("12.34foo bar".to_string());
assert_eq!(reader.read_float().unwrap(), 12.34f32);
assert_eq!(reader.get_read(), "12.34");
assert_eq!(reader.remaining(), "foo bar");
}
#[test]
fn expect_correct() {
let mut reader = StringReader::from("abc".to_string());
reader.expect('a').unwrap();
assert_eq!(reader.cursor(), 1);
}
#[test]
fn expect_incorrect() {
let mut reader = StringReader::from("bcd".to_string());
let result = reader.expect('a');
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
e.get_type(),
&BuiltInExceptions::ReaderExpectedSymbol { symbol: 'a' }
);
assert_eq!(e.cursor(), Some(0));
}
}
#[test]
fn expect_none() {
let mut reader = StringReader::from("".to_string());
let result = reader.expect('a');
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
e.get_type(),
&BuiltInExceptions::ReaderExpectedSymbol { symbol: 'a' }
);
assert_eq!(e.cursor(), Some(0));
}
}
#[test]
fn read_boolean_correct() {
let mut reader = StringReader::from("true".to_string());
assert_eq!(reader.read_boolean().unwrap(), true);
assert_eq!(reader.get_read(), "true");
}
#[test]
fn read_boolean_incorrect() {
let mut reader = StringReader::from("tuesday".to_string());
let result = reader.read_boolean();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(
e.get_type(),
&BuiltInExceptions::ReaderInvalidBool {
value: "tuesday".to_string()
}
);
assert_eq!(e.cursor(), Some(0));
}
}
#[test]
fn read_boolean_none() {
let mut reader = StringReader::from("".to_string());
let result = reader.read_boolean();
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(e.get_type(), &BuiltInExceptions::ReaderExpectedBool);
assert_eq!(e.cursor(), Some(0));
}
}