Skip to content

Commit

Permalink
Add UnifiedDiffOption.
Browse files Browse the repository at this point in the history
Fix also option printing.
  • Loading branch information
OpenCppCoverage committed Mar 9, 2016
1 parent 8fd5c1b commit 1c754e3
Show file tree
Hide file tree
Showing 9 changed files with 228 additions and 6 deletions.
21 changes: 21 additions & 0 deletions CppCoverage/Options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,18 @@ namespace CppCoverage
return inputCoveragePaths_;
}

//-------------------------------------------------------------------------
void Options::AddUnifiedDiffSettings(UnifiedDiffSettings&& unifiedDiffSettings)
{
unifiedDiffSettingsCollection_.push_back(std::move(unifiedDiffSettings));
}

//-------------------------------------------------------------------------
const std::vector<UnifiedDiffSettings>& Options::GetUnifiedDiffSettingsCollection() const
{
return unifiedDiffSettingsCollection_;
}

//-------------------------------------------------------------------------
std::wostream& operator<<(std::wostream& ostr, const Options& options)
{
Expand All @@ -159,11 +171,20 @@ namespace CppCoverage
ostr << L"Export: ";
for (const auto& optionExport : options.exports_)
ostr << optionExport << L" ";
ostr << std::endl;

ostr << L"Input coverage: ";
for (const auto& path : options.inputCoveragePaths_)
ostr << path.wstring() << L" ";
ostr << std::endl;

ostr << L"Unified diff: ";
for (const auto& settings : options.unifiedDiffSettingsCollection_)
{
ostr << settings.GetUnifiedDiffPath() << L" Root folder: ";
ostr << settings.GetDiffParentFolder().get_value_or(L"") << std::endl;
}

return ostr;
}
}
11 changes: 8 additions & 3 deletions CppCoverage/Options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@
#include <boost/filesystem.hpp>

#include "CppCoverageExport.hpp"
#include "CppCoverage/Patterns.hpp"
#include "CppCoverage/StartInfo.hpp"
#include "Patterns.hpp"
#include "StartInfo.hpp"
#include "UnifiedDiffSettings.hpp"
#include "OptionsExport.hpp"

namespace CppCoverage
{
class Patterns;
class OptionsExport;

enum class LogLevel
{
Expand Down Expand Up @@ -68,6 +69,9 @@ namespace CppCoverage
void AddInputCoveragePath(const boost::filesystem::path&);
const std::vector<boost::filesystem::path>& GetInputCoveragePaths() const;

void AddUnifiedDiffSettings(UnifiedDiffSettings&&);
const std::vector<UnifiedDiffSettings>& GetUnifiedDiffSettingsCollection() const;

friend CPPCOVERAGE_DLL std::wostream& operator<<(std::wostream&, const Options&);

private:
Expand All @@ -85,5 +89,6 @@ namespace CppCoverage
bool isAggregateByFileModeEnabled_;
std::vector<OptionsExport> exports_;
std::vector<boost::filesystem::path> inputCoveragePaths_;
std::vector<UnifiedDiffSettings> unifiedDiffSettingsCollection_;
};
}
46 changes: 46 additions & 0 deletions CppCoverage/OptionsParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,54 @@ namespace CppCoverage
}
}
}

//----------------------------------------------------------------------------
std::pair<fs::path, boost::optional<fs::path>>
ExtractUnifiedDiffOption(const std::string& option)
{
auto pos = option.find(OptionsParser::UnifiedDiffSeparator);

if (pos == std::string::npos)
return{ option, boost::none };

return{ option.substr(0, pos), fs::path{option.substr(pos + 1)} };
}

//----------------------------------------------------------------------------
void AddUnifiedDiff(const po::variables_map& variables, Options& options)
{
auto unifiedDiffCollection = GetOptionalValue<std::vector<std::string>>(
variables, ProgramOptions::UnifiedDiffOption);

if (unifiedDiffCollection)
{
for (const auto& unifiedDiff : *unifiedDiffCollection)
{
fs::path unifiedDiffPath;
boost::optional<fs::path> diffParentFolder;

std::tie(unifiedDiffPath, diffParentFolder) = ExtractUnifiedDiffOption(unifiedDiff);

if (!fs::is_regular_file(unifiedDiffPath))
{
throw OptionsParserException(
"Unified diff path " + unifiedDiffPath.string() + " does not exist.");
}
if (diffParentFolder && !is_directory(*diffParentFolder))
{
throw OptionsParserException(
"Unified diff root folder " + diffParentFolder->string() + " does not exist.");
}

options.AddUnifiedDiffSettings(UnifiedDiffSettings{ unifiedDiffPath, diffParentFolder });
}
}
}
}

