Skip to content

Commit 26b833c

Browse files
committed
added basic unit testing
1 parent a483e39 commit 26b833c

23 files changed

Lines changed: 535 additions & 31 deletions

cmake/webframe.cmake

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,29 @@ function(webframe_add_application)
3333
set(oneValueArgs NAME)
3434
set(multiValueArgs
3535
SOURCES
36-
PRIVATE_INCLUDE_DIRS
37-
PUBLIC_INCLUDE_DIRS
38-
PRIVATE_LINK_LIBRARIES
39-
PUBLIC_LINK_LIBRARIES
36+
INCLUDE_DIRS
37+
LINK_LIBRARIES
4038
RUNTIME)
4139
cmake_parse_arguments(APPLICATION
4240
"${options}"
4341
"${oneValueArgs}"
4442
"${multiValueArgs}"
4543
${ARGN})
44+
foreach(RUNTIME ${APPLICATION_RUNTIME})
45+
set(TARGET_NAME ${APPLICATION_NAME}_${RUNTIME})
46+
if(WIN32)
47+
if(RUNTIME STREQUAL "desktop")
48+
add_executable(${TARGET_NAME} WIN32 ${APPLICATION_SOURCES})
49+
else()
50+
add_executable(${TARGET_NAME} ${APPLICATION_SOURCES})
51+
endif()
52+
else()
53+
add_executable(${TARGET_NAME} ${APPLICATION_SOURCES})
54+
endif()
55+
if(APPLICATION_INCLUDE_DIRS)
56+
target_include_directories(${TARGET_NAME} PRIVATE ${APPLICATION_INCLUDE_DIRS})
57+
endif()
58+
target_link_libraries(${TARGET_NAME} PRIVATE webframe_${RUNTIME} ${APPLICATION_LINK_LIBRARIES})
59+
add_dependencies(${TARGET_NAME} webframe_${RUNTIME})
60+
endforeach()
4661
endfunction()

example/main.cpp

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,52 @@
11
#include <webframe.hpp>
22

3+
#include <hyperpage.hpp>
4+
35
class archive_handler : public webframe::handler
46
{
7+
public:
8+
archive_handler(const std::string& archive_path)
9+
{
10+
_archive = std::make_unique<hyperpage::reader>(archive_path);
11+
}
512
protected:
613
void handle_get(const webframe::request* req, webframe::response* res) override
714
{
8-
res->set_status(200);
9-
res->set_header("Content-Type", "text/plain");
10-
const std::string message = "Hello, World!";
11-
res->set_body(reinterpret_cast<const uint8_t *>(message.data()), message.size());
15+
std::string path = req->get_path();
16+
auto page = _archive->load(path);
17+
if (page) {
18+
res->set_status(200);
19+
res->set_header("Content-Type", page->get_mime_type());
20+
res->set_body(page->get_content(), page->get_length());
21+
}
22+
else
23+
{
24+
throw webframe::exception::not_found;
25+
}
26+
}
27+
private:
28+
std::unique_ptr<hyperpage::reader> _archive;
29+
};
30+
31+
class greeting_handler : public webframe::handler
32+
{
33+
protected:
34+
void handle_post(const webframe::request* req, webframe::response* res) override
35+
{
36+
1237
}
1338
};
1439

1540
class example_application : public webframe::application
1641
{
1742
public:
18-
void configure_router(webframe::router *ctrl) override
43+
void configure_router(webframe::router* router) override
1944
{
20-
ctrl->add_route("/archive", new archive_handler());
45+
_archive_handler = std::make_unique<archive_handler>("path/to/archive");
46+
router->set_default(_archive_handler.get());
2147
}
48+
private:
49+
std::unique_ptr<archive_handler> _archive_handler;
2250
};
2351

2452
WEBFRAME_MAIN(example_application)

include/webframe.hpp

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <string>
2828
#include <unordered_map>
2929

30+
#include <webframe/application.hpp>
3031
#include <webframe/exception.hpp>
3132
#include <webframe/handler.hpp>
3233
#include <webframe/router.hpp>
@@ -48,29 +49,23 @@ namespace webframe
4849
class request
4950
{
5051
public:
51-
virtual method get_method() const;
52-
virtual std::string get_path() const;
53-
virtual bool get_header(const std::string &key, std::string &value) const;
54-
virtual std::pair<const uint8_t *, size_t> get_body() const;
55-
virtual void read_body(const std::function<void(const uint8_t *, size_t)> &callback) const;
52+
virtual method get_method() const = 0;
53+
virtual std::string get_path() const = 0;
54+
virtual bool get_header(const std::string &key, std::string &value) const = 0;
55+
virtual std::pair<const uint8_t *, size_t> get_body() const = 0;
56+
virtual void read_body(const std::function<void(const uint8_t *, size_t)> &callback) const = 0;
5657
};
5758

5859
class response
5960
{
6061
public:
61-
virtual void set_status(int status_code);
62-
virtual void set_header(const std::string &key, const std::string &value);
63-
virtual void set_body(const uint8_t *data, size_t size);
64-
virtual void write_body(const std::function<bool(std::pair<const uint8_t *, size_t> &)> &callback);
62+
virtual void set_status(int status_code) = 0;
63+
virtual void set_header(const std::string &key, const std::string &value) = 0;
64+
virtual void set_body(const uint8_t *data, size_t size) = 0;
65+
virtual void write_body(const std::function<bool(std::pair<const uint8_t *, size_t> &)> &callback) = 0 ;
6566
};
6667

67-
class application
68-
{
69-
public:
70-
virtual void configure_desktop();
71-
virtual void configure_server(int argc, const char **argv);
72-
virtual void configure_router(router *ctrl);
73-
};
68+
7469

