Skip to content

Commit 4d9bd3f

Browse files
committed
chore: add Application tests
1 parent e2add96 commit 4d9bd3f

File tree

13 files changed

+319
-135
lines changed

13 files changed

+319
-135
lines changed

cucumber_cpp/library/Application.cpp

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,20 @@ namespace cucumber_cpp::library
4444
return { std::data(subrange), std::data(subrange) + std::size(subrange) };
4545
}
4646

47-
template<class Range, class Delim>
48-
std::string Join(const Range& range, const Delim& delim)
47+
template<class Range>
48+
std::string Join(const Range& range, std::string_view delim)
4949
{
5050
if (range.empty())
5151
return "";
5252

5353
return std::accumulate(std::next(range.begin()), range.end(), range.front(), [&delim](const auto& lhs, const auto& rhs)
5454
{
55-
return lhs + delim + rhs;
55+
std::string join;
56+
join.reserve(lhs.size() + delim.size() + rhs.size());
57+
join.append(lhs);
58+
join.append(delim);
59+
join.append(rhs);
60+
return join;
5661
});
5762
}
5863

@@ -70,6 +75,20 @@ namespace cucumber_cpp::library
7075
{
7176
return std::filesystem::is_regular_file(entry) && entry.path().has_extension() && entry.path().extension() == ".feature";
7277
}
78+
79+
std::vector<std::filesystem::path> GetFeatureFiles(Application::Options& options)
80+
{
81+
std::vector<std::filesystem::path> files;
82+
83+
for (const auto feature : options.features | std::views::transform(to_fs_path))
84+
if (std::filesystem::is_directory(feature))
85+
for (const auto& entry : std::filesystem::directory_iterator{ feature } | std::views::filter(is_feature_file))
86+
files.emplace_back(entry.path());
87+
else
88+
files.emplace_back(feature);
89+
90+
return files;
91+
}
7392
}
7493

7594
ReportHandlerValidator::ReportHandlerValidator(const report::Reporters& reporters)
@@ -163,11 +182,6 @@ namespace cucumber_cpp::library
163182
return contextManager.ProgramContext();
164183
}
165184

166-
const Application::Options& Application::CliOptions() const
167-
{
168-
return options;
169-
}
170-
171185
void Application::AddReportHandler(const std::string& name, std::unique_ptr<report::ReportHandlerV2>&& reporter)
172186
{
173187
reporters.Add(name, std::move(reporter));
@@ -179,13 +193,13 @@ namespace cucumber_cpp::library
179193
reporters.Use(selectedReporter);
180194

181195
auto tagExpression = Join(options.tags, " ");
182-
library::engine::HookExecutorImpl hookExecution{ contextManager };
183-
library::engine::TestExecutionImpl testExecution{ contextManager, reporters, hookExecution, [this]() -> const library::engine::TestExecution::Policy&
196+
engine::HookExecutorImpl hookExecution{ contextManager };
197+
engine::TestExecutionImpl testExecution{ contextManager, reporters, hookExecution, [this]() -> const engine::TestExecution::Policy&
184198
{
185199
if (options.dryrun)
186-
return library::engine::dryRunPolicy;
200+
return engine::dryRunPolicy;
187201
else
188-
return library::engine::executeRunPolicy;
202+
return engine::executeRunPolicy;
189203
}() };
190204

191205
engine::TestRunnerImpl testRunner{ testExecution };
@@ -198,15 +212,13 @@ namespace cucumber_cpp::library
198212

199213
std::vector<std::unique_ptr<engine::FeatureInfo>> Application::GetFeatureTree(std::string_view tagExpression)
200214
{
201-
auto featureFiles = GetFeatureFiles();
215+
const auto featureFiles = GetFeatureFiles(options);
202216
std::vector<std::unique_ptr<engine::FeatureInfo>> vec;
203217
vec.reserve(featureFiles.size());
204218

205219
for (const auto& featurePath : featureFiles)
206220
vec.push_back(featureTreeFactory.Create(featurePath, tagExpression));
207221

208-
vec.shrink_to_fit();
209-
210222
return vec;
211223
}
212224

@@ -218,17 +230,4 @@ namespace cucumber_cpp::library
218230
return 1;
219231
}
220232

221-
std::vector<std::filesystem::path> Application::GetFeatureFiles() const
222-
{
223-
std::vector<std::filesystem::path> files;
224-
225-
for (const auto feature : options.features | std::views::transform(to_fs_path))
226-
if (std::filesystem::is_directory(feature))
227-
for (const auto& entry : std::filesystem::directory_iterator{ feature } | std::views::filter(is_feature_file))
228-
files.emplace_back(entry.path());
229-
else
230-
files.emplace_back(feature);
231-
232-
return files;
233-
}
234233
}

cucumber_cpp/library/Application.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,11 @@ namespace cucumber_cpp::library
5656

5757
CLI::App& CliParser();
5858
Context& ProgramContext();
59-
const Options& CliOptions() const;
6059

