2 * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with consumer library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <mlt++/Mlt.h>
27 #include <framework/mlt_property.h>
28 #include <framework/mlt_animation.h>
31 class TestProperties: public QObject
39 void InstantiationIsAReference()
42 QCOMPARE(p.ref_count(), 1);
45 void CopyAddsReference()
49 QCOMPARE(p.ref_count(), 2);
52 void DestructionRemovesReference()
55 Properties* q = new Properties(p);
56 QCOMPARE(p.ref_count(), 2);
58 QCOMPARE(p.ref_count(), 1);
61 void SetAndGetString()
64 p.set("key", "value");
65 QVERIFY(p.get("key"));
66 QVERIFY(QString(p.get("key")) != QString(""));
67 QCOMPARE(p.get("key"), "value");
75 QCOMPARE(p.get_int("key"), i);
78 void SetAndGetDouble()
83 QCOMPARE(p.get_double("key"), d);
89 int64_t i = 1LL << 32;
91 QCOMPARE(p.get_int64("key"), i);
97 const char *value = "value";
98 char* const s = strdup(value);
99 p.set("key", s, strlen(s), free);
101 QCOMPARE((char*) p.get_data("key", size), value);
102 QCOMPARE(size, int(strlen(value)));
108 const char *s = "-1";
111 QCOMPARE(p.get("key"), s);
113 QCOMPARE(p.get_int("key"), i);
116 void Int64FromString()
119 const char *s = "-1";
122 QCOMPARE(p.get("key"), s);
124 QCOMPARE(p.get_int64("key"), i);
127 void DoubleFromString()
130 const char *s = "-1.234567";
131 double d = -1.234567;
133 QCOMPARE(p.get("key"), s);
135 QCOMPARE(p.get_double("key"), d);
138 void SetNullRemovesProperty()
141 const char *s = NULL;
142 p.set("key", "value");
144 QCOMPARE(p.get("key"), s);
147 void SetAndGetHexColor()
150 const char *hexColorString = "0xaabbccdd";
151 int hexColorInt = 0xaabbccdd;
152 p.set("key", hexColorString);
153 QCOMPARE(p.get_int("key"), hexColorInt);
156 void SetAndGetCssColor()
159 const char *cssColorString = "#aabbcc";
160 int cssColorInt = 0xaabbccff;
161 p.set("key", cssColorString);
162 QCOMPARE(p.get_int("key"), cssColorInt);
164 const char *cssColorAlphaString = "#00aabbcc";
165 int cssColorAlphaInt = 0xaabbcc00;
166 p.set("key", cssColorAlphaString);
167 QCOMPARE(p.get_int("key"), cssColorAlphaInt);
170 void SetAndGetTimeCode()
174 p.set("_profile", profile.get_profile(), 0);
175 const char *timeString = "11:22:33:04";
176 p.set("key", timeString);
177 QCOMPARE(p.get_int("key"), 1023829);
178 p.set("key", 1023829);
179 QCOMPARE(p.get_time("key", mlt_time_smpte), timeString);
182 void SetAndGetTimeClock()
186 p.set("_profile", profile.get_profile(), 0);
187 const char *timeString = "11:22:33.400";
188 p.set("key", timeString);
189 QCOMPARE(p.get_int("key"), 1023835);
190 p.set("key", 1023835);
191 QCOMPARE(p.get_time("key", mlt_time_clock), timeString);
194 void SetSimpleMathExpression()
197 p.set("key", "@16.0/9.0 *2 +3 -1");
198 QCOMPARE(p.get_int("key"), 5);
199 QCOMPARE(p.get_double("key"), 16.0/9.0 *2 +3 -1);
202 void PassOneProperty()
205 const char *s = "value";
207 QCOMPARE(p[1].get("key"), (void*) 0);
208 p[1].pass_property(p[0], "key");
209 QCOMPARE(p[1].get("key"), s);
212 void PassMultipleByPrefix()
215 const char *s = "value";
216 p[0].set("key.one", s);
217 p[0].set("key.two", s);
218 QCOMPARE(p[1].get("key.one"), (void*) 0);
219 QCOMPARE(p[1].get("key.two"), (void*) 0);
220 p[1].pass_values(p[0], "key.");
221 QCOMPARE(p[1].get("one"), s);
222 QCOMPARE(p[1].get("two"), s);
225 void PassMultipleByList()
228 const char *s = "value";
229 p[0].set("key.one", s);
230 p[0].set("key.two", s);
231 QCOMPARE(p[1].get("key.one"), (void*) 0);
232 QCOMPARE(p[1].get("key.two"), (void*) 0);
233 p[1].pass_list(p[0], "key.one key.two");
234 QCOMPARE(p[1].get("key.one"), s);
235 QCOMPARE(p[1].get("key.two"), s);
238 void MirrorProperties()
242 p[0].set("key", "value");
243 QCOMPARE(p[1].get("key"), "value");
246 void InheritProperties()
249 p[0].set("key", "value");
250 QVERIFY(p[1].get("key") == 0);
252 QCOMPARE(p[1].get("key"), "value");
258 QCOMPARE(p.get("key"), (void*) 0);
259 p.parse("key=value");
260 QCOMPARE(p.get("key"), "value");
261 p.parse("key=\"new value\"");
262 QCOMPARE(p.get("key"), "new value");
265 void RenameProperty()
268 p.set("key", "value");
269 QVERIFY(p.get("new key") == 0);
270 p.rename("key", "new key");
271 QCOMPARE(p.get("new key"), "value");
274 void SequenceDetected()
280 QVERIFY(p.is_sequence());
282 QVERIFY(!p.is_sequence());
285 void SerializesToYamlTiny()
288 p[0].set("key1", "value1");
289 p[0].set("key2", "value2");
290 p[1].set("1", "value3");
291 p[1].set("2", "value4");
292 p[0].set("seq", p[1].get_properties(), 0);
293 QCOMPARE(p[0].serialise_yaml(),
303 void RadixRespondsToLocale()
306 p.set_lcnumeric("en_US");
307 p.set("key", "0.125");
308 QCOMPARE(p.get_double("key"), double(1) / double(8));
309 p.set_lcnumeric("de_DE");
310 p.set("key", "0,125");
311 QCOMPARE(p.get_double("key"), double(1) / double(8));
314 void DoubleAnimation()
317 #if defined(__linux__) || defined(__DARWIN__)
318 locale = newlocale( LC_NUMERIC_MASK, "POSIX", NULL );
321 mlt_animation a = mlt_animation_new();
322 struct mlt_animation_item_s item;
324 mlt_animation_parse(a, "50=1; 60=60; 100=0", 100, fps, locale);
325 mlt_animation_remove(a, 60);
326 char *a_serialized = mlt_animation_serialize(a);
327 QCOMPARE(a_serialized, "50=1;100=0");
328 if (a_serialized) free(a_serialized);
329 item.property = mlt_property_init();
331 mlt_animation_get_item(a, &item, 10);
332 QCOMPARE(mlt_property_get_double(item.property, fps, locale), 1.0);
333 QCOMPARE(item.is_key, 0);
335 mlt_animation_get_item(a, &item, 50);
336 QCOMPARE(mlt_property_get_double(item.property, fps, locale), 1.0);
337 QCOMPARE(item.is_key, 1);
339 mlt_animation_get_item(a, &item, 75);
340 QCOMPARE(mlt_property_get_double(item.property, fps, locale), 0.5);
341 QCOMPARE(item.is_key, 0);
343 mlt_animation_get_item(a, &item, 100);
344 QCOMPARE(mlt_property_get_double(item.property, fps, locale), 0.0);
345 QCOMPARE(item.is_key, 1);
347 mlt_animation_get_item(a, &item, 110);
348 QCOMPARE(mlt_property_get_double(item.property, fps, locale), 0.0);
349 QCOMPARE(item.is_key, 0);
351 mlt_property_close(item.property);
352 mlt_animation_close(a);
358 #if defined(__linux__) || defined(__DARWIN__)
359 locale = newlocale( LC_NUMERIC_MASK, "POSIX", NULL );
362 mlt_animation a = mlt_animation_new();
363 struct mlt_animation_item_s item;
365 mlt_animation_parse(a, "50=100; 60=60; 100=0", 100, fps, locale);
366 mlt_animation_remove(a, 60);
367 char *a_serialized = mlt_animation_serialize(a);
368 QCOMPARE(a_serialized, "50=100;100=0");
369 if (a_serialized) free(a_serialized);
370 item.property = mlt_property_init();
372 mlt_animation_get_item(a, &item, 10);
373 QCOMPARE(mlt_property_get_int(item.property, fps, locale), 100);
374 QCOMPARE(item.is_key, 0);
376 mlt_animation_get_item(a, &item, 50);
377 QCOMPARE(mlt_property_get_int(item.property, fps, locale), 100);
378 QCOMPARE(item.is_key, 1);
380 mlt_animation_get_item(a, &item, 75);
381 QCOMPARE(mlt_property_get_int(item.property, fps, locale), 50);
382 QCOMPARE(item.is_key, 0);
384 mlt_animation_get_item(a, &item, 100);
385 QCOMPARE(mlt_property_get_int(item.property, fps, locale), 0);
386 QCOMPARE(item.is_key, 1);
388 mlt_animation_get_item(a, &item, 110);
389 QCOMPARE(mlt_property_get_int(item.property, fps, locale), 0);
390 QCOMPARE(item.is_key, 0);
392 mlt_property_close(item.property);
393 mlt_animation_close(a);
396 void AnimationWithTimeValueKeyframes()
399 #if defined(__linux__) || defined(__DARWIN__)
400 locale = newlocale( LC_NUMERIC_MASK, "POSIX", NULL );
403 mlt_animation a = mlt_animation_new();
404 struct mlt_animation_item_s item;
406 mlt_animation_parse(a, ":2.0=1; :4.0=0", 100, fps, locale);
407 char *a_serialized = mlt_animation_serialize(a);
408 // Time serializes to frame units :-\.
409 QCOMPARE(a_serialized, "50=1;100=0");
410 if (a_serialized) free(a_serialized);
411 item.property = mlt_property_init();
413 mlt_animation_get_item(a, &item, 10);
414 QCOMPARE(mlt_property_get_double(item.property, fps, locale), 1.0);
415 QCOMPARE(item.is_key, 0);
417 mlt_animation_get_item(a, &item, 50);
418 QCOMPARE(mlt_property_get_double(item.property, fps, locale), 1.0);
419 QCOMPARE(item.is_key, 1);
421 mlt_animation_get_item(a, &item, 75);
422 QCOMPARE(mlt_property_get_double(item.property, fps, locale), 0.5);
423 QCOMPARE(item.is_key, 0);
425 mlt_animation_get_item(a, &item, 100);
426 QCOMPARE(mlt_property_get_double(item.property, fps, locale), 0.0);
427 QCOMPARE(item.is_key, 1);
429 mlt_animation_get_item(a, &item, 110);
430 QCOMPARE(mlt_property_get_double(item.property, fps, locale), 0.0);
431 QCOMPARE(item.is_key, 0);
433 mlt_property_close(item.property);
434 mlt_animation_close(a);
437 void DiscreteIntAnimation()
440 #if defined(__linux__) || defined(__DARWIN__)
441 locale = newlocale( LC_NUMERIC_MASK, "POSIX", NULL );
444 mlt_animation a = mlt_animation_new();
445 struct mlt_animation_item_s item;
447 mlt_animation_parse(a, "50|=100; 60|=60; 100|=0", 100, fps, locale);
448 char *a_serialized = mlt_animation_serialize(a);
449 QCOMPARE(a_serialized, "50|=100;60|=60;100|=0");
450 if (a_serialized) free(a_serialized);
451 item.property = mlt_property_init();
453 mlt_animation_get_item(a, &item, 10);
454 QCOMPARE(mlt_property_get_int(item.property, fps, locale), 100);
455 QCOMPARE(item.is_key, 0);
457 mlt_animation_get_item(a, &item, 50);
458 QCOMPARE(mlt_property_get_int(item.property, fps, locale), 100);
459 QCOMPARE(item.is_key, 1);
461 mlt_animation_get_item(a, &item, 55);
462 QCOMPARE(mlt_property_get_int(item.property, fps, locale), 100);
463 QCOMPARE(item.is_key, 0);
465 mlt_animation_get_item(a, &item, 60);
466 QCOMPARE(mlt_property_get_int(item.property, fps, locale), 60);
467 QCOMPARE(item.is_key, 1);
469 mlt_animation_get_item(a, &item, 75);
470 QCOMPARE(mlt_property_get_int(item.property, fps, locale), 60);
471 QCOMPARE(item.is_key, 0);
473 mlt_animation_get_item(a, &item, 100);
474 QCOMPARE(mlt_property_get_int(item.property, fps, locale), 0);
475 QCOMPARE(item.is_key, 1);
477 mlt_animation_get_item(a, &item, 110);
478 QCOMPARE(mlt_property_get_int(item.property, fps, locale), 0);
479 QCOMPARE(item.is_key, 0);
481 mlt_property_close(item.property);
482 mlt_animation_close(a);
485 void StringAnimation()
488 #if defined(__linux__) || defined(__DARWIN__)
489 locale = newlocale( LC_NUMERIC_MASK, "POSIX", NULL );
492 mlt_animation a = mlt_animation_new();
493 struct mlt_animation_item_s item;
495 mlt_animation_parse(a, "50=hello world; 60=\"good night\"; 100=bar", 100, fps, locale);
496 char *a_serialized = mlt_animation_serialize(a);
497 QCOMPARE(a_serialized, "50=hello world;60=\"good night\";100=bar");
498 if (a_serialized) free(a_serialized);
499 item.property = mlt_property_init();
501 mlt_animation_get_item(a, &item, 10);
502 QCOMPARE(mlt_property_get_string(item.property), "hello world");
503 QCOMPARE(item.is_key, 0);
505 mlt_animation_get_item(a, &item, 50);
506 QCOMPARE(mlt_property_get_string(item.property), "hello world");
507 QCOMPARE(item.is_key, 1);
509 mlt_animation_get_item(a, &item, 75);
510 QCOMPARE(mlt_property_get_string(item.property), "\"good night\"");
511 QCOMPARE(item.is_key, 0);
513 mlt_animation_get_item(a, &item, 100);
514 QCOMPARE(mlt_property_get_string(item.property), "bar");
515 QCOMPARE(item.is_key, 1);
517 mlt_animation_get_item(a, &item, 110);
518 QCOMPARE(mlt_property_get_string(item.property), "bar");
519 QCOMPARE(item.is_key, 0);
521 mlt_property_close(item.property);
522 mlt_animation_close(a);
525 void test_property_get_double_pos()
528 #if defined(__linux__) || defined(__DARWIN__)
529 locale = newlocale( LC_NUMERIC_MASK, "POSIX", NULL );
532 mlt_property p = mlt_property_init();
533 mlt_property_set_string(p, "10=100; 20=200");
534 QCOMPARE(mlt_property_get_double(p, fps, locale), 10.0);
535 QCOMPARE(mlt_property_get_double_pos(p, fps, locale, 0, 100), 100.0);
536 QCOMPARE(mlt_property_get_double_pos(p, fps, locale, 15, 100), 150.0);
537 QCOMPARE(mlt_property_get_double_pos(p, fps, locale, 20, 100), 200.0);
539 mlt_property_set_string(p, "1.5");
540 QCOMPARE(mlt_property_get_double(p, fps, locale), 1.5);
541 QCOMPARE(mlt_property_get_double_pos(p, fps, locale, 10, 100), 1.5);
543 mlt_property_close(p);
546 void test_property_get_int_pos()
549 #if defined(__linux__) || defined(__DARWIN__)
550 locale = newlocale( LC_NUMERIC_MASK, "POSIX", NULL );
553 mlt_property p = mlt_property_init();
554 mlt_property_set_string(p, "10=100; 20=200");
555 QCOMPARE(mlt_property_get_int(p, fps, locale), 10);
556 QCOMPARE(mlt_property_get_int_pos(p, fps, locale, 0, 100), 100);
557 QCOMPARE(mlt_property_get_int_pos(p, fps, locale, 15, 100), 150);
558 QCOMPARE(mlt_property_get_int_pos(p, fps, locale, 20, 100), 200);
560 mlt_property_set_string(p, "1.5");
561 QCOMPARE(mlt_property_get_int(p, fps, locale), 1);
562 QCOMPARE(mlt_property_get_int_pos(p, fps, locale, 10, 100), 1);
564 mlt_property_close(p);
567 void SmoothIntAnimation()
570 #if defined(__linux__) || defined(__DARWIN__)
571 locale = newlocale( LC_NUMERIC_MASK, "POSIX", NULL );
574 mlt_animation a = mlt_animation_new();
575 struct mlt_animation_item_s item;
577 mlt_animation_parse(a, "0=80;10~=80; 20~=30; 30~=40; 40~=28; 50=90; 60=0; 70=60; 80=20", 100, fps, locale);
578 item.property = mlt_property_init();
579 char *a_serialized = mlt_animation_serialize(a);
580 QCOMPARE(a_serialized, "0=80;10~=80;20~=30;30~=40;40~=28;50=90;60=0;70=60;80=20");
581 if (a_serialized) free(a_serialized);
583 mlt_animation_get_item(a, &item, 10);
584 QCOMPARE(mlt_property_get_int(item.property, fps, locale), 80);
585 QCOMPARE(item.is_key, 1);
587 mlt_animation_get_item(a, &item, 50);
588 QCOMPARE(mlt_property_get_int(item.property, fps, locale), 90);
589 QCOMPARE(item.is_key, 1);
591 mlt_animation_get_item(a, &item, 55);
592 QCOMPARE(mlt_property_get_int(item.property, fps, locale), 45);
593 QCOMPARE(item.is_key, 0);
595 mlt_animation_get_item(a, &item, 60);
596 QCOMPARE(mlt_property_get_int(item.property, fps, locale), 0);
597 QCOMPARE(item.is_key, 1);
599 mlt_animation_get_item(a, &item, 75);
600 QCOMPARE(mlt_property_get_int(item.property, fps, locale), 40);
601 QCOMPARE(item.is_key, 0);
603 mlt_animation_get_item(a, &item, 100);
604 QCOMPARE(mlt_property_get_int(item.property, fps, locale), 20);
605 QCOMPARE(item.is_key, 0);
607 mlt_animation_get_item(a, &item, 110);
608 QCOMPARE(mlt_property_get_int(item.property, fps, locale), 20);
609 QCOMPARE(item.is_key, 0);
611 mlt_property_close(item.property);
612 mlt_animation_close(a);
615 void test_property_set_double_pos()
618 #if defined(__linux__) || defined(__DARWIN__)
619 locale = newlocale( LC_NUMERIC_MASK, "POSIX", NULL );
622 mlt_property p = mlt_property_init();
623 mlt_property_set_string(p, "10=100; 20=200");
624 mlt_property_set_double_pos(p, 1.5, fps, locale, mlt_keyframe_linear, 30, 100);
625 QCOMPARE(mlt_property_get_double(p, fps, locale), 10.0);
626 QCOMPARE(mlt_property_get_double_pos(p, fps, locale, 0, 100), 100.0);
627 QCOMPARE(mlt_property_get_double_pos(p, fps, locale, 15, 100), 150.0);
628 QCOMPARE(mlt_property_get_double_pos(p, fps, locale, 20, 100), 200.0);
629 QCOMPARE(mlt_property_get_double_pos(p, fps, locale, 25, 100), 100.75);
630 QCOMPARE(mlt_property_get_double_pos(p, fps, locale, 30, 100), 1.5);
631 mlt_property_close(p);
634 void test_property_set_int_pos()
637 #if defined(__linux__) || defined(__DARWIN__)
638 locale = newlocale( LC_NUMERIC_MASK, "POSIX", NULL );
641 mlt_property p = mlt_property_init();
642 mlt_property_set_string(p, "10=100; 20=200");
643 mlt_property_set_int_pos(p, 300, fps, locale, mlt_keyframe_linear, 30, 100);
644 QCOMPARE(mlt_property_get_int(p, fps, locale), 10);
645 QCOMPARE(mlt_property_get_int_pos(p, fps, locale, 0, 100), 100);
646 QCOMPARE(mlt_property_get_int_pos(p, fps, locale, 15, 100), 150);
647 QCOMPARE(mlt_property_get_int_pos(p, fps, locale, 20, 100), 200);
648 QCOMPARE(mlt_property_get_int_pos(p, fps, locale, 25, 100), 250);
649 QCOMPARE(mlt_property_get_int_pos(p, fps, locale, 30, 100), 300);
650 mlt_property_close(p);
653 void PercentAsRatio()
656 p.set("foo", "12.3%");
657 QCOMPARE(p.get_double("foo"), 0.123);
658 p.set("foo", "456 %");
659 QCOMPARE(p.get_double("foo"), 456.0);
663 QTEST_APPLESS_MAIN(TestProperties)
665 #include "test_properties.moc"