11#include " cucumber_cpp/library/Application.hpp"
22#include " cucumber_cpp/library/Context.hpp"
3+ #include " cucumber_cpp/library/Errors.hpp"
4+ #include " cucumber_cpp/library/StepRegistry.hpp"
5+ #include " cucumber_cpp/library/cucumber_expression/Errors.hpp"
36#include " cucumber_cpp/library/engine/ContextManager.hpp"
47#include " cucumber_cpp/library/engine/FeatureFactory.hpp"
58#include " cucumber_cpp/library/engine/FeatureInfo.hpp"
1619#include < CLI/impl/App_inl.hpp>
1720#include < CLI/impl/Option_inl.hpp>
1821#include < algorithm>
22+ #include < exception>
1923#include < filesystem>
2024#include < functional>
2125#include < iostream>
2731#include < ranges>
2832#include < string>
2933#include < string_view>
34+ #include < type_traits>
3035#include < utility>
3136#include < vector>
3237
3338namespace cucumber_cpp ::library
3439{
3540 namespace
3641 {
37- std::string_view const_char_to_sv (const char * value)
38- {
39- return { value };
40- }
41-
42- std::string_view subrange_to_sv (const auto & subrange)
43- {
44- return { std::data (subrange), std::data (subrange) + std::size (subrange) };
45- }
46-
4742 template <class Range >
4843 std::string Join (const Range& range, std::string_view delim)
4944 {
@@ -52,26 +47,16 @@ namespace cucumber_cpp::library
5247
5348 return std::accumulate (std::next (range.begin ()), range.end (), range.front (), [&delim](const auto & lhs, const auto & rhs)
5449 {
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;
50+ return std::format (" {}{}{}" , lhs, delim, rhs);
6151 });
6252 }
6353
64- std::string JoinStringWithSpace (const std::string& a, const std::string& b)
65- {
66- return a + ' ' + b;
67- }
68-
69- std::filesystem::path to_fs_path (const std::string_view& sv)
54+ std::filesystem::path ToFileSystemPath (const std::string_view& sv)
7055 {
7156 return { sv };
7257 }
7358
74- bool is_feature_file (const std::filesystem::directory_entry& entry)
59+ bool IsFeatureFile (const std::filesystem::directory_entry& entry)
7560 {
7661 return std::filesystem::is_regular_file (entry) && entry.path ().has_extension () && entry.path ().extension () == " .feature" ;
7762 }
@@ -80,9 +65,9 @@ namespace cucumber_cpp::library
8065 {
8166 std::vector<std::filesystem::path> files;
8267
83- for (const auto feature : options.features | std::views::transform (to_fs_path ))
68+ for (const auto feature : options.features | std::views::transform (ToFileSystemPath ))
8469 if (std::filesystem::is_directory (feature))
85- for (const auto & entry : std::filesystem::directory_iterator{ feature } | std::views::filter (is_feature_file ))
70+ for (const auto & entry : std::filesystem::directory_iterator{ feature } | std::views::filter (IsFeatureFile ))
8671 files.emplace_back (entry.path ());
8772 else
8873 files.emplace_back (feature);
@@ -102,26 +87,7 @@ namespace cucumber_cpp::library
10287 else
10388 return std::string{};
10489 })
105- {
106- }
107-
108- ResultStatus& ResultStatus::operator =(Result result)
109- {
110- if ((resultStatus == Result::undefined || resultStatus == Result::passed) && result != Result::undefined)
111- resultStatus = result;
112-
113- return *this ;
114- }
115-
116- ResultStatus::operator Result () const
117- {
118- return resultStatus;
119- }
120-
121- bool ResultStatus::IsSuccess () const
122- {
123- return resultStatus == Result::passed;
124- }
90+ {}
12591
12692 Application::Application (std::shared_ptr<ContextStorageFactory> contextStorageFactory)
12793 : contextManager{ std::move (contextStorageFactory) }
@@ -168,6 +134,35 @@ namespace cucumber_cpp::library
168134 {
169135 return cli.exit (e);
170136 }
137+ catch (const InternalError& error)
138+ {
139+ std::cout << " Internal error:\n\n " ;
140+ std::cout << error.what () << std::endl;
141+ return GetExitCode (engine::Result::failed);
142+ }
143+ catch (const UnsupportedAsteriskError& error)
144+ {
145+ std::cout << " UnsupportedAsteriskError error:\n\n " ;
146+ std::cout << error.what () << std::endl;
147+ return GetExitCode (engine::Result::failed);
148+ }
149+ catch (const cucumber_expression::Error& error)
150+ {
151+ std::cout << " Cucumber Expression error:\n\n " ;
152+ std::cout << error.what () << std::endl;
153+ return GetExitCode (engine::Result::failed);
154+ }
155+ catch (const std::exception& error)
156+ {
157+ std::cout << " Generic error:\n\n " ;
158+ std::cout << error.what () << std::endl;
159+ return GetExitCode (engine::Result::failed);
160+ }
161+ catch (...)
162+ {
163+ std::cout << " Unknown error" ;
164+ return GetExitCode (engine::Result::failed);
165+ }
171166
172167 return GetExitCode ();
173168 }
@@ -194,24 +189,25 @@ namespace cucumber_cpp::library
194189
195190 auto tagExpression = Join (options.tags , " " );
196191 engine::HookExecutorImpl hookExecution{ contextManager };
197- engine::TestExecutionImpl testExecution{ contextManager, reporters, hookExecution, [this ]() -> const engine::TestExecution::Policy&
198- {
199- if (options.dryrun )
200- return engine::dryRunPolicy;
201- else
202- return engine::executeRunPolicy;
203- }() };
204192
205- engine::TestRunnerImpl testRunner{ testExecution };
193+ const auto & runPolicy = (options.dryrun ) ? static_cast <const engine::TestExecution::Policy&>(engine::dryRunPolicy)
194+ : static_cast <const engine::TestExecution::Policy&>(engine::executeRunPolicy);
195+ engine::TestExecutionImpl testExecution{ contextManager, reporters, hookExecution, runPolicy };
196+
197+ StepRegistry stepRegistry{ parameterRegistry };
198+ engine::FeatureTreeFactory featureTreeFactory{ stepRegistry };
206199
207- testRunner.Run (GetFeatureTree (tagExpression));
200+ engine::TestRunnerImpl testRunner{ featureTreeFactory, testExecution };
201+
202+ testRunner.Run (GetFeatureTree (featureTreeFactory, tagExpression));
208203
209204 std::cout << ' \n '
210205 << std::flush;
211206 }
212207
213- std::vector<std::unique_ptr<engine::FeatureInfo>> Application::GetFeatureTree (std::string_view tagExpression)
208+ std::vector<std::unique_ptr<engine::FeatureInfo>> Application::GetFeatureTree (const engine::FeatureTreeFactory& featureTreeFactory, std::string_view tagExpression)
214209 {
210+
215211 const auto featureFiles = GetFeatureFiles (options);
216212 std::vector<std::unique_ptr<engine::FeatureInfo>> vec;
217213 vec.reserve (featureFiles.size ());
@@ -224,10 +220,11 @@ namespace cucumber_cpp::library
224220
225221 int Application::GetExitCode () const
226222 {
227- if (contextManager.ProgramContext ().EffectiveExecutionStatus () == engine::Result::passed)
228- return 0 ;
229- else
230- return 1 ;
223+ return GetExitCode (contextManager.ProgramContext ().ExecutionStatus ());
231224 }
232225
226+ int Application::GetExitCode (engine::Result result) const
227+ {
228+ return static_cast <std::underlying_type_t <engine::Result>>(result) - static_cast <std::underlying_type_t <engine::Result>>(engine::Result::passed);
229+ }
233230}
0 commit comments