blob: 2edcd67a088c7b1189e2f0e4bdf0e18e523c5451 [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
#include "commands/command_parser.h"
#include <gtest/gtest.h>
TEST(CommandParser, Parse) {
// [ HELLO i1 v1 | HI v2 ] [X i2 | Y]
std::vector<std::string> c1{"hello", "1", "a"}, c2{"hi", "b"}, c3{"hi", "c", "x", "2"}, c4{"hello", "3", "d", "y"},
c5{"hi", "e", "y"}, c6{"y"}, d1{"hello"}, d2{"hi"}, d3{"hello", "no-int"}, d4{"x", "1", "y"},
d5{"hello", "1", "v", "hi", "v"}, d6{"hello", "1"}, d7{"float_test", "1.1"};
std::int64_t i1 = 0, i2 = 0;
double f1 = 0;
std::string v1, v2;
std::string_view hflag, xflag;
auto parse = [&](auto&& parser) -> Status {
hflag = {}, xflag = {};
while (parser.Good()) {
if (parser.EatEqICaseFlag("hello", hflag)) {
i1 = GET_OR_RET(parser.TakeInt());
v1 = GET_OR_RET(parser.TakeStr());
} else if (parser.EatEqICaseFlag("hi", hflag)) {
v2 = GET_OR_RET(parser.TakeStr());
} else if (parser.EatEqICaseFlag("x", xflag)) {
i2 = GET_OR_RET(parser.TakeInt());
} else if (parser.EatEqICaseFlag("y", xflag)) {
// pass
} else if (parser.EatEqICaseFlag("float_test", hflag)) {
f1 = GET_OR_RET(parser.TakeFloat());
} else {
return parser.InvalidSyntax();
}
}
return {};
};
ASSERT_TRUE(parse(CommandParser(c1)));
ASSERT_EQ(i1, 1);
ASSERT_EQ(v1, "a");
ASSERT_TRUE(parse(CommandParser(c2)));
ASSERT_EQ(v2, "b");
ASSERT_TRUE(parse(CommandParser(c3)));
ASSERT_EQ(v2, "c");
ASSERT_EQ(i2, 2);
ASSERT_TRUE(parse(CommandParser(c4)));
ASSERT_EQ(i1, 3);
ASSERT_EQ(v1, "d");
ASSERT_EQ(xflag, "y");
ASSERT_TRUE(parse(CommandParser(c5)));
ASSERT_EQ(v2, "e");
ASSERT_EQ(xflag, "y");
ASSERT_TRUE(parse(CommandParser(c6)));
ASSERT_EQ(hflag, "");
ASSERT_EQ(xflag, "y");
ASSERT_FALSE(parse(CommandParser(d1)));
ASSERT_FALSE(parse(CommandParser(d2)));
ASSERT_FALSE(parse(CommandParser(d3)));
ASSERT_FALSE(parse(CommandParser(d4)));
ASSERT_FALSE(parse(CommandParser(d5)));
ASSERT_FALSE(parse(CommandParser(d6)));
ASSERT_TRUE(parse(CommandParser(d7)));
ASSERT_EQ(f1, 1.1);
}
TEST(CommandParser, ParseMove) {
// k v [ HELLO a b | HI c ]
std::vector<std::string> c1{"h", "i"}, c2{"g", "k", "HELLO", "l", "m"}, c3{"n", "o", "HI", "p"}, d1{"x"},
d2{"x", "y", "HAHA"}, d3{};
std::string k, v, a, b, c;
auto parse = [&](auto&& parser) -> Status {
k = GET_OR_RET(parser.TakeStr());
v = GET_OR_RET(parser.TakeStr());
if (parser.EatEqICase("HELLO")) {
a = GET_OR_RET(parser.TakeStr());
b = GET_OR_RET(parser.TakeStr());
} else if (parser.EatEqICase("HI")) {
c = GET_OR_RET(parser.TakeStr());
} else if (parser.Good()) {
return parser.InvalidSyntax();
}
return Status::OK();
};
ASSERT_TRUE(parse(CommandParser(std::move(c1))));
ASSERT_EQ(k, "h");
ASSERT_EQ(v, "i");
ASSERT_TRUE(parse(CommandParser(std::move(c2))));
ASSERT_EQ(k, "g");
ASSERT_EQ(v, "k");
ASSERT_EQ(a, "l");
ASSERT_EQ(b, "m");
ASSERT_TRUE(parse(CommandParser(std::move(c3))));
ASSERT_EQ(k, "n");
ASSERT_EQ(v, "o");
ASSERT_EQ(c, "p");
ASSERT_FALSE(parse(CommandParser(std::move(d1))));
ASSERT_FALSE(parse(CommandParser(std::move(d2))));
ASSERT_FALSE(parse(CommandParser(std::move(d3))));
}
TEST(CommandParser, ParseFloat) {
std::vector<std::string> vec{"not float", "-3.5e-6", "3"};
CommandParser p(vec);
ASSERT_FALSE(p.TakeFloat());
auto _ = p.TakeStr();
ASSERT_EQ(p.TakeFloat().GetValue(), -3.5e-6);
ASSERT_EQ(p.TakeFloat().GetValue(), 3);
ASSERT_FALSE(p.TakeFloat());
}