#include "gtest/gtest.h" #include "CommandParser.h" #include typedef std::string ss; void dump(const std::vector & v) { for (auto s : v) { std::cerr << " \"" << ss((const char *)&s[0], s.size()) << "\"" << std::endl; } } #define compare_parsed(expected, results) \ compare_parsed_(expected, results, __LINE__) void compare_parsed_(const std::vector & expected, const std::vector & results, int line) { if (expected != results) { std::cerr << "Line " << line << " unexpected parsed result:" << std::endl; std::cerr << "Expected:" << std::endl; dump(expected); std::cerr << "Actual:" << std::endl; dump(results); } EXPECT_EQ(expected, results); } TEST(CommandParser_parse, parses_a_basic_command) { EncodedString command("w /home/josh/file"); CommandParser cp; EXPECT_TRUE(cp.parse(command)); compare_parsed(std::vector({ ss("w"), ss("/home/josh/file"), }), cp.args()); } TEST(CommandParser_parse, parses_a_command_with_quoted_arguments) { EncodedString command("echo 'Hello There'\" World!\" a'b'c d\"e\"f ' ' \"\" 1 2 3\n"); CommandParser cp; EXPECT_TRUE(cp.parse(command)); compare_parsed(std::vector({ ss("echo"), ss("Hello There World!"), ss("abc"), ss("def"), ss(" "), ss(""), ss("1"), ss("2"), ss("3"), }), cp.args()); } TEST(CommandParser_parse, parses_a_command_with_escaped_characters) { EncodedString command(" echo \\ ' \\' a ' \"b \\\" c\" \\\\too\n"); CommandParser cp; EXPECT_TRUE(cp.parse(command)); compare_parsed(std::vector({ ss("echo"), ss(" "), ss(" ' a "), ss("b \" c"), ss("\\too"), }), cp.args()); } TEST(CommandParser_parse, fails_to_parse_with_an_unterminated_escape_sequence) { EncodedString command("echo hi\\"); CommandParser cp; EXPECT_FALSE(cp.parse(command)); EXPECT_EQ("Unterminated escape sequence", cp.parse_error()); } TEST(CommandParser_parse, fails_to_parse_with_an_unterminated_quoted_region) { EncodedString command("echo Bob's Golf Bag"); CommandParser cp; EXPECT_FALSE(cp.parse(command)); EXPECT_EQ("Unterminated quoted region", cp.parse_error()); }