//-------------------------------------------------------------------------
const char OptionsParser::ExportSeparator = ':';
const char OptionsParser::UnifiedDiffSeparator = '|';

//-------------------------------------------------------------------------
OptionsParser::OptionsParser()
Expand Down Expand Up @@ -296,6 +340,8 @@ namespace CppCoverage

AddExporTypes(variables, options);
AddInputCoverages(variables, options);
AddUnifiedDiff(variables, options);

if (!options.GetStartInfo() && options.GetInputCoveragePaths().empty())
throw OptionsParserException("You must specify a program to execute or use --" + ProgramOptions::InputCoverageValue);

Expand Down
1 change: 1 addition & 0 deletions CppCoverage/OptionsParser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ namespace CppCoverage
{
public:
static const char ExportSeparator;
static const char UnifiedDiffSeparator;

OptionsParser();
~OptionsParser();
Expand Down
14 changes: 13 additions & 1 deletion CppCoverage/ProgramOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,15 @@ namespace CppCoverage
return exportTypeText;
}

//---------------------------------------------------------------------
std::string GetUnifiedDiffHelp()
{
return "Format: <unifiedDiffPath>|<rootFolder>\n"
"<unifiedDiffPath> path of the unified diff file. "
"Git user can use git diff output.\n"
"<rootFolder> (optional) root folder for paths in the diff file.";
}

//---------------------------------------------------------------------
void FillConfigurationOptions(
po::options_description& options,
Expand Down Expand Up @@ -98,7 +107,9 @@ namespace CppCoverage
GetExportTypeText(exportTypes).c_str())
(ProgramOptions::WorkingDirectoryOption.c_str(), po::value<std::string>(), "The program working directory.")
(ProgramOptions::CoverChildrenOption.c_str(), "Enable code coverage for children processes.")
(ProgramOptions::NoAggregateByFileOption.c_str(), "Do not aggregate coverage for same file path.");
(ProgramOptions::NoAggregateByFileOption.c_str(), "Do not aggregate coverage for same file path.")
(ProgramOptions::UnifiedDiffOption.c_str(),
po::value<T_Strings>()->composing(), GetUnifiedDiffHelp().c_str());
}

//-------------------------------------------------------------------------
Expand Down Expand Up @@ -134,6 +145,7 @@ namespace CppCoverage
const std::string ProgramOptions::ExportTypeCoberturaValue = "cobertura";
const std::string ProgramOptions::ExportTypeBinaryValue = "binary";
const std::string ProgramOptions::InputCoverageValue = "input_coverage";
const std::string ProgramOptions::UnifiedDiffOption = "unified_diff";

//-------------------------------------------------------------------------
ProgramOptions::ProgramOptions(const std::vector<std::string>& exportTypes)
Expand Down
1 change: 1 addition & 0 deletions CppCoverage/ProgramOptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ namespace CppCoverage
static const std::string ExportTypeCoberturaValue;
static const std::string ExportTypeBinaryValue;
static const std::string InputCoverageValue;
static const std::string UnifiedDiffOption;

ProgramOptions(const std::vector<std::string>& optionsExportTypes);

Expand Down
2 changes: 0 additions & 2 deletions CppCoverage/StartInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,6 @@ namespace CppCoverage
ostr << *startInfo.workingDirectory_;
else
ostr << "not set.";

ostr << std::endl;
return ostr;
}
}
1 change: 1 addition & 0 deletions CppCoverageTest/CppCoverageTest.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@
<ClCompile Include="CoverageDataMergerTest.cpp" />
<ClCompile Include="CoverageDataTest.cpp" />
<ClCompile Include="CoverageFilterManagerTest.cpp" />
<ClCompile Include="OptionsParserUnifiedDiffTest.cpp" />
<ClCompile Include="WildcardCoverageFilterTest.cpp" />
<ClCompile Include="CoverageRateComputerTest.cpp" />
<ClCompile Include="CoverageRateTest.cpp" />
Expand Down
137 changes: 137 additions & 0 deletions CppCoverageTest/OptionsParserUnifiedDiffTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// OpenCppCoverage is an open source code coverage for C++.
// Copyright (C) 2016 OpenCppCoverage
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

#include "stdafx.h"

#include "CppCoverage/OptionsParser.hpp"
#include "CppCoverage/ProgramOptions.hpp"
#include "CppCoverage/UnifiedDiffSettings.hpp"

