Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add tests for the BASE64 encoding
  • Loading branch information
prantlf committed Sep 14, 2013
commit 95137e25ecaf259684b77117a20bb4136607bc43
1 change: 1 addition & 0 deletions libs/network/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ if (Boost_FOUND)
message_test
message_transform_test
utils_thread_pool
utils_base64_test
)
foreach (test ${TESTS})
if (${CMAKE_CXX_COMPILER_ID} MATCHES GNU)
Expand Down
1 change: 1 addition & 0 deletions libs/network/test/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,4 @@ build-project uri ;

run message_test.cpp ;
run message_transform_test.cpp ;
run utils_base64_test.cpp ;
205 changes: 205 additions & 0 deletions libs/network/test/utils_base64_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
#define BOOST_TEST_MODULE BASE64 Test
#include <boost/config/warning_disable.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/network/utils/base64/encode.hpp>
#include <boost/network/utils/base64/encode-io.hpp>
#include <boost/array.hpp>
#include <algorithm>
#include <iterator>
#include <string>
#include <vector>
#include <sstream>

using namespace boost::network::utils;

// proves that all public functions are compilable; the result check
// is very minimum here, so that the test doesn't look so stupid ;-)
BOOST_AUTO_TEST_CASE(interface_test) {
std::string result;
base64::state<char> state;

// check string literal
BOOST_CHECK_EQUAL(base64::encode<char>("abc"), "YWJj");

base64::encode("abc", std::back_inserter(result));
BOOST_CHECK_EQUAL(result, "YWJj");

result.clear();
base64::encode("abc", std::back_inserter(result), state);
BOOST_CHECK_EQUAL(result, "YWJj");

// check std::string
std::string input("abc");

BOOST_CHECK_EQUAL(base64::encode<char>(input), "YWJj");

result.clear();
base64::encode(input, std::back_inserter(result));
BOOST_CHECK_EQUAL(result, "YWJj");

result.clear();
base64::encode(input.begin(), input.end(), std::back_inserter(result));
BOOST_CHECK_EQUAL(result, "YWJj");

result.clear();
base64::encode(input, std::back_inserter(result), state);
BOOST_CHECK_EQUAL(result, "YWJj");

result.clear();
base64::encode(input.begin(), input.end(), std::back_inserter(result), state);
BOOST_CHECK_EQUAL(result, "YWJj");

// check array of chars
char char_array[] = { 'a', 'b', 'c' };

BOOST_CHECK_EQUAL(base64::encode<char>(char_array), "YWJj");

// check boost::array of chars
boost::array<char, 3> char_boost_array = { { 'a', 'b', 'c' } };

BOOST_CHECK_EQUAL(base64::encode<char>(char_boost_array), "YWJj");

// check std::vector of chars
std::vector<char> char_vector(char_array, char_array + 3);

BOOST_CHECK_EQUAL(base64::encode<char>(char_vector), "YWJj");

// check array of ints
int int_array[] = { 'a', 'b', 'c' };

BOOST_CHECK_EQUAL(base64::encode<char>(int_array), "YWJj");

// check boost::array of ints
boost::array<int, 3> int_boost_array = { { 'a', 'b', 'c' } };

BOOST_CHECK_EQUAL(base64::encode<char>(int_boost_array), "YWJj");

// check std::vector of ints
std::vector<int> int_vector(int_array, int_array + 3);

BOOST_CHECK_EQUAL(base64::encode<char>(int_vector), "YWJj");

// check that base64::encode_rest is compilable and callable
result.clear();
base64::encode_rest(std::back_inserter(result), state);
BOOST_CHECK_EQUAL(result, "");

// check that the iostream interface is compilable and callable
std::ostringstream output;
output << base64::io::encode("abc") <<
base64::io::encode(input.begin(), input.end()) <<
base64::io::encode(int_array) <<
base64::io::encode(int_boost_array) <<
base64::io::encode(char_array) <<
base64::io::encode(char_boost_array) <<
base64::io::encode(char_vector) <<
base64::io::encode_rest<char>;
BOOST_CHECK_EQUAL(output.str(), "YWJjYWJjYWJjYWJjYWJjYWJjYWJj");
}

