diff --git a/test/approximation_test.cpp b/test/approximation_test.cpp index 07964fd..15b6ebc 100644 --- a/test/approximation_test.cpp +++ b/test/approximation_test.cpp @@ -19,22 +19,27 @@ using namespace shape; struct ApproximateCircularArcByLineSegmentsTestParams { + std::string name; ShapeElement circular_arc; LengthDbl number_of_line_segments; bool outer; std::vector expected_line_segments; }; +void PrintTo(const ApproximateCircularArcByLineSegmentsTestParams& params, std::ostream* os) +{ + *os << "circular_arc\n" << params.circular_arc.to_string() << "\n"; + *os << "expected_line_segments\n"; + for (const ShapeElement& line_segment: params.expected_line_segments) + *os << line_segment.to_string() << "\n"; +} + class ApproximateCircularArcByLineSegmentsTest: public testing::TestWithParam { }; TEST_P(ApproximateCircularArcByLineSegmentsTest, ApproximateCircularArcByLineSegments) { ApproximateCircularArcByLineSegmentsTestParams test_params = GetParam(); - std::cout << "circular_arc" << std::endl; - std::cout << test_params.circular_arc.to_string() << std::endl; - std::cout << "expected_line_segments" << std::endl; - for (const ShapeElement& line_segment: test_params.expected_line_segments) - std::cout << line_segment.to_string() << std::endl; + PrintTo(test_params, &std::cout); LengthDbl segment_length = test_params.circular_arc.length() / test_params.number_of_line_segments; std::vector line_segments = approximate_circular_arc_by_line_segments( test_params.circular_arc, @@ -56,40 +61,51 @@ INSTANTIATE_TEST_SUITE_P( ApproximateCircularArcByLineSegmentsTest, testing::ValuesIn(std::vector{ { + "CCW1SegInner", build_shape({{1, 0}, {0, 0, 1}, {0, 1}}, true).elements.front(), 1, false, - build_shape({{1, 0}, {0, 1}}, true).elements + build_shape({{1, 0}, {0, 1}}, true).elements, }, { + "CW1SegOuter", build_shape({{1, 0}, {1, 1, -1}, {0, 1}}, true).elements.front(), 1, true, - build_shape({{1, 0}, {0, 1}}, true).elements + build_shape({{1, 0}, {0, 1}}, true).elements, }, { + "CCW2SegOuter", build_shape({{1, 0}, {0, 0, 1}, {0, 1}}, true).elements.front(), 2, true, - build_shape({{1, 0}, {1, 1}, {0, 1}}, true).elements + build_shape({{1, 0}, {1, 1}, {0, 1}}, true).elements, }, { + "CW2SegInner", build_shape({{1, 0}, {1, 1, -1}, {0, 1}}, true).elements.front(), 2, false, - build_shape({{1, 0}, {0, 0}, {0, 1}}, true).elements + build_shape({{1, 0}, {0, 0}, {0, 1}}, true).elements, }, { + "CCW3SegOuter", build_shape({{1, 0}, {0, 0, 1}, {0, 1}}, true).elements.front(), 3, true, - build_shape({{1, 0}, {1, 0.414213562373095}, {0.414213562373095, 1}, {0, 1}}, true).elements + build_shape({{1, 0}, {1, 0.414213562373095}, {0.414213562373095, 1}, {0, 1}}, true).elements, }, { + "CW3SegInner", build_shape({{1, 0}, {1, 1, -1}, {0, 1}}, true).elements.front(), 3, false, - build_shape({{1, 0}, {0.585786437626905, 0}, {0, 0.585786437626905}, {0, 1}}, true).elements - }})); + build_shape({{1, 0}, {0.585786437626905, 0}, {0, 0.585786437626905}, {0, 1}}, true).elements, + } + }), + [](const testing::TestParamInfo& info) { + return info.param.name; + }); struct ApproximateShapeByLineSegmentsTestParams { + std::string name; Shape shape; LengthDbl segment_length; bool outer; @@ -120,19 +136,26 @@ struct ApproximateShapeByLineSegmentsTestParams nlohmann::json json; file >> json; - return from_json(json); + auto test_params = from_json(json); + test_params.name = file_path; + return test_params; } }; +void PrintTo(const ApproximateShapeByLineSegmentsTestParams& params, std::ostream* os) +{ + *os << "shape " << params.shape.to_string(0) << "\n"; + *os << "segment_length " << shape::to_string(params.segment_length) << "\n"; + *os << "outer " << params.outer << "\n"; + *os << "expected_output " << params.expected_output.to_string(0) << "\n"; +} + class ApproximateShapeByLineSegmentsTest: public testing::TestWithParam { }; TEST_P(ApproximateShapeByLineSegmentsTest, ApproximateShapeByLineSegments) { ApproximateShapeByLineSegmentsTestParams test_params = GetParam(); - std::cout << "shape " << test_params.shape.to_string(0) << std::endl; - std::cout << "segment_length " << shape::to_string(test_params.segment_length) << std::endl; - std::cout << "outer " << test_params.outer << std::endl; - std::cout << "expected_output " << test_params.expected_output.to_string(0) << std::endl; + PrintTo(test_params, &std::cout); #ifdef APPROXIMATION_TEST_ENABLE_DEBUG Writer writer; @@ -161,6 +184,7 @@ INSTANTIATE_TEST_SUITE_P( ApproximateShapeByLineSegmentsTest, testing::ValuesIn(std::vector{ { + "ArcSeg1Outer", build_shape({{1, 0}, {0, 0, 1}, {0, 1}, {0, 0}}), 1.0, true, @@ -169,6 +193,7 @@ INSTANTIATE_TEST_SUITE_P( }, }, { + "ArcSeg2Inner", build_shape({{1, 0}, {0, 0, 1}, {0, 1}, {0, 0}}), 2, false, @@ -180,11 +205,15 @@ INSTANTIATE_TEST_SUITE_P( (fs::path("data") / "tests" / "approximation" / "approximate_shape_by_line_segments" / "0.json").string()), ApproximateShapeByLineSegmentsTestParams::read_json( (fs::path("data") / "tests" / "approximation" / "approximate_shape_by_line_segments" / "1.json").string()), - })); + }), + [](const testing::TestParamInfo& info) { + return fs::path(info.param.name).stem().string(); + }); struct ApproximateByLineSegmentsTestParams { + std::string name; ShapeWithHoles shape_with_holes; LengthDbl segment_length; ShapeWithHoles expected_output; @@ -213,18 +242,25 @@ struct ApproximateByLineSegmentsTestParams nlohmann::json json; file >> json; - return from_json(json); + auto test_params = from_json(json); + test_params.name = file_path; + return test_params; } }; +void PrintTo(const ApproximateByLineSegmentsTestParams& params, std::ostream* os) +{ + *os << "shape_with_holes " << params.shape_with_holes.to_string(0) << "\n"; + *os << "segment_length " << shape::to_string(params.segment_length) << "\n"; + *os << "expected_output " << params.expected_output.to_string(0) << "\n"; +} + class ApproximateByLineSegmentsTest: public testing::TestWithParam { }; TEST_P(ApproximateByLineSegmentsTest, ApproximateByLineSegments) { ApproximateByLineSegmentsTestParams test_params = GetParam(); - std::cout << "shape_with_holes " << test_params.shape_with_holes.to_string(0) << std::endl; - std::cout << "segment_length " << shape::to_string(test_params.segment_length) << std::endl; - std::cout << "expected_output " << test_params.expected_output.to_string(0) << std::endl; + PrintTo(test_params, &std::cout); #ifdef APPROXIMATION_TEST_ENABLE_DEBUG Writer writer; @@ -255,4 +291,7 @@ INSTANTIATE_TEST_SUITE_P( (fs::path("data") / "tests" / "approximation" / "approximate_by_line_segments" / "0.json").string()), ApproximateByLineSegmentsTestParams::read_json( (fs::path("data") / "tests" / "approximation" / "approximate_by_line_segments" / "1.json").string()), - })); + }), + [](const testing::TestParamInfo& info) { + return fs::path(info.param.name).stem().string(); + }); diff --git a/test/boolean_operations_test.cpp b/test/boolean_operations_test.cpp index cfaf73f..22bb243 100644 --- a/test/boolean_operations_test.cpp +++ b/test/boolean_operations_test.cpp @@ -13,6 +13,7 @@ using namespace shape; struct FindHolesBridgesTestParams { + std::string name; ShapeWithHoles shape; std::vector expected_output; @@ -43,15 +44,20 @@ struct FindHolesBridgesTestParams } }; +void PrintTo(const FindHolesBridgesTestParams& params, std::ostream* os) +{ + *os << "shape " << params.shape.to_string(0) << "\n"; + *os << "expected_output\n"; + for (const ShapeElement& bridge: params.expected_output) + *os << "- " << bridge.to_string() << "\n"; +} + class FindHolesBridgesTest: public testing::TestWithParam { }; TEST_P(FindHolesBridgesTest, FindHolesBridges) { FindHolesBridgesTestParams test_params = GetParam(); - std::cout << "shape " << test_params.shape.to_string(0) << std::endl; - std::cout << "expected_output" << std::endl; - for (const ShapeElement& bridge: test_params.expected_output) - std::cout << "- " << bridge.to_string() << std::endl; + PrintTo(test_params, &std::cout); std::vector output = find_holes_bridges(test_params.shape); std::cout << "output" << std::endl; @@ -73,21 +79,25 @@ INSTANTIATE_TEST_SUITE_P( FindHolesBridgesTest, testing::ValuesIn(std::vector{ { // Shape without hole. + "NoHole", {build_rectangle(200, 100)}, {}, }, { // Shape with one touching hole. + "OneTouchingHole", { build_rectangle(200, 100), {build_shape({{0, 50}, {10, 40}, {20, 50}, {10, 60}})} }, {}, }, { // Shape with one non-touching hole. + "OneNonTouchingHole", { build_rectangle(200, 100), {build_shape({{40, 50}, {50, 40}, {60, 50}, {50, 60}})} }, {build_line_segment({0, 50}, {40, 50})}, }, { // Shape with one touching hole and on non-touching hole. + "OneTouchingOneNonTouching", { build_rectangle(200, 100), { @@ -97,6 +107,7 @@ INSTANTIATE_TEST_SUITE_P( }, {build_line_segment({20, 50}, {40, 50})}, }, { // Shape with two touching holes. + "TwoTouchingHoles", { build_rectangle(200, 100), { @@ -106,6 +117,7 @@ INSTANTIATE_TEST_SUITE_P( }, {}, }, { // Shape with two holes touching each other. + "TwoHolesTouchingEachOther", { build_rectangle(200, 100), { @@ -115,6 +127,7 @@ INSTANTIATE_TEST_SUITE_P( }, {build_line_segment({0, 50}, {20, 50})}, }, { // Shape with two holes. + "TwoSeparateHoles", { build_rectangle(200, 100), { @@ -126,7 +139,11 @@ INSTANTIATE_TEST_SUITE_P( build_line_segment({0, 50}, {20, 50}), build_line_segment({40, 50}, {60, 50}), }, - }})); + } + }), + [](const testing::TestParamInfo& info) { + return info.param.name; + }); struct ComputeBooleanUnionTestParams: TestParams @@ -148,18 +165,23 @@ struct ComputeBooleanUnionTestParams: TestParams } }; +void PrintTo(const ComputeBooleanUnionTestParams& params, std::ostream* os) +{ + *os << "Testing " << params.name << " (" << params.description << ")...\n"; + *os << "shapes\n"; + for (const ShapeWithHoles& shape: params.shapes) + *os << "- " << shape.to_string(2) << "\n"; + *os << "expected_output\n"; + for (const ShapeWithHoles& shape: params.expected_output) + *os << "- " << shape.to_string(2) << "\n"; +} + class ComputeBooleanUnionTest: public testing::TestWithParam { }; TEST_P(ComputeBooleanUnionTest, ComputeBooleanUnion) { ComputeBooleanUnionTestParams test_params = GetParam(); - std::cout << "Testing " << test_params.name << " (" << test_params.description << ")" << "..." << std::endl; - std::cout << "shapes" << std::endl; - for (const ShapeWithHoles& shape: test_params.shapes) - std::cout << "- " << shape.to_string(2) << std::endl; - std::cout << "expected_output" << std::endl; - for (const ShapeWithHoles& shape: test_params.expected_output) - std::cout << "- " << shape.to_string(2) << std::endl; + PrintTo(test_params, &std::cout); #ifdef BOOLEAN_OPERATIONS_TEST_ENABLE_DEBUG Writer().add_shapes_with_holes(test_params.shapes).write_json("compute_union_input.json"); @@ -213,7 +235,10 @@ TEST_P(ComputeBooleanUnionTest, ComputeBooleanUnion) INSTANTIATE_TEST_SUITE_P( Shape, ComputeBooleanUnionTest, - testing::ValuesIn(ComputeBooleanUnionTestParams::read_dir((fs::path("data") / "tests" / "boolean_operations" / "union").string()))); + testing::ValuesIn(ComputeBooleanUnionTestParams::read_dir((fs::path("data") / "tests" / "boolean_operations" / "union").string())), + [](const testing::TestParamInfo& info) { + return fs::path(info.param.name).stem().string(); + }); struct ComputeBooleanIntersectionTestParams: TestParams @@ -234,18 +259,23 @@ struct ComputeBooleanIntersectionTestParams: TestParams { }; TEST_P(ComputeBooleanIntersectionTest, ComputeBooleanIntersection) { ComputeBooleanIntersectionTestParams test_params = GetParam(); - std::cout << "Testing " << test_params.name << " (" << test_params.description << ")" << "..." << std::endl; - std::cout << "shapes" << std::endl; - for (const ShapeWithHoles& shape: test_params.shapes) - std::cout << "- " << shape.to_string(2) << std::endl; - std::cout << "expected_output" << std::endl; - for (const ShapeWithHoles& shape: test_params.expected_output) - std::cout << "- " << shape.to_string(2) << std::endl; + PrintTo(test_params, &std::cout); #ifdef BOOLEAN_OPERATIONS_TEST_ENABLE_DEBUG Writer().add_shapes_with_holes(test_params.shapes).write_json("compute_intersection_input.json"); @@ -291,7 +321,10 @@ TEST_P(ComputeBooleanIntersectionTest, ComputeBooleanIntersection) INSTANTIATE_TEST_SUITE_P( Shape, ComputeBooleanIntersectionTest, - testing::ValuesIn(ComputeBooleanIntersectionTestParams::read_dir((fs::path("data") / "tests" / "boolean_operations" / "intersection").string()))); + testing::ValuesIn(ComputeBooleanIntersectionTestParams::read_dir((fs::path("data") / "tests" / "boolean_operations" / "intersection").string())), + [](const testing::TestParamInfo& info) { + return fs::path(info.param.name).stem().string(); + }); struct ComputeBooleanDifferenceTestParams : TestParams @@ -314,20 +347,25 @@ struct ComputeBooleanDifferenceTestParams : TestParams { }; TEST_P(ComputeBooleanDifferenceTest, ComputeBooleanDifference) { ComputeBooleanDifferenceTestParams test_params = GetParam(); - std::cout << "Testing " << test_params.name << " (" << test_params.description << ")" << "..." << std::endl; - std::cout << "shape" << std::endl; - std::cout << "- " << test_params.shape.to_string(2) << std::endl; - std::cout << "shapes" << std::endl; - for (const ShapeWithHoles& shape: test_params.shapes) - std::cout << "- " << shape.to_string(2) << std::endl; - std::cout << "expected_output" << std::endl; - for (const ShapeWithHoles& shape: test_params.expected_output) - std::cout << "- " << shape.to_string(2) << std::endl; + PrintTo(test_params, &std::cout); auto output = compute_difference( test_params.shape, @@ -364,7 +402,10 @@ TEST_P(ComputeBooleanDifferenceTest, ComputeBooleanDifference) INSTANTIATE_TEST_SUITE_P( Shape, ComputeBooleanDifferenceTest, - testing::ValuesIn(ComputeBooleanDifferenceTestParams::read_dir((fs::path("data") / "tests" / "boolean_operations" / "difference").string()))); + testing::ValuesIn(ComputeBooleanDifferenceTestParams::read_dir((fs::path("data") / "tests" / "boolean_operations" / "difference").string())), + [](const testing::TestParamInfo& info) { + return fs::path(info.param.name).stem().string(); + }); struct ComputeBooleanSymmetricDifferenceTestParams : TestParams @@ -386,19 +427,24 @@ struct ComputeBooleanSymmetricDifferenceTestParams : TestParams { }; TEST_P(ComputeBooleanSymmetricDifferenceTest, ComputeBooleanSymetricDifference) { ComputeBooleanSymmetricDifferenceTestParams test_params = GetParam(); - std::cout << "Testing " << test_params.name << " (" << test_params.description << ")" << "..." << std::endl; - std::cout << "shape_1" << std::endl; - std::cout << "- " << test_params.shape_1.to_string(2) << std::endl; - std::cout << "shape_2" << std::endl; - std::cout << "- " << test_params.shape_2.to_string(2) << std::endl; - std::cout << "expected_output" << std::endl; - for (const ShapeWithHoles& shape: test_params.expected_output) - std::cout << "- " << shape.to_string(2) << std::endl; + PrintTo(test_params, &std::cout); auto output = compute_symmetric_difference( test_params.shape_1, @@ -436,11 +482,15 @@ TEST_P(ComputeBooleanSymmetricDifferenceTest, ComputeBooleanSymetricDifference) INSTANTIATE_TEST_SUITE_P( Shape, ComputeBooleanSymmetricDifferenceTest, - testing::ValuesIn(ComputeBooleanSymmetricDifferenceTestParams::read_dir((fs::path("data") / "tests" / "boolean_operations" / "symmetric_difference").string()))); + testing::ValuesIn(ComputeBooleanSymmetricDifferenceTestParams::read_dir((fs::path("data") / "tests" / "boolean_operations" / "symmetric_difference").string())), + [](const testing::TestParamInfo& info) { + return fs::path(info.param.name).stem().string(); + }); struct ExtractOutlineTestParams { + std::string name; Shape shape; Shape expected_output; @@ -466,17 +516,24 @@ struct ExtractOutlineTestParams nlohmann::json json; file >> json; - return from_json(json); + auto test_params = from_json(json); + test_params.name = file_path; + return test_params; } }; +void PrintTo(const ExtractOutlineTestParams& params, std::ostream* os) +{ + *os << "shape " << params.shape.to_string(2) << "\n"; + *os << "expected_output " << params.expected_output.to_string(2) << "\n"; +} + class ExtractOutlineTest: public testing::TestWithParam { }; TEST_P(ExtractOutlineTest, ExtractOutline) { ExtractOutlineTestParams test_params = GetParam(); - std::cout << "shape " << test_params.shape.to_string(2) << std::endl; - std::cout << "expected_output " << test_params.expected_output.to_string(2) << std::endl; + PrintTo(test_params, &std::cout); Shape output = extract_outline(test_params.shape); std::cout << "output " << output.to_string(2) << std::endl; @@ -494,16 +551,21 @@ INSTANTIATE_TEST_SUITE_P( ExtractOutlineTest, testing::ValuesIn(std::vector{ { + "StarShape", build_shape({{0, 0}, {10, 0}, {10, 10}, {1, 1}, {9, 1}, {0, 10}}), build_shape({{0, 0}, {10, 0}, {10, 10}, {5, 5}, {0, 10}}), }, ExtractOutlineTestParams::read_json( (fs::path("data") / "tests" / "boolean_operations" / "extract_outline" / "0.json").string()), - })); + }), + [](const testing::TestParamInfo& info) { + return fs::path(info.param.name).stem().string(); + }); struct ExtractFacesTestParams { + std::string name; Shape shape; std::vector expected_output; @@ -534,15 +596,20 @@ struct ExtractFacesTestParams } }; +void PrintTo(const ExtractFacesTestParams& params, std::ostream* os) +{ + *os << "shape " << params.shape.to_string(2) << "\n"; + *os << "expected_output\n"; + for (const Shape& shape: params.expected_output) + *os << shape.to_string(2) << "\n"; +} + class ExtractFacesTest: public testing::TestWithParam { }; TEST_P(ExtractFacesTest, ExtractFaces) { ExtractFacesTestParams test_params = GetParam(); - std::cout << "shape " << test_params.shape.to_string(2) << std::endl; - std::cout << "expected_output" << std::endl; - for (const Shape& shape: test_params.expected_output) - std::cout << shape.to_string(2) << std::endl; + PrintTo(test_params, &std::cout); std::vector output = extract_faces(test_params.shape); std::cout << "output" << std::endl; @@ -569,22 +636,30 @@ INSTANTIATE_TEST_SUITE_P( ExtractFacesTest, testing::ValuesIn(std::vector{ { + "Rhombus", build_shape({{0, 10}, {10, 0}, {20, 10}, {10, 20}}), {build_shape({{0, 10}, {10, 0}, {20, 10}, {10, 20}})}, }, { + "RhombusReversed", build_shape({{0, 10}, {10, 0}, {20, 10}, {10, 20}}).reverse(), {build_shape({{0, 10}, {10, 0}, {20, 10}, {10, 20}})}, }, { + "SelfIntersectingBowtie", build_shape({{0, 0}, {20, 20}, {20, 0}, {0, 20}}), { build_shape({{0, 0}, {10, 10}, {0, 20}}), build_shape({{20, 0}, {20, 20}, {10, 10}}), }, - }})); + } + }), + [](const testing::TestParamInfo& info) { + return info.param.name; + }); struct BridgeTouchingHolesTestParams { + std::string name; ShapeWithHoles shape; std::vector expected_output; @@ -611,19 +686,26 @@ struct BridgeTouchingHolesTestParams nlohmann::json json; file >> json; - return from_json(json); + auto test_params = from_json(json); + test_params.name = file_path; + return test_params; } }; +void PrintTo(const BridgeTouchingHolesTestParams& params, std::ostream* os) +{ + *os << "shape " << params.shape.to_string(2) << "\n"; + *os << "expected_output\n"; + for (const ShapeWithHoles& shape: params.expected_output) + *os << shape.to_string(2) << "\n"; +} + class BridgeTouchingHolesTest: public testing::TestWithParam { }; TEST_P(BridgeTouchingHolesTest, BridgeTouchingHoles) { BridgeTouchingHolesTestParams test_params = GetParam(); - std::cout << "shape " << test_params.shape.to_string(2) << std::endl; - std::cout << "expected_output" << std::endl; - for (const ShapeWithHoles& shape: test_params.expected_output) - std::cout << shape.to_string(2) << std::endl; + PrintTo(test_params, &std::cout); std::vector output = bridge_touching_holes(test_params.shape); std::cout << "output" << std::endl; @@ -650,9 +732,11 @@ INSTANTIATE_TEST_SUITE_P( BridgeTouchingHolesTest, testing::ValuesIn(std::vector{ { // Shape without hole. + "NoHole", {build_shape({{0, 0}, {2, 0}, {2, 2}, {0, 2}})}, {{build_shape({{0, 0}, {2, 0}, {2, 2}, {0, 2}})}}, }, { // Shape with one hole not touching its outline. + "OneNonTouchingHole", { build_shape({{0, 0}, {20, 0}, {20, 10}, {0, 10}}), {build_shape({{15, 4}, {16, 5}, {15, 6}, {14, 5}})} @@ -661,6 +745,7 @@ INSTANTIATE_TEST_SUITE_P( {build_shape({{15, 4}, {16, 5}, {15, 6}, {14, 5}})} }}, }, { // Shape with one hole touching its outline. + "OneTouchingOutline", { build_shape({{0, 0}, {20, 0}, {20, 10}, {0, 10}}), { @@ -672,6 +757,7 @@ INSTANTIATE_TEST_SUITE_P( {19, 4}, {18, 5}, {19, 6}, {20, 5}, {20, 10}, {0, 10}})}}, }, { // Shape with one hole touching its outline. + "OneTouchingVertex", { build_shape({{0, 0}, {20, 0}, {19, 5}, {20, 10}, {0, 10}}), { @@ -683,6 +769,7 @@ INSTANTIATE_TEST_SUITE_P( {19, 4}, {17, 4}, {17, 6}, {19, 6}, {19, 5}, {20, 10}, {0, 10}})}}, }, { // Shape with one hole touching its outline and another hole touching the first hole. + "OutlineTouchingHoleTouchingHole", { build_shape({{0, 0}, {20, 0}, {20, 50}, {0, 50}}), { @@ -697,6 +784,7 @@ INSTANTIATE_TEST_SUITE_P( {11, 1}, {10, 0}, {20, 0}, {20, 50}, {0, 50}})}}, }, { // Shape with 3 holes. + "ThreeChainedHoles", { build_shape({{0, 0}, {20, 0}, {20, 50}, {0, 50}}), { @@ -714,6 +802,7 @@ INSTANTIATE_TEST_SUITE_P( {11, 1}, {10, 0}, {20, 0}, {20, 50}, {0, 50}})}}, }, { // Shape with one hole touching its outline. + "VertexTouchingHole", { build_shape({{0, 0}, {10, 1}, {20, 0}, {20, 50}, {0, 50}}), { @@ -725,6 +814,7 @@ INSTANTIATE_TEST_SUITE_P( {10, 1}, {9, 1}, {10, 2}, {11, 1}, {10, 1}, {20, 0}, {20, 50}, {0, 50}})}}, }, { // Shape with one hole touching its outline and another hole touching the first hole. + "VertexTouchingHoleTouchingHole", { build_shape({{0, 0}, {10, 1}, {20, 0}, {20, 50}, {0, 50}}), { @@ -739,6 +829,7 @@ INSTANTIATE_TEST_SUITE_P( {11, 1}, {10, 1}, {20, 0}, {20, 50}, {0, 50}})}}, }, { // Shape with 3 holes. + "ThreeChainedHolesVertex", { build_shape({{0, 0}, {10, 1}, {20, 0}, {20, 50}, {0, 50}}), { @@ -758,4 +849,7 @@ INSTANTIATE_TEST_SUITE_P( }, BridgeTouchingHolesTestParams::read_json( (fs::path("data") / "tests" / "shape_with_holes" / "bridge_touching_holes" / "0.json").string()), - })); + }), + [](const testing::TestParamInfo& info) { + return fs::path(info.param.name).stem().string(); + }); diff --git a/test/clean_test.cpp b/test/clean_test.cpp index bf5ff5a..a1ae2f3 100644 --- a/test/clean_test.cpp +++ b/test/clean_test.cpp @@ -14,10 +14,17 @@ namespace fs = boost::filesystem; struct RemoveRedundantVerticesTestParams { + std::string name; Shape shape; Shape expected_shape; }; +void PrintTo(const RemoveRedundantVerticesTestParams& params, std::ostream* os) +{ + *os << "shape " << params.shape.to_string(0) << "\n"; + *os << "expected_shape " << params.expected_shape.to_string(0) << "\n"; +} + class RemoveRedundantVerticesTest: public testing::TestWithParam { }; TEST_P(RemoveRedundantVerticesTest, RemoveRedundantVertices) @@ -33,16 +40,22 @@ INSTANTIATE_TEST_SUITE_P( RemoveRedundantVerticesTest, testing::ValuesIn(std::vector{ { + "DuplicateVertexShape", build_shape({{0, 0}, {0, 0}, {100, 0}, {100, 100}}), - build_shape({{0, 0}, {100, 0}, {100, 100}}) + build_shape({{0, 0}, {100, 0}, {100, 100}}), }, { + "DuplicateVertexPath", build_path({{0, 0}, {0, 0}, {100, 0}}), - build_path({{0, 0}, {100, 0}}) - }})); + build_path({{0, 0}, {100, 0}}), + }}), + [](const testing::TestParamInfo& info) { + return info.param.name; + }); struct CleanExtremeSlopesOuterTestParams { + std::string name; Shape shape; ShapeWithHoles expected_output; @@ -69,17 +82,24 @@ struct CleanExtremeSlopesOuterTestParams nlohmann::json json; file >> json; - return from_json(json); + auto test_params = from_json(json); + test_params.name = file_path; + return test_params; } }; +void PrintTo(const CleanExtremeSlopesOuterTestParams& params, std::ostream* os) +{ + *os << "shape " << params.shape.to_string(2) << "\n"; + *os << "expected output " << params.expected_output.to_string(0) << "\n"; +} + class CleanExtremeSlopesOuterTest: public testing::TestWithParam { }; TEST_P(CleanExtremeSlopesOuterTest, CleanExtremeSlopesOuter) { CleanExtremeSlopesOuterTestParams test_params = GetParam(); - std::cout << "shape " << test_params.shape.to_string(2) << std::endl; - std::cout << "expected output " << test_params.expected_output.to_string(0) << std::endl; + PrintTo(test_params, &std::cout); ShapeWithHoles output = clean_extreme_slopes_outer(test_params.shape); std::cout << "output " << output.to_string(0) << std::endl; //Writer().add_shape_with_holes(output).write_json("clean_extreme_slopes_outer_output.json"); @@ -92,6 +112,7 @@ INSTANTIATE_TEST_SUITE_P( CleanExtremeSlopesOuterTest, testing::ValuesIn(std::vector{ { + "Square", build_shape({{0, 0}, {1, 0}, {1, 1}, {0, 1}}), { {build_shape({{0, 0}, {1, 0}, {1, 1}, {0, 1}})}, @@ -99,24 +120,33 @@ INSTANTIATE_TEST_SUITE_P( }, CleanExtremeSlopesOuterTestParams::read_json( (fs::path("data") / "tests" / "clean" / "clean_extreme_slopes_outer" / "0.json").string()), - })); + }), + [](const testing::TestParamInfo& info) { + return fs::path(info.param.name).stem().string(); + }); struct FixSelfIntersectionsTestParams { + std::string name; ShapeWithHoles shape; std::vector expected_output; }; +void PrintTo(const FixSelfIntersectionsTestParams& params, std::ostream* os) +{ + *os << "shape " << params.shape.to_string(2) << "\n"; + *os << "expected shapes:\n"; + for (const ShapeWithHoles& shape: params.expected_output) + *os << shape.to_string(2) << "\n"; +} + class FixSelfIntersectionsTest: public testing::TestWithParam { }; TEST_P(FixSelfIntersectionsTest, FixSelfIntersections) { FixSelfIntersectionsTestParams test_params = GetParam(); - std::cout << "shape " << test_params.shape.to_string(2) << std::endl; - std::cout << "expected shapes:" << std::endl; - for (const ShapeWithHoles& shape: test_params.expected_output) - std::cout << shape.to_string(2) << std::endl; + PrintTo(test_params, &std::cout); std::vector output = fix_self_intersections(test_params.shape); std::cout << "output:" << std::endl; for (const ShapeWithHoles& shape: output) @@ -137,15 +167,20 @@ INSTANTIATE_TEST_SUITE_P( FixSelfIntersectionsTest, testing::ValuesIn(std::vector{ { + "Square", {build_shape({{0, 0}, {1, 0}, {1, 1}, {0, 1}})}, { {build_shape({{0, 0}, {1, 0}, {1, 1}, {0, 1}})}, }, }, { + "TouchingSquares", {build_shape({{0, 0}, {1, 0}, {1, 1}, {2, 1}, {2, 2}, {1, 2}, {1, 1}, {0, 1}})}, { {build_shape({{0, 0}, {1, 0}, {1, 1}, {0, 1}})}, {build_shape({{1, 1}, {2, 1}, {2, 2}, {1, 2}})}, }, }, - })); + }), + [](const testing::TestParamInfo& info) { + return info.param.name; + }); diff --git a/test/convex_partition_test.cpp b/test/convex_partition_test.cpp index 52ad573..0ccf89f 100644 --- a/test/convex_partition_test.cpp +++ b/test/convex_partition_test.cpp @@ -11,14 +11,20 @@ using namespace shape; struct ConvexPartitionTestParams { ShapeWithHoles shape; + std::string name; }; +void PrintTo(const ConvexPartitionTestParams& params, std::ostream* os) +{ + *os << "shape " << params.shape.to_string(0) << "\n"; +} + class ConvexPartitionTest: public testing::TestWithParam { }; TEST_P(ConvexPartitionTest, ConvexPartition) { ConvexPartitionTestParams test_params = GetParam(); - std::cout << "shape " << test_params.shape.to_string(0) << std::endl; + PrintTo(test_params, &std::cout); std::vector parts = compute_convex_partition(test_params.shape); @@ -66,37 +72,47 @@ INSTANTIATE_TEST_SUITE_P( // Convex inputs: should produce a single convex part. { // Triangle. {build_shape({{0, 0}, {3, 0}, {1, 3}})}, + "Triangle", }, { // Rectangle. {build_rectangle(4, 3)}, + "Rectangle", }, { // Convex trapezoid. {build_shape({{0, 0}, {4, 0}, {3, 2}, {1, 2}})}, + "ConvexTrapezoid", }, { // Convex pentagon. {build_shape({{0, 0}, {4, 0}, {5, 2}, {3, 4}, {1, 4}})}, + "ConvexPentagon", }, // Non-convex inputs: should produce multiple convex parts. { // L-shape. {build_shape({{0, 0}, {3, 0}, {3, 1}, {1, 1}, {1, 2}, {0, 2}})}, + "LShape", }, { // Cross/plus shape. {build_shape({ {1, 0}, {2, 0}, {2, 1}, {3, 1}, {3, 2}, {2, 2}, {2, 3}, {1, 3}, {1, 2}, {0, 2}, {0, 1}, {1, 1}})}, + "CrossShape", }, { // U-shape. {build_shape({ {0, 0}, {3, 0}, {3, 3}, {2, 3}, {2, 1}, {1, 1}, {1, 3}, {0, 3}})}, + "UShape", }, { // W-shape. {build_shape({ {0, 0}, {5, 0}, {5, 3}, {4, 3}, {4, 1}, {3, 1}, {3, 2}, {2, 2}, {2, 1}, {1, 1}, {1, 3}, {0, 3}})}, + "WShape", }, { // T-shape. {build_shape({ {0, 2}, {1, 2}, {1, 0}, {2, 0}, {2, 2}, {3, 2}, {3, 3}, {0, 3}})}, + "TShape", }, { // Staircase shape. {build_shape({ {0, 0}, {4, 0}, {4, 2}, {3, 2}, {3, 1}, {1, 1}, {1, 2}, {0, 2}})}, + "StaircaseShape", }, // Shapes with holes. { // Square ring: square with a square hole. @@ -104,10 +120,15 @@ INSTANTIATE_TEST_SUITE_P( build_shape({{0, 0}, {4, 0}, {4, 4}, {0, 4}}), {build_shape({{1, 1}, {3, 1}, {3, 3}, {1, 3}})} }, + "SquareRing", }, { // Octagon with a diamond hole. { build_shape({{1, 0}, {3, 0}, {4, 1}, {4, 3}, {3, 4}, {1, 4}, {0, 3}, {0, 1}}), {build_shape({{2, 1}, {3, 2}, {2, 3}, {1, 2}})} }, + "OctagonWithDiamondHole", }, - })); + }), + [](const testing::TestParamInfo& info) { + return info.param.name; + }); diff --git a/test/elements_intersections_test.cpp b/test/elements_intersections_test.cpp index ad635f9..e9317da 100644 --- a/test/elements_intersections_test.cpp +++ b/test/elements_intersections_test.cpp @@ -51,15 +51,20 @@ struct ComputeIntersectionsTestParams } }; +void PrintTo(const ComputeIntersectionsTestParams& params, std::ostream* os) +{ + *os << "element_1 " << params.element_1.to_string() << "\n"; + *os << "element_2 " << params.element_2.to_string() << "\n"; + *os << "expected_output\n"; + *os << " " << params.expected_output.to_string(2) << "\n"; +} + class ComputeIntersectionsTest: public testing::TestWithParam { }; TEST_P(ComputeIntersectionsTest, ComputeIntersections) { ComputeIntersectionsTestParams test_params = GetParam(); - std::cout << "element_1 " << test_params.element_1.to_string() << std::endl; - std::cout << "element_2 " << test_params.element_2.to_string() << std::endl; - std::cout << "expected_output" << std::endl; - std::cout << " " << test_params.expected_output.to_string(2) << std::endl; + PrintTo(test_params, &std::cout); #ifdef ELEMENTS_INTERSECTIONS_TEST_ENABLE_DEBUG Writer().add_element(test_params.element_1).add_element(test_params.element_2).write_json("elements_intersections_input.json"); @@ -390,4 +395,8 @@ INSTANTIATE_TEST_SUITE_P( build_circular_arc({51.87571790450103, 829.62616084793081}, {51.898968087141867, 829.66319973722932}, {51.7325166990734, 829.74186840337882}, ShapeElementOrientation::Anticlockwise), build_circular_arc({51.87704326994384, 829.62782063296618}, {51.859870441010187, 829.60894475579755}, {51.734086740113739, 829.74062946385982}, ShapeElementOrientation::Clockwise), {{}, {{51.87704326994384, 829.62782063296618}, {51.87571790450103, 829.62616084793081}}, {}}, - }})); + } + }), + [](const testing::TestParamInfo& info) { + return std::to_string(info.index); + }); diff --git a/test/extract_borders_test.cpp b/test/extract_borders_test.cpp index dc6a8b1..cae03c0 100644 --- a/test/extract_borders_test.cpp +++ b/test/extract_borders_test.cpp @@ -6,10 +6,19 @@ using namespace shape; struct ExtractBordersTestParams { + std::string name; Shape shape; std::vector expected_borders; }; +void PrintTo(const ExtractBordersTestParams& params, std::ostream* os) +{ + *os << "shape " << params.shape.to_string(0) << "\n"; + *os << "expected_borders\n"; + for (const Shape& border: params.expected_borders) + *os << "- " << border.to_string(0) << "\n"; +} + class ExtractBordersTest: public testing::TestWithParam { }; TEST_P(ExtractBordersTest, ExtractBorders) @@ -33,23 +42,31 @@ INSTANTIATE_TEST_SUITE_P( ExtractBordersTest, testing::ValuesIn(std::vector{ { + "Square", build_shape({{0, 0}, {1, 0}, {1, 1}, {0, 1}}), {}, }, { + "Triangle", build_shape({{2, 0}, {3, 1}, {0, 1}}), { build_shape({{3, 0}, {3, 1}, {2, 0}}), build_shape({{0, 0}, {2, 0}, {0, 1}}), - } + }, }, { + "FlatTriangle", build_shape({{0, 0}, {3, 1}, {0, 1}}), { build_shape({{3, 0}, {3, 1}, {0, 0}}), - } + }, }, { + "LargeTriangle", build_shape({{0, 0}, {50, 0}, {30, 30}}), { build_shape({{0, 0}, {30, 30}, {0, 30}}), build_shape({{30, 30}, {50, 0}, {50, 30}}), - } - }})); + }, + } + }), + [](const testing::TestParamInfo& info) { + return info.param.name; + }); diff --git a/test/intersection_tree_test.cpp b/test/intersection_tree_test.cpp index f57079d..541ded3 100644 --- a/test/intersection_tree_test.cpp +++ b/test/intersection_tree_test.cpp @@ -18,8 +18,18 @@ struct IntersectionTreeTestParams std::vector> expected_intersecting_shapes; std::vector> expected_equal_points; + + std::string name; }; +void PrintTo(const IntersectionTreeTestParams& params, std::ostream* os) +{ + *os << "shapes (" << params.shapes.size() << ")\n"; + for (const ShapeWithHoles& shape: params.shapes) + *os << "- " << shape.to_string(0) << "\n"; + *os << "strict " << params.strict << "\n"; +} + class IntersectionTreeTest: public testing::TestWithParam { }; TEST_P(IntersectionTreeTest, IntersectionTree) @@ -91,6 +101,7 @@ INSTANTIATE_TEST_SUITE_P( true, {}, {}, {}, {}, {}, + "Square", //}, { // {{build_shape({{0, 0}, {2, 0}, {2, 2}, {0, 2}}), {}}, {}, {}}, // true, @@ -124,4 +135,7 @@ INSTANTIATE_TEST_SUITE_P( // {}, {}, {}, // {}, {{4, 6}}, }, - })); + }), + [](const testing::TestParamInfo& info) { + return info.param.name; + }); diff --git a/test/no_fit_polygon_test.cpp b/test/no_fit_polygon_test.cpp index 5366d49..9101cd7 100644 --- a/test/no_fit_polygon_test.cpp +++ b/test/no_fit_polygon_test.cpp @@ -16,16 +16,22 @@ struct NoFitPolygonConvexTestParams Shape fixed_shape; Shape orbiting_shape; Shape expected_nfp; + std::string name; }; +void PrintTo(const NoFitPolygonConvexTestParams& params, std::ostream* os) +{ + *os << "fixed_shape " << params.fixed_shape.to_string(0) << "\n"; + *os << "orbiting_shape " << params.orbiting_shape.to_string(0) << "\n"; +} + class NoFitPolygonConvexTest: public testing::TestWithParam { }; TEST_P(NoFitPolygonConvexTest, NoFitPolygonConvex) { NoFitPolygonConvexTestParams test_params = GetParam(); - std::cout << "fixed_shape " << test_params.fixed_shape.to_string(0) << std::endl; - std::cout << "orbiting_shape " << test_params.orbiting_shape.to_string(0) << std::endl; + PrintTo(test_params, &std::cout); Shape nfp = no_fit_polygon(test_params.fixed_shape, test_params.orbiting_shape); @@ -68,24 +74,32 @@ INSTANTIATE_TEST_SUITE_P( build_rectangle(0, 4, 0, 4), build_rectangle(0, 2, 0, 2), build_rectangle(-2, 4, -2, 4), + "SquareAndSmallerSquare", }, { // Rectangle with itself. build_shape({{0, 0}, {3, 0}, {3, 2}, {0, 2}}), build_shape({{0, 0}, {3, 0}, {3, 2}, {0, 2}}), build_rectangle(-3, 3, -2, 2), + "RectangleWithItself", }, { // Square and triangle. build_rectangle(0, 4, 0, 4), build_shape({{0, 0}, {2, 0}, {1, 2}}), build_shape({{-1, -2}, {3, -2}, {4, 0}, {4, 4}, {-2, 4}, {-2, 0}}), + "SquareAndTriangle", }, { // Triangle and triangle. build_shape({{0, 0}, {4, 0}, {2, 4}}), build_shape({{0, 0}, {2, 0}, {1, 2}}), build_shape({{-1, -2}, {3, -2}, {4, 0}, {2, 4}, {0, 4}, {-2, 0}}), + "TriangleAndTriangle", }, { // Convex pentagon and unit square. build_shape({{0, 0}, {4, 0}, {5, 2}, {3, 4}, {1, 4}}), build_rectangle(0, 1, 0, 1), build_shape({{-1, -1}, {4, -1}, {5, 1}, {5, 2}, {3, 4}, {0, 4}, {-1, 0}}), + "ConvexPentagonAndUnitSquare", }, - })); + }), + [](const testing::TestParamInfo& info) { + return info.param.name; + }); //////////////////////////////////////////////////////////////////////////////// @@ -97,16 +111,22 @@ struct NoFitPolygonGeneralTestParams ShapeWithHoles fixed_shape; ShapeWithHoles orbiting_shape; ShapePos expected_num_components; + std::string name; }; +void PrintTo(const NoFitPolygonGeneralTestParams& params, std::ostream* os) +{ + *os << "fixed_shape " << params.fixed_shape.to_string(0) << "\n"; + *os << "orbiting_shape " << params.orbiting_shape.to_string(0) << "\n"; +} + class NoFitPolygonGeneralTest: public testing::TestWithParam { }; TEST_P(NoFitPolygonGeneralTest, NoFitPolygonGeneral) { NoFitPolygonGeneralTestParams test_params = GetParam(); - std::cout << "fixed_shape " << test_params.fixed_shape.to_string(0) << std::endl; - std::cout << "orbiting_shape " << test_params.orbiting_shape.to_string(0) << std::endl; + PrintTo(test_params, &std::cout); std::vector nfp = no_fit_polygon( test_params.fixed_shape, @@ -175,17 +195,24 @@ INSTANTIATE_TEST_SUITE_P( {build_rectangle(0, 4, 0, 4), {}}, {build_rectangle(0, 2, 0, 2), {}}, 1, + "ConvexSquares", }, { // L-shape fixed, unit square orbiting: one connected NFP. {build_shape({{0, 0}, {4, 0}, {4, 2}, {2, 2}, {2, 4}, {0, 4}}), {}}, {build_rectangle(0, 1, 0, 1), {}}, 1, + "LShapeAndUnitSquare", }, { // Two L-shapes. {build_shape({{0, 0}, {4, 0}, {4, 2}, {2, 2}, {2, 4}, {0, 4}}), {}}, {build_shape({{0, 0}, {2, 0}, {2, 1}, {1, 1}, {1, 2}, {0, 2}}), {}}, 1, + "TwoLShapes", }, { // T-shape fixed, unit square orbiting. {build_shape({{0, 2}, {1, 2}, {1, 0}, {2, 0}, {2, 2}, {3, 2}, {3, 3}, {0, 3}}), {}}, {build_rectangle(0, 1, 0, 1), {}}, 1, + "TShapeAndUnitSquare", }, - })); + }), + [](const testing::TestParamInfo& info) { + return info.param.name; + }); diff --git a/test/offset_test.cpp b/test/offset_test.cpp index f2242fb..f0ab466 100644 --- a/test/offset_test.cpp +++ b/test/offset_test.cpp @@ -13,6 +13,7 @@ using namespace shape; struct InflateShapeTestParams { + std::string name; Shape shape; LengthDbl offset; ShapeWithHoles expected_output; @@ -41,18 +42,25 @@ struct InflateShapeTestParams nlohmann::json json; file >> json; - return from_json(json); + auto test_params = from_json(json); + test_params.name = file_path; + return test_params; } }; +void PrintTo(const InflateShapeTestParams& params, std::ostream* os) +{ + *os << "shape " << params.shape.to_string(0) << "\n"; + *os << "offset " << params.offset << "\n"; + *os << "expected_output " << params.expected_output.to_string(0) << "\n"; +} + class InflateShapeTest: public testing::TestWithParam { }; TEST_P(InflateShapeTest, InflateShape) { InflateShapeTestParams test_params = GetParam(); - std::cout << "shape " << test_params.shape.to_string(0) << std::endl; - std::cout << "offset " << test_params.offset << std::endl; - std::cout << "expected_output " << test_params.expected_output.to_string(0) << std::endl; + PrintTo(test_params, &std::cout); #ifdef OFFSET_TEST_DEBUG Writer writer; @@ -78,6 +86,7 @@ INSTANTIATE_TEST_SUITE_P( InflateShapeTest, testing::ValuesIn(std::vector{ { + "VerticalSegment", build_path({{0, 0}, {0, 10}}), 1.0, { @@ -85,6 +94,7 @@ INSTANTIATE_TEST_SUITE_P( }, }, { + "DiagonalSegment", build_path({{6, 5}, {7, 13}}), 1e-3, { @@ -98,6 +108,7 @@ INSTANTIATE_TEST_SUITE_P( }, }, { + "TwoSegmentPath", build_path({{8, 0}, {10, 20}, {12, -10}}), 1e-3, { @@ -115,6 +126,7 @@ INSTANTIATE_TEST_SUITE_P( }, }, { + "ArcPath1", build_path({{1, 0}, {0, 0, 1}, {0, 1}}), 1, { @@ -128,6 +140,7 @@ INSTANTIATE_TEST_SUITE_P( }, }, { + "ArcPath2", build_path({{1, 0}, {0, 0, 1}, {0, 1}}), 2, { @@ -154,7 +167,10 @@ INSTANTIATE_TEST_SUITE_P( (fs::path("data") / "tests" / "offset" / "inflate_shape" / "5.json").string()), InflateShapeTestParams::read_json( (fs::path("data") / "tests" / "offset" / "inflate_shape" / "6.json").string()), - })); + }), + [](const testing::TestParamInfo& info) { + return fs::path(info.param.name).stem().string(); + }); struct InflateShapeWithHolesTestParams: TestParams @@ -176,15 +192,20 @@ struct InflateShapeWithHolesTestParams: TestParams { }; TEST_P(InflateShapeWithHolesTest, InflateShapeWithHoles) { InflateShapeWithHolesTestParams test_params = GetParam(); - std::cout << "Testing " << test_params.name << " (" << test_params.description << ")" << "..." << std::endl; - std::cout << "shape " << test_params.shape.to_string(0) << std::endl; - std::cout << "offset " << test_params.offset << std::endl; - std::cout << "expected_output " << test_params.expected_output.to_string(0) << std::endl; + PrintTo(test_params, &std::cout); #ifdef OFFSET_TEST_DEBUG Writer().add_shape_with_holes(test_params.shape).add_shape_with_holes(test_params.expected_output).write_json("inflate_input.json"); #endif @@ -221,7 +242,10 @@ TEST_P(InflateShapeWithHolesTest, InflateShapeWithHoles) INSTANTIATE_TEST_SUITE_P( Shape, InflateShapeWithHolesTest, - testing::ValuesIn(InflateShapeWithHolesTestParams::read_dir((fs::path("data") / "tests" / "offset" / "inflate").string()))); + testing::ValuesIn(InflateShapeWithHolesTestParams::read_dir((fs::path("data") / "tests" / "offset" / "inflate").string())), + [](const testing::TestParamInfo& info) { + return fs::path(info.param.name).stem().string(); + }); struct DeflateTestParams: TestParams @@ -245,17 +269,22 @@ struct DeflateTestParams: TestParams } }; +void PrintTo(const DeflateTestParams& params, std::ostream* os) +{ + *os << "Testing " << params.name << " (" << params.description << ")...\n"; + *os << "hole " << params.shape.to_string(0) << "\n"; + *os << "offset " << params.offset << "\n"; + *os << "expected_output\n"; + for (const Shape& hole: params.expected_output) + *os << "- " << hole.to_string(2) << "\n"; +} + class DeflateTest: public testing::TestWithParam { }; TEST_P(DeflateTest, Deflate) { DeflateTestParams test_params = GetParam(); - std::cout << "Testing " << test_params.name << " (" << test_params.description << ")" << "..." << std::endl; - std::cout << "hole " << test_params.shape.to_string(0) << std::endl; - std::cout << "offset " << test_params.offset << std::endl; - std::cout << "expected_output" << std::endl; - for (const Shape& hole: test_params.expected_output) - std::cout << "- " << hole.to_string(2) << std::endl; + PrintTo(test_params, &std::cout); auto output = deflate( test_params.shape, @@ -307,4 +336,7 @@ TEST_P(DeflateTest, Deflate) INSTANTIATE_TEST_SUITE_P( Shape, DeflateTest, - testing::ValuesIn(DeflateTestParams::read_dir((fs::path("data") / "tests" / "offset" / "deflate").string()))); + testing::ValuesIn(DeflateTestParams::read_dir((fs::path("data") / "tests" / "offset" / "deflate").string())), + [](const testing::TestParamInfo& info) { + return fs::path(info.param.name).stem().string(); + }); diff --git a/test/rasterization_test.cpp b/test/rasterization_test.cpp index 72f99c9..46177c7 100644 --- a/test/rasterization_test.cpp +++ b/test/rasterization_test.cpp @@ -21,6 +21,7 @@ namespace fs = boost::filesystem; struct RasterizationTestParams { + std::string name; ShapeWithHoles shape; LengthDbl cell_width; LengthDbl cell_height; @@ -49,10 +50,19 @@ struct RasterizationTestParams nlohmann::json json; file >> json; - return from_json(json); + auto test_params = from_json(json); + test_params.name = file_path; + return test_params; } }; +void PrintTo(const RasterizationTestParams& params, std::ostream* os) +{ + *os << "shape " << params.shape.to_string(0) << "\n"; + *os << "cell_width " << params.cell_width + << " cell_height " << params.cell_height << "\n"; +} + bool operator==(const Cell& a, const Cell& b) { return a.column == b.column && a.row == b.row; @@ -63,9 +73,7 @@ class RasterizationTest: public testing::TestWithParam TEST_P(RasterizationTest, Rasterization) { RasterizationTestParams test_params = GetParam(); - std::cout << "shape " << test_params.shape.to_string(0) << std::endl; - std::cout << "cell_width " << test_params.cell_width - << " cell_height " << test_params.cell_height << std::endl; + PrintTo(test_params, &std::cout); #ifdef RASTERIZATION_TEST_DEBUG Writer writer; @@ -144,47 +152,57 @@ INSTANTIATE_TEST_SUITE_P( testing::ValuesIn(std::vector{ // Shape contained within a single cell. { // Tiny triangle inside cell (0,0). + "TinyTriangle", {{build_shape({{0.1, 0.1}, {0.9, 0.1}, {0.5, 0.8}})}, {}}, 1.0, 1.0, }, { // Small rectangle inside cell (2,3). + "SmallRectangle", {{build_shape({{2.2, 3.2}, {2.8, 3.2}, {2.8, 3.8}, {2.2, 3.8}})}, {}}, 1.0, 1.0, }, // Single-column cases (col_min == col_max). { // Tall thin strip spanning 3 rows. + "TallThinStrip3Rows", {{build_shape({{0.4, 0.1}, {0.6, 0.1}, {0.6, 2.9}, {0.4, 2.9}})}, {}}, 1.0, 1.0, }, { // Thin strip in column 1, spanning 4 rows. + "ThinStrip4Rows", {{build_shape({{1.3, 0.5}, {1.7, 0.5}, {1.7, 3.5}, {1.3, 3.5}})}, {}}, 1.0, 1.0, }, // Multi-column rectangles. { // 2x1 rectangle. + "Rectangle2x1", {{build_shape({{0.2, 0.2}, {1.8, 0.2}, {1.8, 0.8}, {0.2, 0.8}})}, {}}, 1.0, 1.0, }, { // 3x3 rectangle with a fully interior cell. + "Rectangle3x3", {{build_shape({{0.1, 0.1}, {2.9, 0.1}, {2.9, 2.9}, {0.1, 2.9}})}, {}}, 1.0, 1.0, }, { // 5x5 rectangle with many fully interior cells. + "Rectangle5x5", {{build_shape({{0.1, 0.1}, {4.9, 0.1}, {4.9, 4.9}, {0.1, 4.9}})}, {}}, 1.0, 1.0, }, // Non-rectangular shapes. { // Right triangle fitting in a 2x2 grid. + "RightTriangle", {{build_shape({{0.1, 0.1}, {1.9, 0.1}, {0.1, 1.9}})}, {}}, 1.0, 1.0, }, { // L-shape: 2 cells wide at bottom, 1 cell wide at top. + "LShape", {{build_shape({{0.1, 0.1}, {1.9, 0.1}, {1.9, 0.9}, {0.9, 0.9}, {0.9, 1.9}, {0.1, 1.9}})}, {}}, 1.0, 1.0, }, // Shape with a hole. { // Square ring: 5x5 outer with 3x3 inner hole. + "SquareRing", { build_shape({{0.1, 0.1}, {4.9, 0.1}, {4.9, 4.9}, {0.1, 4.9}}), {build_shape({{1.1, 1.1}, {3.9, 1.1}, {3.9, 3.9}, {1.1, 3.9}})}, @@ -193,19 +211,25 @@ INSTANTIATE_TEST_SUITE_P( }, // Large cell: entire shape fits within a single cell. { // Rectangle much smaller than the cell. + "LargeCell", {{build_shape({{1.0, 1.0}, {4.0, 1.0}, {4.0, 4.0}, {1.0, 4.0}})}, {}}, 10.0, 10.0, }, // Non-unit cell dimensions. { // Rectangle with 2x3 cells. + "Rectangle2x3Cells", {{build_shape({{0.5, 0.5}, {5.5, 0.5}, {5.5, 5.5}, {0.5, 5.5}})}, {}}, 2.0, 3.0, }, { // Rectangle with 2x3 cells. + "RotatedRectangle", {shape::build_rectangle(100, 50).rotate(30)}, 10, 10, }, RasterizationTestParams::read_json( (fs::path("data") / "tests" / "rasterization" / "0.json").string()), - })); + }), + [](const testing::TestParamInfo& info) { + return fs::path(info.param.name).stem().string(); + }); diff --git a/test/shape_test.cpp b/test/shape_test.cpp index b194f0e..96cac11 100644 --- a/test/shape_test.cpp +++ b/test/shape_test.cpp @@ -24,14 +24,19 @@ struct StrictlyLesserAngleTestParams bool expected_output; }; +void PrintTo(const StrictlyLesserAngleTestParams& params, std::ostream* os) +{ + *os << "vector_1 " << params.vector_1.to_string() << "\n"; + *os << "vector_2 " << params.vector_2.to_string() << "\n"; + *os << "expected_output " << params.expected_output << "\n"; +} + class StrictlyLesserAngleTest: public testing::TestWithParam { }; TEST_P(StrictlyLesserAngleTest, StrictlyLesserAngle) { StrictlyLesserAngleTestParams test_params = GetParam(); - std::cout << "vector_1 " << test_params.vector_1.to_string() << std::endl; - std::cout << "vector_2 " << test_params.vector_2.to_string() << std::endl; - std::cout << "expected_output " << test_params.expected_output << std::endl; + PrintTo(test_params, &std::cout); #ifdef SHAPE_TEST_DEBUG Writer() .add_element(build_line_segment({0, 0}, test_params.vector_1)) @@ -57,7 +62,10 @@ INSTANTIATE_TEST_SUITE_P( {0.00058755222531203799, 0.00073094802962714311}, true, }, - })); + }), + [](const testing::TestParamInfo& info) { + return std::to_string(info.index); + }); struct ShapeElementLengthTestParams @@ -66,13 +74,18 @@ struct ShapeElementLengthTestParams LengthDbl expected_length; }; +void PrintTo(const ShapeElementLengthTestParams& params, std::ostream* os) +{ + *os << "element " << params.element.to_string() << "\n"; + *os << "expected_length " << params.expected_length << "\n"; +} + class ShapeElementLengthTest: public testing::TestWithParam { }; TEST_P(ShapeElementLengthTest, ShapeElementLength) { ShapeElementLengthTestParams test_params = GetParam(); - std::cout << "element " << test_params.element.to_string() << std::endl; - std::cout << "expected_length " << test_params.expected_length << std::endl; + PrintTo(test_params, &std::cout); LengthDbl length = test_params.element.length(); EXPECT_TRUE(equal(length, test_params.expected_length)); std::cout << "length " << length << std::endl; @@ -88,7 +101,10 @@ INSTANTIATE_TEST_SUITE_P( {build_circular_arc({1, 0}, {0, 1}, {0, 0}, ShapeElementOrientation::Anticlockwise), M_PI / 2}, {build_circular_arc({1, 0}, {0, 1}, {0, 0}, ShapeElementOrientation::Clockwise), 3 * M_PI / 2}, {build_circular_arc({1, 0}, {0, -1}, {0, 0}, ShapeElementOrientation::Anticlockwise), 3 * M_PI / 2}, - })); + }), + [](const testing::TestParamInfo& info) { + return std::to_string(info.index); + }); struct ShapeElementLengthPointTestParams @@ -98,14 +114,19 @@ struct ShapeElementLengthPointTestParams LengthDbl expected_length; }; +void PrintTo(const ShapeElementLengthPointTestParams& params, std::ostream* os) +{ + *os << "element " << params.element.to_string() << "\n"; + *os << "point " << params.point.to_string() << "\n"; + *os << "expected_length " << params.expected_length << "\n"; +} + class ShapeElementLengthPointTest: public testing::TestWithParam { }; TEST_P(ShapeElementLengthPointTest, ShapeElementLengthPoint) { ShapeElementLengthPointTestParams test_params = GetParam(); - std::cout << "element " << test_params.element.to_string() << std::endl; - std::cout << "point " << test_params.point.to_string() << std::endl; - std::cout << "expected_length " << test_params.expected_length << std::endl; + PrintTo(test_params, &std::cout); if (!test_params.element.contains(test_params.point)) { throw std::invalid_argument(FUNC_SIGNATURE); } @@ -137,7 +158,10 @@ INSTANTIATE_TEST_SUITE_P( //path_element_pos 21 shape_element_pos 1 point (24.017319578247072, 562.69162748260499) l 0.568959 //path_element_pos 21 shape_element_pos 2 point (24.017319578247072, 562.69162748260499) l 0.568959 - })); + }), + [](const testing::TestParamInfo& info) { + return std::to_string(info.index); + }); struct ShapeElementPointTestParams @@ -147,14 +171,19 @@ struct ShapeElementPointTestParams Point expected_output; }; +void PrintTo(const ShapeElementPointTestParams& params, std::ostream* os) +{ + *os << "element " << params.element.to_string() << "\n"; + *os << "length " << params.length << "\n"; + *os << "expected_output " << params.expected_output.to_string() << "\n"; +} + class ShapeElementPointTest: public testing::TestWithParam { }; TEST_P(ShapeElementPointTest, ShapeElementPoint) { ShapeElementPointTestParams test_params = GetParam(); - std::cout << "element " << test_params.element.to_string() << std::endl; - std::cout << "length " << test_params.length << std::endl; - std::cout << "expected_output " << test_params.expected_output.to_string() << std::endl; + PrintTo(test_params, &std::cout); Point output = test_params.element.point(test_params.length); EXPECT_TRUE(equal(output, test_params.expected_output)); std::cout << "output " << output.to_string() << std::endl; @@ -168,7 +197,10 @@ INSTANTIATE_TEST_SUITE_P( {build_line_segment({0, 0}, {2, 0}), 1, {1, 0}}, {build_circular_arc({1, 0}, {-1, 1}, {0, 0}, ShapeElementOrientation::Anticlockwise), M_PI / 2, {0, 1}}, {build_circular_arc({1, 0}, {-1, 1}, {0, 0}, ShapeElementOrientation::Clockwise), M_PI / 2, {0, -1}}, - })); + }), + [](const testing::TestParamInfo& info) { + return std::to_string(info.index); + }); struct ShapeElementFindPointBetweenTestParams @@ -179,15 +211,20 @@ struct ShapeElementFindPointBetweenTestParams Point expected_output; }; +void PrintTo(const ShapeElementFindPointBetweenTestParams& params, std::ostream* os) +{ + *os << "element " << params.element.to_string() << "\n"; + *os << "point_1 " << params.point_1.to_string() << "\n"; + *os << "point_2 " << params.point_2.to_string() << "\n"; + *os << "expected_output " << params.expected_output.to_string() << "\n"; +} + class ShapeElementFindPointBetweenTest: public testing::TestWithParam { }; TEST_P(ShapeElementFindPointBetweenTest, ShapeElementFindPointBetween) { ShapeElementFindPointBetweenTestParams test_params = GetParam(); - std::cout << "element " << test_params.element.to_string() << std::endl; - std::cout << "point_1 " << test_params.point_1.to_string() << std::endl; - std::cout << "point_2 " << test_params.point_2.to_string() << std::endl; - std::cout << "expected_output " << test_params.expected_output.to_string() << std::endl; + PrintTo(test_params, &std::cout); Point output = test_params.element.find_point_between( test_params.point_1, @@ -216,7 +253,11 @@ INSTANTIATE_TEST_SUITE_P( {25.12314661878088, 562.1174128418544}, {25.12432681320623, 562.1171997938548}, {25.12373636714434, 562.1173043853798}, - }})); + } + }), + [](const testing::TestParamInfo& info) { + return std::to_string(info.index); + }); struct ShapeFindPointBetweenTestParams @@ -227,6 +268,14 @@ struct ShapeFindPointBetweenTestParams ShapePoint expected_output; }; +void PrintTo(const ShapeFindPointBetweenTestParams& params, std::ostream* os) +{ + *os << "shape " << params.shape.to_string(0) << "\n"; + *os << "point_1 element_pos " << params.point_1.element_pos << " point " << params.point_1.point.to_string() << "\n"; + *os << "point_2 element_pos " << params.point_2.element_pos << " point " << params.point_2.point.to_string() << "\n"; + *os << "expected_output element_pos " << params.expected_output.element_pos << " point " << params.expected_output.point.to_string() << "\n"; +} + class ShapeFindPointBetweenTest: public testing::TestWithParam { }; TEST_P(ShapeFindPointBetweenTest, ShapeFindPointBetween) @@ -252,7 +301,10 @@ INSTANTIATE_TEST_SUITE_P( {1, {1, 0.5}}, {0, {0.5, 0}}, }, - })); + }), + [](const testing::TestParamInfo& info) { + return std::to_string(info.index); + }); struct ShapeElementMiddleTestParams @@ -261,15 +313,18 @@ struct ShapeElementMiddleTestParams Point expected_middle; }; +void PrintTo(const ShapeElementMiddleTestParams& params, std::ostream* os) +{ + *os << "circular_arc\n" << params.circular_arc.to_string() << "\n"; + *os << "expected_middle\n" << params.expected_middle.to_string() << "\n"; +} + class ShapeElementMiddleTest: public testing::TestWithParam { }; TEST_P(ShapeElementMiddleTest, ShapeElementMiddle) { ShapeElementMiddleTestParams test_params = GetParam(); - std::cout << "circular_arc" << std::endl; - std::cout << test_params.circular_arc.to_string() << std::endl; - std::cout << "expected_middle" << std::endl; - std::cout << test_params.expected_middle.to_string() << std::endl; + PrintTo(test_params, &std::cout); Point middle = test_params.circular_arc.middle(); std::cout << "computed_middle" << std::endl; @@ -301,7 +356,10 @@ INSTANTIATE_TEST_SUITE_P( build_shape({{-1, 0}, {0, 0, -1}, {0, 1}}, true).elements.front(), {- sqrt(2) / 2, sqrt(2) / 2} } - })); + }), + [](const testing::TestParamInfo& info) { + return std::to_string(info.index); + }); struct ShapeElementMinMaxTestParams @@ -313,16 +371,21 @@ struct ShapeElementMinMaxTestParams LengthDbl expected_y_max; }; +void PrintTo(const ShapeElementMinMaxTestParams& params, std::ostream* os) +{ + *os << "element " << params.element.to_string() << "\n"; + *os << "expected x_min " << params.expected_x_min + << " y_min " << params.expected_y_min + << " x_max " << params.expected_x_max + << " y_max " << params.expected_y_max << "\n"; +} + class ShapeElementMinMaxTest: public testing::TestWithParam { }; TEST_P(ShapeElementMinMaxTest, ShapeElementMinMax) { ShapeElementMinMaxTestParams test_params = GetParam(); - std::cout << "element " << test_params.element.to_string() << std::endl; - std::cout << "expected x_min " << test_params.expected_x_min - << " y_min " << test_params.expected_y_min - << " x_max " << test_params.expected_x_max - << " y_max " << test_params.expected_y_max << std::endl; + PrintTo(test_params, &std::cout); AxisAlignedBoundingBox aabb = test_params.element.min_max(); std::cout << "x_min " << aabb.x_min << " y_min " << aabb.y_min @@ -346,7 +409,10 @@ INSTANTIATE_TEST_SUITE_P( {build_shape({{-1, 0}, {0, 0, 1}, {0, 1}}, true).elements.front(), -1, -1, 1, 1 }, {build_shape({{0, -1}, {0, 0, 1}, {-1, 0}}, true).elements.front(), -1, -1, 1, 1 }, {build_shape({{1, 0}, {0, 0, 1}, {0, -1}}, true).elements.front(), -1, -1, 1, 1 }, - })); + }), + [](const testing::TestParamInfo& info) { + return std::to_string(info.index); + }); struct ShapeElementContainsTestParams @@ -356,14 +422,19 @@ struct ShapeElementContainsTestParams bool expected_output; }; +void PrintTo(const ShapeElementContainsTestParams& params, std::ostream* os) +{ + *os << "element " << params.element.to_string() << "\n"; + *os << "point " << params.point.to_string() << "\n"; + *os << "expceted output " << params.expected_output << "\n"; +} + class ShapeElementContainsTest: public testing::TestWithParam { }; TEST_P(ShapeElementContainsTest, ShapeElementContains) { ShapeElementContainsTestParams test_params = GetParam(); - std::cout << "element " << test_params.element.to_string() << std::endl; - std::cout << "point " << test_params.point.to_string() << std::endl; - std::cout << "expceted output " << test_params.expected_output << std::endl; + PrintTo(test_params, &std::cout); bool output = test_params.element.contains(test_params.point); std::cout << "output " << output << std::endl; EXPECT_EQ(output, test_params.expected_output); @@ -378,7 +449,10 @@ INSTANTIATE_TEST_SUITE_P( {174.91570697722955, 709.95140487030301}, false, }, - })); + }), + [](const testing::TestParamInfo& info) { + return std::to_string(info.index); + }); struct ShapeElementRecomputeCenterTestParams @@ -386,12 +460,17 @@ struct ShapeElementRecomputeCenterTestParams ShapeElement element; }; +void PrintTo(const ShapeElementRecomputeCenterTestParams& params, std::ostream* os) +{ + *os << "element " << params.element.to_string() << "\n"; +} + class ShapeElementRecomputeCenterTest: public testing::TestWithParam { }; TEST_P(ShapeElementRecomputeCenterTest, ShapeElementRecomputeCenter) { ShapeElementRecomputeCenterTestParams test_params = GetParam(); - std::cout << "element " << test_params.element.to_string() << std::endl; + PrintTo(test_params, &std::cout); ShapeElement element = test_params.element; element.recompute_center(); std::cout << "output " << element.to_string() << std::endl; @@ -405,7 +484,10 @@ INSTANTIATE_TEST_SUITE_P( {build_circular_arc({0, 1}, {1, 0}, {0, 0}, ShapeElementOrientation::Anticlockwise)}, {build_circular_arc({1, 0}, {0, -1}, {0, 0}, ShapeElementOrientation::Anticlockwise)}, {build_circular_arc({1, 2}, {2, 1}, {1, 1}, ShapeElementOrientation::Anticlockwise)}, - })); + }), + [](const testing::TestParamInfo& info) { + return std::to_string(info.index); + }); struct ShapeIsConvexTestParams @@ -414,13 +496,18 @@ struct ShapeIsConvexTestParams bool expected_output; }; +void PrintTo(const ShapeIsConvexTestParams& params, std::ostream* os) +{ + *os << "shape " << params.shape.to_string(0) << "\n"; + *os << "expected_output " << params.expected_output << "\n"; +} + class ShapeIsConvexTest: public testing::TestWithParam { }; TEST_P(ShapeIsConvexTest, ShapeIsConvex) { ShapeIsConvexTestParams test_params = GetParam(); - std::cout << "shape " << test_params.shape.to_string(0) << std::endl; - std::cout << "expected_output " << test_params.expected_output << std::endl; + PrintTo(test_params, &std::cout); bool output = test_params.shape.is_convex(); std::cout << "output " << output << std::endl; EXPECT_EQ(output, test_params.expected_output); @@ -484,7 +571,10 @@ INSTANTIATE_TEST_SUITE_P( build_shape({{0, 0}, {2, 0}, {2, 1}, {1, 1, -1}, {0, 1}}), false, }, - })); + }), + [](const testing::TestParamInfo& info) { + return std::to_string(info.index); + }); struct ShapeComputeAreaTestParams @@ -493,13 +583,18 @@ struct ShapeComputeAreaTestParams AreaDbl expected_area; }; +void PrintTo(const ShapeComputeAreaTestParams& params, std::ostream* os) +{ + *os << "shape " << params.shape.to_string(0) << "\n"; + *os << "expected area " << to_string(params.expected_area) << "\n"; +} + class ShapeComputeAreaTest: public testing::TestWithParam { }; TEST_P(ShapeComputeAreaTest, ShapeComputeArea) { ShapeComputeAreaTestParams test_params = GetParam(); - std::cout << "shape " << test_params.shape.to_string(0) << std::endl; - std::cout << "expected area " << to_string(test_params.expected_area) << std::endl; + PrintTo(test_params, &std::cout); AreaDbl area = test_params.shape.compute_area(); std::cout << "area " << to_string(area) << std::endl; EXPECT_TRUE(equal(area, test_params.expected_area)); @@ -529,7 +624,11 @@ INSTANTIATE_TEST_SUITE_P( build_line_segment({43.62858633055728, 195.7612139523166}, {41.39894441055727, 194.5414289923167}), }), 23.6526695078428, - }})); + } + }), + [](const testing::TestParamInfo& info) { + return std::to_string(info.index); + }); struct ShapeComputeFurthestPointsTestParams @@ -540,18 +639,23 @@ struct ShapeComputeFurthestPointsTestParams Shape::FurthestPoint expected_point_max; }; +void PrintTo(const ShapeComputeFurthestPointsTestParams& params, std::ostream* os) +{ + *os << "shape " << params.shape.to_string(0) << "\n"; + *os << "angle " << params.angle << "\n"; + *os << "expected point_min " << params.expected_point_min.point.to_string() + << " pos " << params.expected_point_min.element_pos + << " point_max " << params.expected_point_max.point.to_string() + << " pos " << params.expected_point_max.element_pos + << "\n"; +} + class ShapeComputeFurthestPointsTest: public testing::TestWithParam { }; TEST_P(ShapeComputeFurthestPointsTest, ShapeComputeFurthestPoints) { ShapeComputeFurthestPointsTestParams test_params = GetParam(); - std::cout << "shape " << test_params.shape.to_string(0) << std::endl; - std::cout << "angle " << test_params.angle << std::endl; - std::cout << "expected point_min " << test_params.expected_point_min.point.to_string() - << " pos " << test_params.expected_point_min.element_pos - << " point_max " << test_params.expected_point_max.point.to_string() - << " pos " << test_params.expected_point_max.element_pos - << std::endl; + PrintTo(test_params, &std::cout); auto p = test_params.shape.compute_furthest_points(test_params.angle); std::cout << "point_min " << p.first.point.to_string() << " pos " << p.first.element_pos @@ -584,7 +688,10 @@ INSTANTIATE_TEST_SUITE_P( {Point{4, 4}, 2}, {Point{0, 0}, 0}, }, - })); + }), + [](const testing::TestParamInfo& info) { + return std::to_string(info.index); + }); struct ShapeContainsTestParams @@ -624,15 +731,20 @@ struct ShapeContainsTestParams } }; +void PrintTo(const ShapeContainsTestParams& params, std::ostream* os) +{ + *os << "shape " << params.shape.to_string(0) << "\n"; + *os << "point " << params.point.to_string() << "\n"; + *os << "strict " << params.strict << "\n"; + *os << "expceted output " << params.expected_output << "\n"; +} + class ShapeContainsTest: public testing::TestWithParam { }; TEST_P(ShapeContainsTest, ShapeContains) { ShapeContainsTestParams test_params = GetParam(); - std::cout << "shape " << test_params.shape.to_string(0) << std::endl; - std::cout << "point " << test_params.point.to_string() << std::endl; - std::cout << "strict " << test_params.strict << std::endl; - std::cout << "expceted output " << test_params.expected_output << std::endl; + PrintTo(test_params, &std::cout); bool output = test_params.shape.contains( test_params.point, test_params.strict); @@ -652,7 +764,10 @@ INSTANTIATE_TEST_SUITE_P( }, ShapeContainsTestParams::read_json( (fs::path("data") / "tests" / "shape" / "shape_contains" / "0.json").string()), - })); + }), + [](const testing::TestParamInfo& info) { + return std::to_string(info.index); + }); struct ShapeFindPointStrictlyInsideTestParams @@ -660,12 +775,17 @@ struct ShapeFindPointStrictlyInsideTestParams Shape shape; }; +void PrintTo(const ShapeFindPointStrictlyInsideTestParams& params, std::ostream* os) +{ + *os << "shape " << params.shape.to_string(0) << "\n"; +} + class ShapeFindPointStrictlyInsideTest: public testing::TestWithParam { }; TEST_P(ShapeFindPointStrictlyInsideTest, ShapeFindPointStrictlyInside) { ShapeFindPointStrictlyInsideTestParams test_params = GetParam(); - std::cout << "shape " << test_params.shape.to_string(0) << std::endl; + PrintTo(test_params, &std::cout); Point output = test_params.shape.find_point_strictly_inside(); std::cout << "output " << output.to_string() << std::endl; EXPECT_TRUE(test_params.shape.contains(output, true)); @@ -683,7 +803,11 @@ INSTANTIATE_TEST_SUITE_P( build_shape({{0, 100}, {100, 100}, {100, 0}, {200, 0}, {200, 200}, {0, 200}}), }, { build_shape({{15, 4}, {16, 5}, {15, 6}, {14, 5}}), - }})); + } + }), + [](const testing::TestParamInfo& info) { + return std::to_string(info.index); + }); struct ShapeExtractPathTestParams @@ -694,15 +818,20 @@ struct ShapeExtractPathTestParams Shape expected_path; }; +void PrintTo(const ShapeExtractPathTestParams& params, std::ostream* os) +{ + *os << "shape " << params.shape.to_string(0) << "\n"; + *os << "point_start element_pos " << params.point_start.element_pos << " point " << params.point_start.point.to_string() << "\n"; + *os << "point_end element_pos " << params.point_end.element_pos << " point " << params.point_end.point.to_string() << "\n"; + *os << "expected path " << params.expected_path.to_string(1) << "\n"; +} + class ShapeExtractPathTest: public testing::TestWithParam { }; TEST_P(ShapeExtractPathTest, ShapeExtractPath) { ShapeExtractPathTestParams test_params = GetParam(); - std::cout << "shape " << test_params.shape.to_string(0) << std::endl; - std::cout << "point_start element_pos " << test_params.point_start.element_pos << " point " << test_params.point_start.point.to_string() << std::endl; - std::cout << "point_end element_pos " << test_params.point_end.element_pos << " point " << test_params.point_end.point.to_string() << std::endl; - std::cout << "expected path " << test_params.expected_path.to_string(1) << std::endl; + PrintTo(test_params, &std::cout); Shape path = test_params.shape.extract_path(test_params.point_start, test_params.point_end); std::cout << "path " << path.to_string(1) << std::endl; EXPECT_TRUE(equal(path, test_params.expected_path)); @@ -743,7 +872,10 @@ INSTANTIATE_TEST_SUITE_P( {1, {4, 1}}, build_path({{4, 3}, {4, 4}, {0, 4}, {0, 0}, {4, 0}, {4, 1}}), }, - })); + }), + [](const testing::TestParamInfo& info) { + return std::to_string(info.index); + }); struct ShapeReplaceTestParams @@ -753,17 +885,22 @@ struct ShapeReplaceTestParams Shape expected_output; }; +void PrintTo(const ShapeReplaceTestParams& params, std::ostream* os) +{ + *os << "shape " << params.shape.to_string(0) << "\n"; + for (const Shape::PathReplacement& path: params.paths) { + *os << "start " << path.start.element_pos << " " << path.start.point.to_string() << "\n"; + *os << "end " << path.end.element_pos << " " << path.end.point.to_string() << "\n"; + } + *os << "expceted output " << params.expected_output.to_string(0) << "\n"; +} + class ShapeReplaceTest: public testing::TestWithParam { }; TEST_P(ShapeReplaceTest, ShapeReplace) { ShapeReplaceTestParams test_params = GetParam(); - std::cout << "shape " << test_params.shape.to_string(0) << std::endl; - for (const Shape::PathReplacement& path: test_params.paths) { - std::cout << "start " << path.start.element_pos << " " << path.start.point.to_string() << std::endl; - std::cout << "end " << path.end.element_pos << " " << path.end.point.to_string() << std::endl; - } - std::cout << "expceted output " << test_params.expected_output.to_string(0) << std::endl; + PrintTo(test_params, &std::cout); Shape output = test_params.shape.replace(test_params.paths); std::cout << "output " << output.to_string(0) << std::endl; ASSERT_TRUE(equal(output, test_params.expected_output)); @@ -792,7 +929,11 @@ INSTANTIATE_TEST_SUITE_P( {{0, {0, 1}}, {0, {0, 9}}, build_path({{0, 1}, {1, 5}, {0, 9}}).elements}, }, build_path({{0, 0}, {0, 1}, {1, 5}, {0, 9}, {0, 10}, {1, 10}, {5, 11}, {9, 10}, {10, 10}}), - }})); + } + }), + [](const testing::TestParamInfo& info) { + return std::to_string(info.index); + }); struct ShapeComputeMinMaxTestParams @@ -806,20 +947,25 @@ struct ShapeComputeMinMaxTestParams LengthDbl expected_y_max; }; +void PrintTo(const ShapeComputeMinMaxTestParams& params, std::ostream* os) +{ + *os << "shape " << params.shape.to_string(0) << "\n"; + *os << "point_1 element_pos " << params.point_1.element_pos + << " point " << params.point_1.point.to_string() << "\n"; + *os << "point_2 element_pos " << params.point_2.element_pos + << " point " << params.point_2.point.to_string() << "\n"; + *os << "expected x_min " << params.expected_x_min + << " y_min " << params.expected_y_min + << " x_max " << params.expected_x_max + << " y_max " << params.expected_y_max << "\n"; +} + class ShapeComputeMinMaxTest: public testing::TestWithParam { }; TEST_P(ShapeComputeMinMaxTest, ShapeComputeMinMax) { ShapeComputeMinMaxTestParams test_params = GetParam(); - std::cout << "shape " << test_params.shape.to_string(0) << std::endl; - std::cout << "point_1 element_pos " << test_params.point_1.element_pos - << " point " << test_params.point_1.point.to_string() << std::endl; - std::cout << "point_2 element_pos " << test_params.point_2.element_pos - << " point " << test_params.point_2.point.to_string() << std::endl; - std::cout << "expected x_min " << test_params.expected_x_min - << " y_min " << test_params.expected_y_min - << " x_max " << test_params.expected_x_max - << " y_max " << test_params.expected_y_max << std::endl; + PrintTo(test_params, &std::cout); AxisAlignedBoundingBox aabb = test_params.shape.compute_min_max(test_params.point_1, test_params.point_2); std::cout << "x_min " << aabb.x_min << " y_min " << aabb.y_min @@ -886,4 +1032,7 @@ INSTANTIATE_TEST_SUITE_P( {1, {0, 1}}, {0, {0, 0}}, -1, 0, 0, 1, }, - })); + }), + [](const testing::TestParamInfo& info) { + return std::to_string(info.index); + }); diff --git a/test/shapes_intersections_test.cpp b/test/shapes_intersections_test.cpp index adc49bb..f6920ab 100644 --- a/test/shapes_intersections_test.cpp +++ b/test/shapes_intersections_test.cpp @@ -19,6 +19,7 @@ namespace fs = boost::filesystem; struct IntersectShapeTestParams { + std::string name; Shape shape; bool expected_output; @@ -48,13 +49,18 @@ struct IntersectShapeTestParams } }; +void PrintTo(const IntersectShapeTestParams& params, std::ostream* os) +{ + *os << "shape " << params.shape.to_string(0) << "\n"; + *os << "expected_output " << params.expected_output << "\n"; +} + class IntersectShapeTest: public testing::TestWithParam { }; TEST_P(IntersectShapeTest, IntersectShape) { IntersectShapeTestParams test_params = GetParam(); - std::cout << "shape " << test_params.shape.to_string(0) << std::endl; - std::cout << "expected_output " << test_params.expected_output << std::endl; + PrintTo(test_params, &std::cout); //write_json({{test_params.shape}}, {}, "intersect_input.json"); bool output = intersect(test_params.shape); @@ -68,24 +74,31 @@ INSTANTIATE_TEST_SUITE_P( IntersectShapeTest, testing::ValuesIn(std::vector{ { + "Square", build_shape({{0, 0}, {2, 0}, {2, 2}, {0, 2}}), false, }, { + "Bowtie", build_shape({{0, 0}, {2, 2}, {2, 0}, {0, 2}}), true, }, { + "DoubleSquare", build_shape({{0, 0}, {2, 0}, {2, 2}, {0, 2}, {0, 0}, {2, 0}, {2, 2}, {0, 2}}), true, }, { + "UShapeWithSelfIntersection", build_shape({{0, 0}, {4, 0}, {4, 4}, {2, 4}, {2, 3}, {3, 3}, {3, 2}, {1, 2}, {1, 3}, {2, 3}, {2, 4}, {0, 4}}), true, }, { + "TriangleWithInnerCross1", build_shape({{0, 0}, {6, 0}, {3, 2}, {2, 1}, {4, 1}, {3, 2}}), true, }, { + "TriangleWithInnerCross2", build_shape({{0, 0}, {6, 0}, {3, 2}, {4, 1}, {2, 1}, {3, 2}}), true, }, { + "ComplexNonSelfIntersecting", build_shape({ {31.49606296, 144.25196848}, {0, 144.25196848}, @@ -103,6 +116,7 @@ INSTANTIATE_TEST_SUITE_P( {31.49606295999999, 134.8031497200001}}), false, }, { + "TouchingSquares", build_shape({ {0, 0}, {1, 0}, @@ -113,11 +127,16 @@ INSTANTIATE_TEST_SUITE_P( {1, 1}, {0, 1}}), true, - }})); + } + }), + [](const testing::TestParamInfo& info) { + return info.param.name; + }); struct IntersectShapeShapeElementTestParams { + std::string name; Shape shape; ShapeElement element; bool strict = false; @@ -147,19 +166,26 @@ struct IntersectShapeShapeElementTestParams nlohmann::json json; file >> json; - return from_json(json); + auto test_params = from_json(json); + test_params.name = file_path; + return test_params; } }; +void PrintTo(const IntersectShapeShapeElementTestParams& params, std::ostream* os) +{ + *os << "shape " << params.shape.to_string(0) << "\n"; + *os << "element " << params.element.to_string() << "\n"; + *os << "strict " << params.strict << "\n"; + *os << "expected_output " << params.expected_output << "\n"; +} + class IntersectShapeShapeElementTest: public testing::TestWithParam { }; TEST_P(IntersectShapeShapeElementTest, IntersectShapeShapeElement) { IntersectShapeShapeElementTestParams test_params = GetParam(); - std::cout << "shape " << test_params.shape.to_string(0) << std::endl; - std::cout << "element " << test_params.element.to_string() << std::endl; - std::cout << "strict " << test_params.strict << std::endl; - std::cout << "expected_output " << test_params.expected_output << std::endl; + PrintTo(test_params, &std::cout); #ifdef SHAPES_INTERSECTIONS_TEST_ENABLE_DEBUG Writer().add_shape(test_params.shape).add_element(test_params.element).write_json("intersect_input.json"); @@ -181,26 +207,33 @@ INSTANTIATE_TEST_SUITE_P( IntersectShapeShapeElementTestParams::read_json( (fs::path("data") / "tests" / "shapes_intersections" / "intersect_shape_shape_element" / "0.json").string()), { + "SquareSegmentOutside", build_shape({{0, 0}, {2, 0}, {2, 2}, {0, 2}}), build_line_segment({3, 0}, {3, 2}), false, false, }, { + "RectangleSegmentInside", build_shape({{0, 0}, {2, 0}, {2, 4}, {0, 4}}), build_line_segment({1, 1}, {1, 3}), false, true, }, { + "PathSegmentInside", build_path({{0, 0}, {2, 0}, {2, 4}, {0, 4}}), build_line_segment({1, 1}, {1, 3}), false, false, }, - })); + }), + [](const testing::TestParamInfo& info) { + return fs::path(info.param.name).stem().string(); + }); struct ComputeIntersectionsPathShapeTestParams { + std::string name; Shape path; Shape shape; bool only_min_max; @@ -237,24 +270,31 @@ struct ComputeIntersectionsPathShapeTestParams nlohmann::json json; file >> json; - return from_json(json); + auto test_params = from_json(json); + test_params.name = file_path; + return test_params; } }; +void PrintTo(const ComputeIntersectionsPathShapeTestParams& params, std::ostream* os) +{ + *os << "path " << params.path.to_string(0) << "\n"; + *os << "shape " << params.shape.to_string(0) << "\n"; + *os << "only_min_max " << params.only_min_max << "\n"; + *os << "expected_output\n"; + for (const PathShapeIntersectionPoint& intersection: params.expected_output) { + *os << "path_element_pos " << intersection.path_element_pos + << " shape_element_pos " << intersection.shape_element_pos + << " point " << intersection.point.to_string() << "\n"; + } +} + class ComputeIntersectionsPathShapeTest: public testing::TestWithParam { }; TEST_P(ComputeIntersectionsPathShapeTest, ComputeIntersectionsPathShape) { ComputeIntersectionsPathShapeTestParams test_params = GetParam(); - std::cout << "path " << test_params.path.to_string(0) << std::endl; - std::cout << "shape " << test_params.shape.to_string(0) << std::endl; - std::cout << "only_min_max " << test_params.only_min_max << std::endl; - std::cout << "expected_output" << std::endl; - for (const PathShapeIntersectionPoint& intersection: test_params.expected_output) { - std::cout << "path_element_pos " << intersection.path_element_pos - << " shape_element_pos " << intersection.shape_element_pos - << " point " << intersection.point.to_string() << std::endl; - } + PrintTo(test_params, &std::cout); std::vector output = compute_intersections( test_params.path, @@ -287,6 +327,7 @@ INSTANTIATE_TEST_SUITE_P( ComputeIntersectionsPathShapeTest, testing::ValuesIn(std::vector{ { + "ArcLineArcCrossesTriangle", build_path({ build_circular_arc({64, 0}, {192, 128}, {192, 0}, ShapeElementOrientation::Clockwise), build_line_segment({192, 128}, {704, 128}), @@ -304,11 +345,15 @@ INSTANTIATE_TEST_SUITE_P( (fs::path("data") / "tests" / "shapes_intersections" / "compute_intersections_path_shape" / "1.json").string()), ComputeIntersectionsPathShapeTestParams::read_json( (fs::path("data") / "tests" / "shapes_intersections" / "compute_intersections_path_shape" / "2.json").string()), - })); + }), + [](const testing::TestParamInfo& info) { + return fs::path(info.param.name).stem().string(); + }); struct ComputeStrictIntersectionsPathShapeTestParams { + std::string name; Shape path; Shape shape; bool only_first; @@ -349,20 +394,25 @@ struct ComputeStrictIntersectionsPathShapeTestParams } }; +void PrintTo(const ComputeStrictIntersectionsPathShapeTestParams& params, std::ostream* os) +{ + *os << "path " << params.path.to_string(0) << "\n"; + *os << "shape " << params.shape.to_string(0) << "\n"; + *os << "only_first " << params.only_first << "\n"; + *os << "expected_output\n"; + for (const PathShapeIntersectionPoint& intersection: params.expected_output) { + *os << "path_element_pos " << intersection.path_element_pos + << " shape_element_pos " << intersection.shape_element_pos + << " point " << intersection.point.to_string() << "\n"; + } +} + class ComputeStrictIntersectionsPathShapeTest: public testing::TestWithParam { }; TEST_P(ComputeStrictIntersectionsPathShapeTest, ComputeStrictIntersectionsPathShape) { ComputeStrictIntersectionsPathShapeTestParams test_params = GetParam(); - std::cout << "path " << test_params.path.to_string(0) << std::endl; - std::cout << "shape " << test_params.shape.to_string(0) << std::endl; - std::cout << "only_first " << test_params.only_first << std::endl; - std::cout << "expected_output" << std::endl; - for (const PathShapeIntersectionPoint& intersection: test_params.expected_output) { - std::cout << "path_element_pos " << intersection.path_element_pos - << " shape_element_pos " << intersection.shape_element_pos - << " point " << intersection.point.to_string() << std::endl; - } + PrintTo(test_params, &std::cout); std::vector output = compute_strict_intersections( test_params.path, @@ -395,6 +445,7 @@ INSTANTIATE_TEST_SUITE_P( ComputeStrictIntersectionsPathShapeTest, testing::ValuesIn(std::vector{ { + "ArcLineArcCrossesTriangle", build_path({ build_circular_arc({64, 0}, {192, 128}, {192, 0}, ShapeElementOrientation::Clockwise), build_line_segment({192, 128}, {704, 128}), @@ -403,11 +454,15 @@ INSTANTIATE_TEST_SUITE_P( true, {{1, 0, {408, 128}}}, }, - })); + }), + [](const testing::TestParamInfo& info) { + return info.param.name; + }); struct IntersectShapeShapeTestParams { + std::string name; Shape shape_1; Shape shape_2; bool strict = false; @@ -438,19 +493,26 @@ struct IntersectShapeShapeTestParams nlohmann::json json; file >> json; - return from_json(json); + auto test_params = from_json(json); + test_params.name = file_path; + return test_params; } }; +void PrintTo(const IntersectShapeShapeTestParams& params, std::ostream* os) +{ + *os << "shape_1 " << params.shape_1.to_string(0) << "\n"; + *os << "shape_2 " << params.shape_2.to_string(0) << "\n"; + *os << "strict " << params.strict << "\n"; + *os << "expected_output " << params.expected_output << "\n"; +} + class IntersectShapeShapeTest: public testing::TestWithParam { }; TEST_P(IntersectShapeShapeTest, IntersectShapeShape) { IntersectShapeShapeTestParams test_params = GetParam(); - std::cout << "shape_1 " << test_params.shape_1.to_string(0) << std::endl; - std::cout << "shape_2 " << test_params.shape_2.to_string(0) << std::endl; - std::cout << "strict " << test_params.strict << std::endl; - std::cout << "expected_output " << test_params.expected_output << std::endl; + PrintTo(test_params, &std::cout); #ifdef SHAPES_INTERSECTIONS_TEST_ENABLE_DEBUG Writer() @@ -473,39 +535,46 @@ INSTANTIATE_TEST_SUITE_P( IntersectShapeShapeTest, testing::ValuesIn(std::vector{ { + "SquareOverlapStrict", build_shape({{0, 0}, {2, 0}, {2, 2}, {0, 2}}), build_shape({{0, 0}, {2, 0}, {2, 2}, {0, 2}}), true, true, }, { + "SquarePathOutside", build_shape({{0, 0}, {2, 0}, {2, 2}, {0, 2}}), build_path({{3, 0}, {3, 2}}), false, false, }, { + "RectanglePathInside", build_shape({{0, 0}, {2, 0}, {2, 4}, {0, 4}}), build_path({{1, 1}, {1, 3}}), false, true, }, { + "PathInsideRectangle", build_path({{1, 1}, {1, 3}}), build_shape({{0, 0}, {2, 0}, {2, 4}, {0, 4}}), false, true, }, { + "TwoPaths", build_path({{0, 0}, {2, 0}, {2, 4}, {0, 4}}), build_path({{1, 1}, {1, 3}}), false, false, }, { + "TwoPathsReversed", build_path({{1, 1}, {1, 3}}), build_path({{0, 0}, {2, 0}, {2, 4}, {0, 4}}), false, false, - }, { - IntersectShapeShapeTestParams::read_json( - (fs::path("data") / "tests" / "shapes_intersections" / "intersect_shape_shape" / "0.json").string()), - }, { + }, + IntersectShapeShapeTestParams::read_json( + (fs::path("data") / "tests" / "shapes_intersections" / "intersect_shape_shape" / "0.json").string()), + { + "ArrowShapesMeetAtTip", build_shape({{4, 0}, {0, 0}, {0, 2}, {1, 2}, {2, 3}, {3, 2}, {4, 2}}), build_shape({{0, 2}, {0, 4}, {4, 4}, {4, 2}, {3, 2}, {2, 1}, {1, 2}}), true, @@ -521,11 +590,15 @@ INSTANTIATE_TEST_SUITE_P( // true, // false, }, - })); + }), + [](const testing::TestParamInfo& info) { + return fs::path(info.param.name).stem().string(); + }); struct IntersectShapeWithHolesShapeTestParams { + std::string name; ShapeWithHoles shape_with_holes; Shape shape; bool strict = false; @@ -557,19 +630,26 @@ struct IntersectShapeWithHolesShapeTestParams nlohmann::json json; file >> json; - return from_json(json); + auto test_params = from_json(json); + test_params.name = file_path; + return test_params; } }; +void PrintTo(const IntersectShapeWithHolesShapeTestParams& params, std::ostream* os) +{ + *os << "shape_with_holes " << params.shape_with_holes.to_string(0) << "\n"; + *os << "shape " << params.shape.to_string(0) << "\n"; + *os << "strict " << params.strict << "\n"; + *os << "expected_output " << params.expected_output << "\n"; +} + class IntersectShapeWithHolesShapeTest: public testing::TestWithParam { }; TEST_P(IntersectShapeWithHolesShapeTest, IntersectShapeWithHolesShape) { IntersectShapeWithHolesShapeTestParams test_params = GetParam(); - std::cout << "shape_with_holes " << test_params.shape_with_holes.to_string(0) << std::endl; - std::cout << "shape " << test_params.shape.to_string(0) << std::endl; - std::cout << "strict " << test_params.strict << std::endl; - std::cout << "expected_output " << test_params.expected_output << std::endl; + PrintTo(test_params, &std::cout); #ifdef SHAPES_INTERSECTIONS_TEST_ENABLE_DEBUG Writer() @@ -592,6 +672,7 @@ INSTANTIATE_TEST_SUITE_P( IntersectShapeWithHolesShapeTest, testing::ValuesIn(std::vector{ { + "ShapeInHole", { build_shape({{500, 500}, {0, 500}, {0, 0}, {500, 0}}), {build_shape({{100, 100}, {400, 100}, {400, 400}, {100, 400}})} @@ -600,6 +681,7 @@ INSTANTIATE_TEST_SUITE_P( true, false, }, { + "CircleWithArcInside", { build_circle(10).shift(5, 0), }, @@ -611,6 +693,7 @@ INSTANTIATE_TEST_SUITE_P( true, false, }, { + "UShapeLineAcrossNotch", { build_shape({{0, 0}, {3, 0}, {3, 1}, {1, 1}, {1, 2}, {3, 2}, {3, 3}, {0, 3}}), }, @@ -618,6 +701,7 @@ INSTANTIATE_TEST_SUITE_P( true, false, }, { + "CShapeLineAcrossNotch", { build_shape({{2, 0}, {5, 0}, {5, 3}, {2, 3}, {2, 2}, {4, 2}, {4, 1}, {2, 1}}), }, @@ -625,6 +709,7 @@ INSTANTIATE_TEST_SUITE_P( true, false, }, { + "CircleWithArcOutside", { build_circle(10), }, @@ -636,6 +721,7 @@ INSTANTIATE_TEST_SUITE_P( true, false, }, { + "ArcShapeTangentToPath", { build_shape({ {19.68503937, 17.7480315}, @@ -654,11 +740,15 @@ INSTANTIATE_TEST_SUITE_P( }, IntersectShapeWithHolesShapeTestParams::read_json( (fs::path("data") / "tests" / "shapes_intersections" / "intersect_shape_with_holes_shape" / "0.json").string()), - })); + }), + [](const testing::TestParamInfo& info) { + return fs::path(info.param.name).stem().string(); + }); struct IntersectShapeWithHolesShapeWithHolesTestParams { + std::string name; ShapeWithHoles shape_with_holes_1; ShapeWithHoles shape_with_holes_2; bool strict = false; @@ -693,15 +783,20 @@ struct IntersectShapeWithHolesShapeWithHolesTestParams } }; +void PrintTo(const IntersectShapeWithHolesShapeWithHolesTestParams& params, std::ostream* os) +{ + *os << "shape_with_holes_1 " << params.shape_with_holes_1.to_string(0) << "\n"; + *os << "shape_with_holes_2 " << params.shape_with_holes_2.to_string(0) << "\n"; + *os << "strict " << params.strict << "\n"; + *os << "expected_output " << params.expected_output << "\n"; +} + class IntersectShapeWithHolesShapeWithHolesTest: public testing::TestWithParam { }; TEST_P(IntersectShapeWithHolesShapeWithHolesTest, IntersectShapeWithHolesShapeWithHoles) { IntersectShapeWithHolesShapeWithHolesTestParams test_params = GetParam(); - std::cout << "shape_with_holes_1 " << test_params.shape_with_holes_1.to_string(0) << std::endl; - std::cout << "shape_with_holes_2 " << test_params.shape_with_holes_2.to_string(0) << std::endl; - std::cout << "strict " << test_params.strict << std::endl; - std::cout << "expected_output " << test_params.expected_output << std::endl; + PrintTo(test_params, &std::cout); bool output = intersect( test_params.shape_with_holes_1, @@ -717,6 +812,7 @@ INSTANTIATE_TEST_SUITE_P( IntersectShapeWithHolesShapeWithHolesTest, testing::ValuesIn(std::vector{ { + "ShapeInHole", {build_shape({{100, 200}, {200, 200}, {200, 400}, {100, 400}})}, { build_shape({{500, 500}, {0, 500}, {0, 0}, {500, 0}}), @@ -724,4 +820,8 @@ INSTANTIATE_TEST_SUITE_P( }, true, false, - }})); + } + }), + [](const testing::TestParamInfo& info) { + return info.param.name; + }); diff --git a/test/simplification_test.cpp b/test/simplification_test.cpp index 7423814..ebbe810 100644 --- a/test/simplification_test.cpp +++ b/test/simplification_test.cpp @@ -9,6 +9,7 @@ using namespace shape; struct TryExtendToIntersectionTestParams { + std::string name; ShapeElement element_prev; ShapeElement element_next; bool expected_feasible; @@ -16,14 +17,19 @@ struct TryExtendToIntersectionTestParams Point expected_intersection; }; +void PrintTo(const TryExtendToIntersectionTestParams& params, std::ostream* os) +{ + *os << "element_prev " << params.element_prev.to_string() << "\n"; + *os << "element_next " << params.element_next.to_string() << "\n"; +} + class TryExtendToIntersectionTest: public testing::TestWithParam { }; TEST_P(TryExtendToIntersectionTest, TryExtendToIntersection) { TryExtendToIntersectionTestParams test_params = GetParam(); - std::cout << "element_prev " << test_params.element_prev.to_string() << std::endl; - std::cout << "element_next " << test_params.element_next.to_string() << std::endl; + PrintTo(test_params, &std::cout); ExtendToIntersectionOutput output = try_extend_to_intersection( test_params.element_prev, @@ -49,55 +55,58 @@ INSTANTIATE_TEST_SUITE_P( TryExtendToIntersectionTest, testing::ValuesIn(std::vector{ { // Line + Line, feasible: horizontal then vertical. - // prev goes right; next goes up. Extending both meets at (3, 0). + "LineLineFeasible", build_line_segment({0, 0}, {1, 0}), build_line_segment({3, 1}, {3, 3}), true, {3, 0}, }, { // Line + Line, infeasible: intersection lies behind prev's end. - // The lines meet at (3, 0), but (3, 0) is behind end (5, 0) of prev. + "LineLineInfeasibleBehind", build_line_segment({0, 0}, {5, 0}), build_line_segment({3, 1}, {3, 3}), false, {0, 0}, }, { // Line + Line, infeasible: intersection lies inside next. - // The lines meet at (3, 0), which is strictly between next's endpoints. + "LineLineInfeasibleInsideNext", build_line_segment({0, 0}, {1, 0}), build_line_segment({3, -1}, {3, 3}), false, {0, 0}, }, { // Line + Line, infeasible: parallel lines never meet. + "LineLineParallel", build_line_segment({0, 0}, {1, 0}), build_line_segment({0, 1}, {1, 1}), false, {0, 0}, - }, { // CCW Arc + Line, feasible: arc extends from 0° to 60° (r=2), - // vertical line starts above arc end; both extend to meet at (0, 2). + }, { // CCW Arc + Line, feasible. + "ArcLineFeasible", build_circular_arc({2, 0}, {1, sqrt(3.0)}, {0, 0}, ShapeElementOrientation::Anticlockwise), build_line_segment({0, 3}, {0, 5}), true, {0, 2}, - }, { // Line + CCW Arc, feasible: horizontal line ending at (-1.5, 0), - // arc starts at (1, 0); extending the line forward and the arc - // backward meets the circle at (-1, 0), the candidate closest - // to the gap midpoint (-0.25, 0). + }, { // Line + CCW Arc, feasible. + "LineArcFeasible", build_line_segment({-3, 0}, {-1.5, 0}), build_circular_arc({1, 0}, {0, 1}, {0, 0}, ShapeElementOrientation::Anticlockwise), true, {-1, 0}, - }, { // CCW Arc + CCW Arc, feasible: two unit-radius arcs on intersecting - // circles; extending both meets at (-sqrt(3)/2, 1/2). + }, { // CCW Arc + CCW Arc, feasible. + "ArcArcFeasible", build_circular_arc({1, 0}, {0, 1}, {0, 0}, ShapeElementOrientation::Anticlockwise), build_circular_arc({0, 2}, {-1, 2}, {0, 1}, ShapeElementOrientation::Anticlockwise), true, {-sqrt(3.0) / 2, 0.5}, - }, { // CCW Arc + CCW Arc, infeasible: circles too far apart to intersect. + }, { // CCW Arc + CCW Arc, infeasible: circles too far apart. + "ArcArcTooFarApart", build_circular_arc({1, 0}, {0, 1}, {0, 0}, ShapeElementOrientation::Anticlockwise), build_circular_arc({6, 0}, {5, 1}, {5, 0}, ShapeElementOrientation::Anticlockwise), false, {0, 0}, }, - })); + }), + [](const testing::TestParamInfo& info) { + return info.param.name; + }); //////////////////////////////////////////////////////////////////////////////// @@ -106,6 +115,7 @@ INSTANTIATE_TEST_SUITE_P( struct TryRoundCornerTestParams { + std::string name; ShapeElement element_prev; ShapeElement element_next; LengthDbl radius; @@ -114,15 +124,20 @@ struct TryRoundCornerTestParams std::vector expected_elements; }; +void PrintTo(const TryRoundCornerTestParams& params, std::ostream* os) +{ + *os << "element_prev " << params.element_prev.to_string() << "\n"; + *os << "element_next " << params.element_next.to_string() << "\n"; + *os << "radius " << params.radius << "\n"; +} + class TryRoundCornerTest: public testing::TestWithParam { }; TEST_P(TryRoundCornerTest, TryRoundCorner) { TryRoundCornerTestParams test_params = GetParam(); - std::cout << "element_prev " << test_params.element_prev.to_string() << std::endl; - std::cout << "element_next " << test_params.element_next.to_string() << std::endl; - std::cout << "radius " << test_params.radius << std::endl; + PrintTo(test_params, &std::cout); RoundCornerOutput output = try_round_corner( test_params.element_prev, @@ -150,6 +165,7 @@ TEST_P(TryRoundCornerTest, TryRoundCorner) struct TrySmoothArcToLineTestParams { + std::string name; ShapeElement element_prev; ShapeElement element_next; bool expected_feasible; @@ -158,14 +174,19 @@ struct TrySmoothArcToLineTestParams ShapeElement expected_new_element_next; }; +void PrintTo(const TrySmoothArcToLineTestParams& params, std::ostream* os) +{ + *os << "element_prev " << params.element_prev.to_string() << "\n"; + *os << "element_next " << params.element_next.to_string() << "\n"; +} + class TrySmoothArcToLineTest: public testing::TestWithParam { }; TEST_P(TrySmoothArcToLineTest, TrySmoothArcToLine) { TrySmoothArcToLineTestParams test_params = GetParam(); - std::cout << "element_prev " << test_params.element_prev.to_string() << std::endl; - std::cout << "element_next " << test_params.element_next.to_string() << std::endl; + PrintTo(test_params, &std::cout); SmoothArcToLineOutput output = try_smooth_arc_to_line( test_params.element_prev, @@ -189,67 +210,59 @@ INSTANTIATE_TEST_SUITE_P( TrySmoothArcToLineTest, testing::ValuesIn(std::vector{ { // CCW arc + line, feasible. - // Arc from (1,0) to (0,1), center (0,0), r=1 (quarter circle in Q1). - // Line from (0,1) to (0,2), so element_next.end = (0,2). - // alpha = acos(1/2) = 60°. - // tangent_point = center + r * rotate((0,1), -60°) = (sin60°, cos60°) = (√3/2, 0.5). + "CCWArcLineFeasible", build_circular_arc({1, 0}, {0, 1}, {0, 0}, ShapeElementOrientation::Anticlockwise), build_line_segment({0, 1}, {0, 2}), true, build_circular_arc({1, 0}, {sqrt(3.0) / 2, 0.5}, {0, 0}, ShapeElementOrientation::Anticlockwise), build_line_segment({sqrt(3.0) / 2, 0.5}, {0, 2}), }, { // CW arc + line, feasible. - // Arc from (0,1) to (1,0), center (0,0), r=1 (quarter circle CW in Q1). - // Line from (1,0) to (2,0), so element_next.end = (2,0). - // alpha = acos(1/2) = 60°. - // tangent_point = center + r * rotate((1,0), +60°) = (cos60°, sin60°) = (0.5, √3/2). + "CWArcLineFeasible", build_circular_arc({0, 1}, {1, 0}, {0, 0}, ShapeElementOrientation::Clockwise), build_line_segment({1, 0}, {2, 0}), true, build_circular_arc({0, 1}, {0.5, sqrt(3.0) / 2}, {0, 0}, ShapeElementOrientation::Clockwise), build_line_segment({0.5, sqrt(3.0) / 2}, {2, 0}), }, { // Line + CCW arc, feasible. - // Line from (0,2) to (0,1); CCW arc from (0,1) to (-1,0), center (0,0). - // external_point = element_prev.start = (0,2); alpha = acos(1/2) = 60°. - // tangent_point = center + r * rotate((0,1), +60°) = (-√3/2, 0.5). + "LineCCWArcFeasible", build_line_segment({0, 2}, {0, 1}), build_circular_arc({0, 1}, {-1, 0}, {0, 0}, ShapeElementOrientation::Anticlockwise), true, build_line_segment({0, 2}, {-sqrt(3.0) / 2, 0.5}), build_circular_arc({-sqrt(3.0) / 2, 0.5}, {-1, 0}, {0, 0}, ShapeElementOrientation::Anticlockwise), }, { // Line + CW arc, feasible. - // Line from (-1,√3) to (0,1); CW arc from (0,1) to (1,0), center (0,0). - // external_point = element_prev.start = (-1,√3); distance = 2; alpha = 60°. - // tangent_point = center + r * rotate((-1/2, √3/2), -60°) = (1/2, √3/2). + "LineCWArcFeasible", build_line_segment({-1, sqrt(3.0)}, {0, 1}), build_circular_arc({0, 1}, {1, 0}, {0, 0}, ShapeElementOrientation::Clockwise), true, build_line_segment({-1, sqrt(3.0)}, {0.5, sqrt(3.0) / 2}), build_circular_arc({0.5, sqrt(3.0) / 2}, {1, 0}, {0, 0}, ShapeElementOrientation::Clockwise), }, { // Infeasible: neither (arc, line) nor (line, arc). + "LineLineInfeasible", build_line_segment({0, 0}, {1, 0}), build_line_segment({1, 0}, {1, 2}), false, build_line_segment({0, 0}, {0, 0}), build_line_segment({0, 0}, {0, 0}), }, { // Infeasible: element_next.end is inside the circle. - // Arc from (1,0) to (0,1), center (0,0), r=1. - // Line endpoint (0, 0.5) is at distance 0.5 < 1 from center. + "EndInsideCircle", build_circular_arc({1, 0}, {0, 1}, {0, 0}, ShapeElementOrientation::Anticlockwise), build_line_segment({0, 1}, {0, 0.5}), false, build_line_segment({0, 0}, {0, 0}), build_line_segment({0, 0}, {0, 0}), - }, { // Infeasible: tangent_point lies on arc.end (not strictly interior). - // Arc from (1,0) to (√3/2, 0.5), center (0,0), r=1 [0° to 30°]. - // Line endpoint (0,2): the computed tangent_point would be (√3/2, 0.5) = arc.end. + }, { // Infeasible: tangent point lies on arc.end. + "TangentPointOnArcEnd", build_circular_arc({1, 0}, {sqrt(3.0) / 2, 0.5}, {0, 0}, ShapeElementOrientation::Anticlockwise), build_line_segment({sqrt(3.0) / 2, 0.5}, {0, 2}), false, build_line_segment({0, 0}, {0, 0}), build_line_segment({0, 0}, {0, 0}), }, - })); + }), + [](const testing::TestParamInfo& info) { + return info.param.name; + }); INSTANTIATE_TEST_SUITE_P( @@ -259,6 +272,7 @@ INSTANTIATE_TEST_SUITE_P( { // 90° CCW (left) turn: horizontal then up, r=1. // tangent_length = r*tan(45°) = 1. // T1=(1,0), T2=(2,1), center=(1,1), arc CCW. + "CCWTurn90", build_line_segment({0, 0}, {2, 0}), build_line_segment({2, 0}, {2, 2}), 1.0, @@ -271,6 +285,7 @@ INSTANTIATE_TEST_SUITE_P( }, { // 90° CW (right) turn: horizontal then down, r=1. // tangent_length = r*tan(45°) = 1. // T1=(1,0), T2=(2,-1), center=(1,-1), arc CW. + "CWTurn90", build_line_segment({0, 0}, {2, 0}), build_line_segment({2, 0}, {2, -2}), 1.0, @@ -283,6 +298,7 @@ INSTANTIATE_TEST_SUITE_P( }, { // 90° CCW turn with tangent point at segment start: prev segment // is exactly r long, so the trimmed prev has zero length and is // omitted. T1=(0,0)=element_prev.start, T2=(1,1). + "CCWTurnTangentAtStart", build_line_segment({0, 0}, {1, 0}), build_line_segment({1, 0}, {1, 2}), 1.0, @@ -292,22 +308,28 @@ INSTANTIATE_TEST_SUITE_P( build_line_segment({1, 1}, {1, 2}), }, }, { // Infeasible: element_prev is a circular arc, not a line segment. + "InfeasibleArcPrev", build_circular_arc({1, 0}, {0, 1}, {0, 0}, ShapeElementOrientation::Anticlockwise), build_line_segment({0, 1}, {0, 3}), 1.0, false, {}, }, { // Infeasible: collinear segments, no corner to round. + "InfeasibleCollinear", build_line_segment({0, 0}, {1, 0}), build_line_segment({1, 0}, {3, 0}), 1.0, false, {}, }, { // Infeasible: radius too large (tangent_length = 2 > len_prev = 0.5). + "InfeasibleRadiusTooLarge", build_line_segment({0, 0}, {0.5, 0}), build_line_segment({0.5, 0}, {0.5, 2}), 2.0, false, {}, }, - })); + }), + [](const testing::TestParamInfo& info) { + return info.param.name; + }); diff --git a/test/supports_test.cpp b/test/supports_test.cpp index bea920e..e158560 100644 --- a/test/supports_test.cpp +++ b/test/supports_test.cpp @@ -9,41 +9,47 @@ struct ComputeShapeSupportsTestParams ShapeWithHoles shape; std::vector expected_supporting_parts; std::vector expected_supported_parts; + std::string name; }; -class IrregularComputeShapeSupportsTest: public testing::TestWithParam { }; - -TEST_P(IrregularComputeShapeSupportsTest, ComputeShapeSupports) +void PrintTo(const ComputeShapeSupportsTestParams& params, std::ostream* os) { - ComputeShapeSupportsTestParams test_params = GetParam(); - std::cout << "shape:" << std::endl; - std::cout << "- " << test_params.shape.to_string(0) << std::endl; - std::cout << "expected_supporting_parts:" << std::endl; - for (const auto& support: test_params.expected_supporting_parts) { + *os << "shape:\n"; + *os << "- " << params.shape.to_string(0) << "\n"; + *os << "expected_supporting_parts:\n"; + for (const auto& support: params.expected_supporting_parts) { for (ElementPos element_pos = 0; element_pos < (ElementPos)support.elements.size(); ++element_pos) { const ShapeElement& element = support.elements[element_pos]; if (element_pos == 0) { - std::cout << "- " << element.to_string() << std::endl; + *os << "- " << element.to_string() << "\n"; } else { - std::cout << " " << element.to_string() << std::endl; + *os << " " << element.to_string() << "\n"; } } } - std::cout << "expected_supported_parts:" << std::endl; - for (const auto& support: test_params.expected_supported_parts) { + *os << "expected_supported_parts:\n"; + for (const auto& support: params.expected_supported_parts) { for (ElementPos element_pos = 0; element_pos < (ElementPos)support.elements.size(); ++element_pos) { const ShapeElement& element = support.elements[element_pos]; if (element_pos == 0) { - std::cout << "- " << element.to_string() << std::endl; + *os << "- " << element.to_string() << "\n"; } else { - std::cout << " " << element.to_string() << std::endl; + *os << " " << element.to_string() << "\n"; } } } +} + +class IrregularComputeShapeSupportsTest: public testing::TestWithParam { }; + +TEST_P(IrregularComputeShapeSupportsTest, ComputeShapeSupports) +{ + ComputeShapeSupportsTestParams test_params = GetParam(); + PrintTo(test_params, &std::cout); ShapeSupports supports = compute_shape_supports(test_params.shape); std::cout << "supporting_parts:" << std::endl; @@ -109,10 +115,12 @@ INSTANTIATE_TEST_SUITE_P( {build_shape({{0, 0}, {1, 0}, {1, 1}, {0, 1}}), {}}, {build_shape({{0, 1}, {1, 1}}, true)}, {build_shape({{1, 0}, {0, 0}}, true)}, + "Square", }, { {build_shape({{0, 0}, {1, 0}, {2, 1}, {1, 1}}), {}}, {build_shape({{0, 0}, {1, 1}, {2, 1}}, true)}, {build_shape({{2, 1}, {1, 0}, {0, 0}}, true)}, + "Parallelogram", }, { {build_shape({{0, 0}, {7, 0}, {6, 2}, {5, 2}, {4, 1}, {3, 1}, {2, 2}, {1, 2}}), {}}, { @@ -121,6 +129,7 @@ INSTANTIATE_TEST_SUITE_P( build_shape({{0, 0}, {1, 2}, {2, 2}, {3, 1}}, true), }, {build_shape({{7, 0}, {0, 0}}, true)}, + "MShape", }, { {build_shape({{0, 0}, {2, 0}, {2, 1}, {1, 1}, {1, 2}, {2, 2}, {2, 3}, {0, 3}}), {}}, { @@ -130,6 +139,7 @@ INSTANTIATE_TEST_SUITE_P( build_shape({{2, 0}, {0, 0}}, true), build_shape({{2, 2}, {1, 2}}, true), }, + "UShape", }, { { build_shape({{0, 0}, {3, 0}, {3, 3}, {0, 3}}), @@ -141,6 +151,7 @@ INSTANTIATE_TEST_SUITE_P( build_shape({{3, 0}, {0, 0}}, true), build_shape({{2, 2}, {1, 2}}, true), }, + "SquareWithHole", }, { {build_shape({{15, 0}, {30, 10}, {0, 10}}), {}}, { @@ -148,6 +159,7 @@ INSTANTIATE_TEST_SUITE_P( }, { build_shape({{30, 10}, {15, 0}, {0, 10}}, true), }, + "Triangle", }, { { build_shape({{-10, -10}, {50, -10}, {50, 50}, {-10, 50}}), @@ -159,4 +171,8 @@ INSTANTIATE_TEST_SUITE_P( build_shape({{50, -10}, {-10, -10}}, true), build_shape({{40, 40}, {10, 40}, {0, 0}}, true), }, - }})); + "SquareWithTiltedHole", + }}), + [](const testing::TestParamInfo& info) { + return info.param.name; + }); diff --git a/test/trapezoidation_test.cpp b/test/trapezoidation_test.cpp index 4d8c566..d399711 100644 --- a/test/trapezoidation_test.cpp +++ b/test/trapezoidation_test.cpp @@ -10,6 +10,7 @@ struct TrapezoidationTestParams { ShapeWithHoles shape; std::vector expected_output; + std::string name; template static TrapezoidationTestParams from_json( @@ -38,15 +39,20 @@ struct TrapezoidationTestParams } }; +void PrintTo(const TrapezoidationTestParams& params, std::ostream* os) +{ + *os << "shape " << params.shape.to_string(0) << "\n"; + *os << "expected_output\n"; + for (const GeneralizedTrapezoid& trapezoid: params.expected_output) + *os << "- " << trapezoid << "\n"; +} + class TrapezoidationTest: public testing::TestWithParam { }; TEST_P(TrapezoidationTest, Trapezoidation) { TrapezoidationTestParams test_params = GetParam(); - std::cout << "shape " << test_params.shape.to_string(0) << std::endl; - std::cout << "expected_output" << std::endl; - for (const GeneralizedTrapezoid& trapezoid: test_params.expected_output) - std::cout << "- " << trapezoid << std::endl; + PrintTo(test_params, &std::cout); std::vector output = trapezoidation( test_params.shape); @@ -67,42 +73,51 @@ INSTANTIATE_TEST_SUITE_P( { // Triangle1 {build_shape({{0, 0}, {3, 0}, {1, 3}})}, {GeneralizedTrapezoid(0, 3, 0, 3, 1, 1)}, + "Triangle1", }, { // Triangle2 {build_shape({{2, 0}, {3, 3}, {0, 3}})}, {GeneralizedTrapezoid(0, 3, 2, 2, 0, 3)}, + "Triangle2", }, { // Square {build_shape({{0, 0}, {1, 0}, {1, 1}, {0, 1}})}, {GeneralizedTrapezoid(0, 1, 0, 1, 0, 1)}, + "Square", }, { // Trapezoid1 {build_shape({{0, 0}, {3, 0}, {2, 3}, {1, 3}})}, {GeneralizedTrapezoid(0, 3, 0, 3, 1, 2)}, + "Trapezoid1", }, { // Trapezoid2 {build_shape({{1, 0}, {2, 0}, {3, 3}, {0, 3}})}, {GeneralizedTrapezoid(0, 3, 1, 2, 0, 3)}, + "Trapezoid2", }, { // Triangle3 {build_shape({{4, 0}, {1, 3}, {0, 1}})}, { GeneralizedTrapezoid(1, 3, 0, 3, 1, 1), GeneralizedTrapezoid(0, 1, 4, 4, 0, 3), }, + "Triangle3", }, { // Trapezoid3 {build_shape({{5, 0}, {2, 3}, {1, 3}, {0, 1}})}, { GeneralizedTrapezoid(1, 3, 0, 4, 1, 2), GeneralizedTrapezoid(0, 1, 5, 5, 0, 4), }, + "Trapezoid3", }, { // DoubleTrapezoid1 {build_shape({{0, 0}, {4, 0}, {2, 2}, {4, 4}, {0, 4}, {1, 2}})}, { GeneralizedTrapezoid(2, 4, 1, 2, 0, 4), GeneralizedTrapezoid(0, 2, 0, 4, 1, 2), }, + "DoubleTrapezoid1", }, { // DoubleTrapezoid2 {build_shape({{1, 0}, {2, 0}, {4, 2}, {2, 4}, {1, 4}, {0, 2}})}, { GeneralizedTrapezoid(2, 4, 0, 4, 1, 2), GeneralizedTrapezoid(0, 2, 1, 2, 0, 4), }, + "DoubleTrapezoid2", }, { // ReversedH {build_shape({ {0, 0}, {3, 0}, {3, 1}, {2, 1}, {2, 2}, {3, 2}, @@ -112,6 +127,7 @@ INSTANTIATE_TEST_SUITE_P( GeneralizedTrapezoid(1, 2, 1, 2, 1, 2), GeneralizedTrapezoid(0, 1, 0, 3, 0, 3), }, + "ReversedH", }, { // Cross {build_shape({ {1, 0}, {2, 0}, {2, 1}, {3, 1}, {3, 2}, {2, 2}, @@ -121,6 +137,7 @@ INSTANTIATE_TEST_SUITE_P( GeneralizedTrapezoid(1, 2, 0, 3, 0, 3), GeneralizedTrapezoid(0, 1, 1, 2, 1, 2), }, + "Cross", }, { // U {build_shape({ {0, 0}, {3, 0}, {3, 3}, {2, 3}, @@ -130,6 +147,7 @@ INSTANTIATE_TEST_SUITE_P( GeneralizedTrapezoid(1, 3, 2, 3, 2, 3), GeneralizedTrapezoid(0, 1, 0, 3, 0, 3), }, + "U", }, { // W {build_shape({ {0, 0}, {5, 0}, {5, 3}, {4, 3}, @@ -141,6 +159,7 @@ INSTANTIATE_TEST_SUITE_P( GeneralizedTrapezoid(1, 2, 2, 3, 2, 3), GeneralizedTrapezoid(0, 1, 0, 5, 0, 5), }, + "W", }, { // Shape1 {build_shape({ {185.355, 114.645}, @@ -157,6 +176,7 @@ INSTANTIATE_TEST_SUITE_P( GeneralizedTrapezoid(79.289, 114.645, 150, 220.711, 185.355, 185.355), GeneralizedTrapezoid(0, 79.289, 0, 300, 0, 220.711), }, + "Shape1", }, { // SquareRing { build_shape({{0, 0}, {3, 0}, {3, 3}, {0, 3}}), @@ -167,6 +187,7 @@ INSTANTIATE_TEST_SUITE_P( GeneralizedTrapezoid(1, 2, 2, 3, 2, 3), GeneralizedTrapezoid(0, 1, 0, 3, 0, 3), }, + "SquareRing", }, { // DiamondHole { build_shape({{1, 0}, {3, 0}, {4, 1}, {4, 3}, {3, 4}, {1, 4}, {0, 3}, {0, 1}}), @@ -179,6 +200,7 @@ INSTANTIATE_TEST_SUITE_P( GeneralizedTrapezoid(1, 2, 2, 4, 3, 4), GeneralizedTrapezoid(0, 1, 1, 3, 0, 4), }, + "DiamondHole", }, { // ButterflyHole { build_shape({{1, 0}, {3, 0}, {4, 1}, {4, 3}, {3, 4}, {1, 4}, {0, 3}, {0, 1}}), @@ -191,6 +213,7 @@ INSTANTIATE_TEST_SUITE_P( GeneralizedTrapezoid(1, 3, 3, 4, 3, 4), GeneralizedTrapezoid(0, 1, 1, 3, 0, 4), }, + "ButterflyHole", }, { { build_shape({ @@ -201,6 +224,7 @@ INSTANTIATE_TEST_SUITE_P( GeneralizedTrapezoid(1, 2, 4, 5, 3, 5), GeneralizedTrapezoid(0, 1, 0, 5, 0, 5), }, + "18", }, { // Touching hole top flat { build_shape({{0, 0}, {12, 0}, {12, 12}, {0, 12}}), @@ -210,6 +234,7 @@ INSTANTIATE_TEST_SUITE_P( GeneralizedTrapezoid(6, 12, 9, 12, 6, 12), GeneralizedTrapezoid(0, 6, 0, 12, 0, 12), }, + "TouchingHoleTopFlat", }, { // Touching hole top increasing { build_shape({{0, 0}, {12, 0}, {12, 13}, {0, 11}}), @@ -221,6 +246,7 @@ INSTANTIATE_TEST_SUITE_P( GeneralizedTrapezoid(9, 12, 9, 12, 6, 12), GeneralizedTrapezoid(0, 9, 0, 12, 0, 12), }, + "TouchingHoleTopIncreasing", }, { // Touching hole top decreasing { build_shape({{0, 0}, {12, 0}, {12, 11}, {0, 13}}), @@ -232,6 +258,7 @@ INSTANTIATE_TEST_SUITE_P( GeneralizedTrapezoid(9, 12, 0, 3, 0, 6), GeneralizedTrapezoid(0, 9, 0, 12, 0, 12), }, + "TouchingHoleTopDecreasing", }, { // Touching hole bottom flat { build_shape({{0, 0}, {12, 0}, {12, 12}, {0, 12}}), @@ -241,6 +268,7 @@ INSTANTIATE_TEST_SUITE_P( GeneralizedTrapezoid(0, 3, 0, 6, 0, 3), GeneralizedTrapezoid(0, 3, 6, 12, 9, 12), }, + "TouchingHoleBottomFlat", }, { // Touching hole bottom increasing { build_shape({{0, -1}, {12, 1}, {12, 12}, {0, 12}}), @@ -252,6 +280,7 @@ INSTANTIATE_TEST_SUITE_P( GeneralizedTrapezoid(-1, 0, 0, 0, 0, 6), GeneralizedTrapezoid(0, 1, 6, 6, 7, 12), }, + "TouchingHoleBottomIncreasing", }, { // Touching hole bottom decreasing { build_shape({{0, 1}, {12, -1}, {12, 12}, {0, 12}}), @@ -263,6 +292,7 @@ INSTANTIATE_TEST_SUITE_P( GeneralizedTrapezoid(0, 3, 6, 12, 9, 12), GeneralizedTrapezoid(-1, 0, 12, 12, 6, 12), }, + "TouchingHoleBottomDecreasing", }, { // Touching hole left flat { build_shape({{0, 0}, {12, 0}, {12, 12}, {0, 12}}), @@ -274,6 +304,7 @@ INSTANTIATE_TEST_SUITE_P( GeneralizedTrapezoid(3, 6, 0, 3, 0, 0), GeneralizedTrapezoid(0, 3, 0, 12, 0, 12), }, + "TouchingHoleLeftFlat", }, { // Touching hole left increasing { build_shape({{-1, 0}, {12, 0}, {12, 12}, {1, 12}}), @@ -285,6 +316,7 @@ INSTANTIATE_TEST_SUITE_P( GeneralizedTrapezoid(3, 9, 3, 12, 3, 12), GeneralizedTrapezoid(0, 3, -1, 12, -0.5, 12), }, + "TouchingHoleLeftIncreasing", }, { // Touching hole left decreasing { build_shape({{1, 0}, {12, 0}, {12, 12}, {-1, 12}}), @@ -296,6 +328,7 @@ INSTANTIATE_TEST_SUITE_P( GeneralizedTrapezoid(3, 9, 3, 12, 3, 12), GeneralizedTrapezoid(0, 3, 1, 12, 0.5, 12), }, + "TouchingHoleLeftDecreasing", }, { // Touching hole right flat { build_shape({{0, 0}, {12, 0}, {12, 12}, {0, 12}}), @@ -307,6 +340,7 @@ INSTANTIATE_TEST_SUITE_P( GeneralizedTrapezoid(3, 6, 9, 12, 12, 12), GeneralizedTrapezoid(0, 3, 0, 12, 0, 12), }, + "TouchingHoleRightFlat", }, { // Touching hole right increasing { build_shape({{0, 0}, {11, 0}, {13, 12}, {0, 12}}), @@ -318,6 +352,7 @@ INSTANTIATE_TEST_SUITE_P( GeneralizedTrapezoid(3, 6, 9, 11.5, 12, 12), GeneralizedTrapezoid(0, 3, 0, 11, 0, 11.5), }, + "TouchingHoleRightIncreasing", }, { // Touching hole right decreasing { build_shape({{0, 0}, {13, 0}, {11, 12}, {0, 12}}), @@ -329,5 +364,9 @@ INSTANTIATE_TEST_SUITE_P( GeneralizedTrapezoid(3, 6, 9, 12.5, 12, 12), GeneralizedTrapezoid(0, 3, 0, 13, 0, 12.5), }, + "TouchingHoleRightDecreasing", }, - })); + }), + [](const testing::TestParamInfo& info) { + return info.param.name; + });