Update rive-cpp to 2.0 version
[platform/core/uifw/rive-tizen.git] / submodule / rive-cpp / test / file_test.cpp
1 #include <rive/file.hpp>
2 #include <rive/node.hpp>
3 #include <rive/shapes/rectangle.hpp>
4 #include <rive/shapes/shape.hpp>
5 #include "no_op_renderer.hpp"
6 #include "rive_file_reader.hpp"
7 #include <catch.hpp>
8 #include <cstdio>
9
10 TEST_CASE("file can be read", "[file]") {
11     auto file = ReadRiveFile("../../test/assets/two_artboards.riv");
12
13     // Default artboard should be named Two.
14     REQUIRE(file->artboard()->name() == "Two");
15
16     // There should be a second artboard named One.
17     REQUIRE(file->artboard("One") != nullptr);
18 }
19
20 TEST_CASE("file with animation can be read", "[file]") {
21     auto file = ReadRiveFile("../../test/assets/juice.riv");
22
23     auto artboard = file->artboard();
24     REQUIRE(artboard->name() == "New Artboard");
25
26     auto shin = artboard->find("shin_right");
27     REQUIRE(shin != nullptr);
28     REQUIRE(shin->is<rive::Node>());
29
30     auto shinNode = shin->as<rive::Node>();
31     REQUIRE(shinNode->parent() != nullptr);
32     REQUIRE(shinNode->parent()->name() == "leg_right");
33     REQUIRE(shinNode->parent()->parent() != nullptr);
34     REQUIRE(shinNode->parent()->parent()->name() == "root");
35     REQUIRE(shinNode->parent()->parent() != nullptr);
36     REQUIRE(shinNode->parent()->parent()->parent() != nullptr);
37     REQUIRE(shinNode->parent()->parent()->parent() == artboard);
38
39     auto walkAnimation = artboard->animation("walk");
40     REQUIRE(walkAnimation != nullptr);
41     REQUIRE(walkAnimation->numKeyedObjects() == 22);
42 }
43
44 TEST_CASE("artboards can be counted and accessed via index or name", "[file]") {
45     auto file = ReadRiveFile("../../test/assets/dependency_test.riv");
46
47     // The artboards caqn be counted
48     REQUIRE(file->artboardCount() == 1);
49
50     // Artboards can be access by index
51     REQUIRE(file->artboard(0) != nullptr);
52
53     // Artboards can be accessed by name
54     REQUIRE(file->artboard("Blue") != nullptr);
55 }
56
57 TEST_CASE("dependencies are as expected", "[file]") {
58     // ┌────┐
59     // │Blue│
60     // └────┘
61     //    │ ┌───┐
62     //    └▶│ A │
63     //      └───┘
64     //        │ ┌───┐
65     //        └▶│ B │
66     //          └───┘
67     //            │ ┌───┐
68     //            ├▶│ C │
69     //            │ └───┘
70     //            │ ┌─────────┐
71     //            └▶│Rectangle│
72     //              └─────────┘
73     //                   │ ┌──────────────┐
74     //                   └▶│Rectangle Path│
75     //                     └──────────────┘
76     auto file = ReadRiveFile("../../test/assets/dependency_test.riv");
77
78     auto artboard = file->artboard();
79     REQUIRE(artboard->name() == "Blue");
80
81     auto nodeA = artboard->find<rive::Node>("A");
82     auto nodeB = artboard->find<rive::Node>("B");
83     auto nodeC = artboard->find<rive::Node>("C");
84     auto shape = artboard->find<rive::Shape>("Rectangle");
85     auto path = artboard->find<rive::Path>("Rectangle Path");
86     REQUIRE(nodeA != nullptr);
87     REQUIRE(nodeB != nullptr);
88     REQUIRE(nodeC != nullptr);
89     REQUIRE(shape != nullptr);
90     REQUIRE(path != nullptr);
91
92     REQUIRE(nodeA->parent() == artboard);
93     REQUIRE(nodeB->parent() == nodeA);
94     REQUIRE(nodeC->parent() == nodeB);
95     REQUIRE(shape->parent() == nodeB);
96     REQUIRE(path->parent() == shape);
97
98     REQUIRE(nodeB->dependents().size() == 2);
99
100     REQUIRE(artboard->graphOrder() == 0);
101     REQUIRE(nodeA->graphOrder() > artboard->graphOrder());
102     REQUIRE(nodeB->graphOrder() > nodeA->graphOrder());
103     REQUIRE(nodeC->graphOrder() > nodeB->graphOrder());
104     REQUIRE(shape->graphOrder() > nodeB->graphOrder());
105     REQUIRE(path->graphOrder() > shape->graphOrder());
106
107     artboard->advance(0.0f);
108
109     auto world = shape->worldTransform();
110     REQUIRE(world[4] == 39.203125f);
111     REQUIRE(world[5] == 29.535156f);
112 }
113
114 TEST_CASE("long name in object is parsed correctly", "[file]") {
115     auto file = ReadRiveFile("../../test/assets/long_name.riv");
116     auto artboard = file->artboard();
117
118     // Expect all object in file to be loaded, in this case 7
119     REQUIRE(artboard->objects().size() == 7);
120 }
121
122 // TODO:
123 // ShapePaint (fill/stroke) needs to be implemented in WASM (jsFill/jsStroke) in
124 // order to create Paint objects as necessary.
125
126 // Mutators need to be implemented in WASM (solid/linear/radial) and get access
127 // to their ShapePaint so they can mutate any extra objects they create on it
128 // (like a paint object for skia).
129
130 // Paths need to be implemented in WASM but not so much as a core path (like
131 // parametric/pointspath, etc) but more as a general rendering path. Handed
132 // their commands so they can generate/store a re-usable path. This would be a
133 // Path2D in context2D and a SkPath in CanvasKit.
134
135 // PathComposer is the factory for the Paths. But they do need to surive so they
136 // can be reset/reused as available by the rendering lib.
137
138 // PathComposer needs to be implemented in WASM to compose the paths together
139 // and be accessible from the Shape (jsShape) which will need a call
140 // setupFill/restoreFill and setupStroke/restoreStroke.
141
142 // Draw will be called by C++ on the Shape, the Shape will call draw on the
143 // fill/stroke (propagates to jsFill/jsStroke)