6160
void AddReportHandler(const std::string& name, std::unique_ptr<report::ReportHandlerV2>&& reporter);
6261

6362
private:
6463
[[nodiscard]] int GetExitCode() const;
65-
[[nodiscard]] std::vector<std::filesystem::path> GetFeatureFiles() const;
6664
void DryRunFeatures();
6765
void RunFeatures();
6866
[[nodiscard]] std::vector<std::unique_ptr<engine::FeatureInfo>> GetFeatureTree(std::string_view tagExpression);

cucumber_cpp/library/BodyMacro.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
const std::size_t BODY_STRUCT::ID = registration<BODY_STRUCT>(matcher, type); \
5353
void BODY_STRUCT::ExecuteWithArgs targs
5454

55+
#include <gtest/gtest.h>
56+
5557
#undef GTEST_MESSAGE_AT_
5658
#define GTEST_MESSAGE_AT_(file, line, message, result_type) \
5759
cucumber_cpp::library::engine::CucumberAssertHelper(result_type, file, line, message) = \

cucumber_cpp/library/engine/ContextManager.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,31 @@
77
#include "cucumber_cpp/library/engine/StepInfo.hpp"
88
#include <memory>
99
#include <string>
10+
#include <string_view>
1011
#include <utility>
1112

1213
namespace cucumber_cpp::library::engine
1314
{
14-
auto& GetOrThrow(auto& ptr, std::string typeName)
15+
namespace
1516
{
16-
if (ptr)
17-
return *ptr;
17+
std::string ConstructErrorString(std::string_view typeName, std::string_view postfix)
18+
{
19+
std::string error;
1820

19-
throw ContextNotAvailable{ typeName + " not available" };
21+
error.reserve(typeName.size() + postfix.size());
22+
error.append(typeName);
23+
error.append(postfix);
24+
25+
return error;
26+
}
27+
28+
auto& GetOrThrow(auto& ptr, std::string_view typeName)
29+
{
30+
if (ptr)
31+
return *ptr;
32+
33+
throw ContextNotAvailable{ ConstructErrorString(typeName, " not available") };
34+
}
2035
}
2136

2237
CurrentContext::CurrentContext(std::shared_ptr<ContextStorageFactory> contextStorageFactory)

cucumber_cpp/library/engine/ContextManager.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ namespace cucumber_cpp::library::engine
7272
explicit ContextManager(std::shared_ptr<ContextStorageFactory> contextStorageFactory);
7373

7474
cucumber_cpp::library::engine::ProgramContext& ProgramContext();
75-
cucumber_cpp::library::engine::ProgramContext& ProgramContext() const;
75+
[[nodiscard]] cucumber_cpp::library::engine::ProgramContext& ProgramContext() const;
7676

7777
struct ScopedFeautureContext;
7878
struct ScopedRuleContext;

cucumber_cpp/library/engine/test/TestFeatureFactory.cpp

Lines changed: 10 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#include "cucumber_cpp/library/engine/FeatureFactory.hpp"
22
#include "cucumber_cpp/library/engine/StepType.hpp"
3-
#include <filesystem>
4-
#include <fstream>
3+
#include "cucumber_cpp/library/engine/test_helper/TemporaryFile.hpp"
54
#include <functional>
65
#include <gmock/gmock.h>
76
#include <gtest/gtest.h>
@@ -11,41 +10,6 @@
1110

1211
namespace cucumber_cpp::library::engine
1312
{
14-
struct TemporaryFile
15-
{
16-
TemporaryFile(std::string_view name)
17-
: path{ std::filesystem::temp_directory_path() / name }
18-
{
19-
}
20-
21-
~TemporaryFile()
22-
{
23-
ofs.close();
24-
std::filesystem::remove(path);
25-
}
26-
27-
TemporaryFile& operator<<(const auto& data)
28-
{
29-
ofs << data; // NOLINT
30-
ofs.flush();
31-
return *this;
32-
}
33-
34-
std::filesystem::path Path() const
35-
{
36-
return path;
37-
}
38-
39-
private:
40-
std::ofstream CreateOfstream()
41-
{
42-
std::filesystem::create_directories(path.parent_path());
43-
return { path };
44-
}
45-
46-
std::filesystem::path path;
47-
std::ofstream ofs{ CreateOfstream() };
48-
};
4913

5014
struct TestFeatureFactory : testing::Test
5115
{
@@ -54,7 +18,7 @@ namespace cucumber_cpp::library::engine
5418

5519
TEST_F(TestFeatureFactory, CreateEmptyFeature)
5620
{
57-
auto tmp = TemporaryFile{ "tmpfile.feature" };
21+
auto tmp = test_helper::TemporaryFile{ "tmpfile.feature" };
5822

5923
tmp << "Feature: Test feature\n"
6024
"Custom\n"
@@ -73,7 +37,7 @@ namespace cucumber_cpp::library::engine
7337

7438
TEST_F(TestFeatureFactory, CreateScenario)
7539
{
76-
auto tmp = TemporaryFile{ "tmpfile.feature" };
40+
auto tmp = test_helper::TemporaryFile{ "tmpfile.feature" };
7741

7842
tmp << "Feature: Test feature\n"
7943
"Custom\n"
@@ -98,7 +62,7 @@ namespace cucumber_cpp::library::engine
9862

9963
TEST_F(TestFeatureFactory, CreateRules)
10064
{
101-
auto tmp = TemporaryFile{ "tmpfile.feature" };
65+
auto tmp = test_helper::TemporaryFile{ "tmpfile.feature" };
10266

10367
tmp << "Feature: Test feature\n"
10468
"Custom\n"
@@ -115,9 +79,6 @@ namespace cucumber_cpp::library::engine
11579
" Scenario: Test scenario2\n"
11680
" Custom Scenario\n"
11781
" Description\n";
118-
// " Given I have a step\n"
119-
// " When I do something\n"
120-
// " Then I expect something\n";
12182

12283
const auto feature = featureTreeFactory.Create(tmp.Path(), "");
12384
EXPECT_THAT(feature->Rules().size(), testing::Eq(2));
@@ -148,7 +109,7 @@ namespace cucumber_cpp::library::engine
148109

149110
TEST_F(TestFeatureFactory, CreateSteps)
150111
{
151-
auto tmp = TemporaryFile{ "tmpfile.feature" };
112+
auto tmp = test_helper::TemporaryFile{ "tmpfile.feature" };
152113

153114
tmp << "Feature: Test feature\n"
154115
" Scenario: Test scenario1\n"
@@ -203,7 +164,7 @@ namespace cucumber_cpp::library::engine
203164

204165
TEST_F(TestFeatureFactory, CreateBackground)
205166
{
206-
auto tmp = TemporaryFile{ "tmpfile.feature" };
167+
auto tmp = test_helper::TemporaryFile{ "tmpfile.feature" };
207168

208169
tmp << "Feature: Test feature\n"
209170
" Background: Test background\n"
@@ -249,7 +210,7 @@ namespace cucumber_cpp::library::engine
249210

250211
TEST_F(TestFeatureFactory, CreateTagsTags)
251212
{
252-
auto tmp = TemporaryFile{ "tmpfile.feature" };
213+
auto tmp = test_helper::TemporaryFile{ "tmpfile.feature" };
253214

254215
tmp << "@feature\n"
255216
"Feature: Test feature\n"
@@ -273,7 +234,7 @@ namespace cucumber_cpp::library::engine
273234

274235
TEST_F(TestFeatureFactory, SelectTags)
275236
{
276-
auto tmp = TemporaryFile{ "tmpfile.feature" };
237+
auto tmp = test_helper::TemporaryFile{ "tmpfile.feature" };
277238

278239
tmp << "@feature\n"
279240
"Feature: Test feature\n"
@@ -297,7 +258,7 @@ namespace cucumber_cpp::library::engine
297258

298259
TEST_F(TestFeatureFactory, CreateMultipleScenariosInOneRule)
299260
{
300-
auto tmp = TemporaryFile{ "tmpfile.feature" };
261+
auto tmp = test_helper::TemporaryFile{ "tmpfile.feature" };
301262

302263
tmp << "Feature: Test feature\n"
303264
" Rule: Test rule\n"
@@ -327,7 +288,7 @@ namespace cucumber_cpp::library::engine
327288

328289
TEST_F(TestFeatureFactory, CreateTable)
329290
{
330-
auto tmp = TemporaryFile{ "tmpfile.feature" };
291+
auto tmp = test_helper::TemporaryFile{ "tmpfile.feature" };
331292

332293
tmp << "Feature: Test feature\n"
333294
" Scenario: Test scenario1\n"
Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
1-
add_library(cucumber_cpp.library.engine.test_helper INTERFACE)
1+
add_library(cucumber_cpp.library.engine.test_helper.steps OBJECT)
22

3-
target_link_libraries(cucumber_cpp.library.engine.test_helper INTERFACE
3+
target_link_libraries(cucumber_cpp.library.engine.test_helper.steps PUBLIC
44
cucumber_cpp.library.engine
55
gmock_main
66
)
77

8-
target_sources(cucumber_cpp.library.engine.test_helper INTERFACE
8+
target_sources(cucumber_cpp.library.engine.test_helper.steps PRIVATE
9+
StepImplementations.cpp
10+
)
11+
12+
add_library(cucumber_cpp.library.engine.test_helper STATIC)
13+
14+
target_link_libraries(cucumber_cpp.library.engine.test_helper PUBLIC
15+
cucumber_cpp.library.engine
16+
gmock_main
17+
)
18+
19+
target_sources(cucumber_cpp.library.engine.test_helper PRIVATE
920
ContextManagerInstance.hpp
21+
TemporaryFile.cpp
22+
TemporaryFile.hpp
23+
TestExecutionInstance.hpp
1024
TestRunnerMock.hpp
1125
)

0 commit comments

Comments
 (0)