1825 lines
57 KiB
C++
1825 lines
57 KiB
C++
|
|
#include <gtest/gtest.h>
|
||
|
|
#include <tcl.h>
|
||
|
|
#include "MinMax.hh"
|
||
|
|
#include "Transition.hh"
|
||
|
|
#include "Units.hh"
|
||
|
|
#include "Property.hh"
|
||
|
|
#include "ExceptionPath.hh"
|
||
|
|
#include "TimingRole.hh"
|
||
|
|
#include "Scene.hh"
|
||
|
|
#include "Sta.hh"
|
||
|
|
#include "Sdc.hh"
|
||
|
|
#include "ReportTcl.hh"
|
||
|
|
#include "RiseFallMinMax.hh"
|
||
|
|
#include "Variables.hh"
|
||
|
|
#include "LibertyClass.hh"
|
||
|
|
#include "Search.hh"
|
||
|
|
#include "Path.hh"
|
||
|
|
#include "PathGroup.hh"
|
||
|
|
#include "PathExpanded.hh"
|
||
|
|
#include "SearchPred.hh"
|
||
|
|
#include "SearchClass.hh"
|
||
|
|
#include "ClkNetwork.hh"
|
||
|
|
#include "VisitPathEnds.hh"
|
||
|
|
#include "search/CheckMinPulseWidths.hh"
|
||
|
|
#include "search/CheckMinPeriods.hh"
|
||
|
|
#include "search/CheckMaxSkews.hh"
|
||
|
|
#include "search/ClkSkew.hh"
|
||
|
|
#include "search/ClkInfo.hh"
|
||
|
|
#include "search/Tag.hh"
|
||
|
|
#include "search/PathEnum.hh"
|
||
|
|
#include "search/Genclks.hh"
|
||
|
|
#include "search/Levelize.hh"
|
||
|
|
#include "search/Sim.hh"
|
||
|
|
#include "Bfs.hh"
|
||
|
|
#include "search/WorstSlack.hh"
|
||
|
|
#include "search/ReportPath.hh"
|
||
|
|
#include "GraphDelayCalc.hh"
|
||
|
|
#include "Debug.hh"
|
||
|
|
#include "PowerClass.hh"
|
||
|
|
#include "search/CheckCapacitances.hh"
|
||
|
|
#include "search/CheckSlews.hh"
|
||
|
|
#include "search/CheckFanouts.hh"
|
||
|
|
#include "search/Crpr.hh"
|
||
|
|
#include "search/GatedClk.hh"
|
||
|
|
#include "search/ClkLatency.hh"
|
||
|
|
#include "search/FindRegister.hh"
|
||
|
|
#include "search/TagGroup.hh"
|
||
|
|
#include "search/MakeTimingModelPvt.hh"
|
||
|
|
#include "search/CheckTiming.hh"
|
||
|
|
#include "search/Latches.hh"
|
||
|
|
#include "Graph.hh"
|
||
|
|
#include "Liberty.hh"
|
||
|
|
#include "Network.hh"
|
||
|
|
|
||
|
|
namespace sta {
|
||
|
|
|
||
|
|
|
||
|
|
class SearchMinMaxTest : public ::testing::Test {};
|
||
|
|
|
||
|
|
TEST_F(SearchMinMaxTest, MinCompare) {
|
||
|
|
// For min: value1 < value2 returns true
|
||
|
|
EXPECT_TRUE(MinMax::min()->compare(1.0f, 2.0f));
|
||
|
|
EXPECT_FALSE(MinMax::min()->compare(2.0f, 1.0f));
|
||
|
|
EXPECT_FALSE(MinMax::min()->compare(1.0f, 1.0f));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(SearchMinMaxTest, MaxCompare) {
|
||
|
|
// For max: value1 > value2 returns true
|
||
|
|
EXPECT_TRUE(MinMax::max()->compare(2.0f, 1.0f));
|
||
|
|
EXPECT_FALSE(MinMax::max()->compare(1.0f, 2.0f));
|
||
|
|
EXPECT_FALSE(MinMax::max()->compare(1.0f, 1.0f));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(SearchMinMaxTest, MinMaxFunc) {
|
||
|
|
EXPECT_FLOAT_EQ(MinMax::min()->minMax(1.0f, 2.0f), 1.0f);
|
||
|
|
EXPECT_FLOAT_EQ(MinMax::min()->minMax(2.0f, 1.0f), 1.0f);
|
||
|
|
EXPECT_FLOAT_EQ(MinMax::max()->minMax(1.0f, 2.0f), 2.0f);
|
||
|
|
EXPECT_FLOAT_EQ(MinMax::max()->minMax(2.0f, 1.0f), 2.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(SearchMinMaxTest, FindByName) {
|
||
|
|
EXPECT_EQ(MinMax::find("min"), MinMax::min());
|
||
|
|
EXPECT_EQ(MinMax::find("max"), MinMax::max());
|
||
|
|
EXPECT_EQ(MinMax::find("early"), MinMax::early());
|
||
|
|
EXPECT_EQ(MinMax::find("late"), MinMax::late());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(SearchMinMaxTest, FindByIndex) {
|
||
|
|
EXPECT_EQ(MinMax::find(MinMax::minIndex()), MinMax::min());
|
||
|
|
EXPECT_EQ(MinMax::find(MinMax::maxIndex()), MinMax::max());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(SearchMinMaxTest, EarlyLateAliases) {
|
||
|
|
EXPECT_EQ(MinMax::early(), MinMax::min());
|
||
|
|
EXPECT_EQ(MinMax::late(), MinMax::max());
|
||
|
|
EXPECT_EQ(MinMax::earlyIndex(), MinMax::minIndex());
|
||
|
|
EXPECT_EQ(MinMax::lateIndex(), MinMax::maxIndex());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(SearchMinMaxTest, RangeSize) {
|
||
|
|
auto &range = MinMax::range();
|
||
|
|
EXPECT_EQ(range.size(), 2u);
|
||
|
|
auto &range_idx = MinMax::rangeIndex();
|
||
|
|
EXPECT_EQ(range_idx.size(), 2u);
|
||
|
|
}
|
||
|
|
|
||
|
|
// MinMaxAll tests
|
||
|
|
class SearchMinMaxAllTest : public ::testing::Test {};
|
||
|
|
|
||
|
|
TEST_F(SearchMinMaxAllTest, MatchesMinMax) {
|
||
|
|
EXPECT_TRUE(MinMaxAll::min()->matches(MinMax::min()));
|
||
|
|
EXPECT_FALSE(MinMaxAll::min()->matches(MinMax::max()));
|
||
|
|
EXPECT_TRUE(MinMaxAll::max()->matches(MinMax::max()));
|
||
|
|
EXPECT_FALSE(MinMaxAll::max()->matches(MinMax::min()));
|
||
|
|
EXPECT_TRUE(MinMaxAll::all()->matches(MinMax::min()));
|
||
|
|
EXPECT_TRUE(MinMaxAll::all()->matches(MinMax::max()));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(SearchMinMaxAllTest, MatchesMinMaxAll) {
|
||
|
|
EXPECT_TRUE(MinMaxAll::all()->matches(MinMaxAll::min()));
|
||
|
|
EXPECT_TRUE(MinMaxAll::all()->matches(MinMaxAll::max()));
|
||
|
|
EXPECT_TRUE(MinMaxAll::all()->matches(MinMaxAll::all()));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(SearchMinMaxAllTest, AllRange) {
|
||
|
|
auto &range = MinMaxAll::all()->range();
|
||
|
|
EXPECT_EQ(range.size(), 2u);
|
||
|
|
EXPECT_EQ(range[0], MinMax::min());
|
||
|
|
EXPECT_EQ(range[1], MinMax::max());
|
||
|
|
}
|
||
|
|
|
||
|
|
// Transition tests used in search
|
||
|
|
class SearchTransitionTest : public ::testing::Test {};
|
||
|
|
|
||
|
|
TEST_F(SearchTransitionTest, RiseFallSingletons) {
|
||
|
|
EXPECT_NE(Transition::rise(), nullptr);
|
||
|
|
EXPECT_NE(Transition::fall(), nullptr);
|
||
|
|
EXPECT_NE(Transition::rise(), Transition::fall());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(SearchTransitionTest, RiseFallMatch) {
|
||
|
|
EXPECT_TRUE(Transition::riseFall()->matches(Transition::rise()));
|
||
|
|
EXPECT_TRUE(Transition::riseFall()->matches(Transition::fall()));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(SearchTransitionTest, SdfTransitions) {
|
||
|
|
// All SDF transition types should have unique indices
|
||
|
|
EXPECT_NE(Transition::rise()->sdfTripleIndex(),
|
||
|
|
Transition::fall()->sdfTripleIndex());
|
||
|
|
EXPECT_NE(Transition::tr0Z()->sdfTripleIndex(),
|
||
|
|
Transition::trZ1()->sdfTripleIndex());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(SearchTransitionTest, AsRiseFall) {
|
||
|
|
EXPECT_EQ(Transition::rise()->asRiseFall(), RiseFall::rise());
|
||
|
|
EXPECT_EQ(Transition::fall()->asRiseFall(), RiseFall::fall());
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////
|
||
|
|
// PropertyValue tests
|
||
|
|
////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
class PropertyValueTest : public ::testing::Test {};
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, DefaultConstructor) {
|
||
|
|
PropertyValue pv;
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::Type::none);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, StringConstructor) {
|
||
|
|
PropertyValue pv("hello");
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::Type::string);
|
||
|
|
EXPECT_STREQ(pv.stringValue(), "hello");
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, StdStringConstructor) {
|
||
|
|
std::string s("world");
|
||
|
|
PropertyValue pv(s);
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::Type::string);
|
||
|
|
EXPECT_STREQ(pv.stringValue(), "world");
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, BoolConstructorTrue) {
|
||
|
|
PropertyValue pv(true);
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::Type::bool_);
|
||
|
|
EXPECT_TRUE(pv.boolValue());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, BoolConstructorFalse) {
|
||
|
|
PropertyValue pv(false);
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::Type::bool_);
|
||
|
|
EXPECT_FALSE(pv.boolValue());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, FloatConstructor) {
|
||
|
|
Unit time_unit(1.0f, "s", 3);
|
||
|
|
PropertyValue pv(3.14f, &time_unit);
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::Type::float_);
|
||
|
|
EXPECT_FLOAT_EQ(pv.floatValue(), 3.14f);
|
||
|
|
std::string value_text = pv.to_string(nullptr);
|
||
|
|
EXPECT_FALSE(value_text.empty());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, NullPinConstructor) {
|
||
|
|
const Pin *pin = nullptr;
|
||
|
|
PropertyValue pv(pin);
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::Type::pin);
|
||
|
|
EXPECT_EQ(pv.pin(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, NullNetConstructor) {
|
||
|
|
const Net *net = nullptr;
|
||
|
|
PropertyValue pv(net);
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::Type::net);
|
||
|
|
EXPECT_EQ(pv.net(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, NullInstanceConstructor) {
|
||
|
|
const Instance *inst = nullptr;
|
||
|
|
PropertyValue pv(inst);
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::Type::instance);
|
||
|
|
EXPECT_EQ(pv.instance(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, NullCellConstructor) {
|
||
|
|
const Cell *cell = nullptr;
|
||
|
|
PropertyValue pv(cell);
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::Type::cell);
|
||
|
|
EXPECT_EQ(pv.cell(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, NullPortConstructor) {
|
||
|
|
const Port *port = nullptr;
|
||
|
|
PropertyValue pv(port);
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::Type::port);
|
||
|
|
EXPECT_EQ(pv.port(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, NullLibraryConstructor) {
|
||
|
|
const Library *lib = nullptr;
|
||
|
|
PropertyValue pv(lib);
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::Type::library);
|
||
|
|
EXPECT_EQ(pv.library(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, NullLibertyLibraryConstructor) {
|
||
|
|
const LibertyLibrary *lib = nullptr;
|
||
|
|
PropertyValue pv(lib);
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::Type::liberty_library);
|
||
|
|
EXPECT_EQ(pv.libertyLibrary(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, NullLibertyCellConstructor) {
|
||
|
|
const LibertyCell *cell = nullptr;
|
||
|
|
PropertyValue pv(cell);
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::Type::liberty_cell);
|
||
|
|
EXPECT_EQ(pv.libertyCell(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, NullLibertyPortConstructor) {
|
||
|
|
const LibertyPort *port = nullptr;
|
||
|
|
PropertyValue pv(port);
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::Type::liberty_port);
|
||
|
|
EXPECT_EQ(pv.libertyPort(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, NullClockConstructor) {
|
||
|
|
const Clock *clk = nullptr;
|
||
|
|
PropertyValue pv(clk);
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::Type::clk);
|
||
|
|
EXPECT_EQ(pv.clock(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyConstructorString) {
|
||
|
|
PropertyValue pv1("copy_test");
|
||
|
|
PropertyValue pv2(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::string);
|
||
|
|
EXPECT_STREQ(pv2.stringValue(), "copy_test");
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyConstructorFloat) {
|
||
|
|
PropertyValue pv1(2.718f, nullptr);
|
||
|
|
PropertyValue pv2(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::float_);
|
||
|
|
EXPECT_FLOAT_EQ(pv2.floatValue(), 2.718f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyConstructorBool) {
|
||
|
|
PropertyValue pv1(true);
|
||
|
|
PropertyValue pv2(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::bool_);
|
||
|
|
EXPECT_TRUE(pv2.boolValue());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyConstructorNone) {
|
||
|
|
PropertyValue pv1;
|
||
|
|
PropertyValue pv2(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::none);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyConstructorLibrary) {
|
||
|
|
const Library *lib = nullptr;
|
||
|
|
PropertyValue pv1(lib);
|
||
|
|
PropertyValue pv2(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::library);
|
||
|
|
EXPECT_EQ(pv2.library(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyConstructorCell) {
|
||
|
|
const Cell *cell = nullptr;
|
||
|
|
PropertyValue pv1(cell);
|
||
|
|
PropertyValue pv2(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::cell);
|
||
|
|
EXPECT_EQ(pv2.cell(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyConstructorPort) {
|
||
|
|
const Port *port = nullptr;
|
||
|
|
PropertyValue pv1(port);
|
||
|
|
PropertyValue pv2(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::port);
|
||
|
|
EXPECT_EQ(pv2.port(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyConstructorLibertyLibrary) {
|
||
|
|
const LibertyLibrary *lib = nullptr;
|
||
|
|
PropertyValue pv1(lib);
|
||
|
|
PropertyValue pv2(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::liberty_library);
|
||
|
|
EXPECT_EQ(pv2.libertyLibrary(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyConstructorLibertyCell) {
|
||
|
|
const LibertyCell *cell = nullptr;
|
||
|
|
PropertyValue pv1(cell);
|
||
|
|
PropertyValue pv2(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::liberty_cell);
|
||
|
|
EXPECT_EQ(pv2.libertyCell(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyConstructorLibertyPort) {
|
||
|
|
const LibertyPort *port = nullptr;
|
||
|
|
PropertyValue pv1(port);
|
||
|
|
PropertyValue pv2(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::liberty_port);
|
||
|
|
EXPECT_EQ(pv2.libertyPort(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyConstructorInstance) {
|
||
|
|
const Instance *inst = nullptr;
|
||
|
|
PropertyValue pv1(inst);
|
||
|
|
PropertyValue pv2(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::instance);
|
||
|
|
EXPECT_EQ(pv2.instance(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyConstructorPin) {
|
||
|
|
const Pin *pin = nullptr;
|
||
|
|
PropertyValue pv1(pin);
|
||
|
|
PropertyValue pv2(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::pin);
|
||
|
|
EXPECT_EQ(pv2.pin(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyConstructorNet) {
|
||
|
|
const Net *net = nullptr;
|
||
|
|
PropertyValue pv1(net);
|
||
|
|
PropertyValue pv2(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::net);
|
||
|
|
EXPECT_EQ(pv2.net(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyConstructorClock) {
|
||
|
|
const Clock *clk = nullptr;
|
||
|
|
PropertyValue pv1(clk);
|
||
|
|
PropertyValue pv2(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::clk);
|
||
|
|
EXPECT_EQ(pv2.clock(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveConstructorString) {
|
||
|
|
PropertyValue pv1("move_test");
|
||
|
|
PropertyValue pv2(std::move(pv1));
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::string);
|
||
|
|
EXPECT_STREQ(pv2.stringValue(), "move_test");
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveConstructorFloat) {
|
||
|
|
PropertyValue pv1(1.414f, nullptr);
|
||
|
|
PropertyValue pv2(std::move(pv1));
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::float_);
|
||
|
|
EXPECT_FLOAT_EQ(pv2.floatValue(), 1.414f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveConstructorBool) {
|
||
|
|
PropertyValue pv1(false);
|
||
|
|
PropertyValue pv2(std::move(pv1));
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::bool_);
|
||
|
|
EXPECT_FALSE(pv2.boolValue());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveConstructorNone) {
|
||
|
|
PropertyValue pv1;
|
||
|
|
PropertyValue pv2(std::move(pv1));
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::none);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveConstructorLibrary) {
|
||
|
|
const Library *lib = nullptr;
|
||
|
|
PropertyValue pv1(lib);
|
||
|
|
PropertyValue pv2(std::move(pv1));
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::library);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveConstructorCell) {
|
||
|
|
const Cell *cell = nullptr;
|
||
|
|
PropertyValue pv1(cell);
|
||
|
|
PropertyValue pv2(std::move(pv1));
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::cell);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveConstructorPort) {
|
||
|
|
const Port *port = nullptr;
|
||
|
|
PropertyValue pv1(port);
|
||
|
|
PropertyValue pv2(std::move(pv1));
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::port);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveConstructorLibertyLibrary) {
|
||
|
|
const LibertyLibrary *lib = nullptr;
|
||
|
|
PropertyValue pv1(lib);
|
||
|
|
PropertyValue pv2(std::move(pv1));
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::liberty_library);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveConstructorLibertyCell) {
|
||
|
|
const LibertyCell *cell = nullptr;
|
||
|
|
PropertyValue pv1(cell);
|
||
|
|
PropertyValue pv2(std::move(pv1));
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::liberty_cell);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveConstructorLibertyPort) {
|
||
|
|
const LibertyPort *port = nullptr;
|
||
|
|
PropertyValue pv1(port);
|
||
|
|
PropertyValue pv2(std::move(pv1));
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::liberty_port);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveConstructorInstance) {
|
||
|
|
const Instance *inst = nullptr;
|
||
|
|
PropertyValue pv1(inst);
|
||
|
|
PropertyValue pv2(std::move(pv1));
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::instance);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveConstructorPin) {
|
||
|
|
const Pin *pin = nullptr;
|
||
|
|
PropertyValue pv1(pin);
|
||
|
|
PropertyValue pv2(std::move(pv1));
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::pin);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveConstructorNet) {
|
||
|
|
const Net *net = nullptr;
|
||
|
|
PropertyValue pv1(net);
|
||
|
|
PropertyValue pv2(std::move(pv1));
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::net);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveConstructorClock) {
|
||
|
|
const Clock *clk = nullptr;
|
||
|
|
PropertyValue pv1(clk);
|
||
|
|
PropertyValue pv2(std::move(pv1));
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::clk);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyAssignmentString) {
|
||
|
|
PropertyValue pv1("assign_test");
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = pv1;
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::string);
|
||
|
|
EXPECT_STREQ(pv2.stringValue(), "assign_test");
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyAssignmentFloat) {
|
||
|
|
PropertyValue pv1(9.81f, nullptr);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = pv1;
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::float_);
|
||
|
|
EXPECT_FLOAT_EQ(pv2.floatValue(), 9.81f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyAssignmentBool) {
|
||
|
|
PropertyValue pv1(true);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = pv1;
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::bool_);
|
||
|
|
EXPECT_TRUE(pv2.boolValue());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyAssignmentNone) {
|
||
|
|
PropertyValue pv1;
|
||
|
|
PropertyValue pv2("replace_me");
|
||
|
|
pv2 = pv1;
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::none);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyAssignmentLibrary) {
|
||
|
|
const Library *lib = nullptr;
|
||
|
|
PropertyValue pv1(lib);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = pv1;
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::library);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyAssignmentCell) {
|
||
|
|
const Cell *cell = nullptr;
|
||
|
|
PropertyValue pv1(cell);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = pv1;
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::cell);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyAssignmentPort) {
|
||
|
|
const Port *port = nullptr;
|
||
|
|
PropertyValue pv1(port);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = pv1;
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::port);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyAssignmentLibertyLibrary) {
|
||
|
|
const LibertyLibrary *lib = nullptr;
|
||
|
|
PropertyValue pv1(lib);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = pv1;
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::liberty_library);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyAssignmentLibertyCell) {
|
||
|
|
const LibertyCell *cell = nullptr;
|
||
|
|
PropertyValue pv1(cell);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = pv1;
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::liberty_cell);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyAssignmentLibertyPort) {
|
||
|
|
const LibertyPort *port = nullptr;
|
||
|
|
PropertyValue pv1(port);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = pv1;
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::liberty_port);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyAssignmentInstance) {
|
||
|
|
const Instance *inst = nullptr;
|
||
|
|
PropertyValue pv1(inst);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = pv1;
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::instance);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyAssignmentPin) {
|
||
|
|
const Pin *pin = nullptr;
|
||
|
|
PropertyValue pv1(pin);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = pv1;
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::pin);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyAssignmentNet) {
|
||
|
|
const Net *net = nullptr;
|
||
|
|
PropertyValue pv1(net);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = pv1;
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::net);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, CopyAssignmentClock) {
|
||
|
|
const Clock *clk = nullptr;
|
||
|
|
PropertyValue pv1(clk);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = pv1;
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::clk);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveAssignmentString) {
|
||
|
|
PropertyValue pv1("move_assign");
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = std::move(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::string);
|
||
|
|
EXPECT_STREQ(pv2.stringValue(), "move_assign");
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveAssignmentFloat) {
|
||
|
|
PropertyValue pv1(6.28f, nullptr);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = std::move(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::float_);
|
||
|
|
EXPECT_FLOAT_EQ(pv2.floatValue(), 6.28f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveAssignmentBool) {
|
||
|
|
PropertyValue pv1(false);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = std::move(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::bool_);
|
||
|
|
EXPECT_FALSE(pv2.boolValue());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveAssignmentNone) {
|
||
|
|
PropertyValue pv1;
|
||
|
|
PropertyValue pv2("stuff");
|
||
|
|
pv2 = std::move(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::none);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveAssignmentLibrary) {
|
||
|
|
const Library *lib = nullptr;
|
||
|
|
PropertyValue pv1(lib);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = std::move(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::library);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveAssignmentCell) {
|
||
|
|
const Cell *cell = nullptr;
|
||
|
|
PropertyValue pv1(cell);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = std::move(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::cell);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveAssignmentPort) {
|
||
|
|
const Port *port = nullptr;
|
||
|
|
PropertyValue pv1(port);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = std::move(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::port);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveAssignmentLibertyLibrary) {
|
||
|
|
const LibertyLibrary *lib = nullptr;
|
||
|
|
PropertyValue pv1(lib);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = std::move(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::liberty_library);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveAssignmentLibertyCell) {
|
||
|
|
const LibertyCell *cell = nullptr;
|
||
|
|
PropertyValue pv1(cell);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = std::move(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::liberty_cell);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveAssignmentLibertyPort) {
|
||
|
|
const LibertyPort *port = nullptr;
|
||
|
|
PropertyValue pv1(port);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = std::move(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::liberty_port);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveAssignmentInstance) {
|
||
|
|
const Instance *inst = nullptr;
|
||
|
|
PropertyValue pv1(inst);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = std::move(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::instance);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveAssignmentPin) {
|
||
|
|
const Pin *pin = nullptr;
|
||
|
|
PropertyValue pv1(pin);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = std::move(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::pin);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveAssignmentNet) {
|
||
|
|
const Net *net = nullptr;
|
||
|
|
PropertyValue pv1(net);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = std::move(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::net);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, MoveAssignmentClock) {
|
||
|
|
const Clock *clk = nullptr;
|
||
|
|
PropertyValue pv1(clk);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = std::move(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::clk);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test type-checking exceptions
|
||
|
|
TEST_F(PropertyValueTest, StringValueThrowsOnWrongType) {
|
||
|
|
PropertyValue pv(true);
|
||
|
|
EXPECT_THROW(pv.stringValue(), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, FloatValueThrowsOnWrongType) {
|
||
|
|
PropertyValue pv("not_a_float");
|
||
|
|
EXPECT_THROW(pv.floatValue(), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, BoolValueThrowsOnWrongType) {
|
||
|
|
PropertyValue pv("not_a_bool");
|
||
|
|
EXPECT_THROW(pv.boolValue(), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test PinSeq constructor
|
||
|
|
TEST_F(PropertyValueTest, PinSeqConstructor) {
|
||
|
|
PinSeq *pins = new PinSeq;
|
||
|
|
PropertyValue pv(pins);
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::Type::pins);
|
||
|
|
EXPECT_EQ(pv.pins(), pins);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test ClockSeq constructor
|
||
|
|
TEST_F(PropertyValueTest, ClockSeqConstructor) {
|
||
|
|
ClockSeq *clks = new ClockSeq;
|
||
|
|
PropertyValue pv(clks);
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::Type::clks);
|
||
|
|
EXPECT_NE(pv.clocks(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test ConstPathSeq constructor
|
||
|
|
TEST_F(PropertyValueTest, ConstPathSeqConstructor) {
|
||
|
|
ConstPathSeq *paths = new ConstPathSeq;
|
||
|
|
PropertyValue pv(paths);
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::Type::paths);
|
||
|
|
EXPECT_NE(pv.paths(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test PwrActivity constructor
|
||
|
|
TEST_F(PropertyValueTest, PwrActivityConstructor) {
|
||
|
|
PwrActivity activity;
|
||
|
|
PropertyValue pv(&activity);
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::Type::pwr_activity);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Copy constructor for pins
|
||
|
|
TEST_F(PropertyValueTest, CopyConstructorPins) {
|
||
|
|
PinSeq *pins = new PinSeq;
|
||
|
|
PropertyValue pv1(pins);
|
||
|
|
PropertyValue pv2(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::pins);
|
||
|
|
// Should be a separate copy
|
||
|
|
EXPECT_NE(pv2.pins(), pv1.pins());
|
||
|
|
}
|
||
|
|
|
||
|
|
// Copy constructor for clocks
|
||
|
|
TEST_F(PropertyValueTest, CopyConstructorClocks) {
|
||
|
|
ClockSeq *clks = new ClockSeq;
|
||
|
|
PropertyValue pv1(clks);
|
||
|
|
PropertyValue pv2(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::clks);
|
||
|
|
EXPECT_NE(pv2.clocks(), pv1.clocks());
|
||
|
|
}
|
||
|
|
|
||
|
|
// Copy constructor for paths
|
||
|
|
TEST_F(PropertyValueTest, CopyConstructorPaths) {
|
||
|
|
ConstPathSeq *paths = new ConstPathSeq;
|
||
|
|
PropertyValue pv1(paths);
|
||
|
|
PropertyValue pv2(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::paths);
|
||
|
|
EXPECT_NE(pv2.paths(), pv1.paths());
|
||
|
|
}
|
||
|
|
|
||
|
|
// Copy constructor for PwrActivity
|
||
|
|
TEST_F(PropertyValueTest, CopyConstructorPwrActivity) {
|
||
|
|
PwrActivity activity;
|
||
|
|
PropertyValue pv1(&activity);
|
||
|
|
PropertyValue pv2(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::pwr_activity);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Move constructor for pins
|
||
|
|
TEST_F(PropertyValueTest, MoveConstructorPins) {
|
||
|
|
PinSeq *pins = new PinSeq;
|
||
|
|
PropertyValue pv1(pins);
|
||
|
|
PinSeq *orig_pins = pv1.pins();
|
||
|
|
PropertyValue pv2(std::move(pv1));
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::pins);
|
||
|
|
EXPECT_EQ(pv2.pins(), orig_pins);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Move constructor for clocks
|
||
|
|
TEST_F(PropertyValueTest, MoveConstructorClocks) {
|
||
|
|
ClockSeq *clks = new ClockSeq;
|
||
|
|
PropertyValue pv1(clks);
|
||
|
|
ClockSeq *orig_clks = pv1.clocks();
|
||
|
|
PropertyValue pv2(std::move(pv1));
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::clks);
|
||
|
|
EXPECT_EQ(pv2.clocks(), orig_clks);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Move constructor for paths
|
||
|
|
TEST_F(PropertyValueTest, MoveConstructorPaths) {
|
||
|
|
ConstPathSeq *paths = new ConstPathSeq;
|
||
|
|
PropertyValue pv1(paths);
|
||
|
|
ConstPathSeq *orig_paths = pv1.paths();
|
||
|
|
PropertyValue pv2(std::move(pv1));
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::paths);
|
||
|
|
EXPECT_EQ(pv2.paths(), orig_paths);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Move constructor for PwrActivity
|
||
|
|
TEST_F(PropertyValueTest, MoveConstructorPwrActivity) {
|
||
|
|
PwrActivity activity;
|
||
|
|
PropertyValue pv1(&activity);
|
||
|
|
PropertyValue pv2(std::move(pv1));
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::pwr_activity);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Copy assignment for pins
|
||
|
|
TEST_F(PropertyValueTest, CopyAssignmentPins) {
|
||
|
|
PinSeq *pins = new PinSeq;
|
||
|
|
PropertyValue pv1(pins);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = pv1;
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::pins);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Copy assignment for clocks
|
||
|
|
TEST_F(PropertyValueTest, CopyAssignmentClocks) {
|
||
|
|
ClockSeq *clks = new ClockSeq;
|
||
|
|
PropertyValue pv1(clks);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = pv1;
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::clks);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Copy assignment for paths
|
||
|
|
TEST_F(PropertyValueTest, CopyAssignmentPaths) {
|
||
|
|
ConstPathSeq *paths = new ConstPathSeq;
|
||
|
|
PropertyValue pv1(paths);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = pv1;
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::paths);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Copy assignment for PwrActivity
|
||
|
|
TEST_F(PropertyValueTest, CopyAssignmentPwrActivity) {
|
||
|
|
PwrActivity activity;
|
||
|
|
PropertyValue pv1(&activity);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = pv1;
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::pwr_activity);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Move assignment for pins
|
||
|
|
TEST_F(PropertyValueTest, MoveAssignmentPins) {
|
||
|
|
PinSeq *pins = new PinSeq;
|
||
|
|
PropertyValue pv1(pins);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = std::move(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::pins);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Move assignment for clocks
|
||
|
|
TEST_F(PropertyValueTest, MoveAssignmentClocks) {
|
||
|
|
ClockSeq *clks = new ClockSeq;
|
||
|
|
PropertyValue pv1(clks);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = std::move(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::clks);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Move assignment for paths
|
||
|
|
TEST_F(PropertyValueTest, MoveAssignmentPaths) {
|
||
|
|
ConstPathSeq *paths = new ConstPathSeq;
|
||
|
|
PropertyValue pv1(paths);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = std::move(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::paths);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Move assignment for PwrActivity
|
||
|
|
TEST_F(PropertyValueTest, MoveAssignmentPwrActivity) {
|
||
|
|
PwrActivity activity;
|
||
|
|
PropertyValue pv1(&activity);
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = std::move(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::Type::pwr_activity);
|
||
|
|
}
|
||
|
|
|
||
|
|
// to_string for bool values
|
||
|
|
TEST_F(PropertyValueTest, ToStringBoolTrue) {
|
||
|
|
PropertyValue pv(true);
|
||
|
|
EXPECT_EQ(pv.to_string(nullptr), "1");
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, ToStringBoolFalse) {
|
||
|
|
PropertyValue pv(false);
|
||
|
|
EXPECT_EQ(pv.to_string(nullptr), "0");
|
||
|
|
}
|
||
|
|
|
||
|
|
// to_string for string values
|
||
|
|
TEST_F(PropertyValueTest, ToStringString) {
|
||
|
|
PropertyValue pv("test_str");
|
||
|
|
EXPECT_EQ(pv.to_string(nullptr), "test_str");
|
||
|
|
}
|
||
|
|
|
||
|
|
// to_string for types that return empty
|
||
|
|
TEST_F(PropertyValueTest, ToStringNone) {
|
||
|
|
PropertyValue pv;
|
||
|
|
EXPECT_EQ(pv.to_string(nullptr), "");
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, ToStringPins) {
|
||
|
|
PinSeq *pins = new PinSeq;
|
||
|
|
PropertyValue pv(pins);
|
||
|
|
EXPECT_EQ(pv.to_string(nullptr), "");
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, ToStringClocks) {
|
||
|
|
ClockSeq *clks = new ClockSeq;
|
||
|
|
PropertyValue pv(clks);
|
||
|
|
EXPECT_EQ(pv.to_string(nullptr), "");
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, ToStringPaths) {
|
||
|
|
ConstPathSeq *paths = new ConstPathSeq;
|
||
|
|
PropertyValue pv(paths);
|
||
|
|
EXPECT_EQ(pv.to_string(nullptr), "");
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(PropertyValueTest, ToStringPwrActivity) {
|
||
|
|
PwrActivity activity;
|
||
|
|
PropertyValue pv(&activity);
|
||
|
|
EXPECT_EQ(pv.to_string(nullptr), "");
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////
|
||
|
|
// ExceptionPath tests
|
||
|
|
////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
class ExceptionPathTest : public ::testing::Test {
|
||
|
|
protected:
|
||
|
|
void SetUp() override {
|
||
|
|
initSta();
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// FalsePath
|
||
|
|
TEST_F(ExceptionPathTest, FalsePathBasic) {
|
||
|
|
FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
EXPECT_TRUE(fp.isFalse());
|
||
|
|
EXPECT_FALSE(fp.isLoop());
|
||
|
|
EXPECT_FALSE(fp.isMultiCycle());
|
||
|
|
EXPECT_FALSE(fp.isPathDelay());
|
||
|
|
EXPECT_FALSE(fp.isGroupPath());
|
||
|
|
EXPECT_FALSE(fp.isFilter());
|
||
|
|
EXPECT_EQ(fp.type(), ExceptionPathType::false_path);
|
||
|
|
EXPECT_EQ(fp.minMax(), MinMaxAll::all());
|
||
|
|
EXPECT_EQ(fp.from(), nullptr);
|
||
|
|
EXPECT_EQ(fp.thrus(), nullptr);
|
||
|
|
EXPECT_EQ(fp.to(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, FalsePathTypeString) {
|
||
|
|
FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
EXPECT_EQ(fp.typePriority(), ExceptionPath::falsePathPriority());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, FalsePathTighterThan) {
|
||
|
|
FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
// FalsePath tighterThan always returns false
|
||
|
|
EXPECT_FALSE(fp1.tighterThan(&fp2));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, FalsePathMatches) {
|
||
|
|
FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
EXPECT_TRUE(fp.matches(MinMax::min(), false));
|
||
|
|
EXPECT_TRUE(fp.matches(MinMax::max(), false));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, FalsePathMatchesMinOnly) {
|
||
|
|
FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::min(), true, nullptr);
|
||
|
|
EXPECT_TRUE(fp.matches(MinMax::min(), false));
|
||
|
|
EXPECT_FALSE(fp.matches(MinMax::max(), false));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, FalsePathMergeable) {
|
||
|
|
FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
EXPECT_TRUE(fp1.mergeable(&fp2));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, FalsePathOverrides) {
|
||
|
|
FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
EXPECT_TRUE(fp1.overrides(&fp2));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, FalsePathClone) {
|
||
|
|
FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, "test comment");
|
||
|
|
ExceptionPath *clone = fp.clone(nullptr, nullptr, nullptr, true);
|
||
|
|
EXPECT_TRUE(clone->isFalse());
|
||
|
|
EXPECT_EQ(clone->minMax(), MinMaxAll::all());
|
||
|
|
delete clone;
|
||
|
|
}
|
||
|
|
|
||
|
|
// LoopPath
|
||
|
|
TEST_F(ExceptionPathTest, LoopPathBasic) {
|
||
|
|
LoopPath lp(nullptr, true);
|
||
|
|
EXPECT_TRUE(lp.isFalse());
|
||
|
|
EXPECT_TRUE(lp.isLoop());
|
||
|
|
EXPECT_FALSE(lp.isMultiCycle());
|
||
|
|
EXPECT_EQ(lp.type(), ExceptionPathType::loop);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, LoopPathNotMergeable) {
|
||
|
|
LoopPath lp1(nullptr, true);
|
||
|
|
LoopPath lp2(nullptr, true);
|
||
|
|
EXPECT_FALSE(lp1.mergeable(&lp2));
|
||
|
|
}
|
||
|
|
|
||
|
|
// PathDelay
|
||
|
|
TEST_F(ExceptionPathTest, PathDelayBasic) {
|
||
|
|
PathDelay pd(nullptr, nullptr, nullptr, MinMax::max(), false, false,
|
||
|
|
10.0e-9f, true, nullptr);
|
||
|
|
EXPECT_TRUE(pd.isPathDelay());
|
||
|
|
EXPECT_FALSE(pd.isFalse());
|
||
|
|
EXPECT_FALSE(pd.isMultiCycle());
|
||
|
|
EXPECT_EQ(pd.type(), ExceptionPathType::path_delay);
|
||
|
|
EXPECT_FLOAT_EQ(pd.delay(), 10.0e-9f);
|
||
|
|
EXPECT_FALSE(pd.ignoreClkLatency());
|
||
|
|
EXPECT_FALSE(pd.breakPath());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, PathDelayWithFlags) {
|
||
|
|
PathDelay pd(nullptr, nullptr, nullptr, MinMax::min(), true, true,
|
||
|
|
5.0e-9f, true, nullptr);
|
||
|
|
EXPECT_TRUE(pd.ignoreClkLatency());
|
||
|
|
EXPECT_TRUE(pd.breakPath());
|
||
|
|
EXPECT_FLOAT_EQ(pd.delay(), 5.0e-9f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, PathDelayTypePriority) {
|
||
|
|
PathDelay pd(nullptr, nullptr, nullptr, MinMax::max(), false, false,
|
||
|
|
0.0f, true, nullptr);
|
||
|
|
EXPECT_EQ(pd.typePriority(), ExceptionPath::pathDelayPriority());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, PathDelayTighterThanMax) {
|
||
|
|
PathDelay pd1(nullptr, nullptr, nullptr, MinMax::max(), false, false,
|
||
|
|
5.0e-9f, true, nullptr);
|
||
|
|
PathDelay pd2(nullptr, nullptr, nullptr, MinMax::max(), false, false,
|
||
|
|
10.0e-9f, true, nullptr);
|
||
|
|
// For max, tighter means smaller delay
|
||
|
|
EXPECT_TRUE(pd1.tighterThan(&pd2));
|
||
|
|
EXPECT_FALSE(pd2.tighterThan(&pd1));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, PathDelayTighterThanMin) {
|
||
|
|
PathDelay pd1(nullptr, nullptr, nullptr, MinMax::min(), false, false,
|
||
|
|
10.0e-9f, true, nullptr);
|
||
|
|
PathDelay pd2(nullptr, nullptr, nullptr, MinMax::min(), false, false,
|
||
|
|
5.0e-9f, true, nullptr);
|
||
|
|
// For min, tighter means larger delay
|
||
|
|
EXPECT_TRUE(pd1.tighterThan(&pd2));
|
||
|
|
EXPECT_FALSE(pd2.tighterThan(&pd1));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, PathDelayClone) {
|
||
|
|
PathDelay pd(nullptr, nullptr, nullptr, MinMax::max(), true, true,
|
||
|
|
7.0e-9f, true, nullptr);
|
||
|
|
ExceptionPath *clone = pd.clone(nullptr, nullptr, nullptr, true);
|
||
|
|
EXPECT_TRUE(clone->isPathDelay());
|
||
|
|
EXPECT_FLOAT_EQ(clone->delay(), 7.0e-9f);
|
||
|
|
EXPECT_TRUE(clone->ignoreClkLatency());
|
||
|
|
EXPECT_TRUE(clone->breakPath());
|
||
|
|
delete clone;
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, PathDelayOverrides) {
|
||
|
|
PathDelay pd1(nullptr, nullptr, nullptr, MinMax::max(), false, false,
|
||
|
|
5.0e-9f, true, nullptr);
|
||
|
|
PathDelay pd2(nullptr, nullptr, nullptr, MinMax::max(), false, false,
|
||
|
|
10.0e-9f, true, nullptr);
|
||
|
|
EXPECT_TRUE(pd1.overrides(&pd2));
|
||
|
|
}
|
||
|
|
|
||
|
|
// MultiCyclePath
|
||
|
|
TEST_F(ExceptionPathTest, MultiCyclePathBasic) {
|
||
|
|
MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::all(),
|
||
|
|
true, 3, true, nullptr);
|
||
|
|
EXPECT_TRUE(mcp.isMultiCycle());
|
||
|
|
EXPECT_FALSE(mcp.isFalse());
|
||
|
|
EXPECT_FALSE(mcp.isPathDelay());
|
||
|
|
EXPECT_EQ(mcp.type(), ExceptionPathType::multi_cycle);
|
||
|
|
EXPECT_EQ(mcp.pathMultiplier(), 3);
|
||
|
|
EXPECT_TRUE(mcp.useEndClk());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, MultiCyclePathTypePriority) {
|
||
|
|
MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::all(),
|
||
|
|
false, 2, true, nullptr);
|
||
|
|
EXPECT_EQ(mcp.typePriority(), ExceptionPath::multiCyclePathPriority());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, MultiCyclePathMultiplierAll) {
|
||
|
|
MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::all(),
|
||
|
|
true, 3, true, nullptr);
|
||
|
|
// When min_max_ is all and min_max arg is min, multiplier is 0
|
||
|
|
EXPECT_EQ(mcp.pathMultiplier(MinMax::min()), 0);
|
||
|
|
// For max, returns the actual multiplier
|
||
|
|
EXPECT_EQ(mcp.pathMultiplier(MinMax::max()), 3);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, MultiCyclePathMultiplierSpecific) {
|
||
|
|
MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::max(),
|
||
|
|
true, 5, true, nullptr);
|
||
|
|
EXPECT_EQ(mcp.pathMultiplier(MinMax::min()), 5);
|
||
|
|
EXPECT_EQ(mcp.pathMultiplier(MinMax::max()), 5);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, MultiCyclePathPriorityAll) {
|
||
|
|
MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::all(),
|
||
|
|
true, 3, true, nullptr);
|
||
|
|
int base_priority = mcp.priority();
|
||
|
|
// priority(min_max) returns priority_ + 1 when min_max_ == all
|
||
|
|
EXPECT_EQ(mcp.priority(MinMax::min()), base_priority + 1);
|
||
|
|
EXPECT_EQ(mcp.priority(MinMax::max()), base_priority + 1);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, MultiCyclePathPrioritySpecific) {
|
||
|
|
MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::max(),
|
||
|
|
true, 3, true, nullptr);
|
||
|
|
int base_priority = mcp.priority();
|
||
|
|
// priority(min_max) returns priority_ + 2 when min_max_ matches
|
||
|
|
EXPECT_EQ(mcp.priority(MinMax::max()), base_priority + 2);
|
||
|
|
// Returns base priority when doesn't match
|
||
|
|
EXPECT_EQ(mcp.priority(MinMax::min()), base_priority);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, MultiCyclePathMatchesAll) {
|
||
|
|
MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::all(),
|
||
|
|
true, 3, true, nullptr);
|
||
|
|
EXPECT_TRUE(mcp.matches(MinMax::min(), false));
|
||
|
|
EXPECT_TRUE(mcp.matches(MinMax::max(), false));
|
||
|
|
EXPECT_TRUE(mcp.matches(MinMax::min(), true));
|
||
|
|
EXPECT_TRUE(mcp.matches(MinMax::max(), true));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, MultiCyclePathMatchesMaxSetup) {
|
||
|
|
MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::max(),
|
||
|
|
true, 3, true, nullptr);
|
||
|
|
EXPECT_TRUE(mcp.matches(MinMax::max(), false));
|
||
|
|
EXPECT_TRUE(mcp.matches(MinMax::max(), true));
|
||
|
|
// For min path, not exact: should still match because multicycle setup
|
||
|
|
// affects hold checks
|
||
|
|
EXPECT_TRUE(mcp.matches(MinMax::min(), false));
|
||
|
|
// For min exact: should NOT match
|
||
|
|
EXPECT_FALSE(mcp.matches(MinMax::min(), true));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, MultiCyclePathTighterThan) {
|
||
|
|
MultiCyclePath mcp1(nullptr, nullptr, nullptr, MinMaxAll::all(),
|
||
|
|
true, 2, true, nullptr);
|
||
|
|
MultiCyclePath mcp2(nullptr, nullptr, nullptr, MinMaxAll::all(),
|
||
|
|
true, 5, true, nullptr);
|
||
|
|
EXPECT_TRUE(mcp1.tighterThan(&mcp2));
|
||
|
|
EXPECT_FALSE(mcp2.tighterThan(&mcp1));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, MultiCyclePathClone) {
|
||
|
|
MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::max(),
|
||
|
|
true, 4, true, nullptr);
|
||
|
|
ExceptionPath *clone = mcp.clone(nullptr, nullptr, nullptr, true);
|
||
|
|
EXPECT_TRUE(clone->isMultiCycle());
|
||
|
|
EXPECT_EQ(clone->pathMultiplier(), 4);
|
||
|
|
EXPECT_TRUE(clone->useEndClk());
|
||
|
|
delete clone;
|
||
|
|
}
|
||
|
|
|
||
|
|
// FilterPath
|
||
|
|
TEST_F(ExceptionPathTest, FilterPathBasic) {
|
||
|
|
FilterPath fp(nullptr, nullptr, nullptr, true);
|
||
|
|
EXPECT_TRUE(fp.isFilter());
|
||
|
|
EXPECT_FALSE(fp.isFalse());
|
||
|
|
EXPECT_FALSE(fp.isPathDelay());
|
||
|
|
EXPECT_EQ(fp.type(), ExceptionPathType::filter);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, FilterPathTypePriority) {
|
||
|
|
FilterPath fp(nullptr, nullptr, nullptr, true);
|
||
|
|
EXPECT_EQ(fp.typePriority(), ExceptionPath::filterPathPriority());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, FilterPathNotMergeable) {
|
||
|
|
FilterPath fp1(nullptr, nullptr, nullptr, true);
|
||
|
|
FilterPath fp2(nullptr, nullptr, nullptr, true);
|
||
|
|
EXPECT_FALSE(fp1.mergeable(&fp2));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, FilterPathNotOverrides) {
|
||
|
|
FilterPath fp1(nullptr, nullptr, nullptr, true);
|
||
|
|
FilterPath fp2(nullptr, nullptr, nullptr, true);
|
||
|
|
EXPECT_FALSE(fp1.overrides(&fp2));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, FilterPathTighterThan) {
|
||
|
|
FilterPath fp1(nullptr, nullptr, nullptr, true);
|
||
|
|
FilterPath fp2(nullptr, nullptr, nullptr, true);
|
||
|
|
EXPECT_FALSE(fp1.tighterThan(&fp2));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, FilterPathResetMatch) {
|
||
|
|
FilterPath fp(nullptr, nullptr, nullptr, true);
|
||
|
|
EXPECT_FALSE(fp.resetMatch(nullptr, nullptr, nullptr, MinMaxAll::all(), nullptr));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, FilterPathClone) {
|
||
|
|
FilterPath fp(nullptr, nullptr, nullptr, true);
|
||
|
|
ExceptionPath *clone = fp.clone(nullptr, nullptr, nullptr, true);
|
||
|
|
EXPECT_TRUE(clone->isFilter());
|
||
|
|
delete clone;
|
||
|
|
}
|
||
|
|
|
||
|
|
// GroupPath
|
||
|
|
TEST_F(ExceptionPathTest, GroupPathBasic) {
|
||
|
|
GroupPath gp("group1", false, nullptr, nullptr, nullptr, true, nullptr);
|
||
|
|
EXPECT_TRUE(gp.isGroupPath());
|
||
|
|
EXPECT_FALSE(gp.isFalse());
|
||
|
|
EXPECT_FALSE(gp.isPathDelay());
|
||
|
|
EXPECT_EQ(gp.type(), ExceptionPathType::group_path);
|
||
|
|
EXPECT_STREQ(gp.name(), "group1");
|
||
|
|
EXPECT_FALSE(gp.isDefault());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, GroupPathDefault) {
|
||
|
|
GroupPath gp("default_group", true, nullptr, nullptr, nullptr, true, nullptr);
|
||
|
|
EXPECT_TRUE(gp.isDefault());
|
||
|
|
EXPECT_STREQ(gp.name(), "default_group");
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, GroupPathTypePriority) {
|
||
|
|
GroupPath gp("gp", false, nullptr, nullptr, nullptr, true, nullptr);
|
||
|
|
EXPECT_EQ(gp.typePriority(), ExceptionPath::groupPathPriority());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, GroupPathTighterThan) {
|
||
|
|
GroupPath gp1("gp1", false, nullptr, nullptr, nullptr, true, nullptr);
|
||
|
|
GroupPath gp2("gp2", false, nullptr, nullptr, nullptr, true, nullptr);
|
||
|
|
EXPECT_FALSE(gp1.tighterThan(&gp2));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, GroupPathClone) {
|
||
|
|
GroupPath gp("gp_clone", true, nullptr, nullptr, nullptr, true, "comment");
|
||
|
|
ExceptionPath *clone = gp.clone(nullptr, nullptr, nullptr, true);
|
||
|
|
EXPECT_TRUE(clone->isGroupPath());
|
||
|
|
EXPECT_STREQ(clone->name(), "gp_clone");
|
||
|
|
EXPECT_TRUE(clone->isDefault());
|
||
|
|
delete clone;
|
||
|
|
}
|
||
|
|
|
||
|
|
// ExceptionPath general
|
||
|
|
TEST_F(ExceptionPathTest, PriorityValues) {
|
||
|
|
EXPECT_GT(ExceptionPath::falsePathPriority(), ExceptionPath::pathDelayPriority());
|
||
|
|
EXPECT_GT(ExceptionPath::pathDelayPriority(), ExceptionPath::multiCyclePathPriority());
|
||
|
|
EXPECT_GT(ExceptionPath::multiCyclePathPriority(), ExceptionPath::filterPathPriority());
|
||
|
|
EXPECT_GT(ExceptionPath::filterPathPriority(), ExceptionPath::groupPathPriority());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, FromThruToPriority) {
|
||
|
|
// No from/thru/to
|
||
|
|
EXPECT_EQ(ExceptionPath::fromThruToPriority(nullptr, nullptr, nullptr), 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, SetId) {
|
||
|
|
FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
EXPECT_EQ(fp.id(), 0u);
|
||
|
|
fp.setId(42);
|
||
|
|
EXPECT_EQ(fp.id(), 42u);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, SetPriority) {
|
||
|
|
FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
int orig_priority = fp.priority();
|
||
|
|
fp.setPriority(9999);
|
||
|
|
EXPECT_EQ(fp.priority(), 9999);
|
||
|
|
fp.setPriority(orig_priority);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, FirstPtNone) {
|
||
|
|
FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
EXPECT_EQ(fp.firstPt(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, FirstState) {
|
||
|
|
FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
ExceptionState *state = fp.firstState();
|
||
|
|
EXPECT_NE(state, nullptr);
|
||
|
|
// Should be complete since no from/thru/to
|
||
|
|
EXPECT_TRUE(state->isComplete());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, Hash) {
|
||
|
|
FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
// Same structure should produce same hash
|
||
|
|
EXPECT_EQ(fp1.hash(), fp2.hash());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, MergeablePts) {
|
||
|
|
FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
EXPECT_TRUE(fp1.mergeablePts(&fp2));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, IntersectsPts) {
|
||
|
|
FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
EXPECT_TRUE(fp1.intersectsPts(&fp2, nullptr));
|
||
|
|
}
|
||
|
|
|
||
|
|
// ExceptionState tests
|
||
|
|
TEST_F(ExceptionPathTest, ExceptionStateBasic) {
|
||
|
|
FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
ExceptionState *state = fp.firstState();
|
||
|
|
EXPECT_EQ(state->exception(), &fp);
|
||
|
|
EXPECT_EQ(state->nextThru(), nullptr);
|
||
|
|
EXPECT_EQ(state->index(), 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, ExceptionStateHash) {
|
||
|
|
FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
ExceptionState *state = fp.firstState();
|
||
|
|
// Hash should be deterministic
|
||
|
|
size_t h = state->hash();
|
||
|
|
EXPECT_EQ(h, state->hash());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, ExceptionStateLess) {
|
||
|
|
FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
fp1.setId(1);
|
||
|
|
FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
fp2.setId(2);
|
||
|
|
ExceptionState *s1 = fp1.firstState();
|
||
|
|
ExceptionState *s2 = fp2.firstState();
|
||
|
|
// state1 with lower id should be less
|
||
|
|
ExceptionStateLess less;
|
||
|
|
EXPECT_TRUE(less(s1, s2));
|
||
|
|
EXPECT_FALSE(less(s2, s1));
|
||
|
|
}
|
||
|
|
|
||
|
|
// EmptyExceptionPt
|
||
|
|
TEST_F(ExceptionPathTest, EmptyExceptionPtWhat) {
|
||
|
|
EmptyExpceptionPt e;
|
||
|
|
EXPECT_STREQ(e.what(), "empty exception from/through/to.");
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(ExceptionPathTest, CheckFromThrusToWithNulls) {
|
||
|
|
// nullptr from, thrus, to - should not throw
|
||
|
|
EXPECT_NO_THROW(checkFromThrusTo(nullptr, nullptr, nullptr));
|
||
|
|
}
|
||
|
|
|
||
|
|
// ExceptionPtIterator
|
||
|
|
TEST_F(ExceptionPathTest, PtIteratorEmpty) {
|
||
|
|
FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
ExceptionPtIterator iter(&fp);
|
||
|
|
EXPECT_FALSE(iter.hasNext());
|
||
|
|
}
|
||
|
|
|
||
|
|
// Default values
|
||
|
|
TEST_F(ExceptionPathTest, DefaultValues) {
|
||
|
|
FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
|
||
|
|
EXPECT_FALSE(fp.useEndClk());
|
||
|
|
EXPECT_EQ(fp.pathMultiplier(), 0);
|
||
|
|
EXPECT_FLOAT_EQ(fp.delay(), 0.0f);
|
||
|
|
EXPECT_EQ(fp.name(), nullptr);
|
||
|
|
EXPECT_FALSE(fp.isDefault());
|
||
|
|
EXPECT_FALSE(fp.ignoreClkLatency());
|
||
|
|
EXPECT_FALSE(fp.breakPath());
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////
|
||
|
|
// TimingRole tests
|
||
|
|
////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
class TimingRoleTest : public ::testing::Test {};
|
||
|
|
|
||
|
|
TEST_F(TimingRoleTest, Singletons) {
|
||
|
|
EXPECT_NE(TimingRole::wire(), nullptr);
|
||
|
|
EXPECT_NE(TimingRole::combinational(), nullptr);
|
||
|
|
EXPECT_NE(TimingRole::setup(), nullptr);
|
||
|
|
EXPECT_NE(TimingRole::hold(), nullptr);
|
||
|
|
EXPECT_NE(TimingRole::recovery(), nullptr);
|
||
|
|
EXPECT_NE(TimingRole::removal(), nullptr);
|
||
|
|
EXPECT_NE(TimingRole::regClkToQ(), nullptr);
|
||
|
|
EXPECT_NE(TimingRole::latchEnToQ(), nullptr);
|
||
|
|
EXPECT_NE(TimingRole::latchDtoQ(), nullptr);
|
||
|
|
EXPECT_NE(TimingRole::tristateEnable(), nullptr);
|
||
|
|
EXPECT_NE(TimingRole::tristateDisable(), nullptr);
|
||
|
|
EXPECT_NE(TimingRole::width(), nullptr);
|
||
|
|
EXPECT_NE(TimingRole::period(), nullptr);
|
||
|
|
EXPECT_NE(TimingRole::skew(), nullptr);
|
||
|
|
EXPECT_NE(TimingRole::nochange(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TimingRoleTest, OutputRoles) {
|
||
|
|
EXPECT_NE(TimingRole::outputSetup(), nullptr);
|
||
|
|
EXPECT_NE(TimingRole::outputHold(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TimingRoleTest, GatedClockRoles) {
|
||
|
|
EXPECT_NE(TimingRole::gatedClockSetup(), nullptr);
|
||
|
|
EXPECT_NE(TimingRole::gatedClockHold(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TimingRoleTest, LatchRoles) {
|
||
|
|
EXPECT_NE(TimingRole::latchSetup(), nullptr);
|
||
|
|
EXPECT_NE(TimingRole::latchHold(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TimingRoleTest, DataCheckRoles) {
|
||
|
|
EXPECT_NE(TimingRole::dataCheckSetup(), nullptr);
|
||
|
|
EXPECT_NE(TimingRole::dataCheckHold(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TimingRoleTest, NonSeqRoles) {
|
||
|
|
EXPECT_NE(TimingRole::nonSeqSetup(), nullptr);
|
||
|
|
EXPECT_NE(TimingRole::nonSeqHold(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TimingRoleTest, ClockTreePathRoles) {
|
||
|
|
EXPECT_NE(TimingRole::clockTreePathMin(), nullptr);
|
||
|
|
EXPECT_NE(TimingRole::clockTreePathMax(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TimingRoleTest, SdfIopath) {
|
||
|
|
EXPECT_NE(TimingRole::sdfIopath(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TimingRoleTest, IsTimingCheck) {
|
||
|
|
EXPECT_TRUE(TimingRole::setup()->isTimingCheck());
|
||
|
|
EXPECT_TRUE(TimingRole::hold()->isTimingCheck());
|
||
|
|
EXPECT_TRUE(TimingRole::recovery()->isTimingCheck());
|
||
|
|
EXPECT_TRUE(TimingRole::removal()->isTimingCheck());
|
||
|
|
EXPECT_FALSE(TimingRole::combinational()->isTimingCheck());
|
||
|
|
EXPECT_FALSE(TimingRole::wire()->isTimingCheck());
|
||
|
|
EXPECT_FALSE(TimingRole::regClkToQ()->isTimingCheck());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TimingRoleTest, IsWire) {
|
||
|
|
EXPECT_TRUE(TimingRole::wire()->isWire());
|
||
|
|
EXPECT_FALSE(TimingRole::setup()->isWire());
|
||
|
|
EXPECT_FALSE(TimingRole::combinational()->isWire());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TimingRoleTest, IsTimingCheckBetween) {
|
||
|
|
EXPECT_TRUE(TimingRole::setup()->isTimingCheckBetween());
|
||
|
|
EXPECT_TRUE(TimingRole::hold()->isTimingCheckBetween());
|
||
|
|
// width and period are timing checks but not "between"
|
||
|
|
EXPECT_FALSE(TimingRole::width()->isTimingCheckBetween());
|
||
|
|
EXPECT_FALSE(TimingRole::period()->isTimingCheckBetween());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TimingRoleTest, IsNonSeqTimingCheck) {
|
||
|
|
EXPECT_TRUE(TimingRole::nonSeqSetup()->isNonSeqTimingCheck());
|
||
|
|
EXPECT_TRUE(TimingRole::nonSeqHold()->isNonSeqTimingCheck());
|
||
|
|
EXPECT_FALSE(TimingRole::setup()->isNonSeqTimingCheck());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TimingRoleTest, PathMinMax) {
|
||
|
|
EXPECT_EQ(TimingRole::setup()->pathMinMax(), MinMax::max());
|
||
|
|
EXPECT_EQ(TimingRole::hold()->pathMinMax(), MinMax::min());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TimingRoleTest, FindByName) {
|
||
|
|
EXPECT_EQ(TimingRole::find("setup"), TimingRole::setup());
|
||
|
|
EXPECT_EQ(TimingRole::find("hold"), TimingRole::hold());
|
||
|
|
EXPECT_EQ(TimingRole::find("combinational"), TimingRole::combinational());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TimingRoleTest, UniqueIndices) {
|
||
|
|
// All timing roles should have unique indices
|
||
|
|
EXPECT_NE(TimingRole::setup()->index(), TimingRole::hold()->index());
|
||
|
|
EXPECT_NE(TimingRole::setup()->index(), TimingRole::combinational()->index());
|
||
|
|
EXPECT_NE(TimingRole::wire()->index(), TimingRole::combinational()->index());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TimingRoleTest, GenericRole) {
|
||
|
|
// setup generic role is setup itself
|
||
|
|
EXPECT_EQ(TimingRole::setup()->genericRole(), TimingRole::setup());
|
||
|
|
EXPECT_EQ(TimingRole::hold()->genericRole(), TimingRole::hold());
|
||
|
|
// output setup generic role is setup
|
||
|
|
EXPECT_EQ(TimingRole::outputSetup()->genericRole(), TimingRole::setup());
|
||
|
|
EXPECT_EQ(TimingRole::outputHold()->genericRole(), TimingRole::hold());
|
||
|
|
EXPECT_EQ(TimingRole::gatedClockSetup()->genericRole(), TimingRole::setup());
|
||
|
|
EXPECT_EQ(TimingRole::gatedClockHold()->genericRole(), TimingRole::hold());
|
||
|
|
EXPECT_EQ(TimingRole::latchSetup()->genericRole(), TimingRole::setup());
|
||
|
|
EXPECT_EQ(TimingRole::latchHold()->genericRole(), TimingRole::hold());
|
||
|
|
EXPECT_EQ(TimingRole::recovery()->genericRole(), TimingRole::setup());
|
||
|
|
EXPECT_EQ(TimingRole::removal()->genericRole(), TimingRole::hold());
|
||
|
|
EXPECT_EQ(TimingRole::dataCheckSetup()->genericRole(), TimingRole::setup());
|
||
|
|
EXPECT_EQ(TimingRole::dataCheckHold()->genericRole(), TimingRole::hold());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TimingRoleTest, Less) {
|
||
|
|
EXPECT_TRUE(TimingRole::less(TimingRole::wire(), TimingRole::setup()));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TimingRoleTest, IsDataCheck) {
|
||
|
|
EXPECT_TRUE(TimingRole::dataCheckSetup()->isDataCheck());
|
||
|
|
EXPECT_TRUE(TimingRole::dataCheckHold()->isDataCheck());
|
||
|
|
EXPECT_FALSE(TimingRole::setup()->isDataCheck());
|
||
|
|
EXPECT_FALSE(TimingRole::hold()->isDataCheck());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TimingRoleTest, IsLatchDtoQ) {
|
||
|
|
EXPECT_TRUE(TimingRole::latchDtoQ()->isLatchDtoQ());
|
||
|
|
EXPECT_FALSE(TimingRole::latchEnToQ()->isLatchDtoQ());
|
||
|
|
EXPECT_FALSE(TimingRole::regClkToQ()->isLatchDtoQ());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TimingRoleTest, IsAsyncTimingCheck) {
|
||
|
|
EXPECT_TRUE(TimingRole::recovery()->isAsyncTimingCheck());
|
||
|
|
EXPECT_TRUE(TimingRole::removal()->isAsyncTimingCheck());
|
||
|
|
EXPECT_FALSE(TimingRole::setup()->isAsyncTimingCheck());
|
||
|
|
EXPECT_FALSE(TimingRole::hold()->isAsyncTimingCheck());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TimingRoleTest, ToString) {
|
||
|
|
EXPECT_EQ(TimingRole::setup()->to_string(), "setup");
|
||
|
|
EXPECT_EQ(TimingRole::hold()->to_string(), "hold");
|
||
|
|
EXPECT_EQ(TimingRole::combinational()->to_string(), "combinational");
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TimingRoleTest, IndexMax) {
|
||
|
|
int idx_max = TimingRole::index_max;
|
||
|
|
EXPECT_GE(idx_max, 20);
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////
|
||
|
|
// RiseFallMinMax tests (for coverage of Clock slews)
|
||
|
|
////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
class RiseFallMinMaxTest : public ::testing::Test {};
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, DefaultEmpty) {
|
||
|
|
RiseFallMinMax rfmm;
|
||
|
|
EXPECT_TRUE(rfmm.empty());
|
||
|
|
EXPECT_FALSE(rfmm.hasValue());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, InitValueConstructor) {
|
||
|
|
RiseFallMinMax rfmm(1.0f);
|
||
|
|
EXPECT_FALSE(rfmm.empty());
|
||
|
|
EXPECT_TRUE(rfmm.hasValue());
|
||
|
|
EXPECT_FLOAT_EQ(rfmm.value(RiseFall::rise(), MinMax::min()), 1.0f);
|
||
|
|
EXPECT_FLOAT_EQ(rfmm.value(RiseFall::rise(), MinMax::max()), 1.0f);
|
||
|
|
EXPECT_FLOAT_EQ(rfmm.value(RiseFall::fall(), MinMax::min()), 1.0f);
|
||
|
|
EXPECT_FLOAT_EQ(rfmm.value(RiseFall::fall(), MinMax::max()), 1.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, CopyConstructor) {
|
||
|
|
RiseFallMinMax rfmm1(2.0f);
|
||
|
|
RiseFallMinMax rfmm2(&rfmm1);
|
||
|
|
EXPECT_FLOAT_EQ(rfmm2.value(RiseFall::rise(), MinMax::min()), 2.0f);
|
||
|
|
EXPECT_FLOAT_EQ(rfmm2.value(RiseFall::fall(), MinMax::max()), 2.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, SetValueAll) {
|
||
|
|
RiseFallMinMax rfmm;
|
||
|
|
rfmm.setValue(5.0f);
|
||
|
|
EXPECT_FLOAT_EQ(rfmm.value(RiseFall::rise(), MinMax::min()), 5.0f);
|
||
|
|
EXPECT_FLOAT_EQ(rfmm.value(RiseFall::rise(), MinMax::max()), 5.0f);
|
||
|
|
EXPECT_FLOAT_EQ(rfmm.value(RiseFall::fall(), MinMax::min()), 5.0f);
|
||
|
|
EXPECT_FLOAT_EQ(rfmm.value(RiseFall::fall(), MinMax::max()), 5.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, SetValueRfMm) {
|
||
|
|
RiseFallMinMax rfmm;
|
||
|
|
rfmm.setValue(RiseFall::rise(), MinMax::min(), 1.0f);
|
||
|
|
rfmm.setValue(RiseFall::rise(), MinMax::max(), 2.0f);
|
||
|
|
rfmm.setValue(RiseFall::fall(), MinMax::min(), 3.0f);
|
||
|
|
rfmm.setValue(RiseFall::fall(), MinMax::max(), 4.0f);
|
||
|
|
EXPECT_FLOAT_EQ(rfmm.value(RiseFall::rise(), MinMax::min()), 1.0f);
|
||
|
|
EXPECT_FLOAT_EQ(rfmm.value(RiseFall::rise(), MinMax::max()), 2.0f);
|
||
|
|
EXPECT_FLOAT_EQ(rfmm.value(RiseFall::fall(), MinMax::min()), 3.0f);
|
||
|
|
EXPECT_FLOAT_EQ(rfmm.value(RiseFall::fall(), MinMax::max()), 4.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, SetValueRfBothMmAll) {
|
||
|
|
RiseFallMinMax rfmm;
|
||
|
|
rfmm.setValue(RiseFallBoth::riseFall(), MinMaxAll::all(), 10.0f);
|
||
|
|
EXPECT_FLOAT_EQ(rfmm.value(RiseFall::rise(), MinMax::min()), 10.0f);
|
||
|
|
EXPECT_FLOAT_EQ(rfmm.value(RiseFall::fall(), MinMax::max()), 10.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, SetValueRfBothMm) {
|
||
|
|
RiseFallMinMax rfmm;
|
||
|
|
rfmm.setValue(RiseFallBoth::rise(), MinMax::max(), 7.0f);
|
||
|
|
EXPECT_TRUE(rfmm.hasValue(RiseFall::rise(), MinMax::max()));
|
||
|
|
EXPECT_FALSE(rfmm.hasValue(RiseFall::fall(), MinMax::max()));
|
||
|
|
EXPECT_FLOAT_EQ(rfmm.value(RiseFall::rise(), MinMax::max()), 7.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, HasValue) {
|
||
|
|
RiseFallMinMax rfmm;
|
||
|
|
EXPECT_FALSE(rfmm.hasValue(RiseFall::rise(), MinMax::min()));
|
||
|
|
rfmm.setValue(RiseFall::rise(), MinMax::min(), 1.0f);
|
||
|
|
EXPECT_TRUE(rfmm.hasValue(RiseFall::rise(), MinMax::min()));
|
||
|
|
EXPECT_FALSE(rfmm.hasValue(RiseFall::fall(), MinMax::min()));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, ValueWithExists) {
|
||
|
|
RiseFallMinMax rfmm;
|
||
|
|
float val;
|
||
|
|
bool exists;
|
||
|
|
rfmm.value(RiseFall::rise(), MinMax::min(), val, exists);
|
||
|
|
EXPECT_FALSE(exists);
|
||
|
|
|
||
|
|
rfmm.setValue(RiseFall::rise(), MinMax::min(), 3.14f);
|
||
|
|
rfmm.value(RiseFall::rise(), MinMax::min(), val, exists);
|
||
|
|
EXPECT_TRUE(exists);
|
||
|
|
EXPECT_FLOAT_EQ(val, 3.14f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, MaxValue) {
|
||
|
|
RiseFallMinMax rfmm;
|
||
|
|
float max_val;
|
||
|
|
bool exists;
|
||
|
|
rfmm.maxValue(max_val, exists);
|
||
|
|
EXPECT_FALSE(exists);
|
||
|
|
|
||
|
|
rfmm.setValue(RiseFall::rise(), MinMax::min(), 1.0f);
|
||
|
|
rfmm.setValue(RiseFall::fall(), MinMax::max(), 5.0f);
|
||
|
|
rfmm.maxValue(max_val, exists);
|
||
|
|
EXPECT_TRUE(exists);
|
||
|
|
EXPECT_FLOAT_EQ(max_val, 5.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, ValueMinMaxOnly) {
|
||
|
|
RiseFallMinMax rfmm;
|
||
|
|
rfmm.setValue(RiseFall::rise(), MinMax::min(), 3.0f);
|
||
|
|
rfmm.setValue(RiseFall::fall(), MinMax::min(), 7.0f);
|
||
|
|
// value(MinMax) returns the min of rise/fall for min, max of rise/fall for max
|
||
|
|
float val = rfmm.value(MinMax::min());
|
||
|
|
EXPECT_FLOAT_EQ(val, 3.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, ValueMinMaxOnlyMax) {
|
||
|
|
RiseFallMinMax rfmm;
|
||
|
|
rfmm.setValue(RiseFall::rise(), MinMax::max(), 3.0f);
|
||
|
|
rfmm.setValue(RiseFall::fall(), MinMax::max(), 7.0f);
|
||
|
|
float val = rfmm.value(MinMax::max());
|
||
|
|
EXPECT_FLOAT_EQ(val, 7.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, Clear) {
|
||
|
|
RiseFallMinMax rfmm(3.0f);
|
||
|
|
EXPECT_FALSE(rfmm.empty());
|
||
|
|
rfmm.clear();
|
||
|
|
EXPECT_TRUE(rfmm.empty());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, RemoveValue) {
|
||
|
|
RiseFallMinMax rfmm(1.0f);
|
||
|
|
EXPECT_TRUE(rfmm.hasValue(RiseFall::rise(), MinMax::min()));
|
||
|
|
rfmm.removeValue(RiseFallBoth::rise(), MinMax::min());
|
||
|
|
EXPECT_FALSE(rfmm.hasValue(RiseFall::rise(), MinMax::min()));
|
||
|
|
// Other values still exist
|
||
|
|
EXPECT_TRUE(rfmm.hasValue(RiseFall::rise(), MinMax::max()));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, RemoveValueAll) {
|
||
|
|
RiseFallMinMax rfmm(1.0f);
|
||
|
|
rfmm.removeValue(RiseFallBoth::riseFall(), MinMaxAll::all());
|
||
|
|
EXPECT_TRUE(rfmm.empty());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, MergeValue) {
|
||
|
|
RiseFallMinMax rfmm;
|
||
|
|
rfmm.setValue(RiseFall::rise(), MinMax::min(), 5.0f);
|
||
|
|
// Merge a smaller value for min - should take it
|
||
|
|
rfmm.mergeValue(RiseFall::rise(), MinMax::min(), 3.0f);
|
||
|
|
EXPECT_FLOAT_EQ(rfmm.value(RiseFall::rise(), MinMax::min()), 3.0f);
|
||
|
|
// Merge a larger value for min - should not take it
|
||
|
|
rfmm.mergeValue(RiseFall::rise(), MinMax::min(), 10.0f);
|
||
|
|
EXPECT_FLOAT_EQ(rfmm.value(RiseFall::rise(), MinMax::min()), 3.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, MergeValueMax) {
|
||
|
|
RiseFallMinMax rfmm;
|
||
|
|
rfmm.setValue(RiseFall::rise(), MinMax::max(), 5.0f);
|
||
|
|
// Merge a larger value for max - should take it
|
||
|
|
rfmm.mergeValue(RiseFall::rise(), MinMax::max(), 10.0f);
|
||
|
|
EXPECT_FLOAT_EQ(rfmm.value(RiseFall::rise(), MinMax::max()), 10.0f);
|
||
|
|
// Merge a smaller value for max - should not take it
|
||
|
|
rfmm.mergeValue(RiseFall::rise(), MinMax::max(), 3.0f);
|
||
|
|
EXPECT_FLOAT_EQ(rfmm.value(RiseFall::rise(), MinMax::max()), 10.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, MergeValueBoth) {
|
||
|
|
RiseFallMinMax rfmm;
|
||
|
|
rfmm.mergeValue(RiseFallBoth::riseFall(), MinMaxAll::all(), 5.0f);
|
||
|
|
EXPECT_FLOAT_EQ(rfmm.value(RiseFall::rise(), MinMax::min()), 5.0f);
|
||
|
|
EXPECT_FLOAT_EQ(rfmm.value(RiseFall::fall(), MinMax::max()), 5.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, MergeWith) {
|
||
|
|
RiseFallMinMax rfmm1;
|
||
|
|
rfmm1.setValue(RiseFall::rise(), MinMax::min(), 5.0f);
|
||
|
|
rfmm1.setValue(RiseFall::rise(), MinMax::max(), 5.0f);
|
||
|
|
|
||
|
|
RiseFallMinMax rfmm2;
|
||
|
|
rfmm2.setValue(RiseFall::rise(), MinMax::min(), 3.0f);
|
||
|
|
rfmm2.setValue(RiseFall::rise(), MinMax::max(), 10.0f);
|
||
|
|
rfmm2.setValue(RiseFall::fall(), MinMax::min(), 2.0f);
|
||
|
|
|
||
|
|
rfmm1.mergeWith(&rfmm2);
|
||
|
|
// min: should take 3 (smaller)
|
||
|
|
EXPECT_FLOAT_EQ(rfmm1.value(RiseFall::rise(), MinMax::min()), 3.0f);
|
||
|
|
// max: should take 10 (larger)
|
||
|
|
EXPECT_FLOAT_EQ(rfmm1.value(RiseFall::rise(), MinMax::max()), 10.0f);
|
||
|
|
// fall min: rfmm1 had no value, rfmm2 had 2, so should be 2
|
||
|
|
EXPECT_FLOAT_EQ(rfmm1.value(RiseFall::fall(), MinMax::min()), 2.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, SetValues) {
|
||
|
|
RiseFallMinMax rfmm1(3.0f);
|
||
|
|
RiseFallMinMax rfmm2;
|
||
|
|
rfmm2.setValues(&rfmm1);
|
||
|
|
EXPECT_TRUE(rfmm2.equal(&rfmm1));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, Equal) {
|
||
|
|
RiseFallMinMax rfmm1(1.0f);
|
||
|
|
RiseFallMinMax rfmm2(1.0f);
|
||
|
|
EXPECT_TRUE(rfmm1.equal(&rfmm2));
|
||
|
|
|
||
|
|
rfmm2.setValue(RiseFall::rise(), MinMax::min(), 2.0f);
|
||
|
|
EXPECT_FALSE(rfmm1.equal(&rfmm2));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, EqualDifferentExists) {
|
||
|
|
RiseFallMinMax rfmm1;
|
||
|
|
rfmm1.setValue(RiseFall::rise(), MinMax::min(), 1.0f);
|
||
|
|
RiseFallMinMax rfmm2;
|
||
|
|
EXPECT_FALSE(rfmm1.equal(&rfmm2));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, IsOneValue) {
|
||
|
|
RiseFallMinMax rfmm(5.0f);
|
||
|
|
EXPECT_TRUE(rfmm.isOneValue());
|
||
|
|
|
||
|
|
rfmm.setValue(RiseFall::rise(), MinMax::min(), 3.0f);
|
||
|
|
EXPECT_FALSE(rfmm.isOneValue());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, IsOneValueWithReturn) {
|
||
|
|
RiseFallMinMax rfmm(5.0f);
|
||
|
|
float val;
|
||
|
|
EXPECT_TRUE(rfmm.isOneValue(val));
|
||
|
|
EXPECT_FLOAT_EQ(val, 5.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, IsOneValueEmpty) {
|
||
|
|
RiseFallMinMax rfmm;
|
||
|
|
float val;
|
||
|
|
EXPECT_FALSE(rfmm.isOneValue(val));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, IsOneValueMinMax) {
|
||
|
|
RiseFallMinMax rfmm;
|
||
|
|
rfmm.setValue(RiseFall::rise(), MinMax::min(), 5.0f);
|
||
|
|
rfmm.setValue(RiseFall::fall(), MinMax::min(), 5.0f);
|
||
|
|
float val;
|
||
|
|
EXPECT_TRUE(rfmm.isOneValue(MinMax::min(), val));
|
||
|
|
EXPECT_FLOAT_EQ(val, 5.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, IsOneValueMinMaxDifferent) {
|
||
|
|
RiseFallMinMax rfmm;
|
||
|
|
rfmm.setValue(RiseFall::rise(), MinMax::min(), 5.0f);
|
||
|
|
rfmm.setValue(RiseFall::fall(), MinMax::min(), 3.0f);
|
||
|
|
float val;
|
||
|
|
EXPECT_FALSE(rfmm.isOneValue(MinMax::min(), val));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, IsOneValueMinMaxEmpty) {
|
||
|
|
RiseFallMinMax rfmm;
|
||
|
|
float val;
|
||
|
|
EXPECT_FALSE(rfmm.isOneValue(MinMax::min(), val));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(RiseFallMinMaxTest, IsOneValueMinMaxPartialExists) {
|
||
|
|
RiseFallMinMax rfmm;
|
||
|
|
rfmm.setValue(RiseFall::rise(), MinMax::min(), 5.0f);
|
||
|
|
// fall/min does not exist
|
||
|
|
float val;
|
||
|
|
EXPECT_FALSE(rfmm.isOneValue(MinMax::min(), val));
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////
|
||
|
|
// Scene tests (Corner was renamed to Scene)
|
||
|
|
////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
class SceneTest : public ::testing::Test {};
|
||
|
|
|
||
|
|
TEST_F(SceneTest, BasicConstruction) {
|
||
|
|
Scene scene("default", 0, nullptr, nullptr);
|
||
|
|
EXPECT_EQ(scene.name(), "default");
|
||
|
|
EXPECT_EQ(scene.index(), 0u);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(SceneTest, DifferentIndex) {
|
||
|
|
Scene scene("fast", 1, nullptr, nullptr);
|
||
|
|
EXPECT_EQ(scene.name(), "fast");
|
||
|
|
EXPECT_EQ(scene.index(), 1u);
|
||
|
|
}
|
||
|
|
|
||
|
|
} // namespace sta
|