7570
class runtime
7671
{

include/webframe/application.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#ifndef WEBFRAME_APPLICATION_HPP
2+
#define WEBFRAME_APPLICATION_HPP
3+
4+
namespace webframe
5+
{
6+
class router;
7+
8+
class application
9+
{
10+
public:
11+
application() = default;
12+
virtual ~application() = default;
13+
virtual void configure_desktop();
14+
virtual void configure_server(int argc, const char **argv);
15+
virtual void configure_router(router *ctrl);
16+
virtual void on_dispatch();
17+
};
18+
}
19+
20+
#endif

ports/hyperpage/portfile.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ vcpkg_from_github(
1010

1111
vcpkg_cmake_configure(
1212
SOURCE_PATH "${SOURCE_PATH}"
13+
OPTIONS
14+
-DCMAKE_INSTALL_INCLUDEDIR=include
1315
)
1416

1517
vcpkg_cmake_install()

ports/maxtest/portfile.cmake

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ file(INSTALL "${SOURCE_PATH}/maxtest.hpp"
1111
DESTINATION "${CURRENT_PACKAGES_DIR}/include")
1212

1313
# Create CMake config files for find_package support
14-
file(MAKE_DIRECTORY "${CURRENT_PACKAGES_DIR}/lib/cmake/maxtest")
15-
16-
file(WRITE "${CURRENT_PACKAGES_DIR}/lib/cmake/maxtest/maxtest-config.cmake"
14+
file(WRITE "${CURRENT_PACKAGES_DIR}/share/maxtest/maxtest-config.cmake"
1715
"
1816
include_guard(GLOBAL)
1917

src/CMakeLists.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1+
file(GLOB WEBFRAME_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
2+
set(WEBFRAME_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../include)
3+
14
if(BUILD_RUNTIME)
25
message(STATUS "Building desktop runtime")
36
message(STATUS "Building browser runtime")
47
endif()
58

69
if(BUILD_TESTING)
7-
message(STATUS "Building mock runtime")
10+
file(GLOB WEBFRAME_MOCK_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/runtimes/mock/*.cpp)
11+
webframe_add_runtime(NAME mock
12+
SOURCES ${WEBFRAME_SOURCES} ${WEBFRAME_MOCK_SOURCES}
13+
PUBLIC_INCLUDE_DIRS ${WEBFRAME_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/runtimes/mock)
814
endif()

src/application.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include <webframe.hpp>
2+
3+
namespace webframe
4+
{
5+
void application::configure_desktop()
6+
{
7+
8+
}
9+
10+
void application::configure_server(int argc, const char **argv)
11+
{
12+
13+
}
14+
15+
void application::configure_router(router *ctrl)
16+
{
17+
18+
}
19+
20+
void application::on_dispatch()
21+
{
22+
23+
}
24+
}

src/handler.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#include <webframe.hpp>
2+
3+
namespace webframe
4+
{
5+
void handler::handle_request(const request *req, response *res)
6+
{
7+
try
8+
{
9+
switch (req->get_method())
10+
{
11+
case method::GET:
12+
handle_get(req, res);
13+
break;
14+
case method::POST:
15+
handle_post(req, res);
16+
break;
17+
case method::PUT:
18+
handle_put(req, res);
19+
break;
20+
case method::DELETE:
21+
handle_delete(req, res);
22+
break;
23+
default:
24+
throw exception::bad_request;
25+
}
26+
}
27+
catch (const exception &e)
28+
{
29+
res->set_status(e.get_status_code());
30+
res->set_header("Content-Type", e.get_content_type());
31+
const std::string &message = e.get_message();
32+
res->set_body(reinterpret_cast<const uint8_t *>(message.data()), message.size());
33+
}
34+
}
35+
36+
void handler::handle_get(const request *req, response *res)
37+
{
38+
throw exception::method_not_allowed;
39+
}
40+
41+
void handler::handle_post(const request *req, response *res)
42+
{
43+
throw exception::method_not_allowed;
44+
}
45+
46+
void handler::handle_put(const request *req, response *res)
47+
{
48+
throw exception::method_not_allowed;
49+
}
50+
51+
void handler::handle_delete(const request *req, response *res)
52+
{
53+
throw exception::method_not_allowed;
54+
}
55+
}

src/router.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#include <webframe.hpp>
2+
3+
class global_default_handler : public webframe::handler
4+
{
5+
protected:
6+
void handle_get(const webframe::request* req, webframe::response* res) override
7+
{
8+
throw webframe::exception::not_found;
9+
}
10+
11+
void handle_post(const webframe::request* req, webframe::response* res) override
12+
{
13+
throw webframe::exception::not_found;
14+
}
15+
16+
void handle_put(const webframe::request* req, webframe::response* res) override
17+
{
18+
throw webframe::exception::not_found;
19+
}
20+
21+
void handle_delete(const webframe::request* req, webframe::response* res) override
22+
{
23+
throw webframe::exception::not_found;
24+
}
25+
};
26+
27+
static global_default_handler g_default_handler;
28+
29+
namespace webframe
30+
{
31+
void router::add_route(const std::string& path, handler* h)
32+
{
33+
_handlers[path] = h;
34+
}
35+
36+
void router::set_default(handler* h)
37+
{
38+
_default_handler = h;
39+
}
40+
41+
handler* router::find_route(const std::string& path)
42+
{
43+
auto it = _handlers.find(path);
44+
if (it != _handlers.end()) {
45+
return it->second;
46+
}
47+
return get_default();
48+
}
49+
50+
handler* router::get_default()
51+
{
52+
return _default_handler ? _default_handler : &g_default_handler;
53+
}
54+
}

0 commit comments

Comments
 (0)