Add unit test
This commit is contained in:
parent
86c6b1ca89
commit
3f10b30efc
7 changed files with 161 additions and 0 deletions
BIN
data/debian-12.10.0-amd64-netinst.iso.torrent
Normal file
BIN
data/debian-12.10.0-amd64-netinst.iso.torrent
Normal file
Binary file not shown.
|
@ -15,3 +15,7 @@ boost_dep = dependency('boost', version: '>=1.75.0')
|
|||
libstriezel_dep = dependency('libstriezel')
|
||||
|
||||
subdir('src')
|
||||
|
||||
if get_option('build_testing')
|
||||
subdir('test')
|
||||
endif
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
option('build_tools', type: 'boolean', value: true, description: 'Enable or disable building the cli tools')
|
||||
option('build_testing', type: 'boolean', value: true, description: 'Enable or disable building of automated test programs')
|
||||
|
|
1
test/meson.build
Normal file
1
test/meson.build
Normal file
|
@ -0,0 +1 @@
|
|||
subdir('unit')
|
28
test/unit/main.cpp
Normal file
28
test/unit/main.cpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
/* Copyright 2025, Michele "King_DuckZ" Santullo
|
||||
* This file is part of ducktorrent.
|
||||
*
|
||||
* Ducktorrent 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
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Ducktorrent 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 ducktorrent. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <catch2/catch_session.hpp>
|
||||
|
||||
int main( int argc, char* argv[] ) {
|
||||
// your setup ...
|
||||
|
||||
int result = Catch::Session().run( argc, argv );
|
||||
|
||||
// your clean-up...
|
||||
|
||||
return result;
|
||||
}
|
12
test/unit/meson.build
Normal file
12
test/unit/meson.build
Normal file
|
@ -0,0 +1,12 @@
|
|||
catch2_dep = dependency('Catch2', version: '>=3.5.2')
|
||||
|
||||
unit_test_prog = executable(meson.project_name() + '_unittest',
|
||||
'main.cpp',
|
||||
'test_parser.cpp',
|
||||
install: false,
|
||||
dependencies: [ducktorrent_dep, catch2_dep],
|
||||
)
|
||||
|
||||
test ('unit_' + meson.project_name(),
|
||||
unit_test_prog
|
||||
)
|
115
test/unit/test_parser.cpp
Normal file
115
test/unit/test_parser.cpp
Normal file
|
@ -0,0 +1,115 @@
|
|||
/* Copyright 2025, Michele "King_DuckZ" Santullo
|
||||
* This file is part of ducktorrent.
|
||||
*
|
||||
* Ducktorrent 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
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Ducktorrent 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 ducktorrent. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "catch2/catch_test_macros.hpp"
|
||||
#include "ducktorrent/parser.hpp"
|
||||
|
||||
#define INPUT1_BINARY_BLOB "Njw\0XLóPO_æ5iÄ@\\#ú·<jâ"
|
||||
|
||||
namespace {
|
||||
constexpr char g_input1_binary_blob[] = INPUT1_BINARY_BLOB;
|
||||
constexpr auto g_input1_binary_blob_size = sizeof(g_input1_binary_blob) / sizeof(g_input1_binary_blob[0]) - 1;
|
||||
constexpr char g_input1[] = "d8:announce41:http://bttracker.debian.org:6969/ann"
|
||||
"ounce7:comment33:Debian CD from cdimage.debian.org10:created by13:mktorren"
|
||||
"t 1.113:creation datei1742039925e4:infod6:lengthi663748608e4:name32:debian"
|
||||
"-12.10.0-amd64-netinst.iso12:piece lengthi262144e6:pieces40:"
|
||||
INPUT1_BINARY_BLOB "ee";
|
||||
constexpr auto g_input1_size = sizeof(g_input1) / sizeof(g_input1[0]) - 1u;
|
||||
|
||||
constexpr char g_input2[] = "hello world";
|
||||
constexpr auto g_input2_size = sizeof(g_input2) / sizeof(g_input2[0]) - 1u;
|
||||
|
||||
constexpr char g_input3[] = "d5:helloe";
|
||||
constexpr auto g_input3_size = sizeof(g_input3) / sizeof(g_input3[0]) - 1u;
|
||||
|
||||
constexpr char g_input4[] = "d5:hello5:worldee";
|
||||
constexpr auto g_input4_size = sizeof(g_input4) / sizeof(g_input4[0]) - 1u;
|
||||
|
||||
constexpr char g_input5[] = "d5:hello5:world";
|
||||
constexpr auto g_input5_size = sizeof(g_input5) / sizeof(g_input5[0]) - 1u;
|
||||
|
||||
constexpr char g_input6[] = "d5:hello100:worlde";
|
||||
constexpr auto g_input6_size = sizeof(g_input6) / sizeof(g_input6[0]) - 1u;
|
||||
|
||||
template <typename T>
|
||||
void check_map_entry (
|
||||
const std::map<duck::TorrentStringType, duck::TorrentValue>& map,
|
||||
duck::TorrentStringType key,
|
||||
T expected,
|
||||
int expected_var_which
|
||||
) {
|
||||
REQUIRE(map.contains(key));
|
||||
REQUIRE(map.at(key).get().which() == expected_var_which);
|
||||
const auto& val = boost::get<T>(map.at(key));
|
||||
CHECK(val == expected);
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
TEST_CASE ("Parse valid bencoded test input", "[parse][bencoding]") {
|
||||
using duck::TorrentStringType;
|
||||
using duck::TorrentIntType;
|
||||
|
||||
auto res = duck::parse_torrent(std::string_view{g_input1, g_input1_size});
|
||||
REQUIRE(res.size() == 1);
|
||||
|
||||
const duck::TorrentValue& root = res.front();
|
||||
REQUIRE(root.get().which() == 3);
|
||||
|
||||
const std::map<TorrentStringType, duck::TorrentValue>& main_map =
|
||||
boost::get<
|
||||
boost::spirit::x3::forward_ast< std::map<TorrentStringType, duck::TorrentValue> >
|
||||
>(root).get();
|
||||
|
||||
check_map_entry<TorrentStringType>(main_map, "announce", "http://bttracker.debian.org:6969/announce", 1);
|
||||
check_map_entry<TorrentStringType>(main_map, "comment", "Debian CD from cdimage.debian.org", 1);
|
||||
check_map_entry<TorrentStringType>(main_map, "created by", "mktorrent 1.1", 1);
|
||||
check_map_entry<TorrentIntType>(main_map, "creation date", 1742039925, 0);
|
||||
|
||||
REQUIRE(main_map.contains("info"));
|
||||
REQUIRE(main_map.at("info").get().which() == 3);
|
||||
const std::map<TorrentStringType, duck::TorrentValue>& info_map =
|
||||
boost::get<
|
||||
boost::spirit::x3::forward_ast< std::map<TorrentStringType, duck::TorrentValue> >
|
||||
>(main_map.at("info")).get();
|
||||
|
||||
check_map_entry<TorrentStringType>(info_map, "name", "debian-12.10.0-amd64-netinst.iso", 1);
|
||||
check_map_entry<TorrentIntType>(info_map, "piece length", 262144, 0);
|
||||
check_map_entry<TorrentStringType>(info_map, "pieces", TorrentStringType{g_input1_binary_blob, g_input1_binary_blob_size}, 1);
|
||||
}
|
||||
|
||||
TEST_CASE ("Parse empty test input", "[parse][bencoding]") {
|
||||
CHECK_THROWS_AS(duck::parse_torrent(""), duck::ParseError);
|
||||
}
|
||||
|
||||
TEST_CASE ("Parse invalid test input", "[parse][bencoding]") {
|
||||
std::string_view input;
|
||||
|
||||
input = std::string_view{g_input2, g_input2_size};
|
||||
CHECK_THROWS_AS(duck::parse_torrent(input), duck::ParseError);
|
||||
|
||||
input = std::string_view{g_input3, g_input3_size};
|
||||
CHECK_THROWS_AS(duck::parse_torrent(input), duck::ParseError);
|
||||
|
||||
input = std::string_view{g_input4, g_input4_size};
|
||||
CHECK_THROWS_AS(duck::parse_torrent(input), duck::ParseError);
|
||||
|
||||
input = std::string_view{g_input5, g_input5_size};
|
||||
CHECK_THROWS_AS(duck::parse_torrent(input), duck::ParseError);
|
||||
|
||||
input = std::string_view{g_input6, g_input6_size};
|
||||
CHECK_THROWS_AS(duck::parse_torrent(input), duck::ParseError);
|
||||
}
|
Loading…
Add table
Reference in a new issue