view C++/Tests/OptionParser/main.cpp @ 295:345aaeb5e0ba

Pack: fix constexpr can't be used on void return types
author David Demelier <markand@malikania.fr>
date Thu, 13 Nov 2014 21:07:48 +0100
parents f6d9fdb5eeeb
children 99e83685d4da
line wrap: on
line source

/*
 * main.cpp -- main test file for OptionParser
 *
 * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <gtest/gtest.h>

#include <OptionParser.h>

#define LENGTH(x)	(sizeof (x) / sizeof (x[0]))

/*
 * -a hello -a ok -v -c -p test
 */
TEST(OptionParser, simple)
{
	OptionParser parser;
	const char *argv[] = { "-a", "hello", "-a", "ok", "-v", "-c", "-p", "test" };

	parser.add(Option("a", "attribute", Option::Argument));
	parser.add(Option("v", "verbose"));
	parser.add(Option("c", "check"));
	parser.add(Option("p", "plugin", Option::Argument));

	auto result = parser.parse(LENGTH(argv), argv, OptionParser::Strict);
	auto begin = result.cbegin();

	ASSERT_EQ(5, result.count());
	ASSERT_EQ(8, result.total());

	// -a hello
	ASSERT_EQ("a", begin->name());
	ASSERT_EQ("hello", begin->value());

	// -a ok
	std::advance(begin, 1);
	ASSERT_EQ("a", begin->name());
	ASSERT_EQ("ok", begin->value());

	// -v
	std::advance(begin, 1);
	ASSERT_EQ("v", begin->name());
	ASSERT_EQ("", begin->value());

	// -c
	std::advance(begin, 1);
	ASSERT_EQ("c", begin->name());
	ASSERT_EQ("", begin->value());

	// -p test
	std::advance(begin, 1);
	ASSERT_EQ("p", begin->name());
	ASSERT_EQ("test", begin->value());
}

/*
 * -v install -y -x -p package
 *
 * Split as two kind of groups,
 *	-v are general options
 *	-y, -x -p are dedicated to install
 */
TEST(OptionParser, group)
{
	OptionParser parser;
	const char *argv[] = { "-v", "install", "-y", "-x", "-p", "irccd" };

	parser.add(Option("v", "verbose"));
	parser.add(Option("y", "auto answer yes"));
	parser.add(Option("x", "use regex"));
	parser.add(Option("p", "package", Option::Argument));

	/*
	 * First part: -v install
	 */

	auto result = parser.parse(LENGTH(argv), argv, OptionParser::BreakNonOption);
	auto option = result.cbegin();

	ASSERT_EQ(1, result.count());
	ASSERT_EQ(1, result.total());

	// "-v"
	ASSERT_EQ("v", option->name());
	ASSERT_EQ("", option->value());

	/*
	 * Second part: -y -x package
	 */

	result = parser.parse(LENGTH(argv) - 2, argv + 2, OptionParser::Strict);
	option = result.cbegin();

	ASSERT_EQ(3, result.count());
	ASSERT_EQ(4, result.total());

	// -y	
	ASSERT_EQ("y", option->name());
	ASSERT_EQ("", option->value());

	// -x
	std::advance(option, 1);
	ASSERT_EQ("x", option->name());
	ASSERT_EQ("", option->value());

	// -p irccd
	std::advance(option, 1);
	ASSERT_EQ("p", option->name());
	ASSERT_EQ("irccd", option->value());
}

/*
 * Compact
 *
 * -abc -> -a -b -c
 */
TEST(OptionParser, compact)
{
	OptionParser parser;
	const char *argv[] = { "-abc" };

	parser.add(Option("a", ""));
	parser.add(Option("b", ""));
	parser.add(Option("c", ""));

	auto result = parser.parse(LENGTH(argv), argv);
	auto option = result.cbegin();

	ASSERT_EQ(3, result.count());
	ASSERT_EQ(3, result.total());

	// -a
	ASSERT_EQ("a", option->name());
	ASSERT_EQ("", option->value());

	// -b
	std::advance(option, 1);
	ASSERT_EQ("b", option->name());
	ASSERT_EQ("", option->value());

	// -c
	std::advance(option, 1);
	ASSERT_EQ("c", option->name());
	ASSERT_EQ("", option->value());
}

/*
 * -o readonly -o loop -v -v -f true -f false
 */
TEST(OptionParser, numbered)
{
	OptionParser parser;
	const char *argv[] = { "-o", "readonly", "-o", "loop", "-v", "-v", "-f", "true", "-f", "false" };

	parser.add(Option("o", "option", Option::Argument));
	parser.add(Option("v", "verbose"));
	parser.add(Option("f", "fullscreen", Option::Argument, Option::Single));

	auto result = parser.parse(LENGTH(argv), argv, OptionParser::Silent);
	auto option = result.cbegin();

	ASSERT_EQ(6, result.count());
	ASSERT_EQ(10, result.total());

	// -o readonly
	ASSERT_EQ("o", option->name());
	ASSERT_EQ("readonly", option->value());

	// -o loop
	std::advance(option, 1);
	ASSERT_EQ("o", option->name());
	ASSERT_EQ("loop", option->value());

	// -v
	std::advance(option, 1);
	ASSERT_EQ("v", option->name());
	ASSERT_EQ("", option->value());

	// -v
	std::advance(option, 1);
	ASSERT_EQ("v", option->name());
	ASSERT_EQ("", option->value());

	// -f true
	std::advance(option, 1);
	ASSERT_EQ("f", option->name());
	ASSERT_EQ("true", option->value());

	// -f false
	std::advance(option, 1);
	ASSERT_EQ("f", option->name());
	ASSERT_EQ("false", option->value());
}

/*
 * -o readonly -o loop -v -v -f true -f false
 */
TEST(OptionParser, numberedstrict)
{
	OptionParser parser;
	const char *argv[] = { "-o", "readonly", "-o", "loop", "-v", "-v", "-f", "true", "-f", "false" };

	parser.add(Option("o", "option", Option::Argument));
	parser.add(Option("v", "verbose"));
	parser.add(Option("f", "fullscreen", Option::Argument, Option::Single));

	auto result = parser.parse(LENGTH(argv), argv, OptionParser::Silent | OptionParser::Strict);
	auto option = result.cbegin();

	ASSERT_EQ(5, result.count());
	ASSERT_EQ(8, result.total());

	// -o readonly
	ASSERT_EQ("o", option->name());
	ASSERT_EQ("readonly", option->value());

	// -o loop
	std::advance(option, 1);
	ASSERT_EQ("o", option->name());
	ASSERT_EQ("loop", option->value());

	// -v
	std::advance(option, 1);
	ASSERT_EQ("v", option->name());
	ASSERT_EQ("", option->value());

	// -v
	std::advance(option, 1);
	ASSERT_EQ("v", option->name());
	ASSERT_EQ("", option->value());

	// -f true
	std::advance(option, 1);
	ASSERT_EQ("f", option->name());
	ASSERT_EQ("true", option->value());
}

int main(int argc, char **argv)
{
	testing::InitGoogleTest(&argc, argv);

	return RUN_ALL_TESTS();
}