1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2017 Paul Lemire <paul.lemire350@gmail.com> |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the Qt3D module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | |
29 | |
30 | #include <QtTest/QTest> |
31 | #include <Qt3DAnimation/qlerpclipblend.h> |
32 | #include <Qt3DAnimation/qanimationcliploader.h> |
33 | #include <Qt3DAnimation/private/qlerpclipblend_p.h> |
34 | #include <QObject> |
35 | #include <QSignalSpy> |
36 | #include <Qt3DCore/private/qnodecreatedchangegenerator_p.h> |
37 | #include <Qt3DAnimation/qclipblendnodecreatedchange.h> |
38 | #include <Qt3DCore/qnodecreatedchange.h> |
39 | #include "testpostmanarbiter.h" |
40 | |
41 | class tst_QLerpClipBlend : public QObject |
42 | { |
43 | Q_OBJECT |
44 | |
45 | private Q_SLOTS: |
46 | void initTestCase() |
47 | { |
48 | qRegisterMetaType<Qt3DAnimation::QAbstractClipBlendNode*>(); |
49 | } |
50 | |
51 | void checkDefaultConstruction() |
52 | { |
53 | // GIVEN |
54 | Qt3DAnimation::QLerpClipBlend lerpBlend; |
55 | |
56 | // THEN |
57 | QCOMPARE(lerpBlend.blendFactor(), 0.0f); |
58 | QCOMPARE(lerpBlend.startClip(), static_cast<Qt3DAnimation::QAbstractClipBlendNode *>(nullptr)); |
59 | QCOMPARE(lerpBlend.endClip(), static_cast<Qt3DAnimation::QAbstractClipBlendNode *>(nullptr)); |
60 | } |
61 | |
62 | void checkPropertyChanges() |
63 | { |
64 | // GIVEN |
65 | Qt3DAnimation::QLerpClipBlend lerpBlend; |
66 | |
67 | { |
68 | // WHEN |
69 | QSignalSpy spy(&lerpBlend, SIGNAL(blendFactorChanged(float))); |
70 | const float newValue = 0.5f; |
71 | lerpBlend.setBlendFactor(newValue); |
72 | |
73 | // THEN |
74 | QVERIFY(spy.isValid()); |
75 | QCOMPARE(lerpBlend.blendFactor(), newValue); |
76 | QCOMPARE(spy.count(), 1); |
77 | |
78 | // WHEN |
79 | spy.clear(); |
80 | lerpBlend.setBlendFactor(newValue); |
81 | |
82 | // THEN |
83 | QCOMPARE(lerpBlend.blendFactor(), newValue); |
84 | QCOMPARE(spy.count(), 0); |
85 | } |
86 | |
87 | { |
88 | // WHEN |
89 | QSignalSpy spy(&lerpBlend, SIGNAL(startClipChanged(Qt3DAnimation::QAbstractClipBlendNode*))); |
90 | auto newValue = new Qt3DAnimation::QLerpClipBlend(); |
91 | lerpBlend.setStartClip(newValue); |
92 | |
93 | // THEN |
94 | QVERIFY(spy.isValid()); |
95 | QCOMPARE(lerpBlend.startClip(), newValue); |
96 | QCOMPARE(spy.count(), 1); |
97 | |
98 | // WHEN |
99 | spy.clear(); |
100 | lerpBlend.setStartClip(newValue); |
101 | |
102 | // THEN |
103 | QCOMPARE(lerpBlend.startClip(), newValue); |
104 | QCOMPARE(spy.count(), 0); |
105 | } |
106 | |
107 | { |
108 | // WHEN |
109 | QSignalSpy spy(&lerpBlend, SIGNAL(endClipChanged(Qt3DAnimation::QAbstractClipBlendNode*))); |
110 | auto newValue = new Qt3DAnimation::QLerpClipBlend(); |
111 | lerpBlend.setEndClip(newValue); |
112 | |
113 | // THEN |
114 | QVERIFY(spy.isValid()); |
115 | QCOMPARE(lerpBlend.endClip(), newValue); |
116 | QCOMPARE(spy.count(), 1); |
117 | |
118 | // WHEN |
119 | spy.clear(); |
120 | lerpBlend.setEndClip(newValue); |
121 | |
122 | // THEN |
123 | QCOMPARE(lerpBlend.endClip(), newValue); |
124 | QCOMPARE(spy.count(), 0); |
125 | } |
126 | } |
127 | |
128 | void checkCreationData() |
129 | { |
130 | // GIVEN |
131 | Qt3DAnimation::QLerpClipBlend lerpBlend; |
132 | Qt3DAnimation::QLerpClipBlend startClip; |
133 | Qt3DAnimation::QLerpClipBlend endClip; |
134 | |
135 | lerpBlend.setStartClip(&startClip); |
136 | lerpBlend.setEndClip(&endClip); |
137 | lerpBlend.setBlendFactor(0.8f); |
138 | |
139 | |
140 | // WHEN |
141 | QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges; |
142 | |
143 | { |
144 | Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&lerpBlend); |
145 | creationChanges = creationChangeGenerator.creationChanges(); |
146 | } |
147 | |
148 | // THEN |
149 | { |
150 | QCOMPARE(creationChanges.size(), 3); // 1 + 2 clips |
151 | |
152 | const auto creationChangeData = qSharedPointerCast<Qt3DAnimation::QClipBlendNodeCreatedChange<Qt3DAnimation::QLerpClipBlendData>>(src: creationChanges.first()); |
153 | const Qt3DAnimation::QLerpClipBlendData cloneData = creationChangeData->data; |
154 | |
155 | QCOMPARE(lerpBlend.blendFactor(), cloneData.blendFactor); |
156 | QCOMPARE(lerpBlend.id(), creationChangeData->subjectId()); |
157 | QCOMPARE(lerpBlend.isEnabled(), true); |
158 | QCOMPARE(lerpBlend.isEnabled(), creationChangeData->isNodeEnabled()); |
159 | QCOMPARE(lerpBlend.metaObject(), creationChangeData->metaObject()); |
160 | QCOMPARE(cloneData.startClipId, startClip.id()); |
161 | QCOMPARE(cloneData.endClipId, endClip.id()); |
162 | } |
163 | |
164 | // WHEN |
165 | lerpBlend.setEnabled(false); |
166 | |
167 | { |
168 | Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&lerpBlend); |
169 | creationChanges = creationChangeGenerator.creationChanges(); |
170 | } |
171 | |
172 | // THEN |
173 | { |
174 | QCOMPARE(creationChanges.size(), 3); // 1 + 2 clips |
175 | |
176 | const auto creationChangeData = qSharedPointerCast<Qt3DAnimation::QClipBlendNodeCreatedChange<Qt3DAnimation::QLerpClipBlendData>>(src: creationChanges.first()); |
177 | const Qt3DAnimation::QLerpClipBlendData cloneData = creationChangeData->data; |
178 | |
179 | QCOMPARE(lerpBlend.blendFactor(), cloneData.blendFactor); |
180 | QCOMPARE(lerpBlend.id(), creationChangeData->subjectId()); |
181 | QCOMPARE(lerpBlend.isEnabled(), false); |
182 | QCOMPARE(lerpBlend.isEnabled(), creationChangeData->isNodeEnabled()); |
183 | QCOMPARE(lerpBlend.metaObject(), creationChangeData->metaObject()); |
184 | QCOMPARE(cloneData.startClipId, startClip.id()); |
185 | QCOMPARE(cloneData.endClipId, endClip.id()); |
186 | } |
187 | } |
188 | |
189 | void checkBlendFactorUpdate() |
190 | { |
191 | // GIVEN |
192 | TestArbiter arbiter; |
193 | Qt3DAnimation::QLerpClipBlend lerpBlend; |
194 | arbiter.setArbiterOnNode(&lerpBlend); |
195 | |
196 | { |
197 | // WHEN |
198 | lerpBlend.setBlendFactor(0.4f); |
199 | |
200 | // THEN |
201 | QCOMPARE(arbiter.dirtyNodes.size(), 1); |
202 | QCOMPARE(arbiter.dirtyNodes.front(), &lerpBlend); |
203 | |
204 | arbiter.dirtyNodes.clear(); |
205 | } |
206 | |
207 | { |
208 | // WHEN |
209 | lerpBlend.setBlendFactor(0.4f); |
210 | |
211 | // THEN |
212 | QCOMPARE(arbiter.dirtyNodes.size(), 0); |
213 | } |
214 | |
215 | } |
216 | |
217 | void checkStartClipUpdate() |
218 | { |
219 | // GIVEN |
220 | TestArbiter arbiter; |
221 | Qt3DAnimation::QLerpClipBlend lerpBlend; |
222 | arbiter.setArbiterOnNode(&lerpBlend); |
223 | auto startClip = new Qt3DAnimation::QLerpClipBlend(); |
224 | |
225 | { |
226 | // WHEN |
227 | lerpBlend.setStartClip(startClip); |
228 | |
229 | // THEN |
230 | QCOMPARE(arbiter.dirtyNodes.size(), 1); |
231 | QCOMPARE(arbiter.dirtyNodes.front(), &lerpBlend); |
232 | |
233 | arbiter.dirtyNodes.clear(); |
234 | } |
235 | |
236 | { |
237 | // WHEN |
238 | lerpBlend.setStartClip(startClip); |
239 | |
240 | // THEN |
241 | QCOMPARE(arbiter.dirtyNodes.size(), 0); |
242 | } |
243 | } |
244 | |
245 | void checkEndClipUpdate() |
246 | { |
247 | // GIVEN |
248 | TestArbiter arbiter; |
249 | Qt3DAnimation::QLerpClipBlend lerpBlend; |
250 | arbiter.setArbiterOnNode(&lerpBlend); |
251 | auto endClip = new Qt3DAnimation::QLerpClipBlend(); |
252 | |
253 | { |
254 | // WHEN |
255 | lerpBlend.setEndClip(endClip); |
256 | |
257 | // THEN |
258 | QCOMPARE(arbiter.dirtyNodes.size(), 1); |
259 | QCOMPARE(arbiter.dirtyNodes.front(), &lerpBlend); |
260 | |
261 | arbiter.dirtyNodes.clear(); |
262 | } |
263 | |
264 | { |
265 | // WHEN |
266 | lerpBlend.setEndClip(endClip); |
267 | |
268 | // THEN |
269 | QCOMPARE(arbiter.dirtyNodes.size(), 0); |
270 | } |
271 | } |
272 | |
273 | void checkStartClipBookkeeping() |
274 | { |
275 | // GIVEN |
276 | QScopedPointer<Qt3DAnimation::QLerpClipBlend> lerpBlend(new Qt3DAnimation::QLerpClipBlend); |
277 | { |
278 | // WHEN |
279 | Qt3DAnimation::QLerpClipBlend clip; |
280 | lerpBlend->setStartClip(&clip); |
281 | |
282 | // THEN |
283 | QCOMPARE(clip.parent(), lerpBlend.data()); |
284 | QCOMPARE(lerpBlend->startClip(), &clip); |
285 | } |
286 | // THEN (Should not crash and clip be unset) |
287 | QVERIFY(lerpBlend->startClip() == nullptr); |
288 | |
289 | { |
290 | // WHEN |
291 | Qt3DAnimation::QLerpClipBlend someOtherLerpBlend; |
292 | QScopedPointer<Qt3DAnimation::QLerpClipBlend> clip(new Qt3DAnimation::QLerpClipBlend(&someOtherLerpBlend)); |
293 | lerpBlend->setStartClip(clip.data()); |
294 | |
295 | // THEN |
296 | QCOMPARE(clip->parent(), &someOtherLerpBlend); |
297 | QCOMPARE(lerpBlend->startClip(), clip.data()); |
298 | |
299 | // WHEN |
300 | lerpBlend.reset(); |
301 | clip.reset(); |
302 | |
303 | // THEN Should not crash when the effect is destroyed (tests for failed removal of destruction helper) |
304 | } |
305 | } |
306 | |
307 | void checkEndClipBookkeeping() |
308 | { |
309 | // GIVEN |
310 | QScopedPointer<Qt3DAnimation::QLerpClipBlend> lerpBlend(new Qt3DAnimation::QLerpClipBlend); |
311 | { |
312 | // WHEN |
313 | Qt3DAnimation::QLerpClipBlend clip; |
314 | lerpBlend->setEndClip(&clip); |
315 | |
316 | // THEN |
317 | QCOMPARE(clip.parent(), lerpBlend.data()); |
318 | QCOMPARE(lerpBlend->endClip(), &clip); |
319 | } |
320 | // THEN (Should not crash and clip be unset) |
321 | QVERIFY(lerpBlend->endClip() == nullptr); |
322 | |
323 | { |
324 | // WHEN |
325 | Qt3DAnimation::QLerpClipBlend someOtherLerpBlend; |
326 | QScopedPointer<Qt3DAnimation::QLerpClipBlend> clip(new Qt3DAnimation::QLerpClipBlend(&someOtherLerpBlend)); |
327 | lerpBlend->setEndClip(clip.data()); |
328 | |
329 | // THEN |
330 | QCOMPARE(clip->parent(), &someOtherLerpBlend); |
331 | QCOMPARE(lerpBlend->endClip(), clip.data()); |
332 | |
333 | // WHEN |
334 | lerpBlend.reset(); |
335 | clip.reset(); |
336 | |
337 | // THEN Should not crash when the effect is destroyed (tests for failed removal of destruction helper) |
338 | } |
339 | } |
340 | }; |
341 | |
342 | QTEST_MAIN(tst_QLerpClipBlend) |
343 | |
344 | #include "tst_qlerpclipblend.moc" |
345 | |