Skip to content

Commit 695035f

Browse files
DevmateUtgenCppGeneralFBOrg Botfacebook-github-bot
authored andcommitted
xplat/js/react-native-github/packages/react-native/ReactCommon/react/renderer/components/text/platform/android/react/renderer/components/text/HostPlatformParagraphProps.cpp
Reviewed By: javache Differential Revision: D107233651
1 parent 3278f30 commit 695035f

1 file changed

Lines changed: 151 additions & 0 deletions

File tree

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
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 <react/renderer/components/text/HostPlatformParagraphProps.h>
9+
10+
#include <gtest/gtest.h>
11+
12+
// HostPlatformParagraphProps in this .cpp file is the Android-specific
13+
// implementation. On non-Android platforms `HostPlatformParagraphProps` is a
14+
// type alias to `BaseParagraphProps`, the Android-only fields
15+
// (`disabled`, `selectionColor`, `dataDetectorType`) do not exist, and
16+
// `getDiffProps` / `getDiffPropsImplementationTarget` are not defined. Guard
17+
// the tests with `RN_SERIALIZABLE_STATE`, which is only defined for the
18+
// Android build, so they compile and run only where the code under test
19+
// actually exists.
20+
#ifdef RN_SERIALIZABLE_STATE
21+
22+
#include <react/renderer/components/text/primitives.h>
23+
#include <react/renderer/graphics/Color.h>
24+
25+
namespace facebook::react {
26+
27+
namespace {
28+
29+
folly::dynamic diffAgainstDefault(const HostPlatformParagraphProps& props) {
30+
const HostPlatformParagraphProps defaultProps{};
31+
return props.getDiffProps(&defaultProps);
32+
}
33+
34+
} // namespace
35+
36+
TEST(HostPlatformParagraphPropsTest, getDiffPropsEmitsDisabledWhenChanged) {
37+
HostPlatformParagraphProps props;
38+
props.disabled = true;
39+
40+
auto diff = diffAgainstDefault(props);
41+
42+
ASSERT_TRUE(diff.isObject());
43+
ASSERT_NE(diff.find("disabled"), diff.items().end());
44+
EXPECT_TRUE(diff["disabled"].asBool());
45+
}
46+
47+
TEST(
48+
HostPlatformParagraphPropsTest,
49+
getDiffPropsOmitsDisabledWhenUnchangedBetweenIdenticalProps) {
50+
HostPlatformParagraphProps oldProps;
51+
oldProps.disabled = true;
52+
HostPlatformParagraphProps newProps;
53+
newProps.disabled = true;
54+
55+
auto diff = newProps.getDiffProps(&oldProps);
56+
57+
EXPECT_EQ(diff.find("disabled"), diff.items().end());
58+
}
59+
60+
TEST(
61+
HostPlatformParagraphPropsTest,
62+
getDiffPropsSerializesSelectionColorValueWhenSet) {
63+
HostPlatformParagraphProps props;
64+
// Use a non-default color so the diff branch is taken and we can assert
65+
// on the serialized integer representation.
66+
auto color = colorFromRGBA(/*r=*/10, /*g=*/20, /*b=*/30, /*a=*/255);
67+
props.selectionColor = color;
68+
69+
auto diff = diffAgainstDefault(props);
70+
71+
ASSERT_NE(diff.find("selectionColor"), diff.items().end());
72+
// `selectionColor` is serialized via the `toDynamic(SharedColor)` helper,
73+
// which dereferences the underlying `Color`. The result must equal the
74+
// dynamic representation of the same `Color`.
75+
EXPECT_EQ(diff["selectionColor"], folly::dynamic(*color));
76+
}
77+
78+
TEST(
79+
HostPlatformParagraphPropsTest,
80+
getDiffPropsSerializesSelectionColorAsNullWhenClearedFromPrevious) {
81+
HostPlatformParagraphProps oldProps;
82+
oldProps.selectionColor = colorFromRGBA(255, 0, 0, 255);
83+
HostPlatformParagraphProps newProps;
84+
// newProps.selectionColor is std::nullopt by default — simulates the user
85+
// clearing the prop.
86+
87+
auto diff = newProps.getDiffProps(&oldProps);
88+
89+
ASSERT_NE(diff.find("selectionColor"), diff.items().end());
90+
EXPECT_TRUE(diff["selectionColor"].isNull());
91+
}
92+
93+
TEST(
94+
HostPlatformParagraphPropsTest,
95+
getDiffPropsSerializesDataDetectorTypeAsString) {
96+
HostPlatformParagraphProps props;
97+
props.dataDetectorType = DataDetectorType::PhoneNumber;
98+
99+
auto diff = diffAgainstDefault(props);
100+
101+
ASSERT_NE(diff.find("dataDetectorType"), diff.items().end());
102+
// The diff stores the stringified enum (see `toString(DataDetectorType)`),
103+
// not the raw integer — a regression that drops the conversion would fail
104+
// this assertion.
105+
EXPECT_EQ(diff["dataDetectorType"].asString(), "phoneNumber");
106+
}
107+
108+
TEST(
109+
HostPlatformParagraphPropsTest,
110+
getDiffPropsForwardsParagraphAttributeChanges) {
111+
HostPlatformParagraphProps props;
112+
props.paragraphAttributes.maximumNumberOfLines = 3;
113+
props.paragraphAttributes.ellipsizeMode = EllipsizeMode::Middle;
114+
props.isSelectable = true;
115+
116+
auto diff = diffAgainstDefault(props);
117+
118+
// The diff bundles paragraph-level attribute changes alongside the
119+
// host-platform-specific fields. These keys must be present with the
120+
// values we set.
121+
ASSERT_NE(diff.find("numberOfLines"), diff.items().end());
122+
EXPECT_EQ(diff["numberOfLines"].asInt(), 3);
123+
124+
ASSERT_NE(diff.find("ellipsizeMode"), diff.items().end());
125+
EXPECT_EQ(diff["ellipsizeMode"].asString(), "middle");
126+
127+
ASSERT_NE(diff.find("selectable"), diff.items().end());
128+
EXPECT_TRUE(diff["selectable"].asBool());
129+
}
130+
131+
TEST(
132+
HostPlatformParagraphPropsTest,
133+
getDiffPropsUsesDefaultsWhenPrevPropsIsNull) {
134+
HostPlatformParagraphProps props;
135+
props.disabled = true;
136+
props.dataDetectorType = DataDetectorType::Email;
137+
138+
// Passing nullptr must fall back to a default-constructed instance for
139+
// comparison, so non-default fields still appear in the diff.
140+
auto diff = props.getDiffProps(/*prevProps=*/nullptr);
141+
142+
ASSERT_NE(diff.find("disabled"), diff.items().end());
143+
EXPECT_TRUE(diff["disabled"].asBool());
144+
145+
ASSERT_NE(diff.find("dataDetectorType"), diff.items().end());
146+
EXPECT_EQ(diff["dataDetectorType"].asString(), "email");
147+
}
148+
149+
} // namespace facebook::react
150+
151+
#endif // RN_SERIALIZABLE_STATE

0 commit comments

Comments
 (0)