#include "CppCoverageTest/TestTools.hpp"

namespace cov = CppCoverage;
namespace fs = boost::filesystem;

namespace CppCoverageTest
{
namespace
{
//-------------------------------------------------------------------------
boost::optional<cov::Options> Parse(
const std::vector<cov::UnifiedDiffSettings>& unifiedDiffSettingsCollection)
{
cov::OptionsParser parser;
std::wostringstream ostr;
std::vector<std::string> arguments;

for (const auto& unifiedDiffSettings : unifiedDiffSettingsCollection)
{
arguments.push_back(TestTools::OptionPrefix + cov::ProgramOptions::UnifiedDiffOption);

auto value = unifiedDiffSettings.GetUnifiedDiffPath().string();
auto diffParentFolder = unifiedDiffSettings.GetDiffParentFolder();
if (diffParentFolder)
value += cov::OptionsParser::UnifiedDiffSeparator + diffParentFolder->string();
arguments.push_back(value);
}

auto option = TestTools::Parse(parser, arguments, true, &ostr);

if (!option && ostr.str().empty())
throw std::runtime_error("Expect error message.");
return option;
}


//-------------------------------------------------------------------------
std::vector<cov::UnifiedDiffSettings> ToVector(cov::UnifiedDiffSettings&& unifiedDiffSettings)
{
std::vector<cov::UnifiedDiffSettings> unifiedDiffSettingsCollection;

unifiedDiffSettingsCollection.push_back(std::move(unifiedDiffSettings));
return unifiedDiffSettingsCollection;
}

//-------------------------------------------------------------------------
boost::optional<cov::Options> Parse(cov::UnifiedDiffSettings&& unifiedDiffSettings)
{
return Parse(ToVector(std::move(unifiedDiffSettings)));
}

//---------------------------------------------------------------------
bool AreEqual(
const std::vector<cov::UnifiedDiffSettings>& settings1,
const std::vector<cov::UnifiedDiffSettings>& settings2)
{
return std::equal(settings1.begin(), settings1.end(), settings2.begin(), settings2.end(),
[](const auto& setting1, const auto& setting2)
{
return setting1.GetUnifiedDiffPath() == setting2.GetUnifiedDiffPath()
&& setting1.GetDiffParentFolder() == setting2.GetDiffParentFolder();
});
}

//---------------------------------------------------------------------
void CheckUnifiedDiffSettings(const std::vector<cov::UnifiedDiffSettings>& unifiedDiffSettingsCollection)
{
auto option = Parse(unifiedDiffSettingsCollection);

ASSERT_TRUE(!!option);
ASSERT_TRUE(AreEqual(unifiedDiffSettingsCollection, option->GetUnifiedDiffSettingsCollection()));
}

//---------------------------------------------------------------------
void CheckUnifiedDiffSettings(cov::UnifiedDiffSettings&& unifiedDiffSettings)
{
CheckUnifiedDiffSettings(ToVector(std::move(unifiedDiffSettings)));
}
}

//-------------------------------------------------------------------------
TEST(OptionsParserUnifiedDifftTest, UnifiedDiffPath)
{
CheckUnifiedDiffSettings({ __FILE__, boost::none });
}

//-------------------------------------------------------------------------
TEST(OptionsParserUnifiedDifftTest, NotFoundUnifiedDiffPath)
{
ASSERT_TRUE(!Parse({ "Unknow", boost::none }));
}

//-------------------------------------------------------------------------
TEST(OptionsParserUnifiedDifftTest, DiffParentFolder)
{
CheckUnifiedDiffSettings({ __FILE__, fs::current_path() });
}

//-------------------------------------------------------------------------
TEST(OptionsParserUnifiedDifftTest, NotFoundDiffParentFolder)
{
ASSERT_TRUE(!!Parse({ __FILE__, boost::none }));
ASSERT_FALSE(!!Parse({ __FILE__, fs::path("Unknow") }));
}

//-------------------------------------------------------------------------
TEST(OptionsParserUnifiedDifftTest, TwoDiff)
{
std::vector<cov::UnifiedDiffSettings> unifiedDiffSettingsCollection;
unifiedDiffSettingsCollection.emplace_back(__FILE__, fs::current_path());
unifiedDiffSettingsCollection.emplace_back(__FILE__, boost::none);

CheckUnifiedDiffSettings(unifiedDiffSettingsCollection);
}
}

0 comments on commit 1c754e3

Please sign in to comment.