diff options
| -rw-r--r-- | .gitignore | 6 | ||||
| -rw-r--r-- | CMakeLists.txt | 38 | ||||
| -rw-r--r-- | README.md | 20 | ||||
| -rw-r--r-- | src/unittest/test.cpp | 13 | ||||
| -rw-r--r-- | src/unittest/test_encoder.cpp | 675 |
5 files changed, 746 insertions, 6 deletions
@@ -3,6 +3,12 @@ CMakeCache.txt CMakeFiles Makefile cmake_install.cmake +compile_commands.json + +# Unit tests +CTestTestfile.cmake +Testing +unittest*.cmake # Prerequisites *.d diff --git a/CMakeLists.txt b/CMakeLists.txt index d583050..8613aab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required (VERSION 3.1) -project (ecbor LANGUAGES C) +project (ecbor LANGUAGES C CXX) # Version set (VERSION_MAJOR 1) @@ -9,11 +9,25 @@ set (VERSION_PATCH 0) # Options option (BUILD_DESCRIBE_TOOL "build ecbor-describe" ON) +option (TESTING "build unit test targets" OFF) + +# Testing dependencies +if (TESTING) + find_package(GTest) +endif() # Compiler setup set (CMAKE_C_STANDARD 99) +set (CMAKE_CXX_STANDARD 20) +set (CMAKE_CXX_STANDARD_REQUIRED ON) -add_compile_options (-Wall -Wextra -pedantic -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition) +add_compile_options ( + -Wall + -Wextra + -pedantic + $<$<COMPILE_LANGUAGE:C>:-Wmissing-prototypes> + $<$<COMPILE_LANGUAGE:C>:-Wstrict-prototypes> + $<$<COMPILE_LANGUAGE:C>:-Wold-style-definition>) # Output directory setup set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/lib") @@ -51,8 +65,8 @@ set (DESCRIBE_TOOL_SOURCES add_library (${PROJECT_NAME}_shared SHARED ${LIB_SOURCES}) add_library (${PROJECT_NAME}_static STATIC ${LIB_SOURCES}) -set_target_properties (${PROJECT_NAME}_shared PROPERTIES OUTPUT_NAME ${PROJECT_NAME} PUBLIC_HEADER ${LIB_INCLUDES}) -set_target_properties (${PROJECT_NAME}_static PROPERTIES OUTPUT_NAME ${PROJECT_NAME} PUBLIC_HEADER ${LIB_INCLUDES}) +set_target_properties (${PROJECT_NAME}_shared PROPERTIES OUTPUT_NAME ${PROJECT_NAME} PUBLIC_HEADER ${LIB_INCLUDES} LINKER_LANGUAGE C) +set_target_properties (${PROJECT_NAME}_static PROPERTIES OUTPUT_NAME ${PROJECT_NAME} PUBLIC_HEADER ${LIB_INCLUDES} LINKER_LANGUAGE C) target_compile_options (${PROJECT_NAME}_static PRIVATE -nostdlib) @@ -64,4 +78,18 @@ if (BUILD_DESCRIBE_TOOL) add_executable (${PROJECT_NAME}-describe ${DESCRIBE_TOOL_SOURCES}) target_link_libraries (${PROJECT_NAME}-describe ${PROJECT_NAME}_shared) install (TARGETS ${PROJECT_NAME}-describe DESTINATION bin) -endif (BUILD_DESCRIBE_TOOL)
\ No newline at end of file +endif (BUILD_DESCRIBE_TOOL) + +# Test targets +if (TESTING) + set (UNIT_TEST_SOURCES + "${SRC_DIR}/unittest/test.cpp" + "${SRC_DIR}/unittest/test_encoder.cpp" + ) + + # Unit tests + enable_testing () + add_executable(unittest ${UNIT_TEST_SOURCES}) + target_link_libraries (unittest GTest::GTest ${PROJECT_NAME}_static) + gtest_discover_tests (unittest) +endif() @@ -19,13 +19,31 @@ This will generate the following files: ## Testing -Unit tests can be run by performing: +Functional tests can be run with: ``` cd test/ ./runtests.sh ``` +Unit tests depend on `gtest` and must be explicitly built: + +``` +cmake . -DTESTING=ON +``` + +They can be run either via CMake: + +``` +ctest +``` + +or by directly running the unit tests executable, which provides more verbose output: + +``` +./bin/unittest +``` + ## Installation Installing can be performed with: diff --git a/src/unittest/test.cpp b/src/unittest/test.cpp new file mode 100644 index 0000000..6295664 --- /dev/null +++ b/src/unittest/test.cpp @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2021 Vasile Vilvoiu <vasi@vilvoiu.ro> + * + * libecbor is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See LICENSE for details. + */ +#include "gtest/gtest.h" + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/unittest/test_encoder.cpp b/src/unittest/test_encoder.cpp new file mode 100644 index 0000000..380d45c --- /dev/null +++ b/src/unittest/test_encoder.cpp @@ -0,0 +1,675 @@ +/* + * Copyright (c) 2021 Vasile Vilvoiu <vasi@vilvoiu.ro> + * + * libecbor is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See LICENSE for details. + */ +#include "gtest/gtest.h" +#include "ecbor.h" +#include <cmath> +#include <cstring> +#include <vector> +#include <functional> +#include <tuple> +#include <string> +#include <iostream> +#include <limits> + +void run_encoder_test_normal(std::function<void(ecbor_encode_context_t*)> callback, + std::vector<uint8_t> expected) +{ + // create an encoding context + constexpr size_t BUFFER_SIZE = 4096; + uint8_t buf[BUFFER_SIZE]; + ecbor_encode_context_t ctx; + EXPECT_EQ(ecbor_initialize_encode(&ctx, buf, BUFFER_SIZE), ECBOR_OK); + + callback(&ctx); + + // check output + auto sizef = ECBOR_GET_ENCODED_BUFFER_SIZE(&ctx); + size_t sizes; + EXPECT_EQ(ecbor_get_encoded_buffer_size(&ctx, &sizes), ECBOR_OK); + EXPECT_EQ(sizef, sizes); + EXPECT_EQ(sizef, expected.size()); + + std::cout << "Act: "; + for (size_t i = 0; i < sizef; i++) { + std::cout << std::hex << (uint32_t)ctx.base[i] << std::dec << " "; + } + std::cout << std::endl; + + std::cout << "Exp: "; + for (auto c : expected) { + std::cout << std::hex << (uint32_t)c << std::dec << " "; + } + std::cout << std::endl; + + EXPECT_TRUE(std::memcmp(ctx.base, expected.data(), sizef) == 0); +} + +TEST(encoder, noop) +{ + run_encoder_test_normal([](ecbor_encode_context_t* ctx) -> void { + }, + {}); +} + +TEST(encoder, error_null_parameters) +{ + constexpr size_t BUFFER_SIZE = 4096; + uint8_t buf[BUFFER_SIZE]; + + ecbor_encode_context_t ctx; + ecbor_item_t item = ecbor_uint(3), foo; + + size_t sz; + + EXPECT_EQ(ecbor_initialize_encode(nullptr, buf, BUFFER_SIZE), ECBOR_ERR_NULL_CONTEXT); + EXPECT_EQ(ecbor_initialize_encode(&ctx, nullptr, BUFFER_SIZE), ECBOR_ERR_NULL_OUTPUT_BUFFER); + EXPECT_EQ(ecbor_initialize_encode_streamed(nullptr, buf, BUFFER_SIZE), ECBOR_ERR_NULL_CONTEXT); + EXPECT_EQ(ecbor_initialize_encode_streamed(&ctx, nullptr, BUFFER_SIZE), ECBOR_ERR_NULL_OUTPUT_BUFFER); + + EXPECT_EQ(ecbor_encode(nullptr, &item), ECBOR_ERR_NULL_CONTEXT); + EXPECT_EQ(ecbor_encode(&ctx, nullptr), ECBOR_ERR_NULL_ITEM); + + EXPECT_EQ(ecbor_get_encoded_buffer_size(nullptr, &sz), ECBOR_ERR_NULL_CONTEXT); + EXPECT_EQ(ecbor_get_encoded_buffer_size(&ctx, nullptr), ECBOR_ERR_NULL_PARAMETER); + + EXPECT_EQ(ecbor_array(nullptr, &item, 1), ECBOR_ERR_NULL_ARRAY); + EXPECT_EQ(ecbor_array(&foo, nullptr, 1), ECBOR_ERR_NULL_ITEM); + + EXPECT_EQ(ecbor_map(nullptr, &item, &item, 1), ECBOR_ERR_NULL_MAP); + EXPECT_EQ(ecbor_map(&foo, nullptr, &item, 1), ECBOR_ERR_NULL_ITEM); + EXPECT_EQ(ecbor_map(&foo, &item, nullptr, 1), ECBOR_ERR_NULL_ITEM); +} + +TEST(encoder, appendix_a) +{ + using Test = std::tuple<std::string, std::function<void(ecbor_encode_context_t*)>, std::vector<uint8_t>>; + + std::vector<Test> tests = { + { + "000", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_uint(0); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0x00 } + }, + { + "001", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_uint(1); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0x01 } + }, + { + "002", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_uint(10); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0x0a } + }, + { + "003", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_uint(23); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0x17 } + }, + { + "004", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_uint(24); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0x18, 0x18 } + }, + { + "005", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_uint(25); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0x18, 0x19 } + }, + { + "006", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_uint(100); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0x18, 0x64 } + }, + { + "007", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_uint(1000); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0x19, 0x03, 0xe8 } + }, + { + "008", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_uint(1000000); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0x1a, 0x00, 0x0f, 0x42, 0x40 } + }, + { + "009", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_uint(1000000000000); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0x1b, 0x00, 0x00, 0x00, 0xe8, 0xd4, 0xa5, 0x10, 0x00 } + }, + { + "010", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_uint(18446744073709551615ULL); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } + }, + { + "011", + [](ecbor_encode_context_t* ctx) -> void { + std::vector<uint8_t> bstr_ = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + ecbor_item_t bstr = ecbor_bstr(bstr_.data(), bstr_.size()); + ecbor_item_t tag = ecbor_tag(&bstr, 2); + EXPECT_EQ(ecbor_encode(ctx, &tag), ECBOR_OK); + }, + { 0xc2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, + { + "012", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_int(0); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0x00 } /* NOTE: libecbor cannot produce -0 */ + }, + { + "013", + [](ecbor_encode_context_t* ctx) -> void { + std::vector<uint8_t> bstr_ = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + ecbor_item_t bstr = ecbor_bstr(bstr_.data(), bstr_.size()); + ecbor_item_t tag = ecbor_tag(&bstr, 3); + EXPECT_EQ(ecbor_encode(ctx, &tag), ECBOR_OK); + }, + { 0xc3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, + { + "014", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_int(-1); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0x20 } + }, + { + "015", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_int(-10); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0x29 } + }, + { + "016", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_int(-100); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0x38, 0x63 } + }, + { + "017", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_int(-1000); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0x39, 0x03, 0xe7 } + }, + { + "021", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_fp64(1.1); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0xfb, 0x3f, 0xf1, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a } + }, + { + "024", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_fp32(1e5); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0xfa, 0x47, 0xc3, 0x50, 0x00 } + }, + { + "025", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_fp32(340282346638528859811704183484516925440.0f); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0xfa, 0x7f, 0x7f, 0xff, 0xff } + }, + { + "026", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_fp64(1000000000000000052504760255204420248704468581108159154915854115511802457988908195786371375080447864043704443832883878176942523235360430575644792184786706982848387200926575803737830233794788090059368953234970799945081119038967640880074652742780142494579258788820056842838115669472196386865459400540160.0); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0xfb, 0x7e, 0x37, 0xe4, 0x3c, 0x88, 0x00, 0x75, 0x9c } + }, + { + "030", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_fp64(-4.1); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0xfb, 0xc0, 0x10, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66 } + }, + { + "034", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_fp32(std::numeric_limits<float>::infinity()); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0xfa, 0x7f, 0x80, 0x00, 0x00 } + }, + { + "035", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_fp32(std::nanf("")); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0xfa, 0x7f, 0xc0, 0x00, 0x00 } + }, + { + "036", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_fp32(-std::numeric_limits<float>::infinity()); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0xfa, 0xff, 0x80, 0x00, 0x00 } + }, + { + "037", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_fp64(std::numeric_limits<double>::infinity()); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0xfb, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, + { + "038", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_fp64(std::nan("")); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0xfb, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, + { + "039", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_fp64(-std::numeric_limits<double>::infinity()); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0xfb, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, + { + "040", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_bool(0); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0xf4 } + }, + { + "041", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_bool(1); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0xf5 } + }, + { + "042", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_null(); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0xf6 } + }, + { + "043", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t item = ecbor_undefined(); + EXPECT_EQ(ecbor_encode(ctx, &item), ECBOR_OK); + }, + { 0xf7 } + }, + { + "047", + [](ecbor_encode_context_t* ctx) -> void { + std::string str_ = "2013-03-21T20:04:00Z"; + ecbor_item_t str = ecbor_str(str_.c_str(), str_.size()); + ecbor_item_t tag = ecbor_tag(&str, 0); + EXPECT_EQ(ecbor_encode(ctx, &tag), ECBOR_OK); + }, + { 0xc0, 0x74, 0x32, 0x30, 0x31, 0x33, 0x2d, 0x30, 0x33, 0x2d, 0x32, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x30, 0x34, 0x3a, 0x30, 0x30, 0x5a } + }, + { + "048", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t val = ecbor_uint(1363896240); + ecbor_item_t tag = ecbor_tag(&val, 1); + EXPECT_EQ(ecbor_encode(ctx, &tag), ECBOR_OK); + }, + { 0xc1, 0x1a, 0x51, 0x4b, 0x67, 0xb0 } + }, + { + "049", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t val = ecbor_fp64(1363896240.5); + ecbor_item_t tag = ecbor_tag(&val, 1); + EXPECT_EQ(ecbor_encode(ctx, &tag), ECBOR_OK); + }, + { 0xc1, 0xfb, 0x41, 0xd4, 0x52, 0xd9, 0xec, 0x20, 0x00, 0x00 } + }, + { + "050", + [](ecbor_encode_context_t* ctx) -> void { + std::vector<uint8_t> bstr_ = { 0x01, 0x02, 0x03, 0x04 }; + ecbor_item_t bstr = ecbor_bstr(bstr_.data(), bstr_.size()); + ecbor_item_t tag = ecbor_tag(&bstr, 23); + EXPECT_EQ(ecbor_encode(ctx, &tag), ECBOR_OK); + }, + { 0xd7, 0x44, 0x01, 0x02, 0x03, 0x04 } + }, + { + "051", + [](ecbor_encode_context_t* ctx) -> void { + std::vector<uint8_t> bstr_ = { 0x64, 0x49, 0x45, 0x54, 0x46 }; + ecbor_item_t bstr = ecbor_bstr(bstr_.data(), bstr_.size()); + ecbor_item_t tag = ecbor_tag(&bstr, 24); + EXPECT_EQ(ecbor_encode(ctx, &tag), ECBOR_OK); + }, + { 0xd8, 0x18, 0x45, 0x64, 0x49, 0x45, 0x54, 0x46 } + }, + { + "052", + [](ecbor_encode_context_t* ctx) -> void { + std::string str_ = "http://www.example.com"; + ecbor_item_t str = ecbor_str(str_.c_str(), str_.size()); + ecbor_item_t tag = ecbor_tag(&str, 32); + EXPECT_EQ(ecbor_encode(ctx, &tag), ECBOR_OK); + }, + { 0xd8, 0x20, 0x76, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d } + }, + { + "053", + [](ecbor_encode_context_t* ctx) -> void { + std::vector<uint8_t> bstr_ = {}; + ecbor_item_t bstr = ecbor_bstr(bstr_.data(), bstr_.size()); + EXPECT_EQ(ecbor_encode(ctx, &bstr), ECBOR_OK); + }, + { 0x40 } + }, + { + "054", + [](ecbor_encode_context_t* ctx) -> void { + std::vector<uint8_t> bstr_ = { 0x01, 0x02, 0x03, 0x04 }; + ecbor_item_t bstr = ecbor_bstr(bstr_.data(), bstr_.size()); + EXPECT_EQ(ecbor_encode(ctx, &bstr), ECBOR_OK); + }, + { 0x44, 0x01, 0x02, 0x03, 0x04 } + }, + { + "055", + [](ecbor_encode_context_t* ctx) -> void { + std::string str_ = ""; + ecbor_item_t str = ecbor_str(str_.c_str(), str_.size()); + EXPECT_EQ(ecbor_encode(ctx, &str), ECBOR_OK); + }, + { 0x60 } + }, + { + "056", + [](ecbor_encode_context_t* ctx) -> void { + std::string str_ = "a"; + ecbor_item_t str = ecbor_str(str_.c_str(), str_.size()); + EXPECT_EQ(ecbor_encode(ctx, &str), ECBOR_OK); + }, + { 0x61, 0x61 } + }, + { + "057", + [](ecbor_encode_context_t* ctx) -> void { + std::string str_ = "IETF"; + ecbor_item_t str = ecbor_str(str_.c_str(), str_.size()); + EXPECT_EQ(ecbor_encode(ctx, &str), ECBOR_OK); + }, + { 0x64, 0x49, 0x45, 0x54, 0x46 } + }, + { + "058", + [](ecbor_encode_context_t* ctx) -> void { + std::string str_ = "\"\\"; + ecbor_item_t str = ecbor_str(str_.c_str(), str_.size()); + EXPECT_EQ(ecbor_encode(ctx, &str), ECBOR_OK); + }, + { 0x62, 0x22, 0x5c } + }, + { + "059", + [](ecbor_encode_context_t* ctx) -> void { + std::string str_ = "ü"; + ecbor_item_t str = ecbor_str(str_.c_str(), str_.size()); + EXPECT_EQ(ecbor_encode(ctx, &str), ECBOR_OK); + }, + { 0x62, 0xc3, 0xbc } + }, + { + "060", + [](ecbor_encode_context_t* ctx) -> void { + std::string str_ = "水"; + ecbor_item_t str = ecbor_str(str_.c_str(), str_.size()); + EXPECT_EQ(ecbor_encode(ctx, &str), ECBOR_OK); + }, + { 0x63, 0xe6, 0xb0, 0xb4 } + }, + { + "061", + [](ecbor_encode_context_t* ctx) -> void { + std::string str_ = "𐅑"; + ecbor_item_t str = ecbor_str(str_.c_str(), str_.size()); + EXPECT_EQ(ecbor_encode(ctx, &str), ECBOR_OK); + }, + { 0x64, 0xf0, 0x90, 0x85, 0x91 } + }, + { + "062", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t arr; + EXPECT_EQ(ecbor_array(&arr, nullptr, 0), ECBOR_OK); + EXPECT_EQ(ecbor_encode(ctx, &arr), ECBOR_OK); + }, + { 0x80 } + }, + { + "063", + [](ecbor_encode_context_t* ctx) -> void { + std::vector<ecbor_item_t> items = { + ecbor_uint(1), + ecbor_uint(2), + ecbor_uint(3) + }; + ecbor_item_t arr; + EXPECT_EQ(ecbor_array(&arr, items.data(), items.size()), ECBOR_OK); + EXPECT_EQ(ecbor_encode(ctx, &arr), ECBOR_OK); + }, + { 0x83, 0x01, 0x02, 0x03 } + }, + { + "064", + [](ecbor_encode_context_t* ctx) -> void { + + std::vector<ecbor_item_t> i1items = { + ecbor_uint(2), + ecbor_uint(3) + }; + ecbor_item_t i1arr; + EXPECT_EQ(ecbor_array(&i1arr, i1items.data(), i1items.size()), ECBOR_OK); + + std::vector<ecbor_item_t> i2items = { + ecbor_uint(4), + ecbor_uint(5) + }; + ecbor_item_t i2arr; + EXPECT_EQ(ecbor_array(&i2arr, i2items.data(), i2items.size()), ECBOR_OK); + + std::vector<ecbor_item_t> items = { + ecbor_uint(1), + i1arr, + i2arr + }; + ecbor_item_t arr; + EXPECT_EQ(ecbor_array(&arr, items.data(), items.size()), ECBOR_OK); + EXPECT_EQ(ecbor_encode(ctx, &arr), ECBOR_OK); + }, + { 0x83, 0x01, 0x82, 0x02, 0x03, 0x82, 0x04, 0x05 } + }, + { + "065", + [](ecbor_encode_context_t* ctx) -> void { + std::vector<ecbor_item_t> items; + for (size_t i=1; i<=25; i++) { + items.push_back(ecbor_uint(i)); + } + ecbor_item_t arr; + EXPECT_EQ(ecbor_array(&arr, items.data(), items.size()), ECBOR_OK); + EXPECT_EQ(ecbor_encode(ctx, &arr), ECBOR_OK); + }, + { 0x98, 0x19, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x18, 0x18, 0x19 } + }, + { + "066", + [](ecbor_encode_context_t* ctx) -> void { + ecbor_item_t map; + EXPECT_EQ(ecbor_map(&map, nullptr, nullptr, 0), ECBOR_OK); + EXPECT_EQ(ecbor_encode(ctx, &map), ECBOR_OK); + }, + { 0xa0 } + }, + { + "067", + [](ecbor_encode_context_t* ctx) -> void { + std::vector<ecbor_item_t> keys = { + ecbor_uint(1), + ecbor_uint(3), + }; + std::vector<ecbor_item_t> vals = { + ecbor_uint(2), + ecbor_uint(4), + }; + EXPECT_EQ(keys.size(), vals.size()); + ecbor_item_t map; + + EXPECT_EQ(ecbor_map(&map, keys.data(), vals.data(), keys.size()), ECBOR_OK); + EXPECT_EQ(ecbor_encode(ctx, &map), ECBOR_OK); + }, + { 0xa2, 0x01, 0x02, 0x03, 0x04 } + }, + { + "068", + [](ecbor_encode_context_t* ctx) -> void { + std::string k1_ = "a"; + std::string k2_ = "b"; + std::vector<ecbor_item_t> keys = { + ecbor_str(k1_.c_str(), k1_.size()), + ecbor_str(k2_.c_str(), k2_.size()), + }; + + std::vector<ecbor_item_t> arr_ = { + ecbor_uint(2), + ecbor_uint(3), + }; + ecbor_item_t arr; + EXPECT_EQ(ecbor_array(&arr, arr_.data(), arr_.size()), ECBOR_OK); + + std::vector<ecbor_item_t> vals = { + ecbor_uint(1), + arr + }; + EXPECT_EQ(keys.size(), vals.size()); + + ecbor_item_t map; + EXPECT_EQ(ecbor_map(&map, keys.data(), vals.data(), keys.size()), ECBOR_OK); + EXPECT_EQ(ecbor_encode(ctx, &map), ECBOR_OK); + }, + { 0xa2, 0x61, 0x61, 0x01, 0x61, 0x62, 0x82, 0x02, 0x03 } + }, + { + "069", + [](ecbor_encode_context_t* ctx) -> void { + std::string k_ = "b"; + std::string v_ = "c"; + ecbor_item_t k = ecbor_str(k_.c_str(), k_.size()); + ecbor_item_t v = ecbor_str(v_.c_str(), v_.size()); + ecbor_item_t map; + EXPECT_EQ(ecbor_map(&map, &k, &v, 1), ECBOR_OK); + + std::string str_ = "a"; + std::vector<ecbor_item_t> arr_ = { + ecbor_str(str_.c_str(), str_.size()), + map + }; + ecbor_item_t arr; + EXPECT_EQ(ecbor_array(&arr, arr_.data(), arr_.size()), ECBOR_OK); + + EXPECT_EQ(ecbor_encode(ctx, &arr), ECBOR_OK); + }, + { 0x82, 0x61, 0x61, 0xa1, 0x61, 0x62, 0x61, 0x63 } + }, + { + "070", + [](ecbor_encode_context_t* ctx) -> void { + std::vector<std::string> keys_ = { "a", "b", "c", "d", "e" }; + std::vector<std::string> vals_ = { "A", "B", "C", "D", "E" }; + + std::vector<ecbor_item_t> keys; + for (auto& k_ : keys_) { + keys.push_back(ecbor_str(k_.c_str(), k_.size())); + } + std::vector<ecbor_item_t> vals; + for (auto& v_ : vals_) { + vals.push_back(ecbor_str(v_.c_str(), v_.size())); + } + + EXPECT_EQ(keys.size(), vals.size()); + ecbor_item_t map; + + EXPECT_EQ(ecbor_map(&map, keys.data(), vals.data(), keys.size()), ECBOR_OK); + EXPECT_EQ(ecbor_encode(ctx, &map), ECBOR_OK); + }, + { 0xa5, 0x61, 0x61, 0x61, 0x41, 0x61, 0x62, 0x61, 0x42, 0x61, 0x63, 0x61, 0x43, 0x61, 0x64, 0x61, 0x44, 0x61, 0x65, 0x61, 0x45 } + }, + /* encoding does not support indefinite strings, maps or arrays */ + }; + + size_t idx = 0; + for (auto& t : tests) { + std::cout << "Appendix A test " << std::get<0>(t) << " (index " << idx << ")" << std::endl; + run_encoder_test_normal(std::get<1>(t), std::get<2>(t)); + idx ++; + } +} |
