diff --git a/azalea-brigadier/src/builder/argument_builder.rs b/azalea-brigadier/src/builder/argument_builder.rs index 14d41f4e..d26b2a8a 100644 --- a/azalea-brigadier/src/builder/argument_builder.rs +++ b/azalea-brigadier/src/builder/argument_builder.rs @@ -135,82 +135,3 @@ impl Debug for ArgumentBuilder { .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 builder; - - // @Before - // public void setUp() throws Exception { - // builder = new TestableArgumentBuilder<>(); - // } - - // @Test - // public void testArguments() throws Exception { - // final RequiredArgumentBuilder argument = argument("bar", integer()); - - // builder.then(argument); - - // assertThat(builder.getArguments(), hasSize(1)); - // assertThat(builder.getArguments(), hasItem((CommandNode) 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 target = mock(CommandNode.class); - // builder.redirect(target); - // assertThat(builder.getRedirect(), is(target)); - // } - - // @Test(expected = IllegalStateException.class) - // public void testRedirect_withChild() throws Exception { - // final CommandNode target = mock(CommandNode.class); - // builder.then(literal("foo")); - // builder.redirect(target); - // } - - // @Test(expected = IllegalStateException.class) - // public void testThen_withRedirect() throws Exception { - // final CommandNode target = mock(CommandNode.class); - // builder.redirect(target); - // builder.then(literal("foo")); - // } - - // private static class TestableArgumentBuilder extends ArgumentBuilder> { - // @Override - // protected TestableArgumentBuilder getThis() { - // return this; - // } - - // @Override - // public CommandNode build() { - // return null; - // } - // } - // } -} diff --git a/azalea-brigadier/src/command_dispatcher.rs b/azalea-brigadier/src/command_dispatcher.rs index fc3f3d50..eab42dd8 100644 --- a/azalea-brigadier/src/command_dispatcher.rs +++ b/azalea-brigadier/src/command_dispatcher.rs @@ -10,7 +10,7 @@ use std::{cell::RefCell, cmp::Ordering, collections::HashMap, marker::PhantomDat #[derive(Default)] pub struct CommandDispatcher { - root: Rc>>, + pub root: Rc>>, _marker: PhantomData, } @@ -296,416 +296,3 @@ impl Clone for CommandDispatcher { } } } - -#[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| -> Result>, 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) - } -} diff --git a/azalea-brigadier/src/lib.rs b/azalea-brigadier/src/lib.rs index db46d46e..a294eb19 100644 --- a/azalea-brigadier/src/lib.rs +++ b/azalea-brigadier/src/lib.rs @@ -8,51 +8,3 @@ pub mod modifier; pub mod parse_results; pub mod string_reader; 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| { - 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); - } -} diff --git a/azalea-brigadier/src/string_reader.rs b/azalea-brigadier/src/string_reader.rs index dcb35fcb..9eb09b57 100644 --- a/azalea-brigadier/src/string_reader.rs +++ b/azalea-brigadier/src/string_reader.rs @@ -272,619 +272,3 @@ impl StringReader { 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)); - } - } -} diff --git a/azalea-brigadier/tests/arguments/bool_argument_type_test.rs b/azalea-brigadier/tests/arguments/bool_argument_type_test.rs new file mode 100644 index 00000000..e69de29b diff --git a/azalea-brigadier/tests/arguments/double_argument_type_test.rs b/azalea-brigadier/tests/arguments/double_argument_type_test.rs new file mode 100644 index 00000000..e69de29b diff --git a/azalea-brigadier/tests/arguments/float_argument_type_test.rs b/azalea-brigadier/tests/arguments/float_argument_type_test.rs new file mode 100644 index 00000000..e69de29b diff --git a/azalea-brigadier/tests/arguments/integer_argument_type_test.rs b/azalea-brigadier/tests/arguments/integer_argument_type_test.rs new file mode 100644 index 00000000..e69de29b diff --git a/azalea-brigadier/tests/arguments/long_argument_type_test.rs b/azalea-brigadier/tests/arguments/long_argument_type_test.rs new file mode 100644 index 00000000..e69de29b diff --git a/azalea-brigadier/tests/arguments/string_argument_type_test.rs b/azalea-brigadier/tests/arguments/string_argument_type_test.rs new file mode 100644 index 00000000..e69de29b diff --git a/azalea-brigadier/tests/builder/argument_builder_test.rs b/azalea-brigadier/tests/builder/argument_builder_test.rs new file mode 100644 index 00000000..e570c988 --- /dev/null +++ b/azalea-brigadier/tests/builder/argument_builder_test.rs @@ -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 builder; + +// @Before +// public void setUp() throws Exception { +// builder = new TestableArgumentBuilder<>(); +// } + +// @Test +// public void testArguments() throws Exception { +// final RequiredArgumentBuilder argument = argument("bar", integer()); + +// builder.then(argument); + +// assertThat(builder.getArguments(), hasSize(1)); +// assertThat(builder.getArguments(), hasItem((CommandNode) 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 target = mock(CommandNode.class); +// builder.redirect(target); +// assertThat(builder.getRedirect(), is(target)); +// } + +// @Test(expected = IllegalStateException.class) +// public void testRedirect_withChild() throws Exception { +// final CommandNode target = mock(CommandNode.class); +// builder.then(literal("foo")); +// builder.redirect(target); +// } + +// @Test(expected = IllegalStateException.class) +// public void testThen_withRedirect() throws Exception { +// final CommandNode target = mock(CommandNode.class); +// builder.redirect(target); +// builder.then(literal("foo")); +// } + +// private static class TestableArgumentBuilder extends ArgumentBuilder> { +// @Override +// protected TestableArgumentBuilder getThis() { +// return this; +// } + +// @Override +// public CommandNode build() { +// return null; +// } +// } +// } diff --git a/azalea-brigadier/tests/builder/literal_argument_builder_test.rs b/azalea-brigadier/tests/builder/literal_argument_builder_test.rs new file mode 100644 index 00000000..e69de29b diff --git a/azalea-brigadier/tests/builder/required_argument_builder_test.rs b/azalea-brigadier/tests/builder/required_argument_builder_test.rs new file mode 100644 index 00000000..e69de29b diff --git a/azalea-brigadier/tests/command_dispatcher_test.rs b/azalea-brigadier/tests/command_dispatcher_test.rs new file mode 100644 index 00000000..cb33ac73 --- /dev/null +++ b/azalea-brigadier/tests/command_dispatcher_test.rs @@ -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| -> Result>, 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) +} diff --git a/azalea-brigadier/tests/command_dispatcher_usages_test.rs b/azalea-brigadier/tests/command_dispatcher_usages_test.rs new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/azalea-brigadier/tests/command_dispatcher_usages_test.rs @@ -0,0 +1 @@ + diff --git a/azalea-brigadier/tests/command_suggestions_test.rs b/azalea-brigadier/tests/command_suggestions_test.rs new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/azalea-brigadier/tests/command_suggestions_test.rs @@ -0,0 +1 @@ + diff --git a/azalea-brigadier/tests/context/command_context_test.rs b/azalea-brigadier/tests/context/command_context_test.rs new file mode 100644 index 00000000..e69de29b diff --git a/azalea-brigadier/tests/context/parsed_argument_test.rs b/azalea-brigadier/tests/context/parsed_argument_test.rs new file mode 100644 index 00000000..e69de29b diff --git a/azalea-brigadier/tests/exceptions/dynamic_command_syntax_exception_type_test.rs b/azalea-brigadier/tests/exceptions/dynamic_command_syntax_exception_type_test.rs new file mode 100644 index 00000000..e69de29b diff --git a/azalea-brigadier/tests/exceptions/simple_command_syntax_exception_type_test.rs b/azalea-brigadier/tests/exceptions/simple_command_syntax_exception_type_test.rs new file mode 100644 index 00000000..e69de29b diff --git a/azalea-brigadier/tests/string_reader_test.rs b/azalea-brigadier/tests/string_reader_test.rs new file mode 100644 index 00000000..5008eff8 --- /dev/null +++ b/azalea-brigadier/tests/string_reader_test.rs @@ -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)); + } +} diff --git a/azalea-brigadier/tests/suggestion/suggestion_test.rs b/azalea-brigadier/tests/suggestion/suggestion_test.rs new file mode 100644 index 00000000..e69de29b diff --git a/azalea-brigadier/tests/suggestion/suggestions_builder_test.rs b/azalea-brigadier/tests/suggestion/suggestions_builder_test.rs new file mode 100644 index 00000000..e69de29b diff --git a/azalea-brigadier/tests/suggestion/suggestions_test.rs b/azalea-brigadier/tests/suggestion/suggestions_test.rs new file mode 100644 index 00000000..e69de29b diff --git a/azalea-brigadier/tests/tree/abstract_command_node_test.rs b/azalea-brigadier/tests/tree/abstract_command_node_test.rs new file mode 100644 index 00000000..e69de29b diff --git a/azalea-brigadier/tests/tree/argument_command_node_test.rs b/azalea-brigadier/tests/tree/argument_command_node_test.rs new file mode 100644 index 00000000..e69de29b diff --git a/azalea-brigadier/tests/tree/literal_command_node_test.rs b/azalea-brigadier/tests/tree/literal_command_node_test.rs new file mode 100644 index 00000000..e69de29b diff --git a/azalea-brigadier/tests/tree/root_command_node_test.rs b/azalea-brigadier/tests/tree/root_command_node_test.rs new file mode 100644 index 00000000..e69de29b