/**
Copyright (C) 2024 Matthew Kosarek
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
**/
#include "animator.h"
#include "miracle_config.h"
#include "yaml-cpp/yaml.h"
#include
#include
#include
#include
#include
using namespace miracle;
namespace
{
int argc = 1;
char const* argv[] = { "miracle-wm-tests" };
const std::string path = std::filesystem::current_path() / "test.yaml";
}
class ImmediateServerActionQueue : public mir::ServerActionQueue
{
void enqueue(void const* owner, mir::ServerAction const& action) override
{
action();
}
void enqueue_with_guaranteed_execution(mir::ServerAction const& action) override
{
action();
}
void pause_processing_for(void const* owner) override { };
void resume_processing_for(void const* owner) override { };
};
class AnimatorTest : public testing::Test
{
public:
AnimatorTest() :
runner(argc, argv),
queue { std::make_shared() },
config { std::make_shared(runner, path) }
{
}
miral::MirRunner runner;
std::shared_ptr queue;
std::shared_ptr config;
};
TEST_F(AnimatorTest, CanStepLinearSlideAnimation)
{
YAML::Node node;
YAML::Node item;
item["event"] = "window_move";
item["type"] = "slide";
item["function"] = "linear";
item["duration"] = 1;
node["animations"].push_back(item);
std::fstream file(path, std::ios::app);
file << node;
Animator animator(queue, config);
auto handle = animator.register_animateable();
bool was_called = false;
animator.window_move(
handle,
mir::geometry::Rectangle(
mir::geometry::Point(0, 0),
mir::geometry::Size(0, 0)),
mir::geometry::Rectangle(
mir::geometry::Point(600, 0),
mir::geometry::Size(0, 0)),
mir::geometry::Rectangle(
mir::geometry::Point(0, 0),
mir::geometry::Size(0, 0)),
[&](auto const& asr)
{
was_called = true;
});
animator.step();
EXPECT_EQ(was_called, true);
}
TEST_F(AnimatorTest, LinearSlideResultsInCorrectNewPoint)
{
YAML::Node node;
YAML::Node item;
item["event"] = "window_move";
item["type"] = "slide";
item["function"] = "linear";
item["duration"] = 1;
node["animations"].push_back(item);
std::fstream file(path, std::ios::app);
file << node;
Animator animator(queue, config);
auto handle = animator.register_animateable();
mir::geometry::Point point;
animator.window_move(
handle,
mir::geometry::Rectangle(
mir::geometry::Point(0, 0),
mir::geometry::Size(0, 0)),
mir::geometry::Rectangle(
mir::geometry::Point(600, 0),
mir::geometry::Size(0, 0)),
mir::geometry::Rectangle(
mir::geometry::Point(0, 0),
mir::geometry::Size(0, 0)),
[&](AnimationStepResult const& asr)
{
if (asr.position)
EXPECT_EQ(asr.position.value().x, 600 * Animator::timestep_seconds);
});
animator.step();
}
class AnimationTest : public testing::Test
{
};
TEST_F(AnimationTest, InterruptingSlideResultsInModifiedAnimationDuration)
{
AnimationHandle handle = 0;
AnimationDefinition definition;
definition.duration_seconds = 6;
definition.type = AnimationType::slide;
definition.function = EaseFunction::linear;
Animation animation(
handle,
definition,
mir::geometry::Rectangle(
mir::geometry::Point(0, 0),
mir::geometry::Size(0, 0)),
mir::geometry::Rectangle(
mir::geometry::Point(600, 600),
mir::geometry::Size(0, 0)),
mir::geometry::Rectangle(
mir::geometry::Point(200, 200),
mir::geometry::Size(0, 0)),
[](auto const& asr) { });
ASSERT_NEAR(animation.get_runtime_seconds(), 2, 0.05);
}