proxygen
NestedCommandLineAppTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2015-present Facebook, Inc.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 
18 
19 #include <folly/Subprocess.h>
22 #include <glog/logging.h>
23 
24 namespace folly {
25 namespace test {
26 
27 namespace {
28 
29 std::string getHelperPath() {
30  const auto basename = "nested_command_line_app_test_helper";
31  auto path = fs::executable_path();
32  path.remove_filename() /= basename;
33  if (!fs::exists(path)) {
34  path = path.parent_path().parent_path() / basename / basename;
35  }
36  return path.string();
37 }
38 
39 std::string callHelper(
40  std::initializer_list<std::string> args,
41  int expectedExitCode = 0,
42  int stdoutFd = -1) {
43  static std::string helperPath = getHelperPath();
44 
45  std::vector<std::string> allArgs;
46  allArgs.reserve(args.size() + 1);
47  allArgs.push_back(helperPath);
48  allArgs.insert(allArgs.end(), args.begin(), args.end());
49 
50  Subprocess::Options options;
51  if (stdoutFd != -1) {
52  options.stdoutFd(stdoutFd);
53  } else {
54  options.pipeStdout();
55  }
56  options.pipeStderr();
57 
58  Subprocess proc(allArgs, options);
59  auto p = proc.communicate();
60  EXPECT_EQ(expectedExitCode, proc.wait().exitStatus());
61 
62  return p.first;
63 }
64 
65 } // namespace
66 
67 TEST(ProgramOptionsTest, Errors) {
68  callHelper({}, 1);
69  callHelper({"--wtf", "foo"}, 1);
70  callHelper({"qux"}, 1);
71  callHelper({"--global-foo", "x", "foo"}, 1);
72 }
73 
74 TEST(ProgramOptionsTest, Help) {
75  // Not actually checking help output, just verifying that help doesn't fail
76  callHelper({"--version"});
77  callHelper({"--help"});
78  callHelper({"--help", "foo"});
79  callHelper({"--help", "bar"});
80  callHelper({"--help", "--", "bar"});
81  callHelper({"help"});
82  callHelper({"help", "foo"});
83  callHelper({"help", "bar"});
84 
85  // wrong command name
86  callHelper({"--help", "qux"}, 1);
87  callHelper({"help", "qux"}, 1);
88 
89  // anything after -- is parsed as arguments
90  callHelper({"--", "help", "bar"}, 1);
91 }
92 
93 TEST(ProgramOptionsTest, DevFull) {
94  folly::File full("/dev/full", O_RDWR);
95  callHelper({"--help"}, 1, full.fd());
96 }
97 
98 TEST(ProgramOptionsTest, CutArguments) {
99  // anything after -- is parsed as arguments
100  EXPECT_EQ(
101  "running foo\n"
102  "foo global-foo 43\n"
103  "foo local-foo 42\n"
104  "foo arg b\n"
105  "foo arg --local-foo\n"
106  "foo arg 44\n"
107  "foo arg a\n",
108  callHelper(
109  {"foo", "--global-foo", "43", "--", "b", "--local-foo", "44", "a"}));
110 }
111 
112 TEST(ProgramOptionsTest, Success) {
113  EXPECT_EQ(
114  "running foo\n"
115  "foo global-foo 42\n"
116  "foo local-foo 42\n",
117  callHelper({"foo"}));
118 
119  EXPECT_EQ(
120  "running foo\n"
121  "foo global-foo 43\n"
122  "foo local-foo 44\n"
123  "foo arg a\n"
124  "foo arg b\n",
125  callHelper({"--global-foo", "43", "foo", "--local-foo", "44", "a", "b"}));
126 
127  // Check that global flags can still be given after the command
128  EXPECT_EQ(
129  "running foo\n"
130  "foo global-foo 43\n"
131  "foo local-foo 44\n"
132  "foo arg a\n"
133  "foo arg b\n",
134  callHelper({"foo", "--global-foo", "43", "--local-foo", "44", "a", "b"}));
135 }
136 
137 TEST(ProgramOptionsTest, Aliases) {
138  EXPECT_EQ(
139  "running foo\n"
140  "foo global-foo 43\n"
141  "foo local-foo 44\n"
142  "foo arg a\n"
143  "foo arg b\n",
144  callHelper({"--global-foo", "43", "bar", "--local-foo", "44", "a", "b"}));
145 }
146 
147 TEST(ProgramOptionsTest, BuiltinCommand) {
150  ASSERT_TRUE(
153  NestedCommandLineApp::kHelpCommand.str() + "nonsense"));
154 }
155 
156 } // namespace test
157 } // namespace folly
std::string str() const
Definition: Range.h:591
path executable_path()
Definition: FsUtil.cpp:72
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
static constexpr StringPiece const kVersionCommand
int fd() const
Definition: File.h:85
bool isBuiltinCommand(const std::string &name) const
TEST(ProgramOptionsTest, Errors)
const char * string
Definition: Conv.cpp:212
#define ASSERT_FALSE(condition)
Definition: gtest.h:1868
static constexpr StringPiece const kHelpCommand
#define ASSERT_TRUE(condition)
Definition: gtest.h:1865