Run clang-tidy; improve types.hpp, added subheaders

This commit is contained in:
S David 2024-03-15 18:37:30 -04:00
parent cf9f791de1
commit 8ed2a666f8
31 changed files with 465 additions and 394 deletions

View File

@ -35,9 +35,9 @@ CheckOptions:
- { key: readability-identifier-naming.EnumIgnoredRegexp, value: '^.*_t$' } - { key: readability-identifier-naming.EnumIgnoredRegexp, value: '^.*_t$' }
# Abstract Class Name # Abstract Class Name
# - { key: readability-identifier-naming.AbstractClassPrefix,value: 'I' } - { key: readability-identifier-naming.AbstractClassPrefix, value: 'I' }
# - { key: readability-identifier-naming.AbstractClassIgnoredRegexp, - { key: readability-identifier-naming.AbstractClassIgnoredRegexp,
# value: '^.*able$|^.*Base$|^Abstract.*|^Component$' } value: '^.*able$|^.*Base$|^Abstract.*|^Component$' }
# Template Parameters # Template Parameters
- { key: readability-identifier-naming.TypeTemplateParameterPrefix, - { key: readability-identifier-naming.TypeTemplateParameterPrefix,

3
.gitignore vendored
View File

@ -56,4 +56,7 @@ release/*
*-build/ *-build/
*debug/ *debug/
docs/* docs/*
*.bak

View File

@ -67,4 +67,4 @@ main(int argc, const char* argv[], const char* envp[])
} }
// clang-format off // clang-format off
// vim: set foldmethod=marker foldmarker=#region,#endregion textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : // vim: set foldmethod=marker foldmarker=@{,@} textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :

View File

@ -16,36 +16,33 @@
namespace mdml { namespace mdml {
// NOLINTNEXTLINE(readability-identifier-naming)
class Application { class Application {
public: public:
Application(int argc, c::const_string argv[], c::const_string env[]); virtual ~Application() = default;
// @{ Disabled constructors and operators
Application(Application&&) = delete;
Application(const Application&) = delete; Application(const Application&) = delete;
Application& operator=(const Application&) = delete; auto operator=(const Application&) -> Application& = delete;
auto operator=(Application&&) -> Application& = delete;
// @}
inline static Application& GetInstance() { return *instance_ptr; }; // Getters
virtual ~Application(); auto getArguments() -> const std::vector<std::string>&
// #region Getters
inline const std::vector<std::string>& Arguments()
{ {
return this->arguments; return this->arguments;
} }
inline const Dictionary<const std::string>& Environment() auto getEnvironment() -> const Dictionary<const std::string>&
{ {
return this->environment_variables; return this->environment_variables;
} }
inline const std::string& GetEnv(const std::string& key) virtual auto run() -> int = 0;
{
return this->environment_variables[key];
} /* #endregion */
private:
static count_t instance_count;
static Application* instance_ptr;
protected: protected:
Application(int argc, c::const_string argv[], c::const_string env[]);
void parse_arguments(int argc, c::const_string argv[]); void parse_arguments(int argc, c::const_string argv[]);
void create_env_dictionary(c::const_string envp[]); void create_env_dictionary(c::const_string envp[]);
@ -55,4 +52,4 @@ class Application {
} }
// clang-format off // clang-format off
// vim: set foldmethod=marker foldmarker=#region,#endregion textwidth=81 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : // vim: set foldmethod=marker foldmarker=@{,@} textwidth=81 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :

View File

@ -23,22 +23,26 @@ class IRouteHandler;
class CgiApplication : public Application { class CgiApplication : public Application {
public: public:
using RouteDictionary = Dictionary<route::ptr<IRouteHandler>>; using RouteDictionary = Dictionary<std::shared_ptr<IRouteHandler>>;
CgiApplication(int argc, c::const_string argv[], c::const_string env[]); CgiApplication(int argc, c::const_string argv[], c::const_string env[]);
virtual ~CgiApplication(); ~CgiApplication() override;
Result<std::string> ProcessRequest(); // Disabled copy and assignment operators @{
CgiApplication(const CgiApplication&) = delete;
inline void ImportRoutes(RouteDictionary& route_collection) CgiApplication(CgiApplication&&) = delete;
{ auto operator=(const CgiApplication&) -> CgiApplication& = delete;
this->Routes = std::move(route_collection); auto operator=(CgiApplication&&) -> CgiApplication& = delete;
} // @}
auto run() -> int override;
auto processRequest() -> Result<std::string>;
/// \todo make this private, and have the unit test inspect it with a
/// helper friend class.
RouteDictionary Routes; RouteDictionary Routes;
}; };
} }
// clang-format off // clang-format off
// vim: set foldmethod=marker foldmarker=#region,#endregion textwidth=81 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : // vim: set foldmethod=marker foldmarker=@{,@} textwidth=81 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :

View File

