Some additional tests to challenge the parser, which seems to work well. Without extended analysis into the usage of those node specifications, it is pointless to expand further on its capabilities. For now, it is sufficient to have a foundation for hash-computation in place. __Note__: found a nifty way to give lib::Several an easy toString rendering, without cranking up the header inclusion load.
187 lines
7.2 KiB
C++
187 lines
7.2 KiB
C++
/*
|
||
NodeMeta(Test) - verify render node data feeds
|
||
|
||
Copyright (C)
|
||
2024, Hermann Vosseler <Ichthyostega@web.de>
|
||
|
||
**Lumiera** is free software; you can redistribute it and/or modify it
|
||
under the terms of the GNU General Public License as published by the
|
||
Free Software Foundation; either version 2 of the License, or (at your
|
||
option) any later version. See the file COPYING for further details.
|
||
|
||
* *****************************************************************/
|
||
|
||
/** @file node-meta-test.cpp
|
||
** Naming and hash-key identification of render nodes is covered by \ref NodeMeta_test.
|
||
*/
|
||
|
||
|
||
#include "lib/test/run.hpp"
|
||
#include "steam/engine/proc-node.hpp"
|
||
#include "steam/engine/node-builder.hpp"
|
||
#include "lib/format-util.hpp"
|
||
//#include "steam/engine/test-rand-ontology.hpp" ///////////TODO
|
||
#include "lib/test/diagnostic-output.hpp"/////////////////TODO
|
||
//#include "lib/util.hpp"
|
||
|
||
#include <cmath>
|
||
|
||
//using std::string;
|
||
|
||
|
||
namespace steam {
|
||
namespace engine{
|
||
namespace test {
|
||
|
||
using std::abs;
|
||
// using util::join;
|
||
|
||
|
||
|
||
/***************************************************************//**
|
||
* @test Render node metadata and hash identity keys.
|
||
*/
|
||
class NodeMeta_test : public Test
|
||
{
|
||
virtual void
|
||
run (Arg)
|
||
{
|
||
verify_ID_specification();
|
||
verify_ID_properties();
|
||
}
|
||
|
||
|
||
/** @test evaluation of processing-spec for a ProcID
|
||
* @todo 1/25 ✔ define ⟶ ✔ implement
|
||
*/
|
||
void
|
||
verify_ID_specification()
|
||
{
|
||
auto& p1 = ProcID::describe("N1","(arg)");
|
||
auto& p2 = ProcID::describe("U:N2","+(a1,a2)");
|
||
auto& p3 = ProcID::describe("O:N3","(in/3)(o1,o2/2)");
|
||
|
||
CHECK (p1.genNodeName() == "N1"_expect );
|
||
CHECK (p1.genNodeSymbol() == "N1"_expect );
|
||
CHECK (p1.genNodeDomain() == ""_expect );
|
||
CHECK (p2.genNodeName() == "U:N2"_expect );
|
||
CHECK (p2.genNodeSymbol() == "N2"_expect );
|
||
CHECK (p2.genNodeDomain() == "U"_expect );
|
||
CHECK (p3.genNodeName() == "O:N3"_expect );
|
||
CHECK (p3.genNodeSymbol() == "N3"_expect );
|
||
CHECK (p3.genNodeDomain() == "O"_expect );
|
||
|
||
CHECK (p1.genProcName() == "N1"_expect );
|
||
CHECK (p1.genQualifier() == ""_expect );
|
||
CHECK (p2.genProcName() == "N2.+"_expect ); // domain omitted, qualifier joined with '.'
|
||
CHECK (p2.genQualifier() == ".+"_expect ); // qualifier includes leading '.'
|
||
CHECK (p3.genProcName() == "N3"_expect );
|
||
CHECK (p2.genProcSpec() == "U:N2.+(a1,a2)"_expect );
|
||
CHECK (p3.genProcSpec() == "O:N3(in/3)(o1,o2/2)"_expect );
|
||
|
||
ProcID::ArgModel arg1 = p1.genArgModel();
|
||
ProcID::ArgModel arg2 = p2.genArgModel();
|
||
ProcID::ArgModel arg3 = p3.genArgModel();
|
||
CHECK (not arg1.hasInArgs());
|
||
CHECK (not arg2.hasInArgs());
|
||
CHECK (arg1.outArity() == 1);
|
||
CHECK (arg2.outArity() == 2);
|
||
CHECK (arg3.outArity() == 3);
|
||
CHECK (arg3.inArity() == 3);
|
||
CHECK (arg1.iArg == "[]"_expect );
|
||
CHECK (arg1.oArg == "[arg]"_expect ); // only one argument list -> used for output
|
||
CHECK (arg2.iArg == "[]"_expect );
|
||
CHECK (arg2.oArg == "[a1, a2]"_expect );
|
||
CHECK (arg3.iArg == "[in, in, in]"_expect ); // repetition-abbreviation of arguments unfolded
|
||
CHECK (arg3.oArg == "[o1, o2, o2]"_expect );
|
||
|
||
// give the spec-parser a rough time....
|
||
string nastySpec = "(\":-)\"/2,std::tuple<short,long>/3,{oh,RLY?}/2,\\\")";
|
||
auto hairyModel = ProcID::describe("○", nastySpec).genArgModel();
|
||
CHECK (hairyModel.outArity() == 8);
|
||
CHECK (hairyModel.inArity() == 0);
|
||
CHECK (hairyModel.oArg == "[\":-)\", \":-)\", "
|
||
"std::tuple<short,long>, "
|
||
"std::tuple<short,long>, "
|
||
"std::tuple<short,long>, "
|
||
"{oh,RLY?}, {oh,RLY?}, \\\"]"_expect);
|
||
}
|
||
|
||
|
||
/** @test TODO aspects of node definition relevant for the ProcID
|
||
* @todo WIP 2/25 🔁 define ⟶ implement
|
||
*/
|
||
void
|
||
verify_ID_properties()
|
||
{
|
||
// This operation emulates a data source
|
||
auto src_opA = [](int param, int* res) { *res = param; };
|
||
auto src_opB = [](ulong param, ulong* res){ *res = param; };
|
||
|
||
// A Node with two (source) ports
|
||
ProcNode nA{prepareNode("srcA")
|
||
.preparePort()
|
||
.invoke("a(int)", src_opA)
|
||
.setParam(5)
|
||
.completePort()
|
||
.preparePort()
|
||
.invoke("b(int)", src_opA)
|
||
.setParam(23)
|
||
.completePort()
|
||
.build()};
|
||
|
||
// A different Node with three ports
|
||
ProcNode nB{prepareNode("srcB")
|
||
.preparePort()
|
||
.invoke("a(ulong)", src_opB)
|
||
.setParam(7)
|
||
.completePort()
|
||
.preparePort()
|
||
.invoke("b(ulong)", src_opB)
|
||
.setParam(13)
|
||
.completePort()
|
||
.preparePort()
|
||
.invoke("c(ulong)", src_opB)
|
||
.setParam(17)
|
||
.completePort()
|
||
.build()};
|
||
|
||
// This operation emulates fading of two source chains
|
||
auto fade_op = [](double mix, tuple<int*,ulong*> src, uint64_t* res)
|
||
{
|
||
auto [srcA,srcB] = src;
|
||
*res = uint64_t(abs(*srcA * mix + (1-mix) * int64_t(*srcB)));
|
||
};
|
||
|
||
// Wiring for the Mix, building up three ports
|
||
// Since the first source-chain has only two ports,
|
||
// for the third result port we'll re-use the second source
|
||
ProcNode nM{prepareNode("fade")
|
||
.preparePort()
|
||
.invoke("A_mix(int,ulong)(uint64_t)", fade_op)
|
||
.connectLead(nA)
|
||
.connectLead(nB)
|
||
.completePort()
|
||
.preparePort()
|
||
.invoke("B_mix(int,ulong)(uint64_t)", fade_op)
|
||
.connectLead(nA)
|
||
.connectLead(nB)
|
||
.completePort()
|
||
.preparePort()
|
||
.invoke("C_mix(int,ulong)(uint64_t)", fade_op)
|
||
.connectLeadPort(nA,1)
|
||
.connectLead(nB)
|
||
.setParam(0.5)
|
||
.completePort()
|
||
.build()};
|
||
UNIMPLEMENTED ("verify connectivity");
|
||
}
|
||
};
|
||
|
||
|
||
/** Register this test class... */
|
||
LAUNCHER (NodeMeta_test, "unit node");
|
||
|
||
|
||
|
||
}}} // namespace steam::engine::test
|