1 /*
2  * Copyright (c) 2022 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 #define private public
19 
20 #include "core/animation/animator.h"
21 #include "core/components_ng/base/frame_node.h"
22 #include "core/components_ng/base/view_stack_processor.h"
23 #include "core/components_ng/event/event_hub.h"
24 #include "core/components_ng/pattern/image/image_layout_property.h"
25 #include "core/components_ng/pattern/image_animator/image_animator_model_ng.h"
26 #include "core/components_ng/pattern/image_animator/image_animator_pattern.h"
27 #include "core/components_ng/property/calc_length.h"
28 #include "core/components_ng/property/measure_property.h"
29 #include "core/components_v2/inspector/inspector_constants.h"
30 #include "test/mock/core/pipeline/mock_pipeline_context.h"
31 
32 using namespace testing;
33 using namespace testing::ext;
34 
35 namespace OHOS::Ace::NG {
36 namespace {
37 const InspectorFilter filter;
38 constexpr float DEVICE_WIDTH = 480.f;
39 constexpr float DEVICE_HEIGHT = 800.f;
40 constexpr int32_t STATE_DEFAULT = 0;
41 constexpr int32_t STATE_START = 1;
42 constexpr int32_t STATE_PAUSED = 2;
43 constexpr int32_t STATE_STOPPED = 3;
44 constexpr int32_t DURATION_DEFAULT = 1000;
45 constexpr int32_t ITERATION_DEFAULT = 1;
46 constexpr int32_t FILLMODENG_DEFAULT = 1;
47 constexpr int32_t PREDECODE_DEFAULT = 0;
48 constexpr bool ISREVERSE_DEFAULT = false;
49 constexpr bool ISREVERSE_BACKWARD = true;
50 constexpr bool FIXEDSIZE_DEFAULT = true;
51 constexpr bool FIXEDSIZE_CHANGED = false;
52 
53 constexpr Dimension IMAGE_WIDTH = 170.0_vp;
54 constexpr Dimension IMAGE_HEIGHT = 120.0_vp;
55 constexpr Dimension IMAGE_TOP = 0.0_vp;
56 constexpr Dimension IMAGE_LEFT = 0.0_vp;
57 constexpr int32_t IMAGE_DURATION = 500;
58 const std::string IMAGE_SRC_URL = "file://data/data/com.example.test/res/example.jpg";
59 
60 const std::string STATUS_IDLE_STR = "AnimationStatus.Initial";
61 const std::string FILLMODE_FORWARDS_STR = "FillMode.Forwards";
62 const constexpr float NORMALIZED_DURATION_MAX { 1.0f };
63 } // namespace
64 
65 class ImageAnimatorTestNg : public testing::Test {
66 public:
67     static void SetUpTestCase();
68     static void TearDownTestCase();
69     void SetUp() override;
70     void TearDown() override;
71     static void SetWidth(const Dimension& width);
72     static void SetHeight(const Dimension& height);
73     void GetInstance();
74     RefPtr<LayoutWrapperNode> RunMeasureAndLayout(float width = DEVICE_WIDTH, float height = DEVICE_HEIGHT);
75     void CreateImageAnimator(int32_t number = 1);
76     void CreatePixelMapAnimator(int32_t number = 1);
77     RefPtr<PixelMap> CreatePixelMap(const std::string& src);
78 
79     RefPtr<FrameNode> frameNode_;
80     RefPtr<ImageAnimatorPattern> pattern_;
81     RefPtr<ImageAnimatorEventHub> eventHub_;
82     RefPtr<LayoutProperty> layoutProperty_;
83 };
84 
CreatePixelMap(const std::string & src)85 RefPtr<PixelMap> ImageAnimatorTestNg::CreatePixelMap(const std::string& src)
86 {
87     RefPtr<PixelMap> pixelMap = nullptr;
88     return pixelMap;
89 }
90 
SetUpTestCase()91 void ImageAnimatorTestNg::SetUpTestCase()
92 {
93     MockPipelineContext::SetUp();
94 }
95 
TearDownTestCase()96 void ImageAnimatorTestNg::TearDownTestCase()
97 {
98     MockPipelineContext::TearDown();
99 }
100 
SetUp()101 void ImageAnimatorTestNg::SetUp() {}
102 
TearDown()103 void ImageAnimatorTestNg::TearDown()
104 {
105     frameNode_ = nullptr;
106     pattern_ = nullptr;
107     eventHub_ = nullptr;
108     layoutProperty_ = nullptr;
109 }
110 
SetWidth(const Dimension & width)111 void ImageAnimatorTestNg::SetWidth(const Dimension& width)
112 {
113     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
114     auto layoutProperty = frameNode->GetLayoutProperty();
115     layoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(width), std::nullopt));
116 }
117 
SetHeight(const Dimension & height)118 void ImageAnimatorTestNg::SetHeight(const Dimension& height)
119 {
120     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
121     auto layoutProperty = frameNode->GetLayoutProperty();
122     layoutProperty->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, CalcLength(height)));
123 }
124 
GetInstance()125 void ImageAnimatorTestNg::GetInstance()
126 {
127     RefPtr<UINode> element = ViewStackProcessor::GetInstance()->Finish();
128     frameNode_ = AceType::DynamicCast<FrameNode>(element);
129     pattern_ = frameNode_->GetPattern<ImageAnimatorPattern>();
130     eventHub_ = frameNode_->GetEventHub<ImageAnimatorEventHub>();
131     layoutProperty_ = frameNode_->GetLayoutProperty();
132 }
133 
RunMeasureAndLayout(float width,float height)134 RefPtr<LayoutWrapperNode> ImageAnimatorTestNg::RunMeasureAndLayout(float width, float height)
135 {
136     RefPtr<LayoutWrapperNode> layoutWrapper = frameNode_->CreateLayoutWrapper(false, false);
137     layoutWrapper->SetActive();
138     layoutWrapper->SetRootMeasureNode();
139     LayoutConstraintF LayoutConstraint;
140     LayoutConstraint.parentIdealSize = { DEVICE_WIDTH, DEVICE_HEIGHT };
141     LayoutConstraint.percentReference = { DEVICE_WIDTH, DEVICE_HEIGHT };
142     if (NonNegative(width) && NonNegative(height)) {
143         LayoutConstraint.selfIdealSize = { width, height };
144     } else if (NonNegative(width)) {
145         LayoutConstraint.selfIdealSize = { width, std::nullopt };
146     } else if (NonNegative(height)) {
147         LayoutConstraint.selfIdealSize = { std::nullopt, height };
148     }
149     LayoutConstraint.maxSize = { DEVICE_WIDTH, DEVICE_HEIGHT };
150     layoutWrapper->Measure(LayoutConstraint);
151     layoutWrapper->Layout();
152     layoutWrapper->MountToHostOnMainThread();
153     return layoutWrapper;
154 }
155 
CreateImageAnimator(int32_t number)156 void ImageAnimatorTestNg::CreateImageAnimator(int32_t number)
157 {
158     ImageAnimatorModelNG ImageAnimatorModelNG;
159     ImageAnimatorModelNG.Create();
160     std::vector<ImageProperties> images;
161     for (int32_t index = 0; index < number; index++) {
162         ImageProperties imageProperties;
163         imageProperties.src = IMAGE_SRC_URL;
164         imageProperties.width = IMAGE_WIDTH;
165         imageProperties.height = IMAGE_HEIGHT;
166         imageProperties.top = IMAGE_TOP;
167         imageProperties.left = IMAGE_LEFT;
168         images.push_back(imageProperties);
169     }
170     ImageAnimatorModelNG.SetImages(std::move(images));
171     ImageAnimatorModelNG.SetState(STATE_START);
172     ImageAnimatorModelNG.SetIsReverse(ISREVERSE_DEFAULT);
173     ImageAnimatorModelNG.SetIteration(ITERATION_DEFAULT);
174     GetInstance();
175     RunMeasureAndLayout();
176 }
177 
CreatePixelMapAnimator(int32_t number)178 void ImageAnimatorTestNg::CreatePixelMapAnimator(int32_t number)
179 {
180     ImageAnimatorModelNG ImageAnimatorModelNG;
181     ImageAnimatorModelNG.Create();
182     std::vector<ImageProperties> images;
183     for (int32_t index = 0; index < number; index++) {
184         ImageProperties imageProperties;
185         imageProperties.pixelMap = CreatePixelMap(IMAGE_SRC_URL);
186         imageProperties.width = IMAGE_WIDTH;
187         imageProperties.height = IMAGE_HEIGHT;
188         imageProperties.top = IMAGE_TOP;
189         imageProperties.left = IMAGE_LEFT;
190         images.push_back(imageProperties);
191     }
192     ImageAnimatorModelNG.SetImages(std::move(images));
193     ImageAnimatorModelNG.SetState(STATE_START);
194     ImageAnimatorModelNG.SetIsReverse(ISREVERSE_DEFAULT);
195     ImageAnimatorModelNG.SetIteration(ITERATION_DEFAULT);
196     GetInstance();
197     RunMeasureAndLayout();
198 }
199 
200 /**
201  * @tc.name: ImageAnimatorTest001
202  * @tc.desc: Create ImageAnimator.
203  * @tc.type: FUNC
204  */
205 HWTEST_F(ImageAnimatorTestNg, ImageAnimatorTest001, TestSize.Level1)
206 {
207     /**
208      * @tc.steps: step1. create imageAnimatorView and get frameNode.
209      * @tc.expected: step1. check frameNode exists and tag is correct.
210      */
211 
212     ImageAnimatorModelNG ImageAnimatorModelNG;
213     ImageAnimatorModelNG.Create();
214     auto frameNode = AceType::DynamicCast<FrameNode>(ViewStackProcessor::GetInstance()->Finish());
215     EXPECT_NE(frameNode, nullptr);
216     EXPECT_EQ(frameNode->GetTag(), V2::IMAGE_ANIMATOR_ETS_TAG);
217 
218     /**
219      * @tc.steps: step2. get childNode of frameNode and its imageLayoutProperty.
220      * @tc.expected: step2. check whether childNode, imageLayoutProperty exists and tag of childNode is correct.
221      */
222 
223     auto childNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
224     EXPECT_TRUE(childNode != nullptr && childNode->GetTag() == V2::IMAGE_ETS_TAG);
225     auto imageLayoutProperty = childNode->GetLayoutProperty<ImageLayoutProperty>();
226     EXPECT_NE(imageLayoutProperty, nullptr);
227 }
228 
229 /**
230  * @tc.name: ImageAnimatorTest002
231  * @tc.desc: Set ImageAnimator attributes into ImageAnimatorPattern and get them.
232  * @tc.type: FUNC
233  */
234 HWTEST_F(ImageAnimatorTestNg, ImageAnimatorTest002, TestSize.Level1)
235 {
236     /**
237      * @tc.steps: step1. create ImageAnimatorModelTestNg.
238      */
239 
240     ImageAnimatorModelNG ImageAnimatorModelNG;
241     ImageAnimatorModelNG.Create();
242 
243     /**
244      * @tc.steps: step2. set attributes into ImageAnimatorPattern.
245      * @tc.expected: step2. related function is called.
246      */
247 
248     ImageAnimatorModelNG.SetState(STATE_DEFAULT);
249     ImageAnimatorModelNG.SetDuration(DURATION_DEFAULT);
250     ImageAnimatorModelNG.SetIteration(ITERATION_DEFAULT);
251     ImageAnimatorModelNG.SetFillMode(FILLMODENG_DEFAULT);
252     ImageAnimatorModelNG.SetPreDecode(PREDECODE_DEFAULT);
253     ImageAnimatorModelNG.SetIsReverse(ISREVERSE_DEFAULT);
254     ImageAnimatorModelNG.SetFixedSize(FIXEDSIZE_DEFAULT);
255 
256     /**
257      * @tc.steps: step3. get ImageAnimatorPattern from frameNode.
258      * @tc.expected: step3. check whether frameNode and ImageAnimatorPattern exists.
259      */
260 
261     auto frameNode = AceType::DynamicCast<FrameNode>(ViewStackProcessor::GetInstance()->Finish());
262     EXPECT_NE(frameNode, nullptr);
263     EXPECT_EQ(frameNode->GetTag(), V2::IMAGE_ANIMATOR_ETS_TAG);
264     RefPtr<ImageAnimatorPattern> imageAnimatorPattern =
265         AceType::DynamicCast<OHOS::Ace::NG::ImageAnimatorPattern>(frameNode->GetPattern());
266     EXPECT_NE(imageAnimatorPattern, nullptr);
267 
268     /**
269      * @tc.steps: step4. get attributes from ImageAnimatorPattern by json.
270      * @tc.expected: step4. check whether all attributes is correct.
271      */
272 
273     auto jsonValue = JsonUtil::Create(true);
274     imageAnimatorPattern->ToJsonValue(jsonValue, filter);
275     EXPECT_EQ(jsonValue->GetValue("state")->GetString().c_str(), STATUS_IDLE_STR);
276     EXPECT_EQ(jsonValue->GetValue("duration")->GetString().c_str(), std::to_string(DURATION_DEFAULT));
277     EXPECT_EQ(jsonValue->GetValue("iterations")->GetString().c_str(), std::to_string(ITERATION_DEFAULT));
278     EXPECT_EQ(jsonValue->GetValue("fillMode")->GetString().c_str(), FILLMODE_FORWARDS_STR);
279     EXPECT_EQ(jsonValue->GetValue("reverse")->GetString(), std::string(ISREVERSE_DEFAULT ? "true" : "false"));
280     EXPECT_EQ(jsonValue->GetValue("fixedSize")->GetString(), std::string(FIXEDSIZE_DEFAULT ? "true" : "false"));
281 }
282 
283 /**
284  * @tc.name: ImageAnimatorTest003
285  * @tc.desc: Set Image into ImageAnimator and get its attributes.
286  * @tc.type: FUNC
287  */
288 HWTEST_F(ImageAnimatorTestNg, ImageAnimatorTest003, TestSize.Level1)
289 {
290     /**
291      * @tc.steps: step1. create ImageAnimatorModelTestNg.
292      */
293 
294     ImageAnimatorModelNG ImageAnimatorModelNG;
295     ImageAnimatorModelNG.Create();
296 
297     /**
298      * @tc.steps: step2. set image's attributes into ImageProperties and set ImageProperties into imageAnimatorView.
299      * @tc.expected: step2. related function is called.
300      */
301 
302     ImageProperties imageProperties;
303     imageProperties.src = IMAGE_SRC_URL;
304     imageProperties.width = IMAGE_WIDTH;
305     imageProperties.height = IMAGE_HEIGHT;
306     imageProperties.top = IMAGE_TOP;
307     imageProperties.left = IMAGE_LEFT;
308     imageProperties.duration = IMAGE_DURATION;
309     std::vector<ImageProperties> images;
310     images.push_back(imageProperties);
311     ImageAnimatorModelNG.SetImages(std::move(images));
312 
313     /**
314      * @tc.steps: step3. get ImageAnimatorPattern from frameNode.
315      * @tc.expected: step3. check whether frameNode and ImageAnimatorPattern exists.
316      */
317 
318     auto frameNode = AceType::DynamicCast<FrameNode>(ViewStackProcessor::GetInstance()->Finish());
319     EXPECT_NE(frameNode, nullptr);
320     EXPECT_EQ(frameNode->GetTag(), V2::IMAGE_ANIMATOR_ETS_TAG);
321     RefPtr<ImageAnimatorPattern> imageAnimatorPattern =
322         AceType::DynamicCast<OHOS::Ace::NG::ImageAnimatorPattern>(frameNode->GetPattern());
323     EXPECT_NE(imageAnimatorPattern, nullptr);
324 
325     /**
326      * @tc.steps: step4. get image's attributes from ImageAnimatorPattern by json and splice json string with setting
327      * values.
328      * @tc.expected: step4. check whether two strings are equal.
329      */
330 
331     auto jsonValue = JsonUtil::Create(true);
332     imageAnimatorPattern->ToJsonValue(jsonValue, filter);
333     std::string imagesStr = jsonValue->GetValue("images")->GetString();
334     auto imageArray = JsonUtil::CreateArray(true);
335     auto imageItem = JsonUtil::Create(true);
336     imageItem->Put("src", IMAGE_SRC_URL.c_str());
337     imageItem->Put("left", IMAGE_LEFT.ToString().c_str());
338     imageItem->Put("top", IMAGE_TOP.ToString().c_str());
339     imageItem->Put("width", IMAGE_WIDTH.ToString().c_str());
340     imageItem->Put("height", IMAGE_HEIGHT.ToString().c_str());
341     imageItem->Put("duration", std::to_string(IMAGE_DURATION).c_str());
342     imageArray->Put(imageItem);
343     EXPECT_EQ(imagesStr, imageArray->ToString());
344 }
345 
346 /**
347  * @tc.name: ImageAnimatorTest004
348  * @tc.desc: Set StartEvent into ImageAnimatorPattern and run Forward and Backward.
349  * @tc.type: FUNC
350  */
351 HWTEST_F(ImageAnimatorTestNg, ImageAnimatorTest004, TestSize.Level1)
352 {
353     /**
354      * @tc.steps: step1. create ImageAnimatorModelNG.
355      */
356 
357     ImageAnimatorModelNG ImageAnimatorModelNG;
358     ImageAnimatorModelNG.Create();
359 
360     /**
361      * @tc.steps: step2. set image's attributes and imageAnimatorView's attributes.
362      * @tc.expected: step2. related function is called.
363      */
364 
365     ImageProperties imageProperties;
366     imageProperties.src = IMAGE_SRC_URL;
367     imageProperties.width = IMAGE_WIDTH;
368     imageProperties.height = IMAGE_HEIGHT;
369     imageProperties.top = IMAGE_TOP;
370     imageProperties.left = IMAGE_LEFT;
371     imageProperties.duration = IMAGE_DURATION;
372     std::vector<ImageProperties> images;
373     images.push_back(imageProperties);
374     ImageAnimatorModelNG.SetImages(std::move(images));
375     ImageAnimatorModelNG.SetState(STATE_START);
376     ImageAnimatorModelNG.SetIsReverse(ISREVERSE_DEFAULT);
377     ImageAnimatorModelNG.SetIteration(ITERATION_DEFAULT);
378 
379     /**
380      * @tc.steps: step3. set startEvent into eventHub.
381      * @tc.expected: step3. related function is called and check whether eventHub is not null.
382      */
383 
384     bool startFlag = false;
__anon2d7951af0202() 385     auto startEvent = [&startFlag]() { startFlag = !startFlag; };
386     ImageAnimatorModelNG.SetOnStart(std::move(startEvent));
387     auto element = ViewStackProcessor::GetInstance()->Finish();
388     auto frameNode = AceType::DynamicCast<FrameNode>(element);
389     EXPECT_EQ(frameNode->GetTag(), V2::IMAGE_ANIMATOR_ETS_TAG);
390     auto eventHub = frameNode->GetEventHub<NG::ImageAnimatorEventHub>();
391     EXPECT_NE(eventHub, nullptr);
392 
393     /**
394      * @tc.steps: step4. use OnModifyDone to run Forward.
395      * @tc.expected: step4. related function is called and check whether startFlag is true.
396      */
397 
398     RefPtr<ImageAnimatorPattern> imageAnimatorPattern =
399         AceType::DynamicCast<OHOS::Ace::NG::ImageAnimatorPattern>(frameNode->GetPattern());
400     imageAnimatorPattern->AttachToFrameNode(frameNode);
401     imageAnimatorPattern->OnModifyDone();
402     EXPECT_FALSE(startFlag);
403 
404     /**
405      * @tc.steps: step5. change IsReverse and use OnModifyDone to run Backward.
406      * @tc.expected: step5. related function is called and check whether startFlag is false.
407      */
408 
409     ViewStackProcessor::GetInstance()->Push(element);
410     ImageAnimatorModelNG.SetIsReverse(ISREVERSE_BACKWARD);
411     imageAnimatorPattern->OnModifyDone();
412     EXPECT_TRUE(!startFlag);
413 
414     /**
415      * @tc.steps: step6. add Element to cacheImages_
416      * @tc.expected: step6. cacheImages_.size() > cacheImageNum
417      */
418     auto imageNode = FrameNode::CreateFrameNode(V2::IMAGE_ETS_TAG, -1, AceType::MakeRefPtr<Pattern>());
419     auto imageLayoutProperty = imageNode->GetLayoutProperty();
420     imageLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
421     imageLayoutProperty->UpdateAlignment(Alignment::TOP_LEFT);
422     imageAnimatorPattern->cacheImages_.emplace_back(ImageAnimatorPattern::CacheImageStruct(imageNode));
423     imageAnimatorPattern->OnModifyDone();
424     auto iTemp = ITERATION_DEFAULT / imageAnimatorPattern->images_.size();
425     size_t cacheImageNum = iTemp >= 50 ? 1 : 2;
426     cacheImageNum = std::min(imageAnimatorPattern->images_.size() - 1, cacheImageNum);
427     EXPECT_TRUE(imageAnimatorPattern->cacheImages_.size() >= cacheImageNum);
428 
429     /**
430      * @tc.steps: step7. status_ is Running and isFormAnimationEnd_ is true
431      * @tc.expected: step7. formAnimationRemainder_ is DEFAULT_DURATION
432      */
433     auto pipeline = MockPipelineContext::GetCurrentContext();
434     pipeline->SetIsFormRender(true);
435     imageAnimatorPattern->status_ = Animator::Status::RUNNING;
436     imageAnimatorPattern->isFormAnimationEnd_ = true;
437     imageAnimatorPattern->OnModifyDone();
438     EXPECT_EQ(imageAnimatorPattern->formAnimationRemainder_, 1000);
439 }
440 
441 /**
442  * @tc.name: ImageAnimatorTest005
443  * @tc.desc: Set PauseEvent into ImageAnimatorPattern and run it.
444  * @tc.type: FUNC
445  */
446 HWTEST_F(ImageAnimatorTestNg, ImageAnimatorTest005, TestSize.Level1)
447 {
448     /**
449      * @tc.steps: step1. create ImageAnimatorModelNG.
450      */
451 
452     ImageAnimatorModelNG ImageAnimatorModelNG;
453     ImageAnimatorModelNG.Create();
454 
455     /**
456      * @tc.steps: step2. set image's attributes and imageAnimatorView's attributes.
457      * @tc.expected: step2. related function is called.
458      */
459 
460     ImageProperties imageProperties;
461     imageProperties.src = IMAGE_SRC_URL;
462     imageProperties.width = IMAGE_WIDTH;
463     imageProperties.height = IMAGE_HEIGHT;
464     imageProperties.top = IMAGE_TOP;
465     imageProperties.left = IMAGE_LEFT;
466     imageProperties.duration = IMAGE_DURATION;
467     std::vector<ImageProperties> images;
468     images.push_back(imageProperties);
469     ImageAnimatorModelNG.SetImages(std::move(images));
470     ImageAnimatorModelNG.SetState(STATE_PAUSED);
471     ImageAnimatorModelNG.SetIteration(ITERATION_DEFAULT);
472 
473     /**
474      * @tc.steps: step3. set pauseEvent into eventHub.
475      * @tc.expected: step3. related function is called and check whether eventHub is not null.
476      */
477 
478     bool pauseFlag = false;
__anon2d7951af0302() 479     auto pauseEvent = [&pauseFlag]() { pauseFlag = !pauseFlag; };
480     ImageAnimatorModelNG.SetOnPause(std::move(pauseEvent));
481     auto frameNode = AceType::DynamicCast<FrameNode>(ViewStackProcessor::GetInstance()->Finish());
482     EXPECT_NE(frameNode, nullptr);
483     EXPECT_EQ(frameNode->GetTag(), V2::IMAGE_ANIMATOR_ETS_TAG);
484     auto eventHub = frameNode->GetEventHub<NG::ImageAnimatorEventHub>();
485     EXPECT_NE(eventHub, nullptr);
486 
487     /**
488      * @tc.steps: step4. use OnModifyDone to run pauseEvent.
489      * @tc.expected: step4. related function is called and check whether pauseFlag is true.
490      */
491 
492     RefPtr<ImageAnimatorPattern> imageAnimatorPattern =
493         AceType::DynamicCast<OHOS::Ace::NG::ImageAnimatorPattern>(frameNode->GetPattern());
494     EXPECT_TRUE(imageAnimatorPattern != nullptr);
495     imageAnimatorPattern->AttachToFrameNode(frameNode);
496     imageAnimatorPattern->OnModifyDone();
497     EXPECT_FALSE(pauseFlag);
498 }
499 
500 /**
501  * @tc.name: ImageAnimatorTest006
502  * @tc.desc: Set CancelEvent into ImageAnimatorPattern and run it.
503  * @tc.type: FUNC
504  */
505 HWTEST_F(ImageAnimatorTestNg, ImageAnimatorTest006, TestSize.Level1)
506 {
507     /**
508      * @tc.steps: step1. create ImageAnimatorModelNG.
509      */
510 
511     ImageAnimatorModelNG ImageAnimatorModelNG;
512     ImageAnimatorModelNG.Create();
513 
514     /**
515      * @tc.steps: step2. set image's attributes and imageAnimatorView's attributes.
516      * @tc.expected: step2. related function is called.
517      */
518 
519     ImageProperties imageProperties;
520     imageProperties.src = IMAGE_SRC_URL;
521     imageProperties.width = IMAGE_WIDTH;
522     imageProperties.height = IMAGE_HEIGHT;
523     imageProperties.top = IMAGE_TOP;
524     imageProperties.left = IMAGE_LEFT;
525     imageProperties.duration = IMAGE_DURATION;
526     std::vector<ImageProperties> images;
527     images.push_back(imageProperties);
528     ImageAnimatorModelNG.SetImages(std::move(images));
529     ImageAnimatorModelNG.SetState(STATE_START);
530     ImageAnimatorModelNG.SetIsReverse(ISREVERSE_DEFAULT);
531     ImageAnimatorModelNG.SetIteration(ITERATION_DEFAULT);
532 
533     /**
534      * @tc.steps: step3. set cancelEvent into eventHub.
535      * @tc.expected: step3. related function is called and check whether eventHub is not null.
536      */
537 
538     bool cancelFlag = false;
__anon2d7951af0402() 539     auto cancelEvent = [&cancelFlag]() { cancelFlag = !cancelFlag; };
540     ImageAnimatorModelNG.SetOnCancel(std::move(cancelEvent));
541     auto element = ViewStackProcessor::GetInstance()->Finish();
542     auto frameNode = AceType::DynamicCast<FrameNode>(element);
543     EXPECT_NE(frameNode, nullptr);
544     EXPECT_EQ(frameNode->GetTag(), V2::IMAGE_ANIMATOR_ETS_TAG);
545     auto eventHub = frameNode->GetEventHub<NG::ImageAnimatorEventHub>();
546     EXPECT_NE(eventHub, nullptr);
547 
548     /**
549      * @tc.steps: step4. use OnModifyDone to set animator's status is RUNNING.
550      * @tc.expected: step4. check whether animator's status is correct.
551      */
552 
553     RefPtr<ImageAnimatorPattern> imageAnimatorPattern =
554         AceType::DynamicCast<OHOS::Ace::NG::ImageAnimatorPattern>(frameNode->GetPattern());
555     EXPECT_NE(imageAnimatorPattern, nullptr);
556     imageAnimatorPattern->AttachToFrameNode(frameNode);
557     imageAnimatorPattern->OnModifyDone();
558     EXPECT_EQ(imageAnimatorPattern->animator_->GetStatus(), static_cast<Animator::Status>(STATE_START));
559 
560     /**
561      * @tc.steps: step5. change imageAnimatorView's status and use OnModifyDone to run cancelEvent.
562      * @tc.expected: step5. check whether cancelFlag is true and imageLayoutProperty's url is correct.
563      */
564 
565     ViewStackProcessor::GetInstance()->Push(element);
566     ImageAnimatorModelNG.SetState(STATE_DEFAULT);
567     ImageAnimatorModelNG.SetFixedSize(FIXEDSIZE_CHANGED);
568     imageAnimatorPattern->OnModifyDone();
569     EXPECT_FALSE(cancelFlag);
570     auto imageFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
571     EXPECT_NE(imageFrameNode, nullptr);
572     EXPECT_EQ(imageFrameNode->GetTag(), V2::IMAGE_ETS_TAG);
573     auto imageLayoutProperty = imageFrameNode->GetLayoutProperty<ImageLayoutProperty>();
574     EXPECT_NE(imageLayoutProperty, nullptr);
575     EXPECT_EQ(imageLayoutProperty->GetImageSourceInfoValue(), ImageSourceInfo(IMAGE_SRC_URL));
576 }
577 
578 /**
579  * @tc.name: ImageAnimatorTest007
580  * @tc.desc: Set StopEvent into ImageAnimatorPattern and run it.
581  * @tc.type: FUNC
582  */
583 HWTEST_F(ImageAnimatorTestNg, ImageAnimatorTest007, TestSize.Level1)
584 {
585     /**
586      * @tc.steps: step1. create ImageAnimatorModelNG.
587      */
588 
589     ImageAnimatorModelNG ImageAnimatorModelNG;
590     ImageAnimatorModelNG.Create();
591 
592     /**
593      * @tc.steps: step2. set image's attributes and imageAnimatorView's attributes.
594      * @tc.expected: step2. related function is called.
595      */
596 
597     ImageProperties imageProperties;
598     imageProperties.src = IMAGE_SRC_URL;
599     imageProperties.width = IMAGE_WIDTH;
600     imageProperties.height = IMAGE_HEIGHT;
601     imageProperties.top = IMAGE_TOP;
602     imageProperties.left = IMAGE_LEFT;
603     imageProperties.duration = IMAGE_DURATION;
604     std::vector<ImageProperties> images;
605     images.push_back(imageProperties);
606     ImageAnimatorModelNG.SetImages(std::move(images));
607     ImageAnimatorModelNG.SetState(STATE_START);
608     ImageAnimatorModelNG.SetIsReverse(ISREVERSE_DEFAULT);
609     ImageAnimatorModelNG.SetIteration(ITERATION_DEFAULT);
610 
611     /**
612      * @tc.steps: step3. set stoppedEvent and startEvent into eventHub.
613      * @tc.expected: step3. related function is called and check whether eventHub is not null.
614      */
615 
616     bool stoppedFlag = false;
__anon2d7951af0502() 617     auto stoppedEvent = [&stoppedFlag]() { stoppedFlag = !stoppedFlag; };
618     ImageAnimatorModelNG.SetOnFinish(std::move(stoppedEvent));
619     bool startFlag = false;
__anon2d7951af0602() 620     auto startEvent = [&startFlag]() { startFlag = !startFlag; };
621     ImageAnimatorModelNG.SetOnStart(std::move(startEvent));
622     auto element = ViewStackProcessor::GetInstance()->Finish();
623     auto frameNode = AceType::DynamicCast<FrameNode>(element);
624     EXPECT_NE(frameNode, nullptr);
625     EXPECT_EQ(frameNode->GetTag(), V2::IMAGE_ANIMATOR_ETS_TAG);
626     auto eventHub = frameNode->GetEventHub<NG::ImageAnimatorEventHub>();
627     EXPECT_NE(eventHub, nullptr);
628 
629     /**
630      * @tc.steps: step4. use OnModifyDone to set animator's status is RUNNING.
631      * @tc.expected: step4. check whether startFlag is true.
632      */
633 
634     RefPtr<ImageAnimatorPattern> imageAnimatorPattern =
635         AceType::DynamicCast<OHOS::Ace::NG::ImageAnimatorPattern>(frameNode->GetPattern());
636     EXPECT_NE(imageAnimatorPattern, nullptr);
637     imageAnimatorPattern->AttachToFrameNode(frameNode);
638     imageAnimatorPattern->OnModifyDone();
639     EXPECT_FALSE(startFlag);
640 
641     /**
642      * @tc.steps: step5. change imageAnimatorView's status and use OnModifyDone to run stoppedlEvent.
643      * @tc.expected: step5. check whether stoppedFlag is true.
644      */
645 
646     ViewStackProcessor::GetInstance()->Push(element);
647     ImageAnimatorModelNG.SetState(STATE_STOPPED);
648     imageAnimatorPattern->OnModifyDone();
649     EXPECT_TRUE(stoppedFlag);
650 }
651 
652 /**
653  * @tc.name: ImageAnimatorTest008
654  * @tc.desc: Set RepeatEvent into ImageAnimatorPattern.
655  * @tc.type: FUNC
656  */
657 HWTEST_F(ImageAnimatorTestNg, ImageAnimatorTest008, TestSize.Level1)
658 {
659     /**
660      * @tc.steps: step1. create ImageAnimatorModelNG.
661      */
662 
663     ImageAnimatorModelNG ImageAnimatorModelNG;
664     ImageAnimatorModelNG.Create();
665 
666     /**
667      * @tc.steps: step2. set image's attributes and imageAnimatorView's attributes.
668      * @tc.expected: step2. related function is called.
669      */
670 
671     ImageProperties imageProperties;
672     imageProperties.src = IMAGE_SRC_URL;
673     imageProperties.width = IMAGE_WIDTH;
674     imageProperties.height = IMAGE_HEIGHT;
675     imageProperties.top = IMAGE_TOP;
676     imageProperties.left = IMAGE_LEFT;
677     imageProperties.duration = IMAGE_DURATION;
678     std::vector<ImageProperties> images;
679     images.push_back(imageProperties);
680     ImageAnimatorModelNG.SetImages(std::move(images));
681     ImageAnimatorModelNG.SetState(STATE_START);
682     ImageAnimatorModelNG.SetIsReverse(ISREVERSE_DEFAULT);
683     ImageAnimatorModelNG.SetIteration(ITERATION_DEFAULT);
684 
685     /**
686      * @tc.steps: step3. set repeatEvent and repeatEvent into eventHub.
687      * @tc.expected: step3. related function is called and check whether repeatFlag is true.
688      */
689 
690     bool repeatFlag = false;
__anon2d7951af0702() 691     auto repeatEvent = [&repeatFlag]() { repeatFlag = !repeatFlag; };
692     ImageAnimatorModelNG.SetOnRepeat(std::move(repeatEvent));
693     auto element = ViewStackProcessor::GetInstance()->Finish();
694     auto frameNode = AceType::DynamicCast<FrameNode>(element);
695     EXPECT_NE(frameNode, nullptr);
696     EXPECT_EQ(frameNode->GetTag(), V2::IMAGE_ANIMATOR_ETS_TAG);
697     auto eventHub = frameNode->GetEventHub<NG::ImageAnimatorEventHub>();
698     EXPECT_NE(eventHub, nullptr);
699     auto repeatCallback = eventHub->GetRepeatEvent();
700     EXPECT_NE(repeatCallback, nullptr);
701     repeatCallback();
702     EXPECT_TRUE(repeatFlag);
703 }
704 
705 /**
706  * @tc.name: ImageAnimatorTest009
707  * @tc.desc: Set images with duration by zero into ImageAnimatorPattern.
708  * @tc.type: FUNC
709  */
710 HWTEST_F(ImageAnimatorTestNg, ImageAnimatorTest009, TestSize.Level1)
711 {
712     /**
713      * @tc.steps: step1. create ImageAnimatorModelNG.
714      */
715 
716     ImageAnimatorModelNG ImageAnimatorModelNG;
717     ImageAnimatorModelNG.Create();
718 
719     /**
720      * @tc.steps: step2. set image's duration by zero and imageAnimatorView's attributes.
721      * @tc.expected: step2. related function is called.
722      */
723 
724     ImageProperties imageProperties;
725     imageProperties.src = IMAGE_SRC_URL;
726     imageProperties.width = IMAGE_WIDTH;
727     imageProperties.height = IMAGE_HEIGHT;
728     imageProperties.top = IMAGE_TOP;
729     imageProperties.left = IMAGE_LEFT;
730     std::vector<ImageProperties> images;
731     images.push_back(imageProperties);
732     ImageAnimatorModelNG.SetImages(std::move(images));
733     ImageAnimatorModelNG.SetState(STATE_START);
734     ImageAnimatorModelNG.SetIsReverse(ISREVERSE_DEFAULT);
735     ImageAnimatorModelNG.SetIteration(ITERATION_DEFAULT);
736 
737     /**
738      * @tc.steps: step3. get imageAnimatorPattern from frameNode.
739      * @tc.expected: step3. check whether imageAnimatorPattern is not null.
740      */
741 
742     auto element = ViewStackProcessor::GetInstance()->Finish();
743     auto frameNode = AceType::DynamicCast<FrameNode>(element);
744     EXPECT_NE(frameNode, nullptr);
745     EXPECT_EQ(frameNode->GetTag(), V2::IMAGE_ANIMATOR_ETS_TAG);
746     auto eventHub = frameNode->GetEventHub<NG::ImageAnimatorEventHub>();
747     EXPECT_NE(eventHub, nullptr);
748     RefPtr<ImageAnimatorPattern> imageAnimatorPattern =
749         AceType::DynamicCast<OHOS::Ace::NG::ImageAnimatorPattern>(frameNode->GetPattern());
750     EXPECT_NE(imageAnimatorPattern, nullptr);
751 
752     /**
753      * @tc.steps: step4. use OnModifyDone when image's duration is zero.
754      * @tc.expected: step4. PictureAnimation's duration is correct.
755      */
756 
757     imageAnimatorPattern->AttachToFrameNode(frameNode);
758     auto pictureAnimation = imageAnimatorPattern->CreatePictureAnimation(imageAnimatorPattern->images_.size());
759     EXPECT_EQ(pictureAnimation->GetDuration(),
760         NORMALIZED_DURATION_MAX / static_cast<float>(imageAnimatorPattern->images_.size()));
761 }
762 
763 /**
764  * @tc.name: ImageAnimatorTest010
765  * @tc.desc: Add listener into animator and run it.
766  * @tc.type: FUNC
767  */
768 HWTEST_F(ImageAnimatorTestNg, ImageAnimatorTest010, TestSize.Level1)
769 {
770     /**
771      * @tc.steps: step1. create ImageAnimatorModelTestNg.
772      */
773 
774     ImageAnimatorModelNG ImageAnimatorModelNG;
775     ImageAnimatorModelNG.Create();
776 
777     /**
778      * @tc.steps: step2. set image's duration by zero and imageAnimatorView's attributes.
779      * @tc.expected: step2. related function is called.
780      */
781 
782     ImageProperties imageProperties;
783     imageProperties.src = IMAGE_SRC_URL;
784     imageProperties.width = IMAGE_WIDTH;
785     imageProperties.height = IMAGE_HEIGHT;
786     imageProperties.top = IMAGE_TOP;
787     imageProperties.left = IMAGE_LEFT;
788     imageProperties.duration = IMAGE_DURATION;
789     std::vector<ImageProperties> images;
790     images.push_back(imageProperties);
791     ImageAnimatorModelNG.SetImages(std::move(images));
792     ImageAnimatorModelNG.SetState(STATE_START);
793     ImageAnimatorModelNG.SetIsReverse(ISREVERSE_DEFAULT);
794     ImageAnimatorModelNG.SetIteration(ITERATION_DEFAULT);
795 
796     /**
797      * @tc.steps: step3. use OnModifyDone to set animator's status is RUNNING and Add listener into animator.
798      * @tc.expected: step3. check whether animator's status is correct and interpolators is not empty.
799      */
800 
801     auto element = ViewStackProcessor::GetInstance()->Finish();
802     auto frameNode = AceType::DynamicCast<FrameNode>(element);
803     EXPECT_NE(frameNode, nullptr);
804     EXPECT_EQ(frameNode->GetTag(), V2::IMAGE_ANIMATOR_ETS_TAG);
805     auto eventHub = frameNode->GetEventHub<NG::ImageAnimatorEventHub>();
806     EXPECT_NE(eventHub, nullptr);
807     RefPtr<ImageAnimatorPattern> imageAnimatorPattern =
808         AceType::DynamicCast<OHOS::Ace::NG::ImageAnimatorPattern>(frameNode->GetPattern());
809     EXPECT_NE(imageAnimatorPattern, nullptr);
810     imageAnimatorPattern->AttachToFrameNode(frameNode);
811     imageAnimatorPattern->OnModifyDone();
812     EXPECT_EQ(imageAnimatorPattern->animator_->GetStatus(), static_cast<Animator::Status>(STATE_START));
813     EXPECT_TRUE(!imageAnimatorPattern->animator_->interpolators_.empty());
814     /**
815      * @tc.steps: step4. change fixedSize and use OnModifyDone to run listerner.
816      * @tc.expected: step4. check whether ImageSourceInfoValue, MarginProperty, CalcLayoutConstraint, MeasureType is
817      * correct.
818      */
819 
820     ViewStackProcessor::GetInstance()->Push(element);
821     ImageAnimatorModelNG.SetState(STATE_DEFAULT);
822     ImageAnimatorModelNG.SetFixedSize(FIXEDSIZE_CHANGED);
823     imageAnimatorPattern->OnModifyDone();
824     auto imageFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
825     EXPECT_NE(imageFrameNode, nullptr);
826     EXPECT_EQ(imageFrameNode->GetTag(), V2::IMAGE_ETS_TAG);
827     auto imageLayoutProperty = imageFrameNode->GetLayoutProperty<ImageLayoutProperty>();
828     EXPECT_NE(imageLayoutProperty, nullptr);
829     EXPECT_EQ(imageLayoutProperty->GetImageSourceInfoValue(), ImageSourceInfo(IMAGE_SRC_URL));
830     EXPECT_EQ(imageLayoutProperty->GetMarginProperty()->left->ToString(), IMAGE_LEFT.ToString());
831     EXPECT_EQ(imageLayoutProperty->GetMarginProperty()->top->ToString(), IMAGE_TOP.ToString());
832     const auto& calcLayoutConstraint = imageLayoutProperty->GetCalcLayoutConstraint();
833     EXPECT_NE(calcLayoutConstraint, nullptr);
834     EXPECT_EQ(calcLayoutConstraint->selfIdealSize->Width()->ToString(), IMAGE_WIDTH.ToString());
835     EXPECT_EQ(calcLayoutConstraint->selfIdealSize->Height()->ToString(), IMAGE_HEIGHT.ToString());
836     EXPECT_EQ(imageLayoutProperty->GetMeasureType(), MeasureType::MATCH_CONTENT);
837 }
838 
839 /**
840  * @tc.name: ImageAnimatorTest011
841  * @tc.desc:
842  * @tc.type: FUNC
843  */
844 HWTEST_F(ImageAnimatorTestNg, ImageAnimatorTest011, TestSize.Level1)
845 {
846     /**
847      * @tc.steps: step1. images size is 0.
848      * @tc.expected: do nothing
849      */
850     CreateImageAnimator(0);
851 
852     /**
853      * @tc.steps: step2. SetShowingIndex() greater than images size-1.
854      * @tc.expected: nowImageIndex_ not change
855      */
856     CreateImageAnimator(1);
857     pattern_->SetShowingIndex(1);
858     EXPECT_EQ(pattern_->nowImageIndex_, 0);
859 
860     /**
861      * @tc.steps: step3. SetShowingIndex().
862      * @tc.expected: nowImageIndex_ is change
863      */
864     CreateImageAnimator(2);
865     EXPECT_EQ(pattern_->nowImageIndex_, 0);
866     pattern_->SetShowingIndex(1);
867     EXPECT_EQ(pattern_->nowImageIndex_, 1);
868 
869     // coverage fixedSize_ is false
870     pattern_->nowImageIndex_ = 0;
871     CreateImageAnimator(2);
872     pattern_->fixedSize_ = false;
873     pattern_->SetShowingIndex(1);
874     EXPECT_EQ(pattern_->nowImageIndex_, 1);
875     EXPECT_TRUE(pattern_->cacheImages_.size());
876     pattern_->fixedSize_ = true;
877 
878     // expected:FindCacheImageNode(images_[index].src) != cacheImages_.end() && isLoaded = false
879     CreateImageAnimator(2);
880     EXPECT_TRUE(pattern_->images_.size() == 2);
881     for (auto iter = pattern_->cacheImages_.begin(); iter != pattern_->cacheImages_.end(); ++iter) {
882         RefPtr<FrameNode>& imageFrameNode = iter->imageNode;
883         auto imageLayoutProperty =
884             AccessibilityManager::DynamicCast<ImageLayoutProperty>(imageFrameNode->layoutProperty_);
885         if (imageLayoutProperty->HasImageSourceInfo()) {
886             if (static_cast<int32_t>(pattern_->images_.size()) > 1) {
887                 pattern_->images_[1].src = imageLayoutProperty->GetImageSourceInfoValue().GetSrc();
888                 iter->isLoaded = false;
889             }
890             break;
891         }
892     }
893     auto host = pattern_->GetHost();
894     auto imageFrameNode = AceType::DynamicCast<FrameNode>(host->GetChildren().front());
895     auto imageLayoutProperty = imageFrameNode->GetLayoutProperty<ImageLayoutProperty>();
896     imageLayoutProperty->ResetImageSourceInfo();
897     EXPECT_FALSE(pattern_->IsShowingSrc(imageFrameNode, pattern_->images_[1].src));
898     pattern_->SetShowingIndex(1);
899     EXPECT_EQ(pattern_->nowImageIndex_, 1);
900 
901     // expected:coverage isLoaded = true
902     pattern_->cacheImages_.begin()->isLoaded = true;
903     pattern_->SetShowingIndex(1);
904     EXPECT_EQ(pattern_->nowImageIndex_, 1);
905 
906     /**
907      * @tc.steps: step4. images Unit is PERCENT
908      * @tc.expected: host size not change
909      */
910     ImageAnimatorModelNG ImageAnimatorModelNG_1;
911     ImageAnimatorModelNG_1.Create();
912     std::vector<ImageProperties> images_1;
913     ImageProperties imageProperties_1;
914     imageProperties_1.src = IMAGE_SRC_URL;
915     imageProperties_1.width = Dimension(0.1, DimensionUnit::PERCENT);
916     imageProperties_1.height = Dimension(0.1, DimensionUnit::PERCENT);
917     imageProperties_1.top = IMAGE_TOP;
918     imageProperties_1.left = IMAGE_LEFT;
919     images_1.push_back(imageProperties_1);
920     ImageAnimatorModelNG_1.SetImages(std::move(images_1));
921     ImageAnimatorModelNG_1.SetState(STATE_START);
922     ImageAnimatorModelNG_1.SetIsReverse(ISREVERSE_DEFAULT);
923     ImageAnimatorModelNG_1.SetIteration(ITERATION_DEFAULT);
924     GetInstance();
925     RunMeasureAndLayout();
926     EXPECT_EQ(frameNode_->GetGeometryNode()->GetFrameSize(), SizeF(DEVICE_WIDTH, DEVICE_HEIGHT));
927 
928     /**
929      * @tc.steps: step5. images has PERCENT width/height
930      * @tc.expected: if host has no set width/height, would effected by largest images size
931      */
932     ImageAnimatorModelNG ImageAnimatorModelNG_2;
933     ImageAnimatorModelNG_2.Create();
934     std::vector<ImageProperties> images_2;
935     ImageProperties imageProperties_2;
936     imageProperties_2.src = IMAGE_SRC_URL;
937     imageProperties_2.width = Dimension(100);
938     imageProperties_2.height = Dimension(100);
939     imageProperties_2.top = IMAGE_TOP;
940     imageProperties_2.left = IMAGE_LEFT;
941     images_2.push_back(imageProperties_2);
942     ImageProperties imageProperties_3;
943     imageProperties_3.src = IMAGE_SRC_URL;
944     imageProperties_3.width = Dimension(50);
945     imageProperties_3.height = Dimension(150);
946     imageProperties_3.top = IMAGE_TOP;
947     imageProperties_3.left = IMAGE_LEFT;
948     images_2.push_back(imageProperties_3);
949     ImageAnimatorModelNG_2.SetImages(std::move(images_2));
950     ImageAnimatorModelNG_2.SetState(STATE_START);
951     ImageAnimatorModelNG_2.SetIsReverse(ISREVERSE_DEFAULT);
952     ImageAnimatorModelNG_2.SetIteration(ITERATION_DEFAULT);
953     GetInstance();
954     RunMeasureAndLayout();
955 
956     layoutProperty_->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, std::nullopt));
957     pattern_->AdaptSelfSize();
958     auto idealSize = layoutProperty_->GetCalcLayoutConstraint()->selfIdealSize;
959     EXPECT_EQ(idealSize->Width().value(), CalcLength(100));
960     EXPECT_EQ(idealSize->Height().value(), CalcLength(150));
961 
962     layoutProperty_->GetCalcLayoutConstraint()->selfIdealSize->Reset();
963     layoutProperty_->UpdateUserDefinedIdealSize(CalcSize(CalcLength(DEVICE_WIDTH), std::nullopt));
964     pattern_->AdaptSelfSize();
965     idealSize = layoutProperty_->GetCalcLayoutConstraint()->selfIdealSize;
966     EXPECT_EQ(idealSize->Width().value(), CalcLength(DEVICE_WIDTH));
967     EXPECT_EQ(idealSize->Height().value(), CalcLength(150));
968 
969     layoutProperty_->GetCalcLayoutConstraint()->selfIdealSize->Reset();
970     layoutProperty_->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, CalcLength(DEVICE_HEIGHT)));
971     pattern_->AdaptSelfSize();
972     idealSize = layoutProperty_->GetCalcLayoutConstraint()->selfIdealSize;
973     EXPECT_EQ(idealSize->Width().value(), CalcLength(100));
974     EXPECT_EQ(idealSize->Height().value(), CalcLength(DEVICE_HEIGHT));
975 }
976 
977 /**
978  * @tc.name: ImageAnimatorTest012
979  * @tc.desc: Set duration and check duration is correct assign
980  * @tc.type: FUNC
981  */
982 HWTEST_F(ImageAnimatorTestNg, ImageAnimatorTest012, TestSize.Level1)
983 {
984     /**
985      * @tc.steps: step1. create imageAnimator
986      * @tc.expected: pipeline and animator is not nullptr
987      */
988     CreateImageAnimator(0);
989     auto pipeline = MockPipelineContext::GetCurrentContext();
990     ASSERT_NE(pipeline, nullptr);
991     auto animator = pattern_->animator_;
992     ASSERT_NE(animator, nullptr);
993     /**
994      * @tc.steps: step2. set is form render and set duration
995      * @tc.expected: check duration is correct assign
996      */
997     pipeline->SetIsFormRender(true);
998     pattern_->SetDuration(1500);
999     EXPECT_EQ(animator->GetDuration(), DURATION_DEFAULT);
1000 
1001     /**
1002      * @tc.steps: step3. set is form render and set duration,finalDuration < DEFAULT_DURATION
1003      * @tc.expected: check duration is correct assign
1004      */
1005     pipeline->SetIsFormRender(true);
1006     pattern_->SetDuration(900);
1007     EXPECT_EQ(animator->GetDuration(), DURATION_DEFAULT);
1008     /**
1009      * @tc.steps: step4. set is form render and set duration
1010      * @tc.expected: check duration is correct assign
1011      */
1012     pipeline->SetIsFormRender(true);
1013     pattern_->animator_->status_ = Animator::Status::IDLE;
1014     pattern_->SetDuration(0);
1015     EXPECT_EQ(animator->GetDuration(), 0);
1016 }
1017 
1018 /**
1019  * @tc.name: ImageAnimatorTest013
1020  * @tc.desc: Set iteration and check iteration is correct assign
1021  * @tc.type: FUNC
1022  */
1023 HWTEST_F(ImageAnimatorTestNg, ImageAnimatorTest013, TestSize.Level1)
1024 {
1025     /**
1026      * @tc.steps: step1. create imageAnimator
1027      * @tc.expected: pipeline and animator is not nullptr
1028      */
1029     CreateImageAnimator(0);
1030     auto pipeline = MockPipelineContext::GetCurrentContext();
1031     ASSERT_NE(pipeline, nullptr);
1032     auto animator = pattern_->animator_;
1033     ASSERT_NE(animator, nullptr);
1034     /**
1035      * @tc.steps: step2. set is form render and iteration
1036      * @tc.expected: check iteration is correct assign
1037      */
1038     pipeline->SetIsFormRender(true);
1039     pattern_->SetIteration(5);
1040     EXPECT_EQ(animator->GetIteration(), ITERATION_DEFAULT);
1041 }
1042 
1043 /**
1044  * @tc.name: ImageAnimatorTest014
1045  * @tc.desc: Update duration By Remainder and check duration is correct assign
1046  * @tc.type: FUNC
1047  */
1048 HWTEST_F(ImageAnimatorTestNg, ImageAnimatorTest014, TestSize.Level1)
1049 {
1050     /**
1051      * @tc.steps: step1. create imageAnimator
1052      * @tc.expected: pipeline and animator is not nullptr
1053      */
1054     CreateImageAnimator(0);
1055     auto pipeline = MockPipelineContext::GetCurrentContext();
1056     ASSERT_NE(pipeline, nullptr);
1057     auto animator = pattern_->animator_;
1058     ASSERT_NE(animator, nullptr);
1059     /**
1060      * @tc.steps: step2. set is form render and set duration
1061      * @tc.expected: check duration is correct assign
1062      */
1063     pipeline->SetIsFormRender(true);
1064     pattern_->SetDuration(DURATION_DEFAULT);
1065     pattern_->UpdateFormDurationByRemainder();
1066     EXPECT_EQ(animator->GetDuration(), DURATION_DEFAULT);
1067     /**
1068      * @tc.steps: step3. reset form animation start time and duration
1069      * @tc.expected: check duration is correct assign
1070      */
1071     pattern_->ResetFormAnimationStartTime();
1072     EXPECT_TRUE(!pattern_->isFormAnimationStart_);
1073     pattern_->UpdateFormDurationByRemainder();
1074     EXPECT_EQ(animator->GetDuration(), pattern_->formAnimationRemainder_);
1075 }
1076 
1077 /**
1078  * @tc.name: ImageAnimatorTest015
1079  * @tc.desc: Reset remainder and check remainder is correct assign
1080  * @tc.type: FUNC
1081  */
1082 HWTEST_F(ImageAnimatorTestNg, ImageAnimatorTest015, TestSize.Level1)
1083 {
1084     /**
1085      * @tc.steps: step1. create imageAnimator
1086      * @tc.expected: pipeline and animator is not nullptr
1087      */
1088     CreateImageAnimator(0);
1089     auto pipeline = MockPipelineContext::GetCurrentContext();
1090     ASSERT_NE(pipeline, nullptr);
1091     auto animator = pattern_->animator_;
1092     ASSERT_NE(animator, nullptr);
1093     /**
1094      * @tc.steps: step2. set is form render and reset remainder
1095      * @tc.expected: check remainder is correct assign
1096      */
1097     pipeline->SetIsFormRender(true);
1098     pattern_->ResetFormAnimationFlag();
1099     EXPECT_EQ(pattern_->formAnimationRemainder_, DURATION_DEFAULT);
1100     EXPECT_TRUE(pattern_->isFormAnimationStart_);
1101     EXPECT_TRUE(!pattern_->isFormAnimationEnd_);
1102 }
1103 
1104 /**
1105  * @tc.name: ImageAnimatorTest016
1106  * @tc.desc: get whether is form render and value is correct
1107  * @tc.type: FUNC
1108  */
1109 HWTEST_F(ImageAnimatorTestNg, ImageAnimatorTest016, TestSize.Level1)
1110 {
1111     /**
1112      * @tc.steps: step1. create imageAnimator
1113      * @tc.expected: pipeline and animator is not nullptr
1114      */
1115     CreateImageAnimator(0);
1116     auto pipeline = MockPipelineContext::GetCurrentContext();
1117     ASSERT_NE(pipeline, nullptr);
1118     auto animator = pattern_->animator_;
1119     ASSERT_NE(animator, nullptr);
1120     /**
1121      * @tc.steps: step2. set whether is form render
1122      * @tc.expected: check get form render value is correct
1123      */
1124     pipeline->SetIsFormRender(false);
1125     EXPECT_EQ(pattern_->IsFormRender(), false);
1126     pipeline->SetIsFormRender(true);
1127     EXPECT_EQ(pattern_->IsFormRender(), true);
1128 }
1129 
1130 /**
1131  * @tc.name: ImageAnimatorTest017
1132  * @tc.desc: frameNode->GetChildren() is not empty
1133  * @tc.type: FUNC
1134  */
1135 HWTEST_F(ImageAnimatorTestNg, ImageAnimatorTest017, TestSize.Level1)
1136 {
1137     ImageAnimatorModelNG imageAnimatorModelNG;
1138     auto* stack = ViewStackProcessor::GetInstance();
1139     auto nodeId = static_cast<ElementIdType>(1);
1140     stack->reservedNodeId_ = static_cast<ElementIdType>(1);
1141     auto frameNode = FrameNode::GetOrCreateFrameNode(
__anon2d7951af0802() 1142         V2::IMAGE_ANIMATOR_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<ImageAnimatorPattern>(); });
1143     CHECK_NULL_VOID(frameNode);
1144     auto imageNode = FrameNode::CreateFrameNode(V2::IMAGE_ETS_TAG, nodeId, AceType::MakeRefPtr<Pattern>());
1145     CHECK_NULL_VOID(imageNode);
1146     frameNode->AddChild(imageNode);
1147     frameNode->tag_ = V2::IMAGE_ANIMATOR_ETS_TAG;
1148     ElementRegister::GetInstance()->itemMap_[nodeId] = frameNode;
1149     imageAnimatorModelNG.Create();
1150     EXPECT_FALSE(frameNode->GetChildren().empty());
1151 }
1152 /**
1153  * @tc.name: ImageAnimatorTest018
1154  * @tc.desc: UpdateCacheImageInfo::index < images_.size()
1155  * @tc.type: FUNC
1156  */
1157 HWTEST_F(ImageAnimatorTestNg, ImageAnimatorTest018, TestSize.Level1)
1158 {
1159     CreateImageAnimator(1);
1160     ImageAnimatorPattern::CacheImageStruct cTemp;
1161     int32_t iIndex = 2;
1162     pattern_->UpdateCacheImageInfo(cTemp, iIndex);
1163     EXPECT_TRUE(iIndex >= static_cast<int32_t>(pattern_->images_.size()));
1164 }
1165 
1166 /**
1167  * @tc.name: ImageAnimatorTest019
1168  * @tc.desc: OnDirtyLayoutWrapperSwap
1169  * @tc.type: FUNC
1170  */
1171 HWTEST_F(ImageAnimatorTestNg, ImageAnimatorTest019, TestSize.Level1)
1172 {
1173     /**
1174      * @tc.steps: step1. create paramater
1175      */
1176     auto element = ViewStackProcessor::GetInstance()->Finish();
1177     auto frameNode = AceType::DynamicCast<FrameNode>(element);
1178     RefPtr<ImageAnimatorPattern> imageAnimatorPattern =
1179         AceType::DynamicCast<OHOS::Ace::NG::ImageAnimatorPattern>(frameNode->GetPattern());
1180     auto layoutWrapper = AceType::MakeRefPtr<LayoutWrapperNode>(nullptr, nullptr, nullptr);
1181     DirtySwapConfig config;
1182 
1183     /**
1184      * @tc.steps: step2. set isLayouted_ true
1185      */
1186     imageAnimatorPattern->isLayouted_ = true;
1187 
1188     /**
1189      * @tc.steps: step3. call OnDirtyLayoutWrapperSwap
1190      * @tc.expected: false
1191      */
1192     bool bResult = imageAnimatorPattern->OnDirtyLayoutWrapperSwap(layoutWrapper, config);
1193     EXPECT_FALSE(bResult);
1194 
1195     // fixedSize and images_.size() both are false
1196     imageAnimatorPattern->isLayouted_ = false;
1197     imageAnimatorPattern->fixedSize_ = false;
1198     imageAnimatorPattern->OnDirtyLayoutWrapperSwap(layoutWrapper, config);
1199 
1200     /**
1201      * @tc.steps: step4. Create ImageAnimator
1202      * @tc.expected: Create Success
1203      */
1204     CreateImageAnimator(1);
1205     EXPECT_EQ(imageAnimatorPattern->images_.size(), 1);
1206     imageAnimatorPattern->OnDirtyLayoutWrapperSwap(layoutWrapper, config);
1207 
1208     /**
1209      * @tc.steps: step5. fixedSize and is Reverse both ture
1210      * @tc.expected: GetNextIndex(0) is 0
1211      */
1212     imageAnimatorPattern->fixedSize_ = true;
1213     imageAnimatorPattern->isReverse_ = true;
1214     imageAnimatorPattern->OnDirtyLayoutWrapperSwap(layoutWrapper, config);
1215     EXPECT_EQ(imageAnimatorPattern->GetNextIndex(0), 0);
1216     EXPECT_EQ(imageAnimatorPattern->GetNextIndex(1), 0);
1217 }
1218 
1219 /**
1220  * @tc.name: ImageAnimatorTest020
1221  * @tc.desc: Update duration By Remainder and check duration is correct assign
1222  * @tc.type: FUNC
1223  */
1224 HWTEST_F(ImageAnimatorTestNg, ImageAnimatorTest020, TestSize.Level1)
1225 {
1226     /**
1227      * @tc.steps: step1. create imageAnimator
1228      * @tc.expected: pipeline and animator is not nullptr
1229      */
1230     CreateImageAnimator(0);
1231     auto pipeline = MockPipelineContext::GetCurrentContext();
1232     auto animator = pattern_->animator_;
1233 
1234     /**
1235      * @tc.steps: step2. set is form render and set duration
1236      * @tc.expected: check duration is correct assign
1237      */
1238     pipeline->SetIsFormRender(true);
1239     pattern_->isFormAnimationStart_ = true;
1240     pattern_->formAnimationRemainder_ = 1;
1241     pattern_->SetDuration(DURATION_DEFAULT);
1242     pattern_->UpdateFormDurationByRemainder();
1243     EXPECT_EQ(animator->GetDuration(), pattern_->formAnimationRemainder_);
1244 
1245     /**
1246      * @tc.steps: step3. formAnimationRemainder_ is 0
1247      * @tc.expected: isFormAnimationEnd_ is true
1248      */
1249     pattern_->formAnimationRemainder_ = 0;
1250     pattern_->UpdateFormDurationByRemainder();
1251     EXPECT_TRUE(pattern_->isFormAnimationEnd_);
1252 }
1253 
1254 /**
1255  * @tc.name: ImageAnimatorTest021
1256  * @tc.desc:
1257  * @tc.type: FUNC
1258  */
1259 HWTEST_F(ImageAnimatorTestNg, ImageAnimatorTest021, TestSize.Level1)
1260 {
1261     /**
1262      * @tc.steps: step1. images size is 0.
1263      * @tc.expected: do nothing
1264      */
1265     CreateImageAnimator(0);
1266 
1267     /**
1268      * @tc.steps: step2. SetShowingIndex() greater than images size-1.
1269      * @tc.expected: nowImageIndex_ not change
1270      */
1271     CreateImageAnimator(1);
1272     pattern_->SetShowingIndex(1);
1273     EXPECT_EQ(pattern_->nowImageIndex_, 0);
1274 
1275     /**
1276      * @tc.steps: step3. set calcLayoutConstraint_ null
1277      */
1278     auto host = pattern_->GetHost();
1279     auto& layoutProperty = host->layoutProperty_;
1280     if (layoutProperty->GetCalcLayoutConstraint()) {
1281         layoutProperty->calcLayoutConstraint_ = nullptr;
1282     }
1283 
1284     /**
1285      * @tc.steps: step4. set images width not valid
1286      * @tc.expected: maxWidth and maxHeight are not valid
1287      */
1288     for (auto& image : pattern_->images_) {
1289         image.width = Dimension(0);
1290     }
1291     pattern_->AdaptSelfSize();
1292 
1293     Dimension maxWidth;
1294     Dimension maxHeight;
1295     double maxWidthPx = 0.0;
1296     double maxHeightPx = 0.0;
1297     for (const auto& image : pattern_->images_) {
1298         if (image.width.Unit() != DimensionUnit::PERCENT) {
1299             auto widthPx = image.width.ConvertToPx();
1300             if (widthPx > maxWidthPx) {
1301                 maxWidthPx = widthPx;
1302                 maxWidth = image.width;
1303             }
1304         }
1305         if (image.height.Unit() != DimensionUnit::PERCENT) {
1306             auto heightPx = image.height.ConvertToPx();
1307             if (heightPx > maxHeightPx) {
1308                 maxHeightPx = heightPx;
1309                 maxHeight = image.height;
1310             }
1311         }
1312     }
1313     EXPECT_FALSE(maxWidth.IsValid());
1314     EXPECT_TRUE(maxHeight.IsValid());
1315 }
1316 
1317 /**
1318  * @tc.name: ImageAnimatorTest022
1319  * @tc.desc:
1320  * @tc.type: FUNC
1321  */
1322 HWTEST_F(ImageAnimatorTestNg, ImageAnimatorTest022, TestSize.Level1)
1323 {
1324     /**
1325      * @tc.steps: step1. images size is 0.
1326      * @tc.expected: do nothing
1327      */
1328     CreatePixelMapAnimator(0);
1329 
1330     /**
1331      * @tc.steps: step2. SetShowingIndex() greater than images size-1.
1332      * @tc.expected: nowImageIndex_ not change
1333      */
1334     CreatePixelMapAnimator(1);
1335     pattern_->SetShowingIndex(1);
1336     EXPECT_EQ(pattern_->nowImageIndex_, 0);
1337 
1338     /**
1339      * @tc.steps: step3. SetShowingIndex().
1340      * @tc.expected: nowImageIndex_ is change
1341      */
1342     CreatePixelMapAnimator(2);
1343     EXPECT_EQ(pattern_->nowImageIndex_, 0);
1344     pattern_->SetShowingIndex(1);
1345     EXPECT_EQ(pattern_->nowImageIndex_, 1);
1346 
1347     // coverage fixedSize_ is false
1348     pattern_->nowImageIndex_ = 0;
1349     CreatePixelMapAnimator(2);
1350     pattern_->fixedSize_ = false;
1351     pattern_->SetShowingIndex(1);
1352     EXPECT_EQ(pattern_->nowImageIndex_, 1);
1353     EXPECT_TRUE(pattern_->cacheImages_.size());
1354     pattern_->fixedSize_ = true;
1355 
1356     // expected:images_ size is 2
1357     CreatePixelMapAnimator(2);
1358     EXPECT_TRUE(pattern_->images_.size() == 2);
1359 
1360     CreatePixelMapAnimator(1);
1361     ImageAnimatorPattern::CacheImageStruct cTemp;
1362     int32_t iIndex = 2;
1363     pattern_->UpdateCacheImageInfo(cTemp, iIndex);
1364     // expected:iIndex > images_ size
1365     EXPECT_TRUE(iIndex >= static_cast<int32_t>(pattern_->images_.size()));
1366 }
1367 
1368 } // namespace OHOS::Ace::NG