mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-26 13:20:05 +00:00
8cee461986
* tools: add uint32_t flags parsing This will be required to refactorize other tools.
416 lines
11 KiB
C++
416 lines
11 KiB
C++
// Copyright (c) 2023 Google LLC.
|
|
//
|
|
// Licensed 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 "tools/util/flags.h"
|
|
|
|
#include "gmock/gmock.h"
|
|
|
|
#ifdef UTIL_FLAGS_FLAG
|
|
#undef UTIL_FLAGS_FLAG
|
|
#define UTIL_FLAGS_FLAG(Type, Prefix, Name, Default, Required, IsShort) \
|
|
flags::Flag<Type> Name(Default); \
|
|
flags::FlagRegistration Name##_registration(Name, Prefix #Name, Required, \
|
|
IsShort)
|
|
#else
|
|
#error \
|
|
"UTIL_FLAGS_FLAG is not defined. Either flags.h is not included of the flag name changed."
|
|
#endif
|
|
|
|
class FlagTest : public ::testing::Test {
|
|
protected:
|
|
void SetUp() override { flags::FlagList::reset(); }
|
|
};
|
|
|
|
TEST_F(FlagTest, NoFlags) {
|
|
const char* argv[] = {"binary", nullptr};
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
EXPECT_EQ(flags::positional_arguments.size(), 0);
|
|
}
|
|
|
|
TEST_F(FlagTest, DashIsPositional) {
|
|
const char* argv[] = {"binary", "-", nullptr};
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
|
|
EXPECT_EQ(flags::positional_arguments.size(), 1);
|
|
EXPECT_EQ(flags::positional_arguments[0], "-");
|
|
}
|
|
|
|
TEST_F(FlagTest, Positional) {
|
|
const char* argv[] = {"binary", "A", "BCD", nullptr};
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
|
|
EXPECT_EQ(flags::positional_arguments.size(), 2);
|
|
EXPECT_EQ(flags::positional_arguments[0], "A");
|
|
EXPECT_EQ(flags::positional_arguments[1], "BCD");
|
|
}
|
|
|
|
TEST_F(FlagTest, MissingRequired) {
|
|
FLAG_SHORT_bool(g, false, true);
|
|
|
|
const char* argv[] = {"binary", nullptr};
|
|
EXPECT_FALSE(flags::Parse(argv));
|
|
EXPECT_EQ(flags::positional_arguments.size(), 0);
|
|
}
|
|
|
|
TEST_F(FlagTest, BooleanShortValue) {
|
|
FLAG_SHORT_bool(g, false, false);
|
|
const char* argv[] = {"binary", "-g", nullptr};
|
|
EXPECT_FALSE(g.value());
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
|
|
EXPECT_TRUE(g.value());
|
|
EXPECT_EQ(flags::positional_arguments.size(), 0);
|
|
}
|
|
|
|
TEST_F(FlagTest, BooleanShortDefaultValue) {
|
|
FLAG_SHORT_bool(g, true, false);
|
|
const char* argv[] = {"binary", nullptr};
|
|
EXPECT_TRUE(g.value());
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
|
|
EXPECT_TRUE(g.value());
|
|
}
|
|
|
|
TEST_F(FlagTest, BooleanLongValueNotParsed) {
|
|
FLAG_SHORT_bool(g, false, false);
|
|
const char* argv[] = {"binary", "-g", "false", nullptr};
|
|
EXPECT_FALSE(g.value());
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
|
|
EXPECT_TRUE(g.value());
|
|
EXPECT_EQ(flags::positional_arguments.size(), 1);
|
|
EXPECT_EQ(flags::positional_arguments[0], "false");
|
|
}
|
|
|
|
TEST_F(FlagTest, BooleanLongSplitNotParsed) {
|
|
FLAG_LONG_bool(foo, false, false);
|
|
const char* argv[] = {"binary", "--foo", "true", nullptr};
|
|
EXPECT_FALSE(foo.value());
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
|
|
EXPECT_TRUE(foo.value());
|
|
EXPECT_EQ(flags::positional_arguments.size(), 1);
|
|
EXPECT_EQ(flags::positional_arguments[0], "true");
|
|
}
|
|
|
|
TEST_F(FlagTest, BooleanLongExplicitTrue) {
|
|
FLAG_LONG_bool(foo, false, false);
|
|
const char* argv[] = {"binary", "--foo=true", nullptr};
|
|
EXPECT_FALSE(foo.value());
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
|
|
EXPECT_TRUE(foo.value());
|
|
EXPECT_EQ(flags::positional_arguments.size(), 0);
|
|
}
|
|
|
|
TEST_F(FlagTest, BooleanLongExplicitFalse) {
|
|
FLAG_LONG_bool(foo, false, false);
|
|
const char* argv[] = {"binary", "--foo=false", nullptr};
|
|
EXPECT_FALSE(foo.value());
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
|
|
EXPECT_FALSE(foo.value());
|
|
EXPECT_EQ(flags::positional_arguments.size(), 0);
|
|
}
|
|
|
|
TEST_F(FlagTest, BooleanLongDefaultValue) {
|
|
FLAG_LONG_bool(foo, true, false);
|
|
const char* argv[] = {"binary", nullptr};
|
|
EXPECT_TRUE(foo.value());
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
|
|
EXPECT_TRUE(foo.value());
|
|
EXPECT_EQ(flags::positional_arguments.size(), 0);
|
|
}
|
|
|
|
TEST_F(FlagTest, BooleanLongDefaultValueCancelled) {
|
|
FLAG_LONG_bool(foo, true, false);
|
|
const char* argv[] = {"binary", "--foo=false", nullptr};
|
|
EXPECT_TRUE(foo.value());
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
|
|
EXPECT_FALSE(foo.value());
|
|
EXPECT_EQ(flags::positional_arguments.size(), 0);
|
|
}
|
|
|
|
TEST_F(FlagTest, StringFlagDefaultValue) {
|
|
FLAG_SHORT_string(f, "default", false);
|
|
const char* argv[] = {"binary", nullptr};
|
|
EXPECT_EQ(f.value(), "default");
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
EXPECT_EQ(f.value(), "default");
|
|
EXPECT_EQ(flags::positional_arguments.size(), 0);
|
|
}
|
|
|
|
TEST_F(FlagTest, StringFlagShortMissingString) {
|
|
FLAG_SHORT_string(f, "default", false);
|
|
const char* argv[] = {"binary", "-f", nullptr};
|
|
EXPECT_EQ(f.value(), "default");
|
|
|
|
EXPECT_FALSE(flags::Parse(argv));
|
|
}
|
|
|
|
TEST_F(FlagTest, StringFlagDefault) {
|
|
FLAG_SHORT_string(f, "default", false);
|
|
const char* argv[] = {"binary", nullptr};
|
|
EXPECT_EQ(f.value(), "default");
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
|
|
EXPECT_EQ(f.value(), "default");
|
|
EXPECT_EQ(flags::positional_arguments.size(), 0);
|
|
}
|
|
|
|
TEST_F(FlagTest, StringFlagSet) {
|
|
FLAG_SHORT_string(f, "default", false);
|
|
const char* argv[] = {"binary", "-f", "toto", nullptr};
|
|
EXPECT_EQ(f.value(), "default");
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
|
|
EXPECT_EQ(f.value(), "toto");
|
|
EXPECT_EQ(flags::positional_arguments.size(), 0);
|
|
}
|
|
|
|
TEST_F(FlagTest, StringLongFlagSetSplit) {
|
|
FLAG_LONG_string(foo, "default", false);
|
|
const char* argv[] = {"binary", "--foo", "toto", nullptr};
|
|
EXPECT_EQ(foo.value(), "default");
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
|
|
EXPECT_EQ(foo.value(), "toto");
|
|
EXPECT_EQ(flags::positional_arguments.size(), 0);
|
|
}
|
|
|
|
TEST_F(FlagTest, StringLongFlagSetUnified) {
|
|
FLAG_LONG_string(foo, "default", false);
|
|
const char* argv[] = {"binary", "--foo=toto", nullptr};
|
|
EXPECT_EQ(foo.value(), "default");
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
|
|
EXPECT_EQ(foo.value(), "toto");
|
|
EXPECT_EQ(flags::positional_arguments.size(), 0);
|
|
}
|
|
|
|
TEST_F(FlagTest, StringLongFlagSetEmpty) {
|
|
FLAG_LONG_string(foo, "default", false);
|
|
const char* argv[] = {"binary", "--foo=", nullptr};
|
|
EXPECT_EQ(foo.value(), "default");
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
|
|
EXPECT_EQ(foo.value(), "");
|
|
EXPECT_EQ(flags::positional_arguments.size(), 0);
|
|
}
|
|
|
|
TEST_F(FlagTest, AllPositionalAfterDoubleDash) {
|
|
FLAG_LONG_string(foo, "default", false);
|
|
const char* argv[] = {"binary", "--", "--foo=toto", nullptr};
|
|
EXPECT_EQ(foo.value(), "default");
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
|
|
EXPECT_EQ(foo.value(), "default");
|
|
EXPECT_EQ(flags::positional_arguments.size(), 1);
|
|
EXPECT_EQ(flags::positional_arguments[0], "--foo=toto");
|
|
}
|
|
|
|
TEST_F(FlagTest, NothingAfterDoubleDash) {
|
|
FLAG_LONG_string(foo, "default", false);
|
|
const char* argv[] = {"binary", "--", nullptr};
|
|
EXPECT_EQ(foo.value(), "default");
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
|
|
EXPECT_EQ(foo.value(), "default");
|
|
EXPECT_EQ(flags::positional_arguments.size(), 0);
|
|
}
|
|
|
|
TEST_F(FlagTest, FlagDoubleSetNotAllowed) {
|
|
FLAG_LONG_string(foo, "default", false);
|
|
const char* argv[] = {"binary", "--foo=abc", "--foo=def", nullptr};
|
|
EXPECT_EQ(foo.value(), "default");
|
|
|
|
EXPECT_FALSE(flags::Parse(argv));
|
|
}
|
|
|
|
TEST_F(FlagTest, MultipleFlags) {
|
|
FLAG_LONG_string(foo, "default foo", false);
|
|
FLAG_LONG_string(bar, "default_bar", false);
|
|
const char* argv[] = {"binary", "--foo", "abc", "--bar=def", nullptr};
|
|
EXPECT_EQ(foo.value(), "default foo");
|
|
EXPECT_EQ(bar.value(), "default_bar");
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
EXPECT_EQ(foo.value(), "abc");
|
|
EXPECT_EQ(bar.value(), "def");
|
|
}
|
|
|
|
TEST_F(FlagTest, MixedStringAndBool) {
|
|
FLAG_LONG_string(foo, "default foo", false);
|
|
FLAG_LONG_string(bar, "default_bar", false);
|
|
FLAG_SHORT_bool(g, false, false);
|
|
const char* argv[] = {"binary", "--foo", "abc", "-g", "--bar=def", nullptr};
|
|
EXPECT_EQ(foo.value(), "default foo");
|
|
EXPECT_EQ(bar.value(), "default_bar");
|
|
EXPECT_FALSE(g.value());
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
EXPECT_EQ(foo.value(), "abc");
|
|
EXPECT_EQ(bar.value(), "def");
|
|
EXPECT_TRUE(g.value());
|
|
}
|
|
|
|
TEST_F(FlagTest, UintFlagDefaultValue) {
|
|
FLAG_SHORT_uint(f, 18, false);
|
|
const char* argv[] = {"binary", nullptr};
|
|
EXPECT_EQ(f.value(), 18);
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
EXPECT_EQ(f.value(), 18);
|
|
EXPECT_EQ(flags::positional_arguments.size(), 0);
|
|
}
|
|
|
|
TEST_F(FlagTest, UintFlagShortMissingValue) {
|
|
FLAG_SHORT_uint(f, 19, false);
|
|
const char* argv[] = {"binary", "-f", nullptr};
|
|
EXPECT_EQ(f.value(), 19);
|
|
|
|
EXPECT_FALSE(flags::Parse(argv));
|
|
}
|
|
|
|
TEST_F(FlagTest, UintFlagSet) {
|
|
FLAG_SHORT_uint(f, 20, false);
|
|
const char* argv[] = {"binary", "-f", "21", nullptr};
|
|
EXPECT_EQ(f.value(), 20);
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
|
|
EXPECT_EQ(f.value(), 21);
|
|
EXPECT_EQ(flags::positional_arguments.size(), 0);
|
|
}
|
|
|
|
TEST_F(FlagTest, UintLongFlagSetSplit) {
|
|
FLAG_LONG_uint(foo, 22, false);
|
|
const char* argv[] = {"binary", "--foo", "23", nullptr};
|
|
EXPECT_EQ(foo.value(), 22);
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
|
|
EXPECT_EQ(foo.value(), 23);
|
|
EXPECT_EQ(flags::positional_arguments.size(), 0);
|
|
}
|
|
|
|
TEST_F(FlagTest, UintLongFlagSetUnified) {
|
|
FLAG_LONG_uint(foo, 24, false);
|
|
const char* argv[] = {"binary", "--foo=25", nullptr};
|
|
EXPECT_EQ(foo.value(), 24);
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
|
|
EXPECT_EQ(foo.value(), 25);
|
|
EXPECT_EQ(flags::positional_arguments.size(), 0);
|
|
}
|
|
|
|
TEST_F(FlagTest, UintLongFlagSetEmptyIsWrong) {
|
|
FLAG_LONG_uint(foo, 26, false);
|
|
const char* argv[] = {"binary", "--foo=", nullptr};
|
|
EXPECT_EQ(foo.value(), 26);
|
|
|
|
EXPECT_FALSE(flags::Parse(argv));
|
|
}
|
|
|
|
TEST_F(FlagTest, UintLongFlagSetNegativeFails) {
|
|
FLAG_LONG_uint(foo, 26, false);
|
|
const char* argv[] = {"binary", "--foo=-2", nullptr};
|
|
EXPECT_EQ(foo.value(), 26);
|
|
|
|
EXPECT_FALSE(flags::Parse(argv));
|
|
}
|
|
|
|
TEST_F(FlagTest, UintLongFlagSetOverflowFails) {
|
|
FLAG_LONG_uint(foo, 27, false);
|
|
const char* argv[] = {
|
|
"binary", "--foo=99999999999999999999999999999999999999999999999999999",
|
|
nullptr};
|
|
EXPECT_EQ(foo.value(), 27);
|
|
|
|
EXPECT_FALSE(flags::Parse(argv));
|
|
}
|
|
|
|
TEST_F(FlagTest, UintLongFlagSetInvalidCharTrailing) {
|
|
FLAG_LONG_uint(foo, 28, false);
|
|
const char* argv[] = {"binary", "--foo=12A", nullptr};
|
|
EXPECT_EQ(foo.value(), 28);
|
|
|
|
EXPECT_FALSE(flags::Parse(argv));
|
|
}
|
|
|
|
TEST_F(FlagTest, UintLongFlagSetSpaces) {
|
|
FLAG_LONG_uint(foo, 29, false);
|
|
const char* argv[] = {"binary", "--foo= 12", nullptr};
|
|
EXPECT_EQ(foo.value(), 29);
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
EXPECT_EQ(foo.value(), 12);
|
|
EXPECT_EQ(flags::positional_arguments.size(), 0);
|
|
}
|
|
|
|
TEST_F(FlagTest, UintLongFlagSpacesOnly) {
|
|
FLAG_LONG_uint(foo, 30, false);
|
|
const char* argv[] = {"binary", "--foo= ", nullptr};
|
|
EXPECT_EQ(foo.value(), 30);
|
|
|
|
EXPECT_FALSE(flags::Parse(argv));
|
|
}
|
|
|
|
TEST_F(FlagTest, UintLongFlagSplitNumber) {
|
|
FLAG_LONG_uint(foo, 31, false);
|
|
const char* argv[] = {"binary", "--foo= 2 2", nullptr};
|
|
EXPECT_EQ(foo.value(), 31);
|
|
|
|
EXPECT_FALSE(flags::Parse(argv));
|
|
}
|
|
|
|
TEST_F(FlagTest, UintLongFlagHex) {
|
|
FLAG_LONG_uint(foo, 32, false);
|
|
const char* argv[] = {"binary", "--foo=0xA", nullptr};
|
|
EXPECT_EQ(foo.value(), 32);
|
|
|
|
EXPECT_FALSE(flags::Parse(argv));
|
|
}
|
|
|
|
TEST_F(FlagTest, UintLongFlagZeros) {
|
|
FLAG_LONG_uint(foo, 33, false);
|
|
const char* argv[] = {"binary", "--foo=0000", nullptr};
|
|
EXPECT_EQ(foo.value(), 33);
|
|
|
|
EXPECT_TRUE(flags::Parse(argv));
|
|
EXPECT_EQ(foo.value(), 0);
|
|
EXPECT_EQ(flags::positional_arguments.size(), 0);
|
|
}
|