unit testing for OSC
This commit is contained in:
parent
706fe5a3f9
commit
34d74375cc
|
@ -11,6 +11,7 @@ if (GTest_FOUND)
|
|||
target_link_libraries(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
GTest::gtest
|
||||
LCP::OSC
|
||||
LCP::RDM
|
||||
LCP::UUID
|
||||
LCP::sACN
|
||||
|
|
|
@ -0,0 +1,311 @@
|
|||
/*
|
||||
test_osc.cpp
|
||||
|
||||
Copyright (c) 2023 Kevin Matz (kevin.matz@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <message.h>
|
||||
#include <method.h>
|
||||
|
||||
/// \cite Spec10 First example OSC-String
|
||||
const uint8_t string1_data[] = {
|
||||
'O', 'S', 'C', 0x00, // OSC
|
||||
};
|
||||
|
||||
/// \cite Spec10 Second example OSC-String
|
||||
const uint8_t string2_data[] = {
|
||||
'd', 'a', 't', 'a', // data
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
std::string tag1_string = ",f"; //!< \cite Spec10 First example Type Tag
|
||||
std::string tag2_string = ",iisfff"; //!< \cite Spec10 Second example Type Tag
|
||||
std::string tag3_string = ","; //!< \cite Spec10 Third example Type Tag
|
||||
std::string tag4_string = ",ibb"; //!< \cite Spec10 Fourth example Type Tag
|
||||
|
||||
std::string address1_string = "/resonators/3/frequency"; //!< \cite Spec10 First example address
|
||||
std::string address2_string = "/a/b/c/d/e"; //!< \cite Spec10 Second example address
|
||||
|
||||
/// \cite Spec10 First example Message
|
||||
const uint8_t message1_data[] = {
|
||||
0x2f, 0x6f, 0x73, 0x63, // /osc
|
||||
0x69, 0x6c, 0x6c, 0x61, // illa
|
||||
0x74, 0x6f, 0x72, 0x2f, // tor/
|
||||
0x34, 0x2f, 0x66, 0x72, // 4/fr
|
||||
0x65, 0x71, 0x75, 0x65, // eque
|
||||
0x6e, 0x63, 0x79, 0x00, // ncy
|
||||
0x2c, 0x66, 0x00, 0x00, // ,f
|
||||
0x43, 0xdc, 0x00, 0x00, // 440.0
|
||||
};
|
||||
|
||||
/// \cite Spec10 Second example Message
|
||||
const uint8_t message2_data[] = {
|
||||
0x2f, 0x66, 0x6f, 0x6f, // /foo
|
||||
0x00, 0x00, 0x00, 0x00, //
|
||||
0x2c, 0x69, 0x69, 0x73, // ,iis
|
||||
0x66, 0x66, 0x00, 0x00, // ff
|
||||
0x00, 0x00, 0x03, 0xe8, // 1000
|
||||
0xff, 0xff, 0xff, 0xff, // -1
|
||||
0x68, 0x65, 0x6c, 0x6c, // hell
|
||||
0x6f, 0x00, 0x00, 0x00, // o
|
||||
0x3f, 0x9d, 0xf3, 0xb6, // 1.234
|
||||
0x40, 0xb5, 0xb2, 0x2d, // 5.678
|
||||
};
|
||||
|
||||
|
||||
TEST(OSC, int_in)
|
||||
{
|
||||
uint8_t value1_data[] = { 0x00, 0x00, 0x03, 0xe8 }; // 1000
|
||||
uint8_t value2_data[] = { 0xff, 0xff, 0xff, 0xff }; // -1
|
||||
auto stream1 = std::make_shared<bufferstream>(value1_data, sizeof(value1_data));
|
||||
auto stream2 = std::make_shared<bufferstream>(value2_data, sizeof(value2_data));
|
||||
OSC::int32 value1;
|
||||
OSC::int32 value2;
|
||||
value1.iStream(stream1);
|
||||
value2.iStream(stream2);
|
||||
EXPECT_FALSE(stream1->fail()) << "message 1 stream failed";
|
||||
EXPECT_FALSE(stream2->fail()) << "message 2 stream failed";
|
||||
EXPECT_EQ(value1.value, 1000) << "message 1 value mismatch";
|
||||
EXPECT_EQ(value2.value, -1) << "message 2 value mismatch";
|
||||
}
|
||||
|
||||
|
||||
TEST(OSC, int_out)
|
||||
{
|
||||
uint8_t value1_data[] = { 0x00, 0x00, 0x03, 0xe8 }; // 1000
|
||||
uint8_t value2_data[] = { 0xff, 0xff, 0xff, 0xff }; // -1
|
||||
uint8_t buffer1[sizeof(value1_data)] = {0xff};
|
||||
uint8_t buffer2[sizeof(value2_data)] = {0xff};
|
||||
auto stream1 = std::make_shared<bufferstream>(buffer1, sizeof(buffer1));
|
||||
auto stream2 = std::make_shared<bufferstream>(buffer2, sizeof(buffer2));
|
||||
OSC::int32 value1(1000);
|
||||
OSC::int32 value2(-1);
|
||||
value1.oStream(stream1);
|
||||
value2.oStream(stream2);
|
||||
EXPECT_FALSE(stream1->fail()) << "value 1 stream failed";
|
||||
EXPECT_FALSE(stream2->fail()) << "value 2 stream failed";
|
||||
EXPECT_EQ(value1.streamSize(), sizeof(value1_data)) << "value 1 length mismatch";
|
||||
EXPECT_EQ(value2.streamSize(), sizeof(value2_data)) << "value 2 length mismatch";
|
||||
EXPECT_EQ(memcmp(buffer1, value1_data, sizeof(buffer1)), 0) << "value 1 output mismatch";
|
||||
EXPECT_EQ(memcmp(buffer2, value2_data, sizeof(buffer2)), 0) << "value 2 output mismatch";
|
||||
}
|
||||
|
||||
|
||||
TEST(OSC, float_in)
|
||||
{
|
||||
uint8_t value1_data[] = { 0x3f, 0x9d, 0xf3, 0xb6 }; // 1.234
|
||||
uint8_t value2_data[] = { 0x40, 0xb5, 0xb2, 0x2d }; // 5.678
|
||||
auto stream1 = std::make_shared<bufferstream>(value1_data, sizeof(value1_data));
|
||||
auto stream2 = std::make_shared<bufferstream>(value2_data, sizeof(value2_data));
|
||||
OSC::float32 value1;
|
||||
OSC::float32 value2;
|
||||
value1.iStream(stream1);
|
||||
value2.iStream(stream2);
|
||||
EXPECT_FALSE(stream1->fail()) << "message 1 stream failed";
|
||||
EXPECT_FALSE(stream2->fail()) << "message 2 stream failed";
|
||||
EXPECT_FLOAT_EQ(value1.value, 1.234) << "message 1 value mismatch";
|
||||
EXPECT_FLOAT_EQ(value2.value, 5.678) << "message 2 value mismatch";
|
||||
}
|
||||
|
||||
|
||||
TEST(OSC, float_out)
|
||||
{
|
||||
uint8_t value1_data[] = { 0x3f, 0x9d, 0xf3, 0xb6 }; // 1.234
|
||||
uint8_t value2_data[] = { 0x40, 0xb5, 0xb2, 0x2d }; // 5.678
|
||||
uint8_t buffer1[sizeof(value1_data)] = {0xff};
|
||||
uint8_t buffer2[sizeof(value2_data)] = {0xff};
|
||||
auto stream1 = std::make_shared<bufferstream>(buffer1, sizeof(buffer1));
|
||||
auto stream2 = std::make_shared<bufferstream>(buffer2, sizeof(buffer2));
|
||||
OSC::float32 value1((float)1.234);
|
||||
OSC::float32 value2((float)5.678);
|
||||
value1.oStream(stream1);
|
||||
value2.oStream(stream2);
|
||||
EXPECT_FALSE(stream1->fail()) << "value 1 stream failed";
|
||||
EXPECT_FALSE(stream2->fail()) << "value 2 stream failed";
|
||||
EXPECT_EQ(value1.streamSize(), sizeof(value1_data)) << "value 1 length mismatch";
|
||||
EXPECT_EQ(value2.streamSize(), sizeof(value2_data)) << "value 2 length mismatch";
|
||||
EXPECT_EQ(memcmp(buffer1, value1_data, sizeof(buffer1)), 0) << "value 1 output mismatch";
|
||||
EXPECT_EQ(memcmp(buffer2, value2_data, sizeof(buffer2)), 0) << "value 2 output mismatch";
|
||||
}
|
||||
|
||||
|
||||
TEST(OSC, string_in)
|
||||
{
|
||||
EXPECT_FALSE(sizeof(string1_data) %4) << "string_1 data is not 32-bit aligned";
|
||||
EXPECT_FALSE(sizeof(string2_data) %4) << "string_2 data is not 32-bit aligned";
|
||||
|
||||
OSC::string string1;
|
||||
OSC::string string2;
|
||||
uint8_t buffer1[sizeof(string1_data)];
|
||||
uint8_t buffer2[sizeof(string2_data)];
|
||||
std::copy(std::begin(string1_data),std::end(string1_data), std::begin(buffer1));
|
||||
std::copy(std::begin(string2_data),std::end(string2_data), std::begin(buffer2));
|
||||
auto stream1 = std::make_shared<bufferstream>(buffer1, sizeof(buffer1));
|
||||
auto stream2 = std::make_shared<bufferstream>(buffer2, sizeof(buffer2));
|
||||
string1.iStream(stream1);
|
||||
string2.iStream(stream2);
|
||||
|
||||
EXPECT_FALSE(stream1->fail()) << "string 1 stream failed";
|
||||
EXPECT_FALSE(stream2->fail()) << "string 2 stream failed";
|
||||
EXPECT_EQ(string1.streamSize(), sizeof(string1_data)) << "string_1 data length mismatch";
|
||||
EXPECT_EQ(string2.streamSize(), sizeof(string2_data)) << "string_2 data length mismatch";
|
||||
EXPECT_STREQ(string1.value.c_str(), "OSC") << "string_1 value mismatch";
|
||||
EXPECT_STREQ(string2.value.c_str(), "data") << "string_2 value mismatch";
|
||||
}
|
||||
|
||||
|
||||
TEST(OSC, string_out)
|
||||
{
|
||||
OSC::string string1;
|
||||
OSC::string string2;
|
||||
string1.value = "OSC";
|
||||
string2.value = "data";
|
||||
|
||||
EXPECT_EQ(string1.streamSize(), sizeof(string1_data)) << "string_1 data length mismatch";
|
||||
EXPECT_EQ(string2.streamSize(), sizeof(string2_data)) << "string_2 data length mismatch";
|
||||
|
||||
uint8_t buffer1[sizeof(string1_data)] = {0xff};
|
||||
uint8_t buffer2[sizeof(string2_data)] = {0xff};
|
||||
auto stream1 = std::make_shared<bufferstream>(buffer1, sizeof(buffer1));
|
||||
auto stream2 = std::make_shared<bufferstream>(buffer2, sizeof(buffer2));
|
||||
string1.oStream(stream1);
|
||||
string2.oStream(stream2);
|
||||
|
||||
EXPECT_FALSE(stream1->fail()) << "string 1 stream failed";
|
||||
EXPECT_FALSE(stream2->fail()) << "string 2 stream failed";
|
||||
EXPECT_EQ(memcmp(string1_data, buffer1, sizeof(buffer1)), 0) << "string_1 output mismatch";
|
||||
EXPECT_EQ(memcmp(string2_data, buffer2, sizeof(buffer2)), 0) << "string_2 output mismatch";
|
||||
}
|
||||
|
||||
|
||||
TEST(OSC, tags_in)
|
||||
{
|
||||
std::string tag5_string = ",f[ii[ss]]";
|
||||
|
||||
auto tags1 = OSC::Message::createArguments(tag1_string);
|
||||
auto tags2 = OSC::Message::createArguments(tag2_string);
|
||||
auto tags3 = OSC::Message::createArguments(tag3_string);
|
||||
auto tags4 = OSC::Message::createArguments(tag4_string);
|
||||
auto tags5 = OSC::Message::createArguments(tag5_string);
|
||||
|
||||
EXPECT_EQ(tags1.size(), 1) << "tag string 1: count mismatch";
|
||||
EXPECT_EQ(tags2.size(), 6) << "tag string 2: count mismatch";
|
||||
EXPECT_EQ(tags3.size(), 0) << "tag string 3: count mismatch";
|
||||
EXPECT_EQ(tags4.size(), 3) << "tag string 4: count mismatch";
|
||||
EXPECT_STREQ(tags4.back()->type().c_str(), "b") << "tag string 4: blob not matched";
|
||||
EXPECT_EQ(tags5.size(), 2) << "tag string 5: count mismatch";
|
||||
EXPECT_STREQ(tags5.back()->type().c_str(), "[ii[ss]]") << "tag string 5: array(s) not matched";
|
||||
}
|
||||
|
||||
TEST(OSC, address)
|
||||
{
|
||||
auto *root = new OSC::Method();
|
||||
EXPECT_FALSE(root->setName("\{}")) << "set invalid method name";
|
||||
EXPECT_FALSE(root->setName("\[]")) << "set invalid method name";
|
||||
|
||||
auto *method1 = new OSC::Method(new OSC::Method(new OSC::Method(root,
|
||||
"resonators"),
|
||||
"3"),
|
||||
"frequency");
|
||||
auto *method2 = new OSC::Method(new OSC::Method(new OSC::Method(new OSC::Method(new OSC::Method(root,
|
||||
"a"),
|
||||
"b"),
|
||||
"c"),
|
||||
"d"),
|
||||
"e");
|
||||
EXPECT_STREQ(address1_string.c_str(), method1->address().c_str()) << "address 1 not matched";
|
||||
EXPECT_STREQ(address2_string.c_str(), method2->address().c_str()) << "address 2 not matched";
|
||||
delete root;
|
||||
}
|
||||
|
||||
|
||||
TEST(OSC, message_in)
|
||||
{
|
||||
EXPECT_FALSE(sizeof(message1_data) %4) << "message_1 data is not 32-bit aligned";
|
||||
EXPECT_FALSE(sizeof(message2_data) %4) << "message_2 data is not 32-bit aligned";
|
||||
|
||||
OSC::Message message1;
|
||||
OSC::Message message2;
|
||||
uint8_t buffer1[sizeof(message1_data)];
|
||||
uint8_t buffer2[sizeof(message2_data)];
|
||||
std::copy(std::begin(message1_data),std::end(message1_data), std::begin(buffer1));
|
||||
std::copy(std::begin(message2_data),std::end(message2_data), std::begin(buffer2));
|
||||
auto stream1 = std::make_shared<bufferstream>(buffer1, sizeof(buffer1));
|
||||
auto stream2 = std::make_shared<bufferstream>(buffer2, sizeof(buffer2));
|
||||
message1.iStream(stream1);
|
||||
message2.iStream(stream2);
|
||||
|
||||
EXPECT_FALSE(message1.streamSize() %4) << "Message 1 data size misaligned";
|
||||
EXPECT_FALSE(message2.streamSize() %4) << "Message 2 data size misaligned";
|
||||
|
||||
EXPECT_EQ(message1.streamSize(), sizeof(message1_data)) << "message 1 data size mismatch";
|
||||
EXPECT_EQ(message2.streamSize(), sizeof(message2_data)) << "message 2 data size mismatch";
|
||||
|
||||
EXPECT_FALSE(stream1->fail()) << "message 1 stream failed";
|
||||
EXPECT_FALSE(stream2->fail()) << "message 2 stream failed";
|
||||
|
||||
EXPECT_STREQ(message1.address_pattern.c_str(), "/oscillator/4/frequency") << "message 1: address mismatch";
|
||||
EXPECT_STREQ(message2.address_pattern.c_str(), "/foo") << "message 2: address mismatch";
|
||||
|
||||
EXPECT_STREQ(message1.type_tag().c_str(), ",f") << "message 1: type mismatch";
|
||||
EXPECT_STREQ(message2.type_tag().c_str(), ",iisff") << "message 2: type mismatch";
|
||||
|
||||
auto arg = std::static_pointer_cast<OSC::float32>(message1.arguments.front());
|
||||
EXPECT_FLOAT_EQ(arg->value, (float)440.0) << "message 1: value mismatch";
|
||||
}
|
||||
|
||||
TEST(OSC, message_out)
|
||||
{
|
||||
OSC::Message message1;
|
||||
message1.address_pattern = "/oscillator/4/frequency";
|
||||
message1.addArgument((float)440.0);
|
||||
|
||||
OSC::Message message2;
|
||||
message2.address_pattern = "/foo";
|
||||
message2.addArgument((int)1000);
|
||||
message2.addArgument((int)-1);
|
||||
message2.addArgument(std::string("hello"));
|
||||
message2.addArgument((float)1.234);
|
||||
message2.addArgument((float)5.678);
|
||||
|
||||
EXPECT_FALSE(message1.streamSize() %4) << "Message 1 data size misaligned";
|
||||
EXPECT_FALSE(message2.streamSize() %4) << "Message 2 data size misaligned";
|
||||
EXPECT_EQ(message1.streamSize(), sizeof(message1_data)) << "message 1 data size mismatch";
|
||||
EXPECT_EQ(message2.streamSize(), sizeof(message2_data)) << "message 2 data size mismatch";
|
||||
|
||||
EXPECT_STREQ(message1.type_tag().c_str(), ",f") << "message 1 type tag mismatch";
|
||||
EXPECT_STREQ(message2.type_tag().c_str(), ",iisff") << "message 2 type tag mismatch";
|
||||
|
||||
uint8_t buffer1[sizeof(message1_data)];
|
||||
uint8_t buffer2[sizeof(message2_data)];
|
||||
auto stream1 = std::make_shared<bufferstream>(buffer1, sizeof(buffer1));
|
||||
auto stream2 = std::make_shared<bufferstream>(buffer2, sizeof(buffer2));
|
||||
|
||||
message1.oStream(stream1);
|
||||
message2.oStream(stream2);
|
||||
|
||||
EXPECT_FALSE(stream1->fail()) << "message 1 stream failed";
|
||||
EXPECT_FALSE(stream2->fail()) << "message 2 stream failed";
|
||||
|
||||
EXPECT_EQ(memcmp(buffer1, message1_data, sizeof(buffer1)), 0) << "message 1 output mismatch";
|
||||
EXPECT_EQ(memcmp(buffer2, message2_data, sizeof(buffer2)), 0) << "message 2 output mismatch";
|
||||
}
|
Loading…
Reference in New Issue