#include #include "../c++/data.hpp" #include "../c++/id_map.hpp" #include "../c++/simple.hpp" #include "../c++/interface.hpp" #include namespace { namespace schema { using namespace saw::schema; using ZeroDimArray = Array; using OneDimArray = Array; using TwoDimArray = Array; using ThreeDimArray = Array; using TestStruct = Struct< Member, Member >; using TestUnion = Union< Member, Member >; using TestSameTypeUnion = Union< Member, Member >; using TestTuple = Tuple< TwoDimArray, UInt64 >; using TestInt32Pair = Tuple< Int32, Int32 >; using TestVoidReturnFunction = Function; using TestCalcFunction = Function; using TestInterface = Interface< Member, Member, Member, Member >; } SAW_TEST("One Dimensional Array") { using namespace saw; data arr{500u}; int bar = 0; for(size_t i = 0; i < arr.get_dim_size(0); ++i){ arr.at(i).set(bar++); } int sum = 0; for(size_t i = 0; i < arr.get_dim_size(0); ++i){ sum += arr.at(i).get(); } SAW_EXPECT(sum == 124750, std::to_string(sum) + " is not 124750. Expected that data stays correct"); } SAW_TEST("One dim Array Default init"){ using namespace saw; data arr; SAW_EXPECT(arr.get_dim_size(0) == 0, "Dim should be size 0"); SAW_EXPECT(arr.size() == 0, "Total size should also be zero"); } SAW_TEST("One dimensional Array Add"){ using namespace saw; data arr{5u}; int bar = 0; for(size_t i = 0; i < arr.get_dim_size(0); ++i){ arr.at(i).set(bar++); } arr.add(7); SAW_EXPECT(arr.size() == 6u, "Array size is not 6u. Expected that data stays correct"); SAW_EXPECT(arr.at(5u).get() == 7, "Array at 5u is not 7. Expected that data stays correct"); } SAW_TEST("Two Dimensional Array") { using namespace saw; data arr{10,30u}; int expected_sum = (300 * 301) / 2; int bar = 0; for(size_t i = 0; i < arr.get_dim_size(0); ++i){ for(size_t j = 0; j < arr.get_dim_size(1); ++j){ ++bar; arr.at(i,j).set(bar); } } int sum = 0; for(size_t i = 0; i < arr.get_dim_size(0); ++i){ for(size_t j = 0; j < arr.get_dim_size(1); ++j){ sum += arr.at(i,j).get(); } } SAW_EXPECT(sum == expected_sum, std::to_string(sum) + " is not "+ std::to_string(expected_sum) + ". Expected that data stays correct"); } SAW_TEST("Three Dimensional Array") { using namespace saw; data arr{10,10u,3}; int expected_sum = (300 * 301) / 2; int bar = 0; for(size_t i = 0; i < arr.get_dim_size(0); ++i){ for(size_t j = 0; j < arr.get_dim_size(1); ++j){ for(size_t k = 0; k < arr.get_dim_size(2); ++k){ ++bar; arr.at(i,j,k).set(bar); } } } int sum = 0; for(size_t i = 0; i < arr.get_dim_size(0); ++i){ for(size_t j = 0; j < arr.get_dim_size(1); ++j){ for(size_t k = 0; k < arr.get_dim_size(2); ++k){ sum += arr.at(i,j,k).get(); } } } SAW_EXPECT(sum == expected_sum, std::to_string(sum) + " is not "+ std::to_string(expected_sum) + ". Expected that data stays correct"); } SAW_TEST("KelSimple UInt16 write"){ using namespace saw; data native; data simple; codec codec; auto& buff = simple.get_buffer(); for(uint16_t i = 0; i < 256; ++i){ for(uint16_t j = 0; j < 256; ++j){ native.set(i + j * 256); error_or eov = codec.encode(native, simple); SAW_EXPECT(eov.is_value(), "Encoding error"); SAW_EXPECT(buff.read_composite_length() == 2, "Written incorrect size"); SAW_EXPECT((buff.read(0) == i && buff.read(1) == j), std::string{"Incorrect values in encoding: "} + std::to_string(static_cast(buff.read(0))) + " " + std::to_string(static_cast(buff.read(1)))); buff.read_advance(2); } } } SAW_TEST("KelSimple UInt32 write"){ using namespace saw; data native; data simple; codec codec; auto& buff = simple.get_buffer(); for(uint16_t i = 0; i < 256; ++i){ for(uint16_t j = 0; j < 256; ++j){ native.set(i + j * 256 * 256); error_or eov = codec.encode(native, simple); SAW_EXPECT(eov.is_value(), "Encoding error"); SAW_EXPECT(buff.read_composite_length() == 4, "Written incorrect size"); SAW_EXPECT((buff.read(0) == i && buff.read(1) == 0 && buff.read(2) == j && buff.read(3) == 0), std::string{"Incorrect values in encoding: "} + std::to_string(static_cast(buff.read(0))) + " " + std::to_string(static_cast(buff.read(1)))); buff.read_advance(4); } } } SAW_TEST("KelSimple Array write and read back"){ using namespace saw; data native{2,3}; data simple; codec codec; for(std::size_t i = 0; i < 2; ++i) { for(std::size_t j = 0; j < 3; ++j){ native.at(i,j).set(i+2*j); } } auto eov = codec.encode(native,simple); SAW_EXPECT(eov.is_value(), "Encoding error"); for(std::size_t i = 0; i < 2; ++i) { for(std::size_t j = 0; j < 3; ++j){ native.at(i,j).set(0); } } eov = codec.decode(simple, native); SAW_EXPECT(eov.is_value(), "Decoding error"); for(std::size_t i = 0; i < 2; ++i) { for(std::size_t j = 0; j < 3; ++j){ SAW_EXPECT(native.at(i,j).get() == static_cast(i+2*j), "Values incorrectly decoded"); } } } SAW_TEST("KelSimple Struct write and read back"){ using namespace saw; data native; data simple; auto& tda = native.template get<"two_dim_array">(); tda = {1,2}; tda.at(0,0).set(5); tda.at(0,1).set(3); native.template get<"number">().set(410); codec codec; auto eov = codec.encode(native, simple); SAW_EXPECT(eov.is_value(), "Encoding error"); // Reset values native = {}; eov = codec.decode(simple, native); SAW_EXPECT(eov.is_value(), "Decoding error"); auto& dec_tda = native.template get<"two_dim_array">(); SAW_EXPECT(dec_tda.at(0,0).get() == 5, "Incorrect Decoding in array 0,0"); SAW_EXPECT(dec_tda.at(0,1).get() == 3, "Incorrect Decoding in array 0,1"); SAW_EXPECT(native.template get<"number">().get() == 410, "Incorrect Decoding in number"); } SAW_TEST("Native Union same type compilation"){ using namespace saw; data native; native.template init<"two">().set(50u); SAW_EXPECT(!native.template holds_alternative<"one">(), "Two should be initialized"); SAW_EXPECT(native.template holds_alternative<"two">(), "Two should be initialized"); SAW_EXPECT(native.template get<"two">().get() == 50u, "Should be 50"); } SAW_TEST("KelSimple Union write and read back"){ using namespace saw; data native; data simple; native.template set<"number">(data{}); native.template get<"number">().set(410); codec codec; auto eov = codec.encode(native, simple); SAW_EXPECT(eov.is_value(), "Encoding error"); // Reset values native = {}; eov = codec.decode(simple, native); SAW_EXPECT(eov.is_value(), "Decoding error"); SAW_EXPECT(native.template holds_alternative<"number">(), "Incorrect Decoding in array 0,1"); SAW_EXPECT(native.template get<"number">().get() == 410, "Incorrect Decoding in number"); } SAW_TEST("KelSimple Tuple write and read back"){ using namespace saw; data native; data simple; auto& tda = native.template get<0>(); tda = {1,2}; tda.at(0,0).set(5); tda.at(0,1).set(3); native.template get<1>().set(410); codec codec; auto eov = codec.encode(native, simple); SAW_EXPECT(eov.is_value(), "Encoding error"); // Reset values native = {}; eov = codec.decode(simple, native); SAW_EXPECT(eov.is_value(), "Decoding error"); auto& dec_tda = native.template get<0>(); SAW_EXPECT(dec_tda.at(0,0).get() == 5, "Incorrect Decoding in array 0,0"); SAW_EXPECT(dec_tda.at(0,1).get() == 3, "Incorrect Decoding in array 0,1"); SAW_EXPECT(native.template get<1>().get() == 410, "Incorrect Decoding in number"); } SAW_TEST("KelSimple String write and read back"){ using namespace saw; data native; data simple; std::string str = "FooBananaJoe"; native.set(str); codec codec; auto eov = codec.encode(native, simple); SAW_EXPECT(eov.is_value(), "Encoding error"); // Reset values native = {}; eov = codec.decode(simple, native); SAW_EXPECT(eov.is_value(), "Decoding error"); SAW_EXPECT(native == str, "String should've been decoded back correctly"); } SAW_TEST("Function basics"){ using namespace saw; { data native; native.get<0>().set(5); native.get<1>().set(40); auto func_add = function_factory::create( [](data req){ data resp; resp.set(req.get<0>().get() + req.get<1>().get()); return resp; } ); auto eov = func_add.call(native); SAW_EXPECT(eov.is_value(), "Returned value is an error"); auto& val = eov.get_value(); SAW_EXPECT(val.get() == 45, "Sum is incorrect"); } } SAW_TEST("Interface basics"){ using namespace saw; data native; auto func_add = [](data& req){ data resp; resp.set(req.get<0>().get() + req.get<1>().get()); return resp; }; auto func_sub = [](data& req){ data resp; resp.set(req.get<0>().get() - req.get<1>().get()); return resp; }; auto func_multiply = [](data& req){ data resp; resp.set(req.get<0>().get() * req.get<1>().get()); return resp; }; auto func_void = [](data& req) -> error_or { (void) req; return void_t{}; }; auto iface = interface_factory::create(std::move(func_add), std::move(func_sub), std::move(func_multiply), std::move(func_void)); { data native; native.get<0>().set(5); native.get<1>().set(40); auto eov = iface.template call<"add">(native); SAW_EXPECT(eov.is_value(), "Returned value is an error"); auto& val = eov.get_value(); SAW_EXPECT(val.get() == 45, "Sum is incorrect"); } { data native; native.get<0>().set(5); native.get<1>().set(40); auto eov = iface.template call<"sub">(native); SAW_EXPECT(eov.is_value(), "Returned value is an error"); auto& val = eov.get_value(); SAW_EXPECT(val.get() == -35, "Sum is incorrect"); } { data native; native.get<0>().set(5); native.get<1>().set(40); auto eov = iface.template call<"multiply">(native); SAW_EXPECT(eov.is_value(), "Returned value is an error"); auto& val = eov.get_value(); SAW_EXPECT(val.get() == 200, "Sum is incorrect"); } } }