// checks that functions encoding a single chunk append the correct padding
// if the input byte count is not divisible by 3
BOOST_AUTO_TEST_CASE(padding_test) {
BOOST_CHECK_EQUAL(base64::encode<char>(""), "");
BOOST_CHECK_EQUAL(base64::encode<char>("a"), "YQ==");
BOOST_CHECK_EQUAL(base64::encode<char>("aa"), "YWE=");
BOOST_CHECK_EQUAL(base64::encode<char>("aaa"), "YWFh");
}

// check that functions using encoding state interrupt and resume encoding
// correcly if the byte count of the partial input is not divisible by 3
BOOST_AUTO_TEST_CASE(state_test) {
base64::state<char> state;
std::string result;

// check encoding empty input; including the state value
base64::encode("", std::back_inserter(result), state);
BOOST_CHECK_EQUAL(result, "");
BOOST_CHECK(state.empty());
result.clear();
state.clear();

// check one third of quantum which needs two character padding;
// including how the state develops when encoded by single character
base64::encode("a", std::back_inserter(result), state);
BOOST_CHECK_EQUAL(result, "Y");
BOOST_CHECK(!state.empty());
base64::encode_rest(std::back_inserter(result), state);
BOOST_CHECK_EQUAL(result, "YQ==");
BOOST_CHECK(state.empty());
result.clear();
state.clear();

// check two thirds of quantum which needs one character padding;
// including how the state develops when encoded by single character
base64::encode("a", std::back_inserter(result), state);
BOOST_CHECK_EQUAL(result, "Y");
BOOST_CHECK(!state.empty());
base64::encode("a", std::back_inserter(result), state);
BOOST_CHECK_EQUAL(result, "YW");
BOOST_CHECK(!state.empty());
base64::encode_rest(std::back_inserter(result), state);
BOOST_CHECK_EQUAL(result, "YWE=");
BOOST_CHECK(state.empty());
result.clear();
state.clear();

// check a complete quantum which needs no padding; including
// how the state develops when encoded by single character
base64::encode("a", std::back_inserter(result), state);
BOOST_CHECK_EQUAL(result, "Y");
BOOST_CHECK(!state.empty());
base64::encode("a", std::back_inserter(result), state);
BOOST_CHECK_EQUAL(result, "YW");
BOOST_CHECK(!state.empty());
base64::encode("a", std::back_inserter(result), state);
BOOST_CHECK_EQUAL(result, "YWFh");
BOOST_CHECK(state.empty());
base64::encode_rest(std::back_inserter(result), state);
BOOST_CHECK_EQUAL(result, "YWFh");
BOOST_CHECK(state.empty());
}

// checks that the base64 output can be returned as wchar_t too
BOOST_AUTO_TEST_CASE(wide_character_test) {
BOOST_CHECK(base64::encode<wchar_t>("abc") == L"YWJj");
BOOST_CHECK(base64::encode<wchar_t>(std::string("abc")) == L"YWJj");

std::wostringstream output;
output << base64::io::encode("abc") << base64::io::encode_rest<char>;
BOOST_CHECK(output.str() == L"YWJj");
}

// checks that the base64-io manipulators are compilable and work
BOOST_AUTO_TEST_CASE(io_test) {
// check complete quantum where no state has to be remembered
std::ostringstream output;
output << base64::io::encode("abc") << base64::io::encode_rest<char>;
BOOST_CHECK_EQUAL(output.str(), "YWJj");

// check that encode_rest clears the state
output.str("");
output << base64::io::encode("a");
BOOST_CHECK(!base64::io::empty_state<char>(output));
output << base64::io::encode_rest<char>;
BOOST_CHECK(base64::io::empty_state<char>(output));

// check that forced clearing the state works
output.str("");
output << base64::io::encode("a");
BOOST_CHECK(!base64::io::empty_state<char>(output));
output << base64::io::clear_state<char>;
BOOST_CHECK(base64::io::empty_state<char>(output));

// check one third of quantum which has to be remembered in state
output.str("");
output << base64::io::encode("a") << base64::io::encode("bc") <<
base64::io::encode_rest<char>;
BOOST_CHECK_EQUAL(output.str(), "YWJj");

// check two thirds of quantum which have to be remembered in state.
output.str("");
output << base64::io::encode("ab") << base64::io::encode("c") <<
base64::io::encode_rest<char>;
BOOST_CHECK_EQUAL(output.str(), "YWJj");
}