@ -12,30 +12,25 @@
#include "private/debuginfo.hpp" #include "private/debuginfo.hpp"
#include "types.hpp" #include "types.hpp"
#include <algorithm>
#include <exception>
#include <optional>
#include <sstream>
#include <stdexcept>
#include <string>
namespace mdml { namespace mdml {
class exception : public std::exception { namespace messages {
constexpr auto kExceptionDefault = "An exception has ocurred!";
}
class Exception : public std::exception {
public: public:
exception(c::const_string _message = default_error); Exception(c::const_string _message = messages::kExceptionDefault);
exception(const std::string& message); Exception(const std::string& message);
exception(const mdml::exception& other) = default; Exception(const mdml::Exception& other) = default;
exception(const std::exception& inner); Exception(const std::exception& inner);
exception& operator=(const exception&) = delete; auto operator=(const Exception&) -> Exception& = delete;
virtual const char* what() const noexcept override; auto what() const noexcept -> const char* override;
const std::string& stacktrace() const noexcept; auto stacktrace() const noexcept -> const std::string&;
constexpr static auto default_error = "An exception has ocurred!";
private: private:
void build_what_message(); void build_what_message();

View File

@ -16,9 +16,9 @@
namespace mdml { namespace mdml {
struct IRouteHandler { struct IRouteHandler {
virtual ~IRouteHandler() = default; virtual ~IRouteHandler() = default;
virtual Result<std::string> Process( virtual auto process(
const std::string& name, const std::string& request_uri const std::string& name, const std::string& request_uri
) = 0; ) -> Result<std::string> = 0;
}; };
} }

View File

@ -31,31 +31,31 @@ class MarkdownRouteHandler : public IRouteHandler {
, OutputStream() , OutputStream()
{ {
}*/ }*/
virtual ~MarkdownRouteHandler(); ~MarkdownRouteHandler() override;
void LoadTemplate(const fs::path& template_name); void loadTemplate(const fs::path& template_name);
void LoadMarkdown(const fs::path& markdown_page_name); void loadMarkdown(const fs::path& markdown_page_name);
virtual Result<std::string> Process( auto process(const std::string& name, const std::string& request_uri)
const std::string& name, const std::string& request_uri -> Result<std::string> override;
);
std::string& GetHtmlData() { return html_data; } auto getHtmlData() -> std::string& { return html_data; }
std::string& GetMarkdownData() { return markdown_data; } auto getMarkdownData() -> std::string& { return markdown_data; }
static Dictionary<route::ptr<IRouteHandler>> GenerateRoutes(MarkdownRouteHandler& ref, // NOLINTNEXTLINE(readability-identifier-naming)
std::filesystem::path content_dir, static auto GenerateRoutes(
MarkdownRouteHandler& ref, std::filesystem::path content_dir,
std::filesystem::path main_template std::filesystem::path main_template
); ) -> Dictionary<std::shared_ptr<IRouteHandler>>;
std::reference_wrapper<std::ostream> OutputStream; std::reference_wrapper<std::ostream> OutputStream;
const fs::path& getWorkingDir() { return this->work_dir; } auto getWorkingDir() -> const fs::path& { return this->work_dir; }
protected: protected:
std::string render_document( auto render_document(
const std::string& title, const std::string& request_uri const std::string& title, const std::string& request_uri
); ) -> std::string;
static void load_document( static void load_document(
const fs::path& document_path, std::string& out_document const fs::path& document_path, std::string& out_document

View File

@ -0,0 +1,46 @@
/* assert.hpp
* Copyright © 2024 Saul D. Beniquez
* License: Mozilla Public License v. 2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v.2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
#include "types/ctypes.hpp"
#include "Exception.hpp"
#include <sstream>
#define ASSERT(condition) \
if (condition == false) { \
mdml::assert_impl(#condition); \
}
#define ASSERT_MSG(condition, msg) \
if (condition == false) { \
mdml::assert_impl(#condition, msg); \
}
namespace mdml {
inline void
assert_impl(c::const_string failed_condition, c::const_string assert_reason = "")
{
std::stringstream assert_buffer;
assert_buffer << failed_condition << " is false!";
if (std::strlen(assert_reason) > 0) {
assert_buffer << std::endl
<< "\tassert_resion: " << assert_reason;
}
assert_buffer << std::flush;
throw Exception(assert_buffer.str());
}
}
// clang-format off
// vim: set foldmethod=syntax foldminlines=10 textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :

View File

@ -20,7 +20,7 @@
namespace mdml { namespace mdml {
std::string generate_stacktrace(unsigned short framesToRemove = 1); auto generate_stacktrace(unsigned short framesToRemove = 1) -> std::string;
void print_cmdline(int argc, const char* argv[]); void print_cmdline(int argc, const char* argv[]);

View File

@ -14,17 +14,17 @@ struct Platform {
#ifdef __linux__ #ifdef __linux__
static constexpr bool LINUX = true; static constexpr bool LINUX = true;
#else #else
static constexpr bool LINUX = false; static constexpr bool kLinux = false;
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
static constexpr bool WINDOWS = true; static constexpr bool WINDOWS = true;
#else #else
static constexpr bool WINDOWS = false; static constexpr bool kWindows = false;
#endif #endif
#ifdef __APPLE__ #ifdef __APPLE__
static constexpr bool MACOS = true; static constexpr bool kMacos = true;
#else #else
static constexpr bool MACOS = false; static constexpr bool MACOS = false;
#endif #endif
@ -32,7 +32,7 @@ struct Platform {
#ifdef __FreeBSD__ #ifdef __FreeBSD__
static constexpr bool FREEBSD = true; static constexpr bool FREEBSD = true;
#else #else
static constexpr bool FREEBSD = false; static constexpr bool kFreebsd = false;
#endif #endif
// I don't own any AIX, Solaris, HP-UX, or pure Darwin systems, sorry :) // I don't own any AIX, Solaris, HP-UX, or pure Darwin systems, sorry :)

View File

@ -9,50 +9,11 @@
#pragma once #pragma once
#include <functional>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <utility>
namespace mdml {
namespace c {
using string = char*;
using const_string = const char*;
}
namespace route {
template<typename T>
using ptr = std::shared_ptr<T>;
template<typename T>
inline static ptr<T>
make_ptr()
{
return std::make_shared<T>();
}
}
enum error_t : bool { NO_ERROR = false, ERROR = true };
using count_t = size_t;
template<typename T>
using reference = std::reference_wrapper<T>;
template<typename T>
using optional_reference = std::optional<std::reference_wrapper<T>>;
template<typename T>
using const_reference = std::reference_wrapper<const T>;
template<typename T>
using opt_const_reference = std::optional<const_reference<const T>>;
template<typename value_t>
using Dictionary = std::map<const std::string, value_t>;
}
#include "types/Result.hpp" #include "types/Result.hpp"
#include "types/ctypes.hpp"
#include "types/Collections.hpp"
#include "types/References.hpp"
// clang-format off // clang-format off
// vim: set foldmethod=marker foldmarker=#region,#endregion textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : // vim: set foldmethod=marker foldmarker=#region,#endregion textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :

View File

@ -0,0 +1,20 @@
/* Collections.hpp
* Copyright © 2024 Saul D. Beniquez
* License: Mozilla Public License v. 2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v.2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
#include <map>
namespace mdml {
template<typename TValue>
using Dictionary = std::map<const std::string, TValue>;
}
// clang-format off
// vim: set foldmethod=syntax foldminlines=10 textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :

View File

@ -0,0 +1,30 @@
/* ReferenTypes.hpp
* Copyright © 2024 Saul D. Beniquez
* License: Mozilla Public License v. 2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v.2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
#include <functional>
namespace mdml {
template<typename T>
using Reference = std::reference_wrapper<T>;
template<typename T>
using OptionalReference = std::optional<std::reference_wrapper<T>>;
template<typename T>
using ConstReference = std::reference_wrapper<const T>;
template<typename T>
using OptConstReference = std::optional<ConstReference<const T>>;
}
// clang-format off
// vim: set foldmethod=syntax foldminlines=10 textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :

View File

@ -8,35 +8,39 @@
*/ */
#pragma once #pragma once
#include "types.hpp"
#include <utility> #include <utility>
namespace mdml { namespace mdml {
enum error_t : bool { NoError = false, Error = true };
template<typename T> template<typename T>
struct Result { struct Result {
inline Result(const error_t& error_flag, const T error_data) Result(const error_t& error_flag, const T kErrorData)
: val(error_flag, error_data) : val(error_flag, kErrorData)
, IsError(this->val.first) , IsError(this->val.first)
, ErrorData(this->val.second) , ErrorData(this->val.second)
{ {
} }
inline Result(const bool& error_flag, const T error_data) Result(bool error_flag, const T kErrorData)
: val(error_t(error_flag), error_data) : val(static_cast<error_t>(error_flag), kErrorData)
, IsError(this->val.first) , IsError(this->val.first)
, ErrorData(this->val.second) , ErrorData(this->val.second)
{ {
} }
// @{ Copy Constructors and assignment operator
virtual ~Result() = default; virtual ~Result() = default;
Result(const Result& other) = default; Result(const Result& other) = default;
inline Result& operator=(const Result& other) Result(Result&& other) = default;
auto operator=(const Result& other) -> Result&
{ {
this->val = other.val; this->val = other.val;
this->IsError = this->val.first; this->IsError = this->val.first;
this->ErrorData = this->val.data; this->ErrorData = this->val.data;
} }
//@}
error_t& IsError; error_t& IsError;
T& ErrorData; T& ErrorData;
@ -46,4 +50,4 @@ struct Result {
} }
// clang-format off // clang-format off
// vim: set foldmethod=marker foldmarker=#region,#endregion textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : // vim: set foldmethod=marker foldmarker=@{,@} textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :

24
include/types/ctypes.hpp Normal file
View File

@ -0,0 +1,24 @@
/* ctypes.hpp
* Copyright © 2024 Saul D. Beniquez
* License: Mozilla Public License v. 2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v.2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
#include <cstddef>
namespace mdml {
using count_t = std::size_t;
namespace c {
using string = char*;
using const_string = const char*;
}
}
// clang-format off
// vim: set foldmethod=syntax foldminlines=10 textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :

View File

@ -8,55 +8,30 @@
*/ */
#include "Application.hpp" #include "Application.hpp"
#include "exception.hpp" #include "Exception.hpp"
#include "types.hpp" #include "types.hpp"
#include "private/assert.hpp"
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <vector> #include <vector>
using namespace mdml; using namespace mdml;
count_t Application::instance_count = 0;
Application* Application::instance_ptr = nullptr;
Application::Application(int argc, c::const_string argv[], c::const_string env[]) Application::Application(int argc, c::const_string argv[], c::const_string env[])
: arguments(), environment_variables() : arguments(), environment_variables()
{ {
if (Application::instance_count != 0) { ASSERT_MSG(
std::stringstream buffer; argv != nullptr, "Application constructor has null argv parameter"
buffer << this->instance_count; );
ASSERT_MSG(
env != nullptr, "Application constructor has null env parameter"
);
auto fatal_exception = std::logic_error(
"Cannot instantiate more than one "
"mdml::Application class at a time.\n"
" instance_count = " +
buffer.str()
);
throw mdml::exception(fatal_exception);
}
if (argv == nullptr || env == nullptr) {
std::string problem = (argv == nullptr) ? "argv " : "envp ";
auto message = "Cannot instantiate the application class "
"with null " +
problem + "parameter";
auto fatal_exception = std::logic_error(message);
throw mdml::exception(fatal_exception);
}
++(Application::instance_count);
this->parse_arguments(argc, argv); this->parse_arguments(argc, argv);
this->create_env_dictionary(env); this->create_env_dictionary(env);
Application::instance_ptr = this;
}
Application::~Application()
{
--(Application::instance_count);
Application::instance_ptr = nullptr;
} }
void void
@ -93,4 +68,4 @@ Application::create_env_dictionary(c::const_string envp[])
} }
// clang-format off // clang-format off
// vim: set foldmethod=marker foldmarker=#region,#endregion textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : // vim: set foldmethod=marker foldmarker=@{,@} textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :

View File

@ -3,7 +3,7 @@
set(MDML_SOURCES set(MDML_SOURCES
libmdml.cpp libmdml.cpp
exception.cpp Exception.cpp
debuginfo.cpp debuginfo.cpp
Application.cpp Application.cpp
CgiApplication.cpp CgiApplication.cpp

View File

@ -7,20 +7,21 @@
* obtain one at https://mozilla.org/MPL/2.0/. * obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#include "Application.hpp"
#include "CgiApplication.hpp" #include "CgiApplication.hpp"
#include "Application.hpp"
#include "IRouteHandler.hpp" #include "IRouteHandler.hpp"
#include "exception.hpp"
#include "Exception.hpp"
#include "types.hpp" #include "types.hpp"
#include "private/assert.hpp"
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <string> #include <string>
using namespace mdml; using namespace mdml;
struct MarkdownTemplateRequestHandler : public IRouteHandler {};
CgiApplication::CgiApplication( CgiApplication::CgiApplication(
int argc, c::const_string argv[], c::const_string env[] int argc, c::const_string argv[], c::const_string env[]
) )
@ -40,55 +41,67 @@ CgiApplication::~CgiApplication()
} }
} }
Result<std::string> auto
CgiApplication::ProcessRequest() CgiApplication::run() -> int
{ {
auto result = processRequest();
return result.IsError;
}
auto
CgiApplication::processRequest() -> Result<std::string>
{
auto& environment = Application::environment_variables;
auto dictionary_pair = environment.find("REQUEST_URI");
ASSERT_MSG(
dictionary_pair != environment.end(),
"No REQUEST_URI in Environment!"
)
try { try {
auto& environment = Application::environment_variables; /* Parse REQUEST_URI to get the route's basename */
auto request_uri = dictionary_pair->second;
auto question_pos = request_uri.find('?');
auto ampersand_pos = request_uri.find('&');
auto page_name = request_uri;
// Check if REQUEST_URI is in the environment map const auto kNotFound = std::string::npos;
if (environment.find("REQUEST_URI") == environment.end()) {
throw mdml::exception("No REQUEST_URI in Environment!");
}
/* Parse REQUEST_URI to get the route's basename */
auto request_URI = environment["REQUEST_URI"];
auto question_pos = request_URI.find('?');
auto ampersand_pos = request_URI.find('&');
auto page_name = request_URI;
auto not_found = std::string::npos;
if (question_pos == not_found) { /** \todo Make this make sense. Maybe create an array of parameters,
if (ampersand_pos != not_found) { * and ignore whether it starts with a ? or &. */
question_pos = ampersand_pos; if (question_pos == kNotFound) {
} if (ampersand_pos != kNotFound) {
} question_pos = ampersand_pos;
if (question_pos != not_found) {
page_name = request_URI.substr(0, question_pos);
} }
}
if (question_pos != kNotFound) {
page_name = request_uri.substr(0, question_pos);
}
if (Routes.find(page_name) != Routes.end()) { if (Routes.find(page_name) != Routes.end()) {
auto route_handler = Routes[page_name]; auto route_handler = Routes[page_name];
auto result = auto result =
route_handler->Process(page_name, request_URI); route_handler->process(page_name, request_uri);
if (result.IsError) { /*
auto except = if (result.IsError) {
mdml::exception(result.ErrorData.c_str()); auto except =
throw except; Exception(result.ErrorData.c_str()); throw except;
} }
*/
return result; return result;
} else { } else {
std::stringstream buffer; std::stringstream buffer;
buffer << "Unknown route: " << page_name << std::endl; buffer << "Unknown route: " << page_name << std::endl;
return { ERROR, buffer.str() }; return { Error, buffer.str() };
// throw mdml::exception(buffer.str().c_str());
} }
} catch (const mdml::exception& except) { } catch (std::exception& stdexcept) {
throw except; throw Exception(stdexcept);
} catch (const std::exception& except) {
throw mdml::exception(except);
} }
} }
// clang-format off // clang-format off
// vim: set foldmethod=marker foldmarker=#region,#endregion textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : // vim: set foldmethod=marker foldmarker=@{,@} textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :

View File

@ -7,7 +7,7 @@
file, You can obtain one at http://mozilla.org/MPL/2.0/. file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
#include "exception.hpp" #include "Exception.hpp"
#include "private/debuginfo.hpp" #include "private/debuginfo.hpp"
#include "types.hpp" #include "types.hpp"
@ -20,75 +20,75 @@
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
using mdml::exception; using namespace mdml;
constexpr unsigned DEFAULT_STACKFRAMES_TO_STRIP = 3; constexpr unsigned kDefaultStackframesToStrip = 3;
// Helper classes and functions. #region // Helper classes and functions. @{
exception::exception(c::const_string error_message) Exception::Exception(c::const_string error_message)
: std::exception() : std::exception()
, error_message(error_message) , error_message(error_message)
, what_message() , what_message()
, stack_trace(mdml::generate_stacktrace(DEFAULT_STACKFRAMES_TO_STRIP)) , stack_trace(mdml::generate_stacktrace(kDefaultStackframesToStrip))
, inner_exception_ptr() , inner_exception_ptr()
{ {
build_what_message(); build_what_message();
} }
exception::exception(const std::string& error_message) Exception::Exception(const std::string& error_message)
: std::exception() : std::exception()
, error_message(error_message) , error_message(error_message)
, what_message() , what_message()
, stack_trace(mdml::generate_stacktrace(DEFAULT_STACKFRAMES_TO_STRIP)) , stack_trace(mdml::generate_stacktrace(kDefaultStackframesToStrip))
, inner_exception_ptr() , inner_exception_ptr()
{ {
build_what_message(); build_what_message();
} }
exception::exception(const std::exception& inner) Exception::Exception(const std::exception& inner)
: std::exception(inner) : std::exception(inner)
, error_message(inner.what()) , error_message(inner.what())
, what_message() , what_message()
, inner_exception_ptr(std::make_exception_ptr(&inner)) , inner_exception_ptr(std::make_exception_ptr(&inner))
, stack_trace(mdml::generate_stacktrace(DEFAULT_STACKFRAMES_TO_STRIP)) , stack_trace(mdml::generate_stacktrace(kDefaultStackframesToStrip))
{ {
build_what_message(); build_what_message();
} }
const char* auto
exception::what() const noexcept Exception::what() const noexcept -> const char*
{ {
return this->what_message.c_str(); return this->what_message.c_str();
} }
const std::string& auto
exception::stacktrace() const noexcept Exception::stacktrace() const noexcept -> const std::string&
{ {
return this->stack_trace; return this->stack_trace;
} }
std::string auto
prepend_tabs_to_lines(const std::string& input) prepend_tabs_to_lines(const std::string& input) -> std::string
{ {
std::ostringstream results_buffer; std::ostringstream results_buffer;
std::istringstream input_buffer(input); std::istringstream input_buffer(input);
// Function to add a tab character before each line // Function to add a tab character before each line
auto addTabBeforeLine = [&results_buffer](const std::string& line) { auto add_tab_before_line = [&results_buffer](const std::string& line) {
results_buffer << '\t' << line << '\n'; results_buffer << '\t' << line << '\n';
}; };
// Process each line and add a tab character before it // Process each line and add a tab character before it
std::string line; std::string line;
while (std::getline(input_buffer, line)) { while (std::getline(input_buffer, line)) {
addTabBeforeLine(line); add_tab_before_line(line);
} }
return results_buffer.str(); return results_buffer.str();
} }
void void
exception::build_what_message() Exception::build_what_message()
{ {
std::stringstream buffer; std::stringstream buffer;
@ -97,7 +97,7 @@ exception::build_what_message()
std::string indented_stacktrace = std::string indented_stacktrace =
prepend_tabs_to_lines(this->stack_trace); prepend_tabs_to_lines(this->stack_trace);
buffer << "mdml::exception::what(): { " << std::endl buffer << "mdml::Exception::what(): { " << std::endl
<< "\terror: " << error_message.c_str() << std::endl << "\terror: " << error_message.c_str() << std::endl
<< "\tstack_trace: " << std::endl << "\tstack_trace: " << std::endl
<< indented_stacktrace << std::endl << indented_stacktrace << std::endl

View File

@ -7,10 +7,10 @@
* obtain one at https://mozilla.org/MPL/2.0/. * obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#include "Application.hpp"
#include "IRouteHandler.hpp"
#include "MarkdownRouteHandler.hpp" #include "MarkdownRouteHandler.hpp"
#include "exception.hpp" #include "Application.hpp"
#include "Exception.hpp"
#include "IRouteHandler.hpp"
#include "types.hpp" #include "types.hpp"
#include "cmark.h" #include "cmark.h"
@ -23,8 +23,10 @@
using namespace mdml; using namespace mdml;
namespace fs = std::filesystem;
namespace { namespace {
const auto NOT_FOUND = std::string::npos; const auto kNotFound = std::string::npos;
void void
string_replace( string_replace(
@ -33,9 +35,9 @@ string_replace(
) )
{ {
for (auto pattern_pos = out_buffer.find(pattern); for (auto pattern_pos = out_buffer.find(pattern);
pattern_pos != NOT_FOUND; pattern_pos != kNotFound;
pattern_pos = out_buffer.find(pattern)) { pattern_pos = out_buffer.find(pattern)) {
if (pattern_pos != NOT_FOUND) { if (pattern_pos != kNotFound) {
out_buffer.replace( out_buffer.replace(
pattern_pos, pattern.length(), replacement pattern_pos, pattern.length(), replacement
); );
@ -44,7 +46,6 @@ string_replace(
} }
} }
MarkdownRouteHandler::MarkdownRouteHandler(fs::path working_dir) MarkdownRouteHandler::MarkdownRouteHandler(fs::path working_dir)
: IRouteHandler(), OutputStream(std::cout), work_dir(working_dir) : IRouteHandler(), OutputStream(std::cout), work_dir(working_dir)
{ {
@ -53,7 +54,7 @@ MarkdownRouteHandler::MarkdownRouteHandler(fs::path working_dir)
MarkdownRouteHandler::~MarkdownRouteHandler() {} MarkdownRouteHandler::~MarkdownRouteHandler() {}
void void
MarkdownRouteHandler::LoadTemplate(const fs::path& template_filename) MarkdownRouteHandler::loadTemplate(const fs::path& template_filename)
{ {
fs::path full_html_path; fs::path full_html_path;
@ -66,7 +67,7 @@ MarkdownRouteHandler::LoadTemplate(const fs::path& template_filename)
} }
void void
MarkdownRouteHandler::LoadMarkdown(const fs::path& markdown_filename) MarkdownRouteHandler::loadMarkdown(const fs::path& markdown_filename)
{ {
fs::path full_md_path; fs::path full_md_path;
@ -79,31 +80,30 @@ MarkdownRouteHandler::LoadMarkdown(const fs::path& markdown_filename)
this->load_document(full_md_path, this->markdown_data); this->load_document(full_md_path, this->markdown_data);
} }
Result<std::string> auto
MarkdownRouteHandler::Process( MarkdownRouteHandler::process(
const std::string& name, const std::string& request_uri const std::string& name, const std::string& request_uri
) ) -> Result<std::string>
{ {
auto document = render_document(name, request_uri); auto document = render_document(name, request_uri);
auto& out = OutputStream.get(); auto& out = OutputStream.get();
out << document << std::flush; out << document << std::flush;
return { NO_ERROR, document }; return { NoError, document };
} }
Dictionary<route::ptr<IRouteHandler>> auto
MarkdownRouteHandler::GenerateRoutes(MarkdownRouteHandler& ref, MarkdownRouteHandler::GenerateRoutes(
std::filesystem::path content_dir, std::filesystem::path main_template MarkdownRouteHandler& ref, fs::path content_dir, fs::path main_template
) ) -> Dictionary<std::shared_ptr<IRouteHandler>>
{ {
if (content_dir.is_relative()) { if (content_dir.is_relative()) {
content_dir = ref.work_dir / content_dir; content_dir = ref.work_dir / content_dir;
} }
Dictionary<route::ptr<IRouteHandler>> results; Dictionary<std::shared_ptr<IRouteHandler>> results;
for (const auto& entry : for (const auto& entry : fs::directory_iterator(content_dir)) {
std::filesystem::directory_iterator(content_dir)) {
if (entry.is_regular_file()) { if (entry.is_regular_file()) {
auto filename = entry.path().filename().string(); auto filename = entry.path().filename().string();
auto routename = entry.path().stem().string(); auto routename = entry.path().stem().string();
@ -112,16 +112,17 @@ MarkdownRouteHandler::GenerateRoutes(MarkdownRouteHandler& ref,
// Check if the file has a .md extension and a specific // Check if the file has a .md extension and a specific
// name pattern // name pattern
if (extension == ".md") { if (extension == ".md") {
auto& routeHandler = ref; auto& route_handler = ref;
// Load template and document // Load template and document
routeHandler.LoadTemplate( route_handler.loadTemplate(
(ref.work_dir / main_template).string() (ref.work_dir / main_template).string()
); );
routeHandler.LoadMarkdown(entry.path().string()); route_handler.loadMarkdown(entry.path().string()
);
// Move the routeHandler into the vector // Move the routeHandler into the vector
results.emplace(routename, &routeHandler); results.emplace(routename, &route_handler);
} }
} }
} }
@ -136,17 +137,17 @@ MarkdownRouteHandler::load_document(
{ {
if (!fs::exists(document_path) || !fs::is_regular_file(document_path)) { if (!fs::exists(document_path) || !fs::is_regular_file(document_path)) {
auto error = "File not found: " + document_path.string(); auto error = "File not found: " + document_path.string();
throw mdml::exception(error); throw Exception(error);
} }
try { try {
std::ifstream file(document_path); std::ifstream file(document_path);
if (file.is_open()) { if (file.is_open()) {
std::string htmlContent( std::string html_content(
(std::istreambuf_iterator<char>(file)), (std::istreambuf_iterator<char>(file)),
std::istreambuf_iterator<char>() std::istreambuf_iterator<char>()
); );
out_document = htmlContent; out_document = html_content;
} else { } else {
auto error_message = auto error_message =
(std::stringstream() (std::stringstream()
@ -154,19 +155,19 @@ MarkdownRouteHandler::load_document(
<< document_path.filename() << "', at path " << document_path.filename() << "', at path "
<< document_path.parent_path() << ". ") << document_path.parent_path() << ". ")
.str(); .str();
throw mdml::exception(error_message); throw Exception(error_message);
} }
} catch (const mdml::exception& e) { } catch (const Exception& e) {
throw e; throw e;
} catch (const std::exception& e) { } catch (const std::exception& e) {
throw mdml::exception(e); throw Exception(e);
} }
} }
std::string auto
MarkdownRouteHandler::render_document( MarkdownRouteHandler::render_document(
const std::string& title, const std::string& request_uri const std::string& title, const std::string& request_uri
) ) -> std::string
{ {
std::string result = this->html_data; std::string result = this->html_data;
std::string token = "%content%"; std::string token = "%content%";
@ -183,4 +184,4 @@ MarkdownRouteHandler::render_document(
return result; return result;
} }
// clang-format off // clang-format off
// vim: set foldmethod=marker foldmarker=#region,#endregion textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : // vim: set foldmethod=marker foldmarker=@{,@} textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :

View File

@ -27,26 +27,26 @@ namespace mdml {
namespace { namespace {
// Extracts the mangled symbol from a string like <func_name+0x34> // Extracts the mangled symbol from a string like <func_name+0x34>
std::string auto
extract_mangled_symbol(const std::string& input) extract_mangled_symbol(const std::string& input) -> std::string
{ {
std::string result; std::string result;
bool insideAngleBrackets = false; bool inside_angle_brackets = false;
for (char c : input) { for (char c : input) {
if (c == '<') { if (c == '<') {
insideAngleBrackets = true; inside_angle_brackets = true;
continue; continue;
} }
if (c == '>') { if (c == '>') {
insideAngleBrackets = false; inside_angle_brackets = false;
continue; continue;
} }
if (c == '+') { if (c == '+') {
break; break;
} }
if (insideAngleBrackets) { if (inside_angle_brackets) {
result += c; result += c;
} }
} }
@ -57,8 +57,8 @@ extract_mangled_symbol(const std::string& input)
// There are a lot of C and platform-specific hacks contained within // There are a lot of C and platform-specific hacks contained within
// I am sorry. 🤡 // I am sorry. 🤡
std::string auto
generate_stacktrace(unsigned short framesToRemove) generate_stacktrace(unsigned short framesToRemove) -> std::string
{ {
std::stringstream buffer; std::stringstream buffer;
#ifndef BOOST_STACKTRACER #ifndef BOOST_STACKTRACER
@ -69,9 +69,9 @@ generate_stacktrace(unsigned short framesToRemove)
size_t columns_to_print = 0; size_t columns_to_print = 0;
// preconfigure column length for certain platforms // preconfigure column length for certain platforms
if (Platform::FREEBSD) { if (Platform::kFreebsd) {
columns_to_print = 2; columns_to_print = 2;
} else if (Platform::MACOS) { } else if (Platform::kMacos) {
columns_to_print = 4; columns_to_print = 4;
} }

View File

@ -14,4 +14,4 @@ some_function()
} }
// clang-format off // clang-format off
// vim: set foldmethod=marker foldmarker=#region,#endregion textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : // vim: set foldmethod=marker foldmarker=@{,@} textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :

View File

@ -7,7 +7,7 @@
* obtain one at https://mozilla.org/MPL/2.0/. * obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#include "exception.hpp" #include "Exception.hpp"
#include "tests-common.hpp" #include "tests-common.hpp"
#include "Application.hpp" #include "Application.hpp"
@ -15,33 +15,49 @@
#include <functional> #include <functional>
#include <optional> #include <optional>
struct simulated_launch { struct LaunchParameters {
static const char* argv[]; static const char* argv[];
static const char* env[]; static const char* env[];
}; };
inline const char* simulated_launch::argv[] = { "param1", "param2", "param3" }; inline const char* LaunchParameters::argv[] = { "param1", "param2", "param3" };
inline const char* simulated_launch::env[] = { "PATH=/usr/bin", inline const char* LaunchParameters::env[] = {
"VAR2=TWO", "PATH=/usr/bin",
nullptr }; "VAR2=TWO",
};
template<typename T>
using opt_reference = std::optional<std::reference_wrapper<T>>;
BEGIN_TEST_SUITE("Application-test") BEGIN_TEST_SUITE("Application-test")
{ {
using namespace mdml;
struct DerivedApplication : public mdml::Application {
DerivedApplication(
int argc = 0, c::const_string argv[] = {},
c::const_string env[] = {}
)
: Application(argc, argv, env)
{
}
auto run() -> int override { return 0; }
};
struct TestFixture {
TestFixture() : derived_app() {}
DerivedApplication derived_app;
};
TEST("Application Class construction") TEST("Application Class construction")
{ {
auto simple_construction = []() { auto simple_construction = []() {
auto test_object = mdml::Application( auto test_object = DerivedApplication(
3, simulated_launch::argv, simulated_launch::env 3, LaunchParameters::argv, LaunchParameters::env
); );
}; };
auto double_construction = []() { auto double_construction = []() {
auto test_object = mdml::Application( auto test_object = DerivedApplication(
3, simulated_launch::argv, simulated_launch::env 3, LaunchParameters::argv, LaunchParameters::env
); );
auto throws_errors = mdml::Application( auto throws_errors = DerivedApplication(
3, simulated_launch::argv, simulated_launch::env 3, LaunchParameters::argv, LaunchParameters::env
); );
}; };
@ -49,51 +65,29 @@ BEGIN_TEST_SUITE("Application-test")
{ {
REQUIRE_NOTHROW(simple_construction()); REQUIRE_NOTHROW(simple_construction());
} }
SECTION("Double construction")
{
REQUIRE_THROWS_AS(
double_construction(), mdml::exception
);
}
SECTION("Get existing instance")
{
opt_reference<mdml::Application> app;
try {
auto test_object = mdml::Application(
3,
simulated_launch::argv,
simulated_launch::env
);
app = test_object;
} catch (const mdml::exception& e) {
app = mdml::Application::GetInstance();
}
}
auto incorrect_construction = []() {
mdml::Application obj(0, nullptr, nullptr);
};
SECTION("Incorrect parameters") SECTION("Incorrect parameters")
{ {
REQUIRE_THROWS_AS( auto incorrect_construction = []() {
incorrect_construction(), mdml::exception DerivedApplication obj(0, nullptr, nullptr);
); };
REQUIRE_THROWS_AS(incorrect_construction(), Exception);
} }
} }
TEST("Application Parameter capture") TEST("Application Parameter capture")
{ {
SECTION("Arguments are captured in vector") SECTION("getArguments are captured in vector")
{ {
auto correct_construction = []() { auto correct_construction = [&]() {
auto test_object = mdml::Application( auto test_object = DerivedApplication(
3, 3,
simulated_launch::argv, LaunchParameters::argv,
simulated_launch::env LaunchParameters::env
); );
auto args_list = test_object.Arguments(); auto args_list = test_object.getArguments();
SECTION("Argument verification") SECTION("getArgument verification")
{ {
REQUIRE(args_list[0] == "param1"); REQUIRE(args_list[0] == "param1");
REQUIRE(args_list[1] == "param2"); REQUIRE(args_list[1] == "param2");
@ -103,13 +97,13 @@ BEGIN_TEST_SUITE("Application-test")
} }
SECTION("Environemnt variables are catpured in map") SECTION("Environemnt variables are catpured in map")
{ {
auto correct_construction = []() { auto correct_construction = [&]() {
auto test_object = mdml::Application( auto test_object = DerivedApplication(
3, 3,
simulated_launch::argv, LaunchParameters::argv,
simulated_launch::env LaunchParameters::env
); );
auto environ = test_object.Environment(); auto environ = test_object.getEnvironment();
SECTION("Varaible verification") SECTION("Varaible verification")
{ {

View File

@ -8,50 +8,49 @@
*/ */
#include "CgiApplication.hpp" #include "CgiApplication.hpp"
#include "Exception.hpp"
#include "IRouteHandler.hpp" #include "IRouteHandler.hpp"
#include "exception.hpp"
#include "tests-common.hpp" #include "tests-common.hpp"
#include <catch2/matchers/catch_matchers_string.hpp> #include <catch2/matchers/catch_matchers_string.hpp>
BEGIN_TEST_SUITE("CgiApplication") BEGIN_TEST_SUITE("CgiApplication")
{ {
struct simulated_launch {
static const char* argv[];
static const char* env[];
};
inline const char* simulated_launch::argv[] = { "param1", "param2", "param3" };
inline const char* simulated_launch::env[] = {
"PATH=/usr/bin",
"VAR2=TWO",
"REQUEST_URI=markdown?msg=hello-world",
nullptr
};
// Define a test oute handler for the "/markdown" route
class ExampleRouteHandler : public mdml::IRouteHandler {
public:
virtual mdml::Result<std::string> Process(
const std::string& name, const std::string& request_uri
) override
{
// Implement test logic for the route
// handler
return { mdml::NO_ERROR, "Processed" };
}
virtual ~ExampleRouteHandler() = default;
};
using namespace mdml; using namespace mdml;
struct SimulatedLaunch {
static const char* argv[];
static const char* env[];
};
inline const char* SimulatedLaunch::argv[] = { "param1",
"param2",
"param3" };
inline const char* SimulatedLaunch::env[] = {
"PATH=/usr/bin",
"VAR2=TWO",
"REQUEST_URI=markdown?msg=hello-world",
nullptr
};
// Define a test oute handler for the "/markdown" route
class ExampleRouteHandler : public mdml::IRouteHandler {
public:
auto process(
const std::string& name, const std::string& request_uri
) -> mdml::Result<std::string> override
{
// Implement test logic for the route
// handler
return { mdml::NoError, "processed" };
}
~ExampleRouteHandler() override = default;
};
struct TestFixture { struct TestFixture {
const char* envp[4] = { "PATH=/usr/bin", const char* envp[4] = { "PATH=/usr/bin",
"VAR2=TWO", "VAR2=TWO",
"REQUEST_URI=markdown?msg=hello-world", "REQUEST_URI=markdown?msg=hello-world",
nullptr }; nullptr };
TestFixture() : cgi_app(1, simulated_launch::argv, envp) {} TestFixture() : cgi_app(1, SimulatedLaunch::argv, envp) {}
CgiApplication cgi_app; CgiApplication cgi_app;
}; };
@ -60,15 +59,15 @@ class ExampleRouteHandler : public mdml::IRouteHandler {
{ {
CgiApplication test( CgiApplication test(
1, simulated_launch::argv, simulated_launch::env 1, SimulatedLaunch::argv, SimulatedLaunch::env
); );
}; };
TEST("CgiApplication RegisterRoutes Test") TEST("CgiApplication RegisterRoutes Test")
{ {
CgiApplication test( CgiApplication test_app(
1, simulated_launch::argv, simulated_launch::env 1, SimulatedLaunch::argv, SimulatedLaunch::env
); );
mdml::CgiApplication::RouteDictionary routes; mdml::CgiApplication::RouteDictionary routes;
@ -76,40 +75,42 @@ class ExampleRouteHandler : public mdml::IRouteHandler {
routes.emplace("test2", new ExampleRouteHandler()); routes.emplace("test2", new ExampleRouteHandler());
routes.emplace("fasdfdshjk", new ExampleRouteHandler()); routes.emplace("fasdfdshjk", new ExampleRouteHandler());
test.ImportRoutes(routes); test_app.Routes = std::move(routes);
REQUIRE(routes.size() < 1); REQUIRE(routes.size() < 1);
REQUIRE(test.Routes.size() == 3); REQUIRE(test_app.Routes.size() == 3);
REQUIRE(test.Routes.at("test") != nullptr); REQUIRE(test_app.Routes.at("test") != nullptr);
}; };
TEST("CgiApplication::ProcessRequest no REQUEST_URI variable") TEST("CgiApplication::processRequest no REQUEST_URI variable")
{ {
const char* no_request_env[] = { "PATH=/usr/bin", const char* no_request_env[] = { "PATH=/usr/bin",
"VAR2=TWO", "VAR2=TWO",
nullptr }; nullptr };
CgiApplication test(1, simulated_launch::argv, no_request_env); CgiApplication test_app(
1, SimulatedLaunch::argv, no_request_env
);
REQUIRE_THROWS_AS( REQUIRE_THROWS_AS(
[&]() { test.ProcessRequest(); }(), mdml::exception [&]() { test_app.processRequest(); }(), mdml::Exception
); );
} }
FIXTURE_TEST("CgiApplication ProcessRequest with valid route") FIXTURE_TEST("CgiApplication processRequest with valid route")
{ {
// Add the test route handler to the Routes dictionary // Add the test route handler to the Routes dictionary
auto handler = mdml::route::make_ptr<ExampleRouteHandler>(); auto handler = std::make_shared<ExampleRouteHandler>();
cgi_app.Routes["markdown"] = handler; cgi_app.Routes["markdown"] = handler;
auto result = cgi_app.ProcessRequest(); auto result = cgi_app.processRequest();
// Add assertions to check the result // Add assertions to check the result
CHECK(result.ErrorData == "Processed"); CHECK(result.ErrorData == "processed");
REQUIRE(result.IsError == false); REQUIRE(result.IsError == false);
} }
FIXTURE_TEST("CgiApplication ProcessRequest with unknown route") FIXTURE_TEST("CgiApplication processRequest with unknown route")
{ {
// Remove the "markdown" route from the Routes // Remove the "markdown" route from the Routes
@ -121,36 +122,35 @@ class ExampleRouteHandler : public mdml::IRouteHandler {
cgi_app.Routes.erase(key); cgi_app.Routes.erase(key);
} }
auto result = cgi_app.ProcessRequest(); auto result = cgi_app.processRequest();
// Add assertions to check the result // Add assertions to check the result
CHECK(result.ErrorData != "Success"); CHECK(result.ErrorData != "Success");
REQUIRE(result.IsError == true); REQUIRE(result.IsError == true);
} }
FIXTURE_TEST("CgiApplication ProcessRequest Route throws exception") FIXTURE_TEST("CgiApplication processRequest Route throws exception")
{ {
// Define a test oute handler for the "/markdown" route // Define a test oute handler for the "/markdown" route
class BadRouteHandler : public IRouteHandler { class BadRouteHandler : public IRouteHandler {
public: public:
virtual Result<std::string> Process( auto process(
const std::string& name, const std::string& name,
const std::string& request_uri const std::string& request_uri
) override ) -> Result<std::string> override
{ {
throw std::runtime_error("ERROR"); throw std::runtime_error("Error");
return { mdml::ERROR, return { mdml::Error,
"This line never executes" }; "This line never executes" };
} }
virtual ~BadRouteHandler() = default; ~BadRouteHandler() override = default;
}; };
auto handler = mdml::route::make_ptr<BadRouteHandler>(); auto handler = std::make_shared<BadRouteHandler>();
cgi_app.Routes["markdown"] = handler; cgi_app.Routes["markdown"] = handler;
REQUIRE_THROWS_AS( REQUIRE_THROWS_AS(cgi_app.processRequest(), mdml::Exception);
[&]() { cgi_app.ProcessRequest(); }(), mdml::exception // REQUIRE(cgi_app.processRequest().IsError);
);
} }
} }
// clang-format off // clang-format off
// vim: set foldmethod=marker foldmarker=#region,#endregion textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : // vim: set foldmethod=marker foldmarker=@{,@} textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :

View File

@ -118,4 +118,4 @@ BEGIN_TEST_SUITE("MarkdownRouteHandler Unit Tests")
} }
} }
// clang-format off // clang-format off
// vim: set foldmethod=marker foldmarker=#region,#endregion textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : // vim: set foldmethod=marker foldmarker=@{,@} textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :

View File

@ -12,6 +12,8 @@
#include "types.hpp" #include "types.hpp"
#include "types/Result.hpp" #include "types/Result.hpp"
#include <string>
BEGIN_TEST_SUITE("mdml::Result") BEGIN_TEST_SUITE("mdml::Result")
{ {
TEST("Construction of Result object") TEST("Construction of Result object")
@ -19,14 +21,15 @@ BEGIN_TEST_SUITE("mdml::Result")
SECTION("Using bool to initialize") SECTION("Using bool to initialize")
{ {
REQUIRE_NOTHROW([]() { REQUIRE_NOTHROW([]() {
mdml::Result test{ false, "Success" }; mdml::Result<std::string> test{ false,
"Success" };
}()); }());
} }
SECTION("Using error_t to initialize") SECTION("Using error_t to initialize")
{ {
REQUIRE_NOTHROW([]() { REQUIRE_NOTHROW([]() {
mdml::Result test{ mdml::NO_ERROR, "Success" }; mdml::Result test{ mdml::NoError, "Success" };
}()); }());
} }
} }
@ -60,4 +63,4 @@ BEGIN_TEST_SUITE("mdml::Result")
} }
// clang-format off // clang-format off
// vim: set foldmethod=marker foldmarker=#region,#endregion textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : // vim: set foldmethod=marker foldmarker=@{,@} textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :

View File

@ -33,5 +33,5 @@
#endif #endif
// clang-format off // clang-format off
// vim: set foldmethod=marker foldmarker=#region,#endregion textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : // vim: set foldmethod=marker foldmarker=@{,@} textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :

View File

@ -7,7 +7,7 @@
* obtain one at https://mozilla.org/MPL/2.0/. * obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#include "exception.hpp" #include "Exception.hpp"
#include "tests-common.hpp" #include "tests-common.hpp"
@ -28,13 +28,15 @@ throw_local_exception()
auto local = std::logic_error("This is a stack variable"); auto local = std::logic_error("This is a stack variable");
// Stack variables should not be used outside their stack frames. // Stack variables should not be used outside their stack frames.
throw mdml::exception(local); throw mdml::Exception(local);
} }
BEGIN_TEST_SUITE("mdml::exception") BEGIN_TEST_SUITE("Exception")
{ {
using namespace mdml;
auto throw_an_exception = []() { auto throw_an_exception = []() {
throw mdml::exception("An error occurred!!"); throw Exception("An error occurred!!");
}; };
TEST("TEST: Can throw new exception type") TEST("TEST: Can throw new exception type")
@ -46,20 +48,20 @@ BEGIN_TEST_SUITE("mdml::exception")
{ {
SECTION("1. Blank constructor") SECTION("1. Blank constructor")
{ {
mdml::exception obj; Exception obj;
} }
SECTION("2a. With cstring parameter") SECTION("2a. With cstring parameter")
{ {
mdml::exception obj("Sample Error"); Exception obj("Sample Error");
} }
SECTION("2b. With std::string parameter") SECTION("2b. With std::string parameter")
{ {
mdml::exception obj(std::string("Sample Error")); Exception obj(std::string("Sample Error"));
} }
SECTION("3. With STL exception") SECTION("3. With STL exception")
{ {
mdml::exception obj(std::runtime_error("Sample Error")); Exception obj(std::runtime_error("Sample Error"));
} }
SECTION("4. With destroyed stack") SECTION("4. With destroyed stack")
{ {
@ -84,22 +86,21 @@ BEGIN_TEST_SUITE("mdml::exception")
SECTION("1. Unspecified error or exception") SECTION("1. Unspecified error or exception")
{ {
mdml::exception obj; Exception obj;
REQUIRE_THAT( REQUIRE_THAT(
obj.what(), obj.what(),
Match::ContainsSubstring( Match::ContainsSubstring(
mdml::exception::default_error, messages::kExceptionDefault, CaseSensitive::Yes
CaseSensitive::Yes
) )
); );
} }
SECTION("2. custom error or exception") SECTION("2. custom error or exception")
{ {
constexpr auto test_message = "This is a test."; constexpr auto kTestMessage = "This is a test.";
mdml::exception test_object_one(test_message); Exception test_object_one(kTestMessage);
mdml::exception test_object_two( Exception test_object_two(
std::logic_error("Makes no sense") std::logic_error("Makes no sense")
); );
SECTION(" a: what() does not contain default message") SECTION(" a: what() does not contain default message")
@ -107,7 +108,7 @@ BEGIN_TEST_SUITE("mdml::exception")
REQUIRE_THAT( REQUIRE_THAT(
test_object_one.what(), test_object_one.what(),
!Match::ContainsSubstring( !Match::ContainsSubstring(
mdml::exception::default_error messages::kExceptionDefault
) )
); );
} }
@ -115,7 +116,7 @@ BEGIN_TEST_SUITE("mdml::exception")
{ {
REQUIRE_THAT( REQUIRE_THAT(
test_object_one.what(), test_object_one.what(),
Match::ContainsSubstring(test_message) Match::ContainsSubstring(kTestMessage)
); );
} }
SECTION(" c: what() contains inner exception message") SECTION(" c: what() contains inner exception message")
@ -130,7 +131,7 @@ BEGIN_TEST_SUITE("mdml::exception")
TEST("TEST: what() contains stacktrace with Catch2 runtime methods") TEST("TEST: what() contains stacktrace with Catch2 runtime methods")
{ {
mdml::exception test_object("Test"); Exception test_object("Test");
SECTION(" a: what() does not contain default message") SECTION(" a: what() does not contain default message")
{ {
REQUIRE_THAT( REQUIRE_THAT(
@ -143,4 +144,4 @@ BEGIN_TEST_SUITE("mdml::exception")
} }
// clang-format off // clang-format off
// vim: set foldmethod=marker foldmarker=#region,#endregion textwidth=80 ts=4 sts=0 sw=4 noexpandtab ft=cpp.doxygen : // vim: set foldmethod=marker foldmarker=@{,@} textwidth=80 ts=4 sts=0 sw=4 noexpandtab ft=cpp.doxygen :

View File

@ -7,7 +7,7 @@
* obtain one at https://mozilla.org/MPL/2.0/. * obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#include "exception.hpp" #include "Exception.hpp"
#include "tests-common.hpp" #include "tests-common.hpp"
@ -26,7 +26,7 @@ BEGIN_TEST_SUITE("Catch2")
TEST("Basic Functionality") TEST("Basic Functionality")
{ {
auto throw_something = []() { auto throw_something = []() {
throw std::runtime_error("ERROR"); throw std::runtime_error("Error");
}; };
try { try {
CHECK_THROWS(throw_something()); CHECK_THROWS(throw_something());
@ -47,4 +47,4 @@ BEGIN_TEST_SUITE("Catch2")
} }
// clang-format off // clang-format off
// vim: set foldmethod=marker foldmarker=#region,#endregion textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : // vim: set foldmethod=marker foldmarker=@{,@} textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :

View File

@ -33,5 +33,5 @@
#endif #endif
// clang-format off // clang-format off
// vim: set foldmethod=marker foldmarker=#region,#endregion textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : // vim: set foldmethod=marker foldmarker=@{,@} textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :