Skip to content

Commit 9c797e0

Browse files
DevmateUtgenCppGeneralFBOrg Botfacebook-github-bot
authored andcommitted
xplat/js/react-native-github/packages/react-native/ReactCommon/yoga/yoga/event/event.cpp
Reviewed By: cortinico Differential Revision: D111680864
1 parent b58c046 commit 9c797e0

1 file changed

Lines changed: 124 additions & 0 deletions

File tree

tests/EventPublisherTest.cpp

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#include <gtest/gtest.h>
9+
#include <yoga/Yoga.h>
10+
#include <yoga/event/event.h>
11+
12+
#include <array>
13+
#include <string_view>
14+
#include <unordered_set>
15+
16+
namespace facebook::yoga::test {
17+
18+
// Every enum value declared in LayoutPassReason (excluding the COUNT sentinel).
19+
// Kept in sync with yoga/event/event.h; a missing entry causes the "all known
20+
// reasons" test to catch the omission on the next run.
21+
constexpr std::array<LayoutPassReason, 9> kAllKnownReasons = {
22+
LayoutPassReason::kInitial,
23+
LayoutPassReason::kAbsLayout,
24+
LayoutPassReason::kStretch,
25+
LayoutPassReason::kMultilineStretch,
26+
LayoutPassReason::kFlexLayout,
27+
LayoutPassReason::kMeasureChild,
28+
LayoutPassReason::kAbsMeasureChild,
29+
LayoutPassReason::kFlexMeasure,
30+
LayoutPassReason::kGridLayout,
31+
};
32+
33+
TEST(
34+
LayoutPassReasonToStringTest,
35+
everyKnownReasonMapsToDistinctNonUnknownLabel) {
36+
std::unordered_set<std::string_view> labels;
37+
for (auto reason : kAllKnownReasons) {
38+
const char* label = LayoutPassReasonToString(reason);
39+
ASSERT_NE(label, nullptr)
40+
<< "LayoutPassReasonToString returned nullptr for enum value "
41+
<< static_cast<int>(reason);
42+
EXPECT_STRNE(label, "")
43+
<< "Empty label for enum value " << static_cast<int>(reason);
44+
EXPECT_STRNE(label, "unknown")
45+
<< "Enum value " << static_cast<int>(reason)
46+
<< " unexpectedly fell through to the default case";
47+
labels.emplace(label);
48+
}
49+
EXPECT_EQ(labels.size(), kAllKnownReasons.size())
50+
<< "At least two LayoutPassReason values share the same label";
51+
}
52+
53+
TEST(LayoutPassReasonToStringTest, fallsBackToUnknownForUnrecognizedValues) {
54+
// Out-of-range integer cast: exercises the switch's default branch, which
55+
// guards against silent regressions when new enum values are added without
56+
// updating the switch.
57+
EXPECT_STREQ(
58+
LayoutPassReasonToString(static_cast<LayoutPassReason>(9999)), "unknown");
59+
60+
// COUNT is the sentinel used to size arrays and is not a real reason, so
61+
// it must also fall through to the default case.
62+
EXPECT_STREQ(LayoutPassReasonToString(LayoutPassReason::COUNT), "unknown");
63+
}
64+
65+
class EventPublisherTest : public ::testing::Test {
66+
protected:
67+
// Event maintains a process-global subscriber list; clear it around each
68+
// test to keep the tests independent regardless of ordering.
69+
void SetUp() override {
70+
Event::reset();
71+
}
72+
void TearDown() override {
73+
Event::reset();
74+
}
75+
};
76+
77+
TEST_F(
78+
EventPublisherTest,
79+
resetDetachesPreviouslyRegisteredSubscribersFromFutureEvents) {
80+
int callCount = 0;
81+
Event::subscribe(
82+
[&](YGNodeConstRef, Event::Type, Event::Data) { ++callCount; });
83+
84+
// Sanity-check that the subscriber is actually wired up before reset.
85+
Event::publish<Event::LayoutPassStart>(nullptr);
86+
ASSERT_EQ(callCount, 1);
87+
88+
Event::reset();
89+
Event::publish<Event::LayoutPassStart>(nullptr);
90+
Event::publish<Event::LayoutPassEnd>(
91+
nullptr, Event::TypedData<Event::LayoutPassEnd>{nullptr});
92+
93+
EXPECT_EQ(callCount, 1)
94+
<< "Subscriber should not have been invoked after Event::reset()";
95+
}
96+
97+
TEST_F(EventPublisherTest, publishForwardsToEverySubscriberWithNodeAndType) {
98+
YGNodeRef sentinelNode = YGNodeNew();
99+
100+
int subscriberACallCount = 0;
101+
int subscriberBCallCount = 0;
102+
YGNodeConstRef subscriberAReceivedNode = nullptr;
103+
Event::Type subscriberAReceivedType = Event::NodeAllocation;
104+
105+
Event::subscribe([&](YGNodeConstRef node, Event::Type type, Event::Data) {
106+
++subscriberACallCount;
107+
subscriberAReceivedNode = node;
108+
subscriberAReceivedType = type;
109+
});
110+
Event::subscribe([&](YGNodeConstRef, Event::Type, Event::Data) {
111+
++subscriberBCallCount;
112+
});
113+
114+
Event::publish<Event::LayoutPassStart>(sentinelNode);
115+
116+
EXPECT_EQ(subscriberACallCount, 1);
117+
EXPECT_EQ(subscriberBCallCount, 1);
118+
EXPECT_EQ(subscriberAReceivedNode, sentinelNode);
119+
EXPECT_EQ(subscriberAReceivedType, Event::LayoutPassStart);
120+
121+
YGNodeFree(sentinelNode);
122+
}
123+
124+
} // namespace facebook::yoga::test

0 commit comments

Comments
 (0)