Add paint stroke sampling tests
This commit is contained in:
128
tests/paint/stroke_tests.cpp
Normal file
128
tests/paint/stroke_tests.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
#include "paint/stroke.h"
|
||||
#include "test_harness.h"
|
||||
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
|
||||
using pp::foundation::StatusCode;
|
||||
using pp::paint::StrokePoint;
|
||||
using pp::paint::StrokeSamplingConfig;
|
||||
using pp::paint::max_stroke_samples;
|
||||
using pp::paint::sample_stroke;
|
||||
|
||||
namespace {
|
||||
|
||||
bool near(float a, float b)
|
||||
{
|
||||
return std::fabs(a - b) < 0.0001F;
|
||||
}
|
||||
|
||||
void samples_straight_line_at_fixed_spacing(pp::tests::Harness& h)
|
||||
{
|
||||
const std::array points {
|
||||
StrokePoint { .x = 0.0F, .y = 0.0F, .pressure = 0.25F },
|
||||
StrokePoint { .x = 10.0F, .y = 0.0F, .pressure = 0.75F },
|
||||
};
|
||||
|
||||
const auto result = sample_stroke(points, StrokeSamplingConfig { .spacing = 2.5F });
|
||||
PP_EXPECT(h, result.ok());
|
||||
PP_EXPECT(h, result.value().size() == 5U);
|
||||
PP_EXPECT(h, near(result.value()[0].x, 0.0F));
|
||||
PP_EXPECT(h, near(result.value()[1].x, 2.5F));
|
||||
PP_EXPECT(h, near(result.value()[2].x, 5.0F));
|
||||
PP_EXPECT(h, near(result.value()[3].x, 7.5F));
|
||||
PP_EXPECT(h, near(result.value()[4].x, 10.0F));
|
||||
PP_EXPECT(h, near(result.value()[2].pressure, 0.5F));
|
||||
PP_EXPECT(h, near(result.value()[4].distance, 10.0F));
|
||||
}
|
||||
|
||||
void carries_spacing_across_segments(pp::tests::Harness& h)
|
||||
{
|
||||
const std::array points {
|
||||
StrokePoint { .x = 0.0F, .y = 0.0F, .pressure = 1.0F },
|
||||
StrokePoint { .x = 3.0F, .y = 0.0F, .pressure = 1.0F },
|
||||
StrokePoint { .x = 3.0F, .y = 4.0F, .pressure = 0.0F },
|
||||
};
|
||||
|
||||
const auto result = sample_stroke(points, StrokeSamplingConfig { .spacing = 2.0F });
|
||||
PP_EXPECT(h, result.ok());
|
||||
PP_EXPECT(h, result.value().size() == 5U);
|
||||
PP_EXPECT(h, near(result.value()[1].x, 2.0F));
|
||||
PP_EXPECT(h, near(result.value()[1].y, 0.0F));
|
||||
PP_EXPECT(h, near(result.value()[2].x, 3.0F));
|
||||
PP_EXPECT(h, near(result.value()[2].y, 1.0F));
|
||||
PP_EXPECT(h, near(result.value()[3].x, 3.0F));
|
||||
PP_EXPECT(h, near(result.value()[3].y, 3.0F));
|
||||
PP_EXPECT(h, near(result.value()[4].distance, 7.0F));
|
||||
}
|
||||
|
||||
void can_skip_endpoint_and_clamps_pressure(pp::tests::Harness& h)
|
||||
{
|
||||
const std::array points {
|
||||
StrokePoint { .x = 0.0F, .y = 0.0F, .pressure = -1.0F },
|
||||
StrokePoint { .x = 5.0F, .y = 0.0F, .pressure = 2.0F },
|
||||
};
|
||||
|
||||
const auto result = sample_stroke(
|
||||
points,
|
||||
StrokeSamplingConfig {
|
||||
.spacing = 2.0F,
|
||||
.include_endpoint = false,
|
||||
});
|
||||
PP_EXPECT(h, result.ok());
|
||||
PP_EXPECT(h, result.value().size() == 3U);
|
||||
PP_EXPECT(h, near(result.value()[0].pressure, 0.0F));
|
||||
PP_EXPECT(h, near(result.value()[2].pressure, 1.0F));
|
||||
PP_EXPECT(h, near(result.value()[2].distance, 4.0F));
|
||||
}
|
||||
|
||||
void rejects_invalid_sampling_inputs(pp::tests::Harness& h)
|
||||
{
|
||||
const std::array one_point {
|
||||
StrokePoint { .x = 0.0F, .y = 0.0F },
|
||||
};
|
||||
const std::array zero_length {
|
||||
StrokePoint { .x = 1.0F, .y = 1.0F },
|
||||
StrokePoint { .x = 1.0F, .y = 1.0F },
|
||||
};
|
||||
const std::array non_finite {
|
||||
StrokePoint { .x = 0.0F, .y = 0.0F },
|
||||
StrokePoint { .x = std::nanf(""), .y = 1.0F },
|
||||
};
|
||||
const std::array valid {
|
||||
StrokePoint { .x = 0.0F, .y = 0.0F },
|
||||
StrokePoint { .x = 10.0F, .y = 0.0F },
|
||||
};
|
||||
|
||||
const auto missing_points = sample_stroke(one_point, StrokeSamplingConfig {});
|
||||
const auto bad_spacing = sample_stroke(valid, StrokeSamplingConfig { .spacing = 0.0F });
|
||||
const auto bad_limit = sample_stroke(valid, StrokeSamplingConfig { .max_samples = max_stroke_samples + 1U });
|
||||
const auto no_distance = sample_stroke(zero_length, StrokeSamplingConfig {});
|
||||
const auto bad_point = sample_stroke(non_finite, StrokeSamplingConfig {});
|
||||
const auto too_many = sample_stroke(valid, StrokeSamplingConfig { .spacing = 1.0F, .max_samples = 2U });
|
||||
|
||||
PP_EXPECT(h, !missing_points.ok());
|
||||
PP_EXPECT(h, missing_points.status().code == StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !bad_spacing.ok());
|
||||
PP_EXPECT(h, bad_spacing.status().code == StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !bad_limit.ok());
|
||||
PP_EXPECT(h, bad_limit.status().code == StatusCode::out_of_range);
|
||||
PP_EXPECT(h, !no_distance.ok());
|
||||
PP_EXPECT(h, no_distance.status().code == StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !bad_point.ok());
|
||||
PP_EXPECT(h, bad_point.status().code == StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !too_many.ok());
|
||||
PP_EXPECT(h, too_many.status().code == StatusCode::out_of_range);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
pp::tests::Harness harness;
|
||||
harness.run("samples_straight_line_at_fixed_spacing", samples_straight_line_at_fixed_spacing);
|
||||
harness.run("carries_spacing_across_segments", carries_spacing_across_segments);
|
||||
harness.run("can_skip_endpoint_and_clamps_pressure", can_skip_endpoint_and_clamps_pressure);
|
||||
harness.run("rejects_invalid_sampling_inputs", rejects_invalid_sampling_inputs);
|
||||
return harness.finish();
|
||||
}
|
||||
Reference in New Issue
Block a user