Files
pvxs/test/testpvreq.cpp
T
Michael Davidsaver 4d7ca87f8a pvRequest parsing
2020-03-02 15:37:43 -08:00

207 lines
4.4 KiB
C++

/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* pvxs is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <atomic>
#include <testMain.h>
#include <epicsUnitTest.h>
#include <epicsEvent.h>
#include <pvxs/unittest.h>
#include <pvxs/log.h>
#include <pvxs/client.h>
#include "utilpvt.h"
namespace {
using namespace pvxs;
struct TestBuilder : client::detail::CommonBuilder<TestBuilder>
{
TestBuilder()
:client::detail::CommonBuilder<TestBuilder>(nullptr, "")
{}
Value makeReq() const {
return _build();
}
};
void testEmpty()
{
testShow()<<__func__;
auto req = TestBuilder().makeReq();
testShow()<<req;
testEq(std::string(SB()<<"\n"<<req), R"out(
struct {
struct {
} field
}
)out");
}
void testAssemble()
{
testShow()<<__func__;
auto req = TestBuilder()
.field("foo")
.field("bar.baz")
.record("abc", "xyz")
.record("pipeline", true)
.makeReq();
testShow()<<req;
testEq(std::string(SB()<<"\n"<<req), R"out(
struct {
struct {
struct {
} foo
struct {
struct {
} baz
} bar
} fields
struct {
struct {
string abc = "xyz"
bool pipeline = true
} _options
} record
}
)out");
}
void testParse1()
{
testShow()<<__func__;
auto req = TestBuilder()
.pvRequest("field(foo)field(bar.baz)record[abc=xyz]record[pipeline=true]")
.makeReq();
testShow()<<req;
testEq(std::string(SB()<<"\n"<<req), R"out(
struct {
struct {
struct {
} foo
struct {
struct {
} baz
} bar
} fields
struct {
struct {
string abc = "xyz"
string pipeline = "true"
} _options
} record
}
)out");
}
void testParse2()
{
testShow()<<__func__;
auto req = TestBuilder()
.pvRequest("field(foo,bar.baz)record[abc=xyz,pipeline=true]")
.makeReq();
testShow()<<req;
testEq(std::string(SB()<<"\n"<<req), R"out(
struct {
struct {
struct {
} foo
struct {
struct {
} baz
} bar
} fields
struct {
struct {
string abc = "xyz"
string pipeline = "true"
} _options
} record
}
)out");
}
void testValid()
{
testShow()<<__func__;
std::vector<std::string> valid({
"field()",
"field(a,b,a.b)field(x)",
"a", // short-hand
"field(a,b,a.b)field(x)",
// should these be valid?
"field(,)",
"field(foo,)",
"record[foo=bar,]",
});
for(auto& pvr : valid) {
try {
testCase(true)<<pvr<<"\n"<<TestBuilder().pvRequest(pvr).makeReq();
}catch(std::exception& e){
testCase(false)<<pvr<<" : "<<typeid(e).name()<<" : "<<e.what();
}
}
}
void testError()
{
testShow()<<__func__;
std::vector<std::string> errors({
"field(",
"field(value",
"field(value,alarm",
"field[]",
"record()",
"field(!@#)",
"record[",
"record[key",
"record[key=",
"record[key=]",
"record[,]",
});
for(auto& pvr : errors) {
testThrows<std::runtime_error>([&pvr](){
auto req = TestBuilder()
.pvRequest(pvr)
.makeReq();
testShow()<<req;
})<<pvr;
}
}
} // namespace
MAIN(testpvreq)
{
testPlan(22);
logger_config_env();
testEmpty();
testAssemble();
testParse1();
testParse2();
testValid();
testError();
cleanup_for_valgrind();
return testDone();
}