#include #include #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