241 lines
7.8 KiB
C++
241 lines
7.8 KiB
C++
/**
|
|
* @file apply_test.cpp
|
|
* @author Nat Goodspeed
|
|
* @date 2022-12-19
|
|
* @brief Test for apply.
|
|
*
|
|
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
|
* Copyright (c) 2022, Linden Research, Inc.
|
|
* $/LicenseInfo$
|
|
*/
|
|
|
|
// Precompiled header
|
|
#include "linden_common.h"
|
|
// associated header
|
|
#include "apply.h"
|
|
// STL headers
|
|
// std headers
|
|
#include <iomanip>
|
|
// external library headers
|
|
// other Linden headers
|
|
#include "llsd.h"
|
|
#include "llsdutil.h"
|
|
#include <array>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
// for ensure_equals
|
|
std::ostream& operator<<(std::ostream& out, const std::vector<std::string>& stringvec)
|
|
{
|
|
const char* delim = "[";
|
|
for (const auto& str : stringvec)
|
|
{
|
|
out << delim << std::quoted(str);
|
|
delim = ", ";
|
|
}
|
|
return out << ']';
|
|
}
|
|
|
|
// the above must be declared BEFORE ensure_equals(std::vector<std::string>)
|
|
#include "../test/lltut.h"
|
|
|
|
/*****************************************************************************
|
|
* TUT
|
|
*****************************************************************************/
|
|
namespace tut
|
|
{
|
|
namespace statics
|
|
{
|
|
/*------------------------------ data ------------------------------*/
|
|
// Although we're using types from the LLSD namespace, we're not
|
|
// constructing LLSD values, but rather instances of the C++ types
|
|
// supported by LLSD.
|
|
static LLSD::Boolean b{true};
|
|
static LLSD::Integer i{17};
|
|
static LLSD::Real f{3.14};
|
|
static LLSD::String s{ "hello" };
|
|
static LLSD::UUID uu{ "baadf00d-dead-beef-baad-feedb0ef" };
|
|
static LLSD::Date dt{ "2022-12-19" };
|
|
static LLSD::URI uri{ "http://secondlife.com" };
|
|
static LLSD::Binary bin{ 0x01, 0x02, 0x03, 0x04, 0x05 };
|
|
|
|
static std::vector<LLSD::String> quick
|
|
{
|
|
"The", "quick", "brown", "fox", "etc."
|
|
};
|
|
|
|
static std::array<int, 5> fibs
|
|
{
|
|
0, 1, 1, 2, 3
|
|
};
|
|
|
|
// ensure that apply() actually reaches the target method --
|
|
// lack of ensure_equals() failure could be due to no-op apply()
|
|
bool called{ false };
|
|
// capture calls from collect()
|
|
std::vector<std::string> collected;
|
|
|
|
/*------------------------- test functions -------------------------*/
|
|
void various(LLSD::Boolean b, LLSD::Integer i, LLSD::Real f, const LLSD::String& s,
|
|
const LLSD::UUID& uu, const LLSD::Date& dt,
|
|
const LLSD::URI& uri, const LLSD::Binary& bin)
|
|
{
|
|
called = true;
|
|
ensure_equals( "b mismatch", b, statics::b);
|
|
ensure_equals( "i mismatch", i, statics::i);
|
|
ensure_equals( "f mismatch", f, statics::f);
|
|
ensure_equals( "s mismatch", s, statics::s);
|
|
ensure_equals( "uu mismatch", uu, statics::uu);
|
|
ensure_equals( "dt mismatch", dt, statics::dt);
|
|
ensure_equals("uri mismatch", uri, statics::uri);
|
|
ensure_equals("bin mismatch", bin, statics::bin);
|
|
}
|
|
|
|
void strings(std::string s0, std::string s1, std::string s2, std::string s3, std::string s4)
|
|
{
|
|
called = true;
|
|
ensure_equals("s0 mismatch", s0, statics::quick[0]);
|
|
ensure_equals("s1 mismatch", s1, statics::quick[1]);
|
|
ensure_equals("s2 mismatch", s2, statics::quick[2]);
|
|
ensure_equals("s3 mismatch", s3, statics::quick[3]);
|
|
ensure_equals("s4 mismatch", s4, statics::quick[4]);
|
|
}
|
|
|
|
void ints(int i0, int i1, int i2, int i3, int i4)
|
|
{
|
|
called = true;
|
|
ensure_equals("i0 mismatch", i0, statics::fibs[0]);
|
|
ensure_equals("i1 mismatch", i1, statics::fibs[1]);
|
|
ensure_equals("i2 mismatch", i2, statics::fibs[2]);
|
|
ensure_equals("i3 mismatch", i3, statics::fibs[3]);
|
|
ensure_equals("i4 mismatch", i4, statics::fibs[4]);
|
|
}
|
|
|
|
void sdfunc(const LLSD& sd)
|
|
{
|
|
called = true;
|
|
ensure_equals("sd mismatch", sd.asInteger(), statics::i);
|
|
}
|
|
|
|
void intfunc(int i)
|
|
{
|
|
called = true;
|
|
ensure_equals("i mismatch", i, statics::i);
|
|
}
|
|
|
|
void voidfunc()
|
|
{
|
|
called = true;
|
|
}
|
|
|
|
// recursion tail
|
|
void collect()
|
|
{
|
|
called = true;
|
|
}
|
|
|
|
// collect(arbitrary)
|
|
template <typename... ARGS>
|
|
void collect(const std::string& first, ARGS&&... rest)
|
|
{
|
|
statics::collected.push_back(first);
|
|
collect(std::forward<ARGS>(rest)...);
|
|
}
|
|
} // namespace statics
|
|
|
|
struct apply_data
|
|
{
|
|
apply_data()
|
|
{
|
|
// reset called before each test
|
|
statics::called = false;
|
|
statics::collected.clear();
|
|
}
|
|
};
|
|
typedef test_group<apply_data> apply_group;
|
|
typedef apply_group::object object;
|
|
apply_group applygrp("apply");
|
|
|
|
template<> template<>
|
|
void object::test<1>()
|
|
{
|
|
set_test_name("apply(tuple)");
|
|
LL::apply(statics::various,
|
|
std::make_tuple(statics::b, statics::i, statics::f, statics::s,
|
|
statics::uu, statics::dt, statics::uri, statics::bin));
|
|
ensure("apply(tuple) failed", statics::called);
|
|
}
|
|
|
|
template<> template<>
|
|
void object::test<2>()
|
|
{
|
|
set_test_name("apply(array)");
|
|
LL::apply(statics::ints, statics::fibs);
|
|
ensure("apply(array) failed", statics::called);
|
|
}
|
|
|
|
template<> template<>
|
|
void object::test<3>()
|
|
{
|
|
set_test_name("apply(vector)");
|
|
LL::apply(statics::strings, statics::quick);
|
|
ensure("apply(vector) failed", statics::called);
|
|
}
|
|
|
|
// The various apply(LLSD) tests exercise only the success cases because
|
|
// the failure cases trigger assert() fail, which is hard to catch.
|
|
template<> template<>
|
|
void object::test<4>()
|
|
{
|
|
set_test_name("apply(LLSD())");
|
|
LL::apply(statics::voidfunc, LLSD());
|
|
ensure("apply(LLSD()) failed", statics::called);
|
|
}
|
|
|
|
template<> template<>
|
|
void object::test<5>()
|
|
{
|
|
set_test_name("apply(fn(int), LLSD scalar)");
|
|
LL::apply(statics::intfunc, LLSD(statics::i));
|
|
ensure("apply(fn(int), LLSD scalar) failed", statics::called);
|
|
}
|
|
|
|
template<> template<>
|
|
void object::test<6>()
|
|
{
|
|
set_test_name("apply(fn(LLSD), LLSD scalar)");
|
|
// This test verifies that LLSDParam<LLSD> doesn't send the compiler
|
|
// into infinite recursion when the target is itself LLSD.
|
|
LL::apply(statics::sdfunc, LLSD(statics::i));
|
|
ensure("apply(fn(LLSD), LLSD scalar) failed", statics::called);
|
|
}
|
|
|
|
template<> template<>
|
|
void object::test<7>()
|
|
{
|
|
set_test_name("apply(LLSD array)");
|
|
LL::apply(statics::various,
|
|
llsd::array(statics::b, statics::i, statics::f, statics::s,
|
|
statics::uu, statics::dt, statics::uri, statics::bin));
|
|
ensure("apply(LLSD array) failed", statics::called);
|
|
}
|
|
|
|
template<> template<>
|
|
void object::test<8>()
|
|
{
|
|
set_test_name("VAPPLY()");
|
|
// Make a std::array<std::string> from statics::quick. We can't call a
|
|
// variadic function with a data structure of dynamic length.
|
|
std::array<std::string, 5> strray;
|
|
for (size_t i = 0; i < strray.size(); ++i)
|
|
strray[i] = statics::quick[i];
|
|
// This doesn't work: the compiler doesn't know which overload of
|
|
// collect() to pass to LL::apply().
|
|
// LL::apply(statics::collect, strray);
|
|
// That's what VAPPLY() is for.
|
|
VAPPLY(statics::collect, strray);
|
|
ensure("VAPPLY() failed", statics::called);
|
|
ensure_equals("collected mismatch", statics::collected, statics::quick);
|
|
}
|
|
} // namespace tut
|