2 * Copyright 2016 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <folly/experimental/NestedCommandLineApp.h>
19 #include <folly/Subprocess.h>
20 #include <folly/experimental/io/FsUtil.h>
21 #include <folly/portability/GTest.h>
22 #include <glog/logging.h>
24 namespace folly { namespace test {
28 std::string getHelperPath() {
29 const auto basename = "nested_command_line_app_test_helper";
30 auto path = fs::executable_path();
31 path.remove_filename() /= basename;
32 if (!fs::exists(path)) {
33 path = path.parent_path().parent_path() / basename / basename;
38 std::string callHelper(std::initializer_list<std::string> args,
39 int expectedExitCode = 0,
41 static std::string helperPath = getHelperPath();
43 std::vector<std::string> allArgs;
44 allArgs.reserve(args.size() + 1);
45 allArgs.push_back(helperPath);
46 allArgs.insert(allArgs.end(), args.begin(), args.end());
48 Subprocess::Options options;
50 options.stdout(stdoutFd);
56 Subprocess proc(allArgs, options);
57 auto p = proc.communicate();
58 EXPECT_EQ(expectedExitCode, proc.wait().exitStatus());
65 TEST(ProgramOptionsTest, Errors) {
67 callHelper({"--wtf", "foo"}, 1);
68 callHelper({"qux"}, 1);
69 callHelper({"--global-foo", "x", "foo"}, 1);
72 TEST(ProgramOptionsTest, Help) {
73 // Not actually checking help output, just verifying that help doesn't fail
74 callHelper({"--version"});
75 callHelper({"--help"});
76 callHelper({"--help", "foo"});
77 callHelper({"--help", "bar"});
79 callHelper({"help", "foo"});
80 callHelper({"help", "bar"});
83 callHelper({"--help", "qux"}, 1);
84 callHelper({"help", "qux"}, 1);
87 TEST(ProgramOptionsTest, DevFull) {
88 folly::File full("/dev/full", O_RDWR);
89 callHelper({"--help"}, 1, full.fd());
92 TEST(ProgramOptionsTest, Success) {
101 "foo global-foo 43\n"
105 callHelper({"--global-foo", "43", "foo", "--local-foo", "44",
108 // Check that global flags can still be given after the command
111 "foo global-foo 43\n"
115 callHelper({"foo", "--global-foo", "43", "--local-foo", "44",
119 TEST(ProgramOptionsTest, Aliases) {
122 "foo global-foo 43\n"
126 callHelper({"--global-foo", "43", "bar", "--local-foo", "44",