#include "paint/stroke_script.h" #include "test_harness.h" #include #include using pp::foundation::StatusCode; using pp::paint::max_stroke_script_bytes; using pp::paint::max_stroke_script_line_length; using pp::paint::parse_stroke_script; namespace { void parses_comments_and_multiple_strokes(pp::tests::Harness& h) { constexpr std::string_view script_text = "# scripted automation fixture\n" "stroke 0 0 0.25 10 0 0.75 2\n" "\n" "stroke 10 0 1 10 10 0.5 5 # trailing comment\n"; const auto script = parse_stroke_script(script_text); PP_EXPECT(h, script.ok()); PP_EXPECT(h, script.value().strokes.size() == 2U); PP_EXPECT(h, script.value().strokes[0].start.x == 0.0F); PP_EXPECT(h, script.value().strokes[0].start.pressure == 0.25F); PP_EXPECT(h, script.value().strokes[0].end.x == 10.0F); PP_EXPECT(h, script.value().strokes[0].spacing == 2.0F); PP_EXPECT(h, script.value().strokes[1].end.y == 10.0F); PP_EXPECT(h, script.value().strokes[1].end.pressure == 0.5F); } void rejects_malformed_stroke_scripts(pp::tests::Harness& h) { const auto empty = parse_stroke_script(""); const auto comments_only = parse_stroke_script("# nope\n\n"); const auto unknown = parse_stroke_script("move 0 0 1 10 0 1 2\n"); const auto missing_tokens = parse_stroke_script("stroke 0 0 1 10 0 1\n"); const auto too_many_tokens = parse_stroke_script("stroke 0 0 1 10 0 1 2 extra\n"); const auto bad_number = parse_stroke_script("stroke 0 0 1 10 nope 1 2\n"); const auto nan_number = parse_stroke_script("stroke 0 0 1 10 nan 1 2\n"); const auto zero_spacing = parse_stroke_script("stroke 0 0 1 10 0 1 0\n"); PP_EXPECT(h, !empty.ok()); PP_EXPECT(h, empty.status().code == StatusCode::invalid_argument); PP_EXPECT(h, !comments_only.ok()); PP_EXPECT(h, comments_only.status().code == StatusCode::invalid_argument); PP_EXPECT(h, !unknown.ok()); PP_EXPECT(h, unknown.status().code == StatusCode::invalid_argument); PP_EXPECT(h, !missing_tokens.ok()); PP_EXPECT(h, missing_tokens.status().code == StatusCode::invalid_argument); PP_EXPECT(h, !too_many_tokens.ok()); PP_EXPECT(h, too_many_tokens.status().code == StatusCode::invalid_argument); PP_EXPECT(h, !bad_number.ok()); PP_EXPECT(h, bad_number.status().code == StatusCode::invalid_argument); PP_EXPECT(h, !nan_number.ok()); PP_EXPECT(h, nan_number.status().code == StatusCode::invalid_argument); PP_EXPECT(h, !zero_spacing.ok()); PP_EXPECT(h, zero_spacing.status().code == StatusCode::invalid_argument); } void rejects_oversized_stroke_scripts(pp::tests::Harness& h) { const std::string oversized_script(max_stroke_script_bytes + 1U, 'x'); const std::string oversized_line(max_stroke_script_line_length + 1U, 'x'); const auto too_large_script = parse_stroke_script(oversized_script); const auto too_large_line = parse_stroke_script(oversized_line); PP_EXPECT(h, !too_large_script.ok()); PP_EXPECT(h, too_large_script.status().code == StatusCode::out_of_range); PP_EXPECT(h, !too_large_line.ok()); PP_EXPECT(h, too_large_line.status().code == StatusCode::out_of_range); } } int main() { pp::tests::Harness harness; harness.run("parses_comments_and_multiple_strokes", parses_comments_and_multiple_strokes); harness.run("rejects_malformed_stroke_scripts", rejects_malformed_stroke_scripts); harness.run("rejects_oversized_stroke_scripts", rejects_oversized_stroke_scripts); return harness.finish(); }