2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 // Enable debug log for test coverage
19 #define DEBUG_ENABLED 1
21 #include "dali-scene3d/public-api/loader/scene-definition.h"
22 #include "dali-scene3d/public-api/loader/utils.h"
23 #include <dali-test-suite-utils.h>
26 using namespace Dali::Scene3D::Loader;
28 int UtcDaliSceneDefinitionAddNode(void)
30 SceneDefinition sceneDef;
32 DALI_TEST_EQUAL(sceneDef.GetNodeCount(), 0u);
33 auto node = new NodeDefinition();
34 node->mName = "First";
36 auto result = sceneDef.AddNode(std::unique_ptr<NodeDefinition>{ node });
37 DALI_TEST_EQUAL(result, node);
38 DALI_TEST_EQUAL(sceneDef.GetNodeCount(), 1u);
39 DALI_TEST_EQUAL(sceneDef.GetNode(0), node);
40 DALI_TEST_EQUAL(sceneDef.FindNode(node->mName), node);
42 auto node2 = new NodeDefinition();
43 node2->mName = node->mName;
44 result = sceneDef.AddNode(std::unique_ptr<NodeDefinition>{ node2 });
45 DALI_TEST_EQUAL(result, node2);
46 DALI_TEST_EQUAL(sceneDef.GetNodeCount(), 2u);
47 DALI_TEST_EQUAL(sceneDef.GetNode(1), node2);
49 auto child = new NodeDefinition();
50 child->mName = "Second";
51 child->mParentIdx = 0;
53 DALI_TEST_CHECK(node->mChildren.empty()); // these are hooked up by AddNode, base on parent idx.
55 result = sceneDef.AddNode(std::unique_ptr<NodeDefinition>{ child });
56 DALI_TEST_EQUAL(result, child);
57 DALI_TEST_EQUAL(sceneDef.GetNodeCount(), 3u);
58 DALI_TEST_EQUAL(sceneDef.GetNode(2), child);
59 DALI_TEST_EQUAL(sceneDef.FindNode(child->mName), child);
61 DALI_TEST_EQUAL(node->mChildren[0], 2u); // these are hooked up by AddNode, base on parent idx.
66 int UtcDaliSceneDefinitionAddRootsFail(void)
68 SceneDefinition sceneDef;
70 DALI_TEST_ASSERTION(sceneDef.AddRootNode(0), "index out of bounds");
71 DALI_TEST_CHECK(sceneDef.GetRoots().empty());
72 DALI_TEST_EQUAL(sceneDef.GetNodeCount(), 0u);
82 SceneDefinition sceneDef;
84 NodeDefinition* childA;
85 NodeDefinition* childB;
89 root{ new NodeDefinition{ "Root" }},
90 childA{ new NodeDefinition{ "A" }},
91 childB{ new NodeDefinition{ "B" }}
93 childA->mParentIdx = 0;
94 childB->mParentIdx = 0;
96 root = sceneDef.AddNode(std::unique_ptr<NodeDefinition>{ root });
97 childA = sceneDef.AddNode(std::unique_ptr<NodeDefinition>{ childA });
98 childB = sceneDef.AddNode(std::unique_ptr<NodeDefinition>{ childB });
109 struct NodeVisitor : NodeDefinition::IVisitor
114 NodeDefinition* node;
116 bool operator==(const Visit& other) const
118 return event == other.event && node == other.node;
122 void Start(NodeDefinition& n) override
124 visits.push_back({ START, &n });
127 void Finish(NodeDefinition& n) override
129 visits.push_back({ FINISH, &n });
132 std::vector<Visit> visits;
135 struct ConstNodeVisitor : NodeDefinition::IConstVisitor
140 const NodeDefinition* node;
142 bool operator==(const Visit& other) const
144 return event == other.event && node == other.node;
148 void Start(const NodeDefinition& n) override
150 visits.push_back({ START, &n });
153 void Finish(const NodeDefinition& n) override
155 visits.push_back({ FINISH, &n });
158 std::vector<Visit> visits;
163 int UtcDaliSceneDefinitionAddRemoveRootNode(void)
167 DALI_TEST_EQUAL(ctx.sceneDef.AddRootNode(0), 0);
168 DALI_TEST_EQUAL(ctx.sceneDef.GetRoots().size(), 1u);
169 DALI_TEST_EQUAL(ctx.sceneDef.GetRoots()[0], 0);
171 ctx.sceneDef.RemoveRootNode(0);
172 DALI_TEST_EQUAL(ctx.sceneDef.GetRoots().size(), 0);
174 DALI_TEST_EQUAL(ctx.sceneDef.GetNodeCount(), 3u);
179 int UtcDaliSceneDefinitionVisit(void)
184 ctx.sceneDef.Visit(0, Customization::Choices{}, visitor);
186 const NodeVisitor::Visit expected[] {
188 { START, ctx.childA },
189 { FINISH, ctx.childA },
190 { START, ctx.childB },
191 { FINISH, ctx.childB },
192 { FINISH, ctx.root },
194 DALI_TEST_CHECK(std::equal(visitor.visits.begin(), visitor.visits.end(), expected));
199 int UtcDaliSceneDefinitionConstVisit(void)
203 ConstNodeVisitor visitor;
204 ctx.sceneDef.Visit(0, Customization::Choices{}, visitor);
206 const ConstNodeVisitor::Visit expected[] {
208 { START, ctx.childA },
209 { FINISH, ctx.childA },
210 { START, ctx.childB },
211 { FINISH, ctx.childB },
212 { FINISH, ctx.root },
214 DALI_TEST_CHECK(std::equal(visitor.visits.begin(), visitor.visits.end(), expected));
219 int UtcDaliSceneDefinitionVisitCustomized(void)
223 ctx.root->mCustomization.reset(new NodeDefinition::CustomizationDefinition{ "A/B" });
225 const NodeVisitor::Visit expected[] {
227 { START, ctx.childB },
228 { FINISH, ctx.childB },
229 { FINISH, ctx.root },
232 Customization::Choices choices;
233 for (auto i : { 1, 2 })
235 choices.Set("A/B", i);
238 ctx.sceneDef.Visit(0, choices, visitor);
240 DALI_TEST_CHECK(std::equal(visitor.visits.begin(), visitor.visits.end(), std::begin(expected)));
246 int UtcDaliSceneDefinitionConstVisitCustomized(void)
250 ctx.root->mCustomization.reset(new NodeDefinition::CustomizationDefinition{ "A/B" });
252 const ConstNodeVisitor::Visit expected[] {
254 { START, ctx.childB },
255 { FINISH, ctx.childB },
256 { FINISH, ctx.root },
259 Customization::Choices choices;
260 for (auto i : { 1, 2 })
262 choices.Set("A/B", i);
264 ConstNodeVisitor visitor;
265 ctx.sceneDef.Visit(0, choices, visitor);
267 DALI_TEST_CHECK(std::equal(visitor.visits.begin(), visitor.visits.end(), std::begin(expected)));
273 int UtcDaliSceneDefinitionGetCustomizationOptions(void)
277 ctx.sceneDef.AddRootNode(0); // GetCustomizationOptions requires this.
279 ctx.root->mCustomization.reset(new NodeDefinition::CustomizationDefinition{ "A/B" });
280 ctx.childA->mCustomization.reset(new NodeDefinition::CustomizationDefinition{ "hello" });
281 ctx.childB->mCustomization.reset(new NodeDefinition::CustomizationDefinition{ "goodbye" });
283 Customization::Choices choices;
284 Customization::Map options;
285 ctx.sceneDef.GetCustomizationOptions(choices, options, &choices);
287 DALI_TEST_EQUAL(choices.Size(), 2u);
288 DALI_TEST_EQUAL(options.Size(), 2u);
293 Customization customization;
294 Customization::OptionType choice;
297 std::vector<TestOption> testOptions {
298 { "A/B", { 2, { "Root" } }, 0 },
299 { "hello", { 0, { "A" } }, 0 },
301 for (auto& testOption: testOptions)
303 auto iFind = choices.Get(testOption.name);
304 DALI_TEST_EQUAL(iFind, testOption.choice);
306 auto iFindOption = options.Get(testOption.name);
307 DALI_TEST_CHECK(iFindOption != nullptr);
308 DALI_TEST_EQUAL(iFindOption->numOptions, testOption.customization.numOptions);
309 DALI_TEST_EQUAL(iFindOption->nodes.size(), testOption.customization.nodes.size());
310 DALI_TEST_CHECK(std::equal(iFindOption->nodes.begin(), iFindOption->nodes.end(),
311 testOption.customization.nodes.begin()));
315 choices.Set("A/B", 1);
316 *options.Get("A/B") = {};
318 testOptions[0].choice = 1;
319 testOptions[1].name = "goodbye";
320 testOptions[1].customization.nodes[0] = "B";
322 ctx.sceneDef.GetCustomizationOptions(choices, options, &choices);
324 DALI_TEST_EQUAL(choices.Size(), 2u);
325 DALI_TEST_EQUAL(options.Size(), 3u);
327 for (auto& testOption: testOptions)
329 auto iFind = choices.Get(testOption.name);
330 DALI_TEST_EQUAL(iFind, testOption.choice);
332 auto iFindOption = options.Get(testOption.name);
333 DALI_TEST_CHECK(iFindOption != nullptr);
334 DALI_TEST_EQUAL(iFindOption->numOptions, testOption.customization.numOptions);
335 DALI_TEST_EQUAL(iFindOption->nodes.size(), testOption.customization.nodes.size());
336 DALI_TEST_CHECK(std::equal(iFindOption->nodes.begin(), iFindOption->nodes.end(),
337 testOption.customization.nodes.begin()));
343 int UtcDaliSceneDefinitionFindNode(void)
347 Index result = INVALID_INDEX;
348 for (auto n: { ctx.root, ctx.childA, ctx.childB })
350 ctx.sceneDef.FindNode(n->mName, &result);
351 DALI_TEST_CHECK(result != INVALID_INDEX);
352 DALI_TEST_EQUAL(ctx.sceneDef.GetNode(result), n);
358 int UtcDaliSceneDefinitionConstFindNode(void)
362 Index result = INVALID_INDEX;
363 for (auto n: { ctx.root, ctx.childA, ctx.childB })
365 const_cast<const TestContext&>(ctx).sceneDef.FindNode(n->mName, &result);
366 DALI_TEST_CHECK(result != INVALID_INDEX);
367 DALI_TEST_EQUAL(ctx.sceneDef.GetNode(result), n);
373 int UtcDaliSceneDefinitionFindNodeIndex(void)
377 Index result = INVALID_INDEX;
378 for (auto n: { ctx.root, ctx.childA, ctx.childB })
380 result = ctx.sceneDef.FindNodeIndex(*n);
381 DALI_TEST_CHECK(result != INVALID_INDEX);
382 DALI_TEST_EQUAL(ctx.sceneDef.GetNode(result), n);
388 int UtcDaliSceneDefinitionFindNodes(void)
392 std::vector<NodeDefinition*> nodes;
393 auto nodeConsumer = [&nodes](NodeDefinition& nd) {
394 nodes.push_back(&nd);
397 auto nodePredicate = [](const NodeDefinition& nd) {
398 return nd.mName.length() == 1;
401 ctx.sceneDef.FindNodes(nodePredicate, nodeConsumer, 1);
402 DALI_TEST_EQUAL(nodes.size(), 1);
403 DALI_TEST_EQUAL(nodes[0]->mName, "A");
404 DALI_TEST_EQUAL(nodes[0], ctx.childA);
407 ctx.sceneDef.FindNodes(nodePredicate, nodeConsumer);
409 DALI_TEST_EQUAL(nodes.size(), 2);
410 DALI_TEST_EQUAL(nodes[0]->mName, "A");
411 DALI_TEST_EQUAL(nodes[0], ctx.childA);
412 DALI_TEST_EQUAL(nodes[1]->mName, "B");
413 DALI_TEST_EQUAL(nodes[1], ctx.childB);
418 int UtcDaliSceneDefinitionRemoveNode(void)
421 DALI_TEST_EQUAL(ctx.sceneDef.RemoveNode("doesn't exist"), false);
424 DALI_TEST_EQUAL(ctx.sceneDef.GetNodeCount(), 3u);
425 DALI_TEST_EQUAL(ctx.root->mChildren.size(), 2u);
428 DALI_TEST_EQUAL(ctx.sceneDef.FindNode("B", &result), ctx.childB);
429 DALI_TEST_EQUAL(result, 2);
431 DALI_TEST_EQUAL(ctx.sceneDef.RemoveNode("A"), true);
434 DALI_TEST_EQUAL(ctx.sceneDef.GetNodeCount(), 2u);
437 DALI_TEST_EQUAL(ctx.sceneDef.FindNode("A", &result), static_cast<NodeDefinition*>(nullptr));
438 DALI_TEST_EQUAL(result, 12345); // doesn't change
440 DALI_TEST_EQUAL(ctx.sceneDef.FindNode("B", &result), ctx.childB);
441 DALI_TEST_EQUAL(result, 1); // dropped
443 DALI_TEST_EQUAL(ctx.root->mChildren.size(), 1u);
444 DALI_TEST_EQUAL(ctx.root->mChildren[0], 1u);
447 DALI_TEST_EQUAL(ctx.sceneDef.RemoveNode("Root"), true);
448 DALI_TEST_EQUAL(ctx.sceneDef.GetNodeCount(), 0);
453 int UtcDaliSceneDefinitionReparentNode(void)
457 ctx.sceneDef.ReparentNode("B", "A", 0);
459 DALI_TEST_EQUAL(ctx.childB->mParentIdx, ctx.sceneDef.FindNodeIndex(*ctx.childA));
460 DALI_TEST_EQUAL(ctx.childA->mChildren.size(), 1u);
461 DALI_TEST_EQUAL(ctx.childA->mChildren[0], ctx.sceneDef.FindNodeIndex(*ctx.childB));