1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "gtest/gtest.h"
17 
18 #include "core/components/text_field/render_text_field.h"
19 #include "core/components/text_field/text_field_component.h"
20 
21 using namespace testing;
22 using namespace testing::ext;
23 
24 namespace OHOS::Ace {
25 namespace {
26 
27 constexpr int32_t TEXT_FIELD_MAXLINE_THREE = 3;
28 constexpr size_t TEXT_FIELD_MAXLENGTH = 100;
29 const std::string TEXT_FIELD_PLACEHOLDER_VALUE = "please input";
30 const TextInputType TEXT_FIELD_TEXTINPUTTYPE_EMAIL = TextInputType::EMAIL_ADDRESS;
31 const TextInputAction TEXT_FIELD_TEXTINPUTACTION_SEARCH = TextInputAction::SEARCH;
32 const TextAlign TEXT_FIELD_TEXTALIGN_CENTER = TextAlign::CENTER;
33 constexpr bool TEXT_FIELD_ISENABLE_FALSE = false;
34 
35 } // namespace
36 
37 class MockRenderTextField final : public RenderTextField {
38     DECLARE_ACE_TYPE(MockRenderTextField, RenderTextField);
39 
40 public:
41     MockRenderTextField() = default;
42     ~MockRenderTextField() override = default;
43 
GetTextMaxLines() const44     int32_t GetTextMaxLines() const
45     {
46         return maxLines_;
47     }
48 
GetMaxLength() const49     size_t GetMaxLength() const
50     {
51         return maxLength_;
52     }
53 
ShowCursor() const54     bool ShowCursor() const
55     {
56         return showCursor_;
57     }
58 
GetCursorColor()59     const Color& GetCursorColor()
60     {
61         return cursorColor_;
62     }
63 
GetPlaceholder() const64     const std::string& GetPlaceholder() const
65     {
66         return placeholder_;
67     }
68 
GetPlaceholderColor() const69     const Color& GetPlaceholderColor() const
70     {
71         return placeholderColor_;
72     }
73 
GetTextInputType() const74     TextInputType GetTextInputType() const
75     {
76         return keyboard_;
77     }
78 
GetAction() const79     TextInputAction GetAction() const
80     {
81         return action_;
82     }
83 
GetTextAlign() const84     TextAlign GetTextAlign() const
85     {
86         return textAlign_;
87     }
88 
IsEnabled() const89     bool IsEnabled() const
90     {
91         return enabled_;
92     }
93 
IsExtend() const94     bool IsExtend() const
95     {
96         return extend_;
97     }
98 
GetCursorPositionForMoveUp()99     int32_t GetCursorPositionForMoveUp() override
100     {
101         return 0;
102     }
103 
GetCursorPositionForMoveDown()104     int32_t GetCursorPositionForMoveDown() override
105     {
106         return 0;
107     }
108 
GetCursorPositionForClick(const Offset & offset)109     int32_t GetCursorPositionForClick(const Offset& offset) override
110     {
111         return 0;
112     }
113 
PreferredLineHeight()114     double PreferredLineHeight() override
115     {
116         return 0.0;
117     }
118 
AdjustCursorAndSelection(int32_t currentCursorPosition)119     int32_t AdjustCursorAndSelection(int32_t currentCursorPosition) override
120     {
121         return 0;
122     }
123 
GetDirectionStatusOfPosition(int32_t position) const124     DirectionStatus GetDirectionStatusOfPosition(int32_t position) const override
125     {
126         return DirectionStatus::LEFT_LEFT;
127     }
128 
GetCaretRect(int32_t extent,Rect & caretRect,double caretHeightOffset=0.0) const129     bool GetCaretRect(int32_t extent, Rect& caretRect, double caretHeightOffset = 0.0) const override
130     {
131         return false;
132     }
133 
GetHandleOffset(int32_t extend)134     Offset GetHandleOffset(int32_t extend) override
135     {
136         return Offset();
137     }
138 
ComputeDeflateSizeOfErrorAndCountText() const139     Size ComputeDeflateSizeOfErrorAndCountText() const override
140     {
141         return Size();
142     }
143 
GetCopyOption()144     CopyOptions GetCopyOption()
145     {
146         return copyOption_;
147     }
148 };
149 
150 class RenderTextFieldTest : public testing::Test {
151 public:
152     static void SetUpTestCase();
153     static void TearDownTestCase();
154     void SetUp();
155     void TearDown();
156 };
157 
SetUpTestCase()158 void RenderTextFieldTest::SetUpTestCase() {}
TearDownTestCase()159 void RenderTextFieldTest::TearDownTestCase() {}
SetUp()160 void RenderTextFieldTest::SetUp() {}
TearDown()161 void RenderTextFieldTest::TearDown() {}
162 
163 /**
164  * @tc.name: RenderTextFieldUpdate001
165  * @tc.desc: Verify the Update Interface of RenderTextField work correctly with show cursor.
166  * @tc.type: FUNC
167  */
168 HWTEST_F(RenderTextFieldTest, RenderTextFieldUpdate001, TestSize.Level1)
169 {
170     /**
171      * @tc.steps: step1. construct TextFieldComponent and RenderTextField.
172      */
173     RefPtr<TextFieldComponent> textField = AceType::MakeRefPtr<TextFieldComponent>();
174     textField->SetShowCursor(true);
175     RefPtr<MockRenderTextField> renderTextField = AceType::MakeRefPtr<MockRenderTextField>();
176 
177     /**
178      * @tc.steps: step2. call the Update interface of RenderTextField.
179      * @tc.expected: step2. RenderTextField is set as needLayout,  showCursor_ is set as true
180      */
181     renderTextField->Update(textField);
182     EXPECT_TRUE(renderTextField->NeedLayout());
183     EXPECT_EQ(renderTextField->ShowCursor(), true);
184 }
185 
186 /**
187  * @tc.name: RenderTextFieldUpdate002
188  * @tc.desc: Verify the Update Interface of RenderTextField work correctly with textfield component.
189  * @tc.type: FUNC
190  */
191 HWTEST_F(RenderTextFieldTest, RenderTextFieldUpdate002, TestSize.Level1)
192 {
193     /**
194      * @tc.steps: step1. construct TextFieldComponent and RenderTextField.
195      */
196     RefPtr<TextFieldComponent> textField = AceType::MakeRefPtr<TextFieldComponent>();
197     textField->SetShowCursor(true);
198     textField->SetCursorColor(Color::RED);
199     RefPtr<MockRenderTextField> renderTextField = AceType::MakeRefPtr<MockRenderTextField>();
200 
201     /**
202      * @tc.steps: step2. call the Update interface of RenderTextField.
203      * @tc.expected: step2. renderTextField is set as needLayout, cursorColor_ is set as RED.
204      */
205     renderTextField->Update(textField);
206     EXPECT_TRUE(renderTextField->NeedLayout());
207     EXPECT_EQ(renderTextField->GetCursorColor(), Color::RED);
208 }
209 
210 /**
211  * @tc.name: RenderTextFieldUpdate003
212  * @tc.desc: Verify the Update Interface of RenderTextField work correctly with maxLength.
213  * @tc.type: FUNC
214  */
215 HWTEST_F(RenderTextFieldTest, RenderTextFieldUpdate003, TestSize.Level1)
216 {
217     /**
218      * @tc.steps: step1. construct TextFieldComponent and RenderTextField.
219      */
220     RefPtr<TextFieldComponent> textField = AceType::MakeRefPtr<TextFieldComponent>();
221     textField->SetMaxLength(TEXT_FIELD_MAXLENGTH);
222     RefPtr<MockRenderTextField> renderTextField = AceType::MakeRefPtr<MockRenderTextField>();
223 
224     /**
225      * @tc.steps: step2. call the Update interface of RenderTextField.
226      * @tc.expected: step2. RenderTextField is set as needLayout,  maxLength_ is set as 100
227      */
228     renderTextField->Update(textField);
229     EXPECT_TRUE(renderTextField->NeedLayout());
230     EXPECT_EQ(renderTextField->GetMaxLength(), TEXT_FIELD_MAXLENGTH);
231 }
232 
233 /**
234  * @tc.name: RenderTextFieldUpdate004
235  * @tc.desc: Verify the Update Interface of RenderTextField work correctly with placeholder.
236  * @tc.type: FUNC
237  */
238 HWTEST_F(RenderTextFieldTest, RenderTextFieldUpdate004, TestSize.Level1)
239 {
240     /**
241      * @tc.steps: step1. construct TextFieldComponent and RenderTextField.
242      */
243     RefPtr<TextFieldComponent> textField = AceType::MakeRefPtr<TextFieldComponent>();
244     textField->SetPlaceholderColor(Color::RED);
245     textField->SetPlaceholder(TEXT_FIELD_PLACEHOLDER_VALUE);
246 
247     RefPtr<MockRenderTextField> renderTextField = AceType::MakeRefPtr<MockRenderTextField>();
248 
249     /**
250      * @tc.steps: step2. call the Update interface of RenderTextField.
251      * @tc.expected: step2. RenderTextField is set as needLayout,  showCursor_ is set as false
252      */
253     renderTextField->Update(textField);
254     EXPECT_TRUE(renderTextField->NeedLayout());
255     EXPECT_EQ(renderTextField->GetPlaceholderColor(), Color::RED);
256     EXPECT_EQ(renderTextField->GetPlaceholder(), TEXT_FIELD_PLACEHOLDER_VALUE);
257 }
258 
259 /**
260  * @tc.name: RenderTextFieldUpdate005
261  * @tc.desc: Verify the Update Interface of RenderTextField work correctly with maxLines.
262  * @tc.type: FUNC
263  */
264 HWTEST_F(RenderTextFieldTest, RenderTextFieldUpdate005, TestSize.Level1)
265 {
266     /**
267      * @tc.steps: step1. construct TextFieldComponent and RenderTextField.
268      */
269     RefPtr<TextFieldComponent> textField = AceType::MakeRefPtr<TextFieldComponent>();
270     textField->SetTextMaxLines(TEXT_FIELD_MAXLINE_THREE);
271     RefPtr<MockRenderTextField> renderTextField = AceType::MakeRefPtr<MockRenderTextField>();
272 
273     /**
274      * @tc.steps: step2. call the Update interface of RenderTextField.
275      * @tc.expected: step2. RenderTextField is set as needLayout,  maxLines_ is set as 3
276      */
277     renderTextField->Update(textField);
278     EXPECT_TRUE(renderTextField->NeedLayout());
279     EXPECT_EQ(renderTextField->GetTextMaxLines(), TEXT_FIELD_MAXLINE_THREE);
280 }
281 
282 /**
283  * @tc.name: RenderTextFieldUpdate006
284  * @tc.desc: Verify the Update Interface of RenderTextField work correctly with keyboard_.
285  * @tc.type: FUNC
286  */
287 HWTEST_F(RenderTextFieldTest, RenderTextFieldUpdate006, TestSize.Level1)
288 {
289     /**
290      * @tc.steps: step1. construct TextFieldComponent and RenderTextField.
291      */
292     RefPtr<TextFieldComponent> textField = AceType::MakeRefPtr<TextFieldComponent>();
293     textField->SetTextInputType(TEXT_FIELD_TEXTINPUTTYPE_EMAIL);
294     RefPtr<MockRenderTextField> renderTextField = AceType::MakeRefPtr<MockRenderTextField>();
295 
296     /**
297      * @tc.steps: step2. call the Update interface of RenderTextField.
298      * @tc.expected: step2. RenderTextField is set as needLayout,
299      *               keyboard_ is set as TextInputType::EMAIL_ADDRESS
300      */
301     renderTextField->Update(textField);
302     EXPECT_TRUE(renderTextField->NeedLayout());
303     EXPECT_EQ(renderTextField->GetTextInputType(), TEXT_FIELD_TEXTINPUTTYPE_EMAIL);
304 }
305 
306 /**
307  * @tc.name: RenderTextFieldUpdate007
308  * @tc.desc: Verify the Update Interface of RenderTextField work correctly with action_.
309  * @tc.type: FUNC
310  */
311 HWTEST_F(RenderTextFieldTest, RenderTextFieldUpdate007, TestSize.Level1)
312 {
313     /**
314      * @tc.steps: step1. construct TextFieldComponent and RenderTextField.
315      */
316     RefPtr<TextFieldComponent> textField = AceType::MakeRefPtr<TextFieldComponent>();
317     textField->SetAction(TEXT_FIELD_TEXTINPUTACTION_SEARCH);
318     RefPtr<MockRenderTextField> renderTextField = AceType::MakeRefPtr<MockRenderTextField>();
319 
320     /**
321      * @tc.steps: step2. call the Update interface of RenderTextField.
322      * @tc.expected: step2. RenderTextField is set as needLayout,  action_ is set as TextInputAction::SEARCH
323      */
324     renderTextField->Update(textField);
325     EXPECT_TRUE(renderTextField->NeedLayout());
326     EXPECT_EQ(renderTextField->GetAction(), TEXT_FIELD_TEXTINPUTACTION_SEARCH);
327 }
328 
329 /**
330  * @tc.name: RenderTextFieldUpdate008
331  * @tc.desc: Verify the Update Interface of RenderTextField work correctly with textAlign_.
332  * @tc.type: FUNC
333  */
334 HWTEST_F(RenderTextFieldTest, RenderTextFieldUpdate008, TestSize.Level1)
335 {
336     /**
337      * @tc.steps: step1. construct TextFieldComponent and RenderTextField.
338      */
339     RefPtr<TextFieldComponent> textField = AceType::MakeRefPtr<TextFieldComponent>();
340     textField->SetTextAlign(TEXT_FIELD_TEXTALIGN_CENTER);
341     RefPtr<MockRenderTextField> renderTextField = AceType::MakeRefPtr<MockRenderTextField>();
342 
343     /**
344      * @tc.steps: step2. call the Update interface of RenderTextField.
345      * @tc.expected: step2. RenderTextField is set as needLayout,  textAlign_ is set as TextAlign::CENTER
346      */
347     renderTextField->Update(textField);
348     EXPECT_TRUE(renderTextField->NeedLayout());
349     EXPECT_EQ(renderTextField->GetTextAlign(), TEXT_FIELD_TEXTALIGN_CENTER);
350 }
351 
352 /**
353  * @tc.name: RenderTextFieldUpdate009
354  * @tc.desc: Verify the Update Interface of RenderTextField work correctly with enabled_.
355  * @tc.type: FUNC
356  */
357 HWTEST_F(RenderTextFieldTest, RenderTextFieldUpdate009, TestSize.Level1)
358 {
359     /**
360      * @tc.steps: step1. construct TextFieldComponent and RenderTextField.
361      */
362     RefPtr<TextFieldComponent> textField = AceType::MakeRefPtr<TextFieldComponent>();
363     textField->SetEnabled(TEXT_FIELD_ISENABLE_FALSE);
364     RefPtr<MockRenderTextField> renderTextField = AceType::MakeRefPtr<MockRenderTextField>();
365 
366     /**
367      * @tc.steps: step2. call the Update interface of RenderTextField.
368      * @tc.expected: step2. RenderTextField is set as needLayout,  enabled_ is set as false
369      */
370     renderTextField->Update(textField);
371     EXPECT_TRUE(renderTextField->NeedLayout());
372     EXPECT_TRUE(!renderTextField->IsEnabled());
373 }
374 
375 /**
376  * @tc.name: RenderTextFieldUpdate010
377  * @tc.desc: Verify the Update Interface of RenderTextField work correctly with extend_.
378  * @tc.type: FUNC
379  */
380 HWTEST_F(RenderTextFieldTest, RenderTextFieldUpdate010, TestSize.Level1)
381 {
382     /**
383      * @tc.steps: step1. construct TextFieldComponent and RenderTextField.
384      */
385     RefPtr<TextFieldComponent> textField = AceType::MakeRefPtr<TextFieldComponent>();
386     textField->SetExtend(true);
387     RefPtr<MockRenderTextField> renderTextField = AceType::MakeRefPtr<MockRenderTextField>();
388 
389     /**
390      * @tc.steps: step2. call the Update interface of RenderTextField.
391      * @tc.expected: step2. RenderTextField is set as needLayout,  extend_ is set as true.
392      */
393     renderTextField->Update(textField);
394     EXPECT_TRUE(renderTextField->NeedLayout());
395     EXPECT_TRUE(renderTextField->IsExtend());
396 }
397 
398 /**
399  * @tc.name: RenderTextFieldUpdate011
400  * @tc.desc: Verify the Update Inline style of RenderTextField work correctly.
401  * @tc.type: FUNC
402  * @tc.require: issueI5JQ3F
403  */
404 HWTEST_F(RenderTextFieldTest, RenderTextFieldUpdate011, TestSize.Level1)
405 {
406     GTEST_LOG_(INFO) << "RenderTextFieldTest RenderTextFieldUpdate011 start";
407     /**
408      * @tc.steps: step1. construct TextFieldComponent and RenderTextField.
409      */
410     RefPtr<TextFieldComponent> textField = AceType::MakeRefPtr<TextFieldComponent>();
411     textField->SetInputStyle(InputStyle::INLINE);
412     RefPtr<MockRenderTextField> renderTextField = AceType::MakeRefPtr<MockRenderTextField>();
413 
414     /**
415      * @tc.steps: step2. call the Update interface of RenderTextField.
416      * @tc.expected: step2. RenderTextField style is set as InputStyle::INLINE.
417      */
418     renderTextField->Update(textField);
419     EXPECT_EQ(renderTextField->GetInputStyle(), InputStyle::INLINE);
420     GTEST_LOG_(INFO) << "RenderTextFieldTest RenderTextFieldUpdate011 end";
421 }
422 
423 /**
424  * @tc.name: RenderTextFieldUpdate012
425  * @tc.desc: Verify the Update Default style of RenderTextField work correctly.
426  * @tc.type: FUNC
427  * @tc.require: issueI5JQ3F
428  */
429 HWTEST_F(RenderTextFieldTest, RenderTextFieldUpdate012, TestSize.Level1)
430 {
431     GTEST_LOG_(INFO) << "RenderTextFieldTest RenderTextFieldUpdate012 start";
432     /**
433      * @tc.steps: step1. construct TextFieldComponent and RenderTextField.
434      */
435     RefPtr<TextFieldComponent> textField = AceType::MakeRefPtr<TextFieldComponent>();
436     textField->SetInputStyle(InputStyle::INLINE);
437     RefPtr<MockRenderTextField> renderTextField = AceType::MakeRefPtr<MockRenderTextField>();
438 
439     /**
440      * @tc.steps: step2. call the Update interface of RenderTextField.
441      * @tc.expected: step2. RenderTextField style is set as InputStyle::DEFAULT.
442      */
443     renderTextField->Update(textField);
444     EXPECT_EQ(renderTextField->GetInputStyle(), InputStyle::DEFAULT);
445     GTEST_LOG_(INFO) << "RenderTextFieldTest RenderTextFieldUpdate012 start";
446 }
447 
448 /**
449  * @tc.name: RenderTextFieldUpdate013
450  * @tc.desc: Verify the Update Interface of RenderTextField work correctly with copyOption_.
451  * @tc.type: FUNC
452  * @tc.require: issueI5NYZF
453  */
454 HWTEST_F(RenderTextFieldTest, RenderTextFieldUpdate013, TestSize.Level1)
455 {
456     GTEST_LOG_(INFO) << "RenderTextFieldTest RenderTextFieldUpdate013 start";
457     /**
458      * @tc.steps: step1. construct TextFieldComponent and RenderTextField.
459      */
460     RefPtr<TextFieldComponent> textField = AceType::MakeRefPtr<TextFieldComponent>();
461     textField->SetCopyOption(CopyOptions::InApp);
462     RefPtr<MockRenderTextField> renderTextField = AceType::MakeRefPtr<MockRenderTextField>();
463 
464     /**
465      * @tc.steps: step2. call the Update interface of RenderTextField.
466      * @tc.expected: step2. RenderTextField copyOption is set as CopyOptions::InApp.
467      */
468     renderTextField->Update(textField);
469     EXPECT_EQ(renderTextField->GetCopyOption(), CopyOptions::InApp);
470     GTEST_LOG_(INFO) << "RenderTextFieldTest RenderTextFieldUpdate013 start";
471 }
472 
473 } // namespace OHOS::Ace
474