Rewrote menu handling for vie custom call.
The intended trajectory of this patch is to abstract out all i/o for custom_call. The reason is that kjellander@ will need to be able to configure custom calls using flags, and using the same framework to gather all input gathering to a single place will make this a lot easier. This patch focuses on choices. The next will focus on field entries, like "enter ip address" or "enter port number." BUG= TEST=Manually tested all menus in custom call, ran new unit tests. Review URL: https://webrtc-codereview.appspot.com/757005 git-svn-id: http://webrtc.googlecode.com/svn/trunk@2758 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
95
src/video_engine/test/auto_test/primitives/choice_helpers.cc
Normal file
95
src/video_engine/test/auto_test/primitives/choice_helpers.cc
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "video_engine/test/auto_test/primitives/choice_helpers.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
static const int kNoDefault = 0;
|
||||
|
||||
ChoiceBuilder::ChoiceBuilder(const Choices& choices)
|
||||
: choices_(choices), default_choice_(kNoDefault), input_source_(stdin) {
|
||||
}
|
||||
|
||||
int ChoiceBuilder::Choose() {
|
||||
if (!title_.empty()) {
|
||||
printf("\n%s\n", title_.c_str());
|
||||
}
|
||||
|
||||
Choices::const_iterator iterator = choices_.begin();
|
||||
for (int number = 1; iterator != choices_.end(); ++iterator, ++number)
|
||||
printf(" %d. %s\n", number, (*iterator).c_str());
|
||||
|
||||
if (default_choice_ != kNoDefault)
|
||||
printf(" Hit enter for default (%s):\n", default_choice_text_.c_str());
|
||||
printf("# ");
|
||||
char input[8];
|
||||
fgets(input, 8, input_source_);
|
||||
int selection;
|
||||
if (input[0] == '\n')
|
||||
selection = default_choice_;
|
||||
else
|
||||
selection = atoi(input);
|
||||
|
||||
if (selection < 1 || selection > static_cast<int>(choices_.size())) {
|
||||
printf("Please select one of the given options.\n");
|
||||
return Choose();
|
||||
}
|
||||
|
||||
return selection;
|
||||
}
|
||||
|
||||
ChoiceBuilder& ChoiceBuilder::WithDefault(const std::string& default_choice) {
|
||||
Choices::const_iterator iterator = std::find(
|
||||
choices_.begin(), choices_.end(), default_choice);
|
||||
assert(iterator != choices_.end() && "No such choice.");
|
||||
|
||||
// Store the value as the choice number, e.g. its index + 1.
|
||||
default_choice_ = (iterator - choices_.begin()) + 1;
|
||||
default_choice_text_ = default_choice;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ChoiceBuilder& ChoiceBuilder::WithInputSource(FILE* input_source) {
|
||||
input_source_ = input_source;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ChoiceBuilder& ChoiceBuilder::WithTitle(const std::string& title) {
|
||||
title_ = title;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Choices SplitChoices(const std::string& raw_choices) {
|
||||
Choices result;
|
||||
size_t current_pos = 0;
|
||||
size_t next_newline = 0;
|
||||
while ((next_newline = raw_choices.find('\n', current_pos)) !=
|
||||
std::string::npos) {
|
||||
std::string choice = raw_choices.substr(
|
||||
current_pos, next_newline - current_pos);
|
||||
result.push_back(choice);
|
||||
current_pos = next_newline + 1;
|
||||
}
|
||||
std::string last_choice = raw_choices.substr(current_pos);
|
||||
if (!last_choice.empty())
|
||||
result.push_back(last_choice);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ChoiceBuilder FromChoices(const std::string& raw_choices) {
|
||||
return ChoiceBuilder(SplitChoices(raw_choices));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
73
src/video_engine/test/auto_test/primitives/choice_helpers.h
Normal file
73
src/video_engine/test/auto_test/primitives/choice_helpers.h
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_VIDEO_ENGINE_TEST_AUTO_TEST_PRIMITIVES_CHOICE_HELPERS_H_
|
||||
#define WEBRTC_VIDEO_ENGINE_TEST_AUTO_TEST_PRIMITIVES_CHOICE_HELPERS_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
typedef std::vector<std::string> Choices;
|
||||
|
||||
/**
|
||||
* Used to ask the user to make a choice. This class will allow you to
|
||||
* configure how to ask the question, and then ask it. For instance,
|
||||
*
|
||||
* int choice = FromChoices("Choice 1\n"
|
||||
* "Choice 2\n").WithDefault("Choice 1").Choose();
|
||||
*
|
||||
* will print a menu presenting the two choices and ask for input. The user,
|
||||
* can input 1, 2 or just hit enter since we specified a default in this case.
|
||||
* The Choose call will block until the user gives valid input one way or the
|
||||
* other. The choice variable is guaranteed to contain either 1 or 2 after
|
||||
* this particular call.
|
||||
*
|
||||
* The class uses stdout and stdin by default, but stdin can be replaced using
|
||||
* WithInputSource for unit tests.
|
||||
*/
|
||||
class ChoiceBuilder {
|
||||
public:
|
||||
explicit ChoiceBuilder(const Choices& choices);
|
||||
|
||||
// Specifies the choice as the default. The choice must be one of the choices
|
||||
// passed in the constructor. If this method is not called, the user has to
|
||||
// choose an option explicitly.
|
||||
ChoiceBuilder& WithDefault(const std::string& default_choice);
|
||||
|
||||
// Replaces the input source where we ask for input. Default is stdin.
|
||||
ChoiceBuilder& WithInputSource(FILE* input_source);
|
||||
|
||||
// Prints a title above the choice list when the choice is made.
|
||||
ChoiceBuilder& WithTitle(const std::string& title);
|
||||
|
||||
// Prints the choice list and requests input from the input source. Returns
|
||||
// the choice number (choices start at 1).
|
||||
int Choose();
|
||||
|
||||
private:
|
||||
Choices choices_;
|
||||
int default_choice_;
|
||||
std::string default_choice_text_;
|
||||
std::string title_;
|
||||
FILE* input_source_;
|
||||
};
|
||||
|
||||
// Convenience function that creates a choice builder given a string where
|
||||
// choices are separated by \n.
|
||||
ChoiceBuilder FromChoices(const std::string& raw_choices);
|
||||
|
||||
// Creates choices from a string where choices are separated by \n.
|
||||
Choices SplitChoices(const std::string& raw_choices);
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // CHOICE_HELPERS_H_
|
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "video_engine/test/auto_test/primitives/choice_helpers.h"
|
||||
|
||||
namespace {
|
||||
|
||||
FILE* FakeStdin(const std::string& input) {
|
||||
FILE* fake_stdin = tmpfile();
|
||||
|
||||
EXPECT_EQ(input.size(),
|
||||
fwrite(input.c_str(), sizeof(char), input.size(), fake_stdin));
|
||||
rewind(fake_stdin);
|
||||
|
||||
return fake_stdin;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class ChoiceHelpersTest : public testing::Test {
|
||||
};
|
||||
|
||||
TEST_F(ChoiceHelpersTest, SplitReturnsEmptyChoicesForEmptyInput) {
|
||||
EXPECT_TRUE(SplitChoices("").empty());
|
||||
}
|
||||
|
||||
TEST_F(ChoiceHelpersTest, SplitHandlesSingleChoice) {
|
||||
Choices choices = SplitChoices("Single Choice");
|
||||
EXPECT_EQ(1u, choices.size());
|
||||
EXPECT_EQ("Single Choice", choices[0]);
|
||||
}
|
||||
|
||||
TEST_F(ChoiceHelpersTest, SplitHandlesSingleChoiceWithEndingNewline) {
|
||||
Choices choices = SplitChoices("Single Choice\n");
|
||||
EXPECT_EQ(1u, choices.size());
|
||||
EXPECT_EQ("Single Choice", choices[0]);
|
||||
}
|
||||
|
||||
TEST_F(ChoiceHelpersTest, SplitHandlesMultipleChoices) {
|
||||
Choices choices = SplitChoices(
|
||||
"Choice 1\n"
|
||||
"Choice 2\n"
|
||||
"Choice 3");
|
||||
EXPECT_EQ(3u, choices.size());
|
||||
EXPECT_EQ("Choice 1", choices[0]);
|
||||
EXPECT_EQ("Choice 2", choices[1]);
|
||||
EXPECT_EQ("Choice 3", choices[2]);
|
||||
}
|
||||
|
||||
TEST_F(ChoiceHelpersTest, SplitHandlesMultipleChoicesWithEndingNewline) {
|
||||
Choices choices = SplitChoices(
|
||||
"Choice 1\n"
|
||||
"Choice 2\n"
|
||||
"Choice 3\n");
|
||||
EXPECT_EQ(3u, choices.size());
|
||||
EXPECT_EQ("Choice 1", choices[0]);
|
||||
EXPECT_EQ("Choice 2", choices[1]);
|
||||
EXPECT_EQ("Choice 3", choices[2]);
|
||||
}
|
||||
|
||||
TEST_F(ChoiceHelpersTest, CanSelectUsingChoiceBuilder) {
|
||||
FILE* fake_stdin = FakeStdin("1\n2\n");
|
||||
EXPECT_EQ(1, FromChoices("Choice 1\n"
|
||||
"Choice 2").WithInputSource(fake_stdin).Choose());
|
||||
EXPECT_EQ(2, FromChoices("Choice 1\n"
|
||||
"Choice 2").WithInputSource(fake_stdin).Choose());
|
||||
fclose(fake_stdin);
|
||||
}
|
||||
|
||||
TEST_F(ChoiceHelpersTest, RetriesIfGivenInvalidChoice) {
|
||||
FILE* fake_stdin = FakeStdin("3\n0\n99\n23409234809\na\nwhatever\n1\n");
|
||||
EXPECT_EQ(1, FromChoices("Choice 1\n"
|
||||
"Choice 2").WithInputSource(fake_stdin).Choose());
|
||||
fclose(fake_stdin);
|
||||
}
|
||||
|
||||
TEST_F(ChoiceHelpersTest, RetriesOnEnterIfNoDefaultSet) {
|
||||
FILE* fake_stdin = FakeStdin("\n2\n");
|
||||
EXPECT_EQ(2, FromChoices("Choice 1\n"
|
||||
"Choice 2").WithInputSource(fake_stdin).Choose());
|
||||
fclose(fake_stdin);
|
||||
}
|
||||
|
||||
TEST_F(ChoiceHelpersTest, PicksDefaultOnEnterIfDefaultSet) {
|
||||
FILE* fake_stdin = FakeStdin("\n");
|
||||
EXPECT_EQ(2, FromChoices("Choice 1\n"
|
||||
"Choice 2").WithInputSource(fake_stdin)
|
||||
.WithDefault("Choice 2").Choose());
|
||||
fclose(fake_stdin);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
File diff suppressed because it is too large
Load Diff
@ -57,6 +57,9 @@
|
||||
# Test primitives
|
||||
'primitives/base_primitives.cc',
|
||||
'primitives/base_primitives.h',
|
||||
'primitives/choice_helpers.cc',
|
||||
'primitives/choice_helpers.h',
|
||||
'primitives/choice_helpers_unittest.cc',
|
||||
'primitives/codec_primitives.cc',
|
||||
'primitives/codec_primitives.h',
|
||||
'primitives/framedrop_primitives.h',
|
||||
|
Reference in New Issue
Block a user