| /* |
| * Copyright 2020 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "modules/skottie/include/ExternalLayer.h" |
| #include "modules/skottie/src/SkottiePriv.h" |
| #include "modules/skottie/src/SkottieValue.h" |
| #include "modules/skottie/src/animator/Animator.h" |
| #include "src/utils/SkJSON.h" |
| #include "tests/Test.h" |
| |
| #include <cmath> |
| |
| using namespace skottie; |
| using namespace skottie::internal; |
| |
| namespace { |
| |
| template <typename T> |
| class MockProperty final : public AnimatablePropertyContainer { |
| public: |
| explicit MockProperty(const char* jprop) { |
| AnimationBuilder abuilder(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, |
| {100, 100}, 10, 1, 0); |
| skjson::DOM json_dom(jprop, strlen(jprop)); |
| |
| fDidBind = this->bind(abuilder, json_dom.root(), &fValue); |
| } |
| |
| operator bool() const { return fDidBind; } |
| |
| const T& operator()(float t) { this->seek(t); return fValue; } |
| |
| private: |
| void onSync() override {} |
| |
| T fValue = T(); |
| bool fDidBind; |
| }; |
| |
| } // namespace |
| |
| DEF_TEST(Skottie_Keyframe, reporter) { |
| { |
| MockProperty<ScalarValue> prop(R"({})"); |
| REPORTER_ASSERT(reporter, !prop); |
| } |
| { |
| MockProperty<ScalarValue> prop(R"({ "a": 1, "k": [] })"); |
| REPORTER_ASSERT(reporter, !prop); |
| } |
| { |
| // New style |
| MockProperty<ScalarValue> prop(R"({ |
| "a": 1, |
| "k": [ |
| { "t": 1, "s": 1 }, |
| { "t": 2, "s": 2 }, |
| { "t": 3, "s": 4 } |
| ] |
| })"); |
| REPORTER_ASSERT(reporter, prop); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop( -1), 1)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop( 0), 1)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop( 1), 1)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(1.5), 1.5f)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop( 2), 2)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(2.5), 3)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop( 3), 4)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop( 4), 4)); |
| } |
| { |
| // New style hold (hard stops) |
| MockProperty<ScalarValue> prop(R"({ |
| "a": 1, |
| "k": [ |
| { "t": 1, "s": 1, "h": true }, |
| { "t": 2, "s": 2, "h": true }, |
| { "t": 3, "s": 4, "h": true } |
| ] |
| })"); |
| REPORTER_ASSERT(reporter, prop); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(0 ), 1)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(1 ), 1)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(1.5), 1)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(std::nextafter(2.f, 0.f)), 1)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(2 ), 2)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(2.5), 2)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(std::nextafter(3.f, 0.f)), 2)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(3 ), 4)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(4 ), 4)); |
| } |
| { |
| // Legacy style |
| MockProperty<ScalarValue> prop(R"({ |
| "a": 1, |
| "k": [ |
| { "t": 1, "s": 1, "e": 2 }, |
| { "t": 2, "s": 2, "e": 4 }, |
| { "t": 3 } |
| ] |
| })"); |
| REPORTER_ASSERT(reporter, prop); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(-1), 1)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop( 0), 1)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop( 1 ), 1)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop( 1.5), 1.5f)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop( 2 ), 2)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop( 2.5), 3)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop( 3 ), 4)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop( 4 ), 4)); |
| } |
| { |
| // Legacy style hold (hard stops) |
| MockProperty<ScalarValue> prop(R"({ |
| "a": 1, |
| "k": [ |
| { "t": 1, "s": 1, "e": 2, "h": true }, |
| { "t": 2, "s": 2, "e": 4, "h": true }, |
| { "t": 3 } |
| ] |
| })"); |
| REPORTER_ASSERT(reporter, prop); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(0 ), 1)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(1 ), 1)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(1.5), 1)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(std::nextafter(2.f, 0.f)), 1)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(2 ), 2)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(2.5), 2)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(std::nextafter(3.f, 0.f)), 2)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(3 ), 4)); |
| REPORTER_ASSERT(reporter, SkScalarNearlyEqual(prop(4 ), 4)); |
| } |
| } |