Slic3r/src/test/GUI/test_cli.cpp
supermerill 96b0865d87 bugfix: gcodewriter.unlift(), medial axis taper & min width
tests: thin.t almost complete, bugfix test_data typo.
2019-04-09 18:57:31 +02:00

291 lines
12 KiB
C++

#define CATCH_CONFIG_DISABLE
#include <catch.hpp>
#include <fstream>
#include <cstdio>
#include "../test_data.hpp"
#include "../../slic3r.hpp"
#include "../../libslic3r/GCodeReader.hpp"
using namespace Slic3r;
using namespace Slic3r::Test;
using namespace std::string_literals;
bool file_exists(const std::string& name, const std::string& ext) {
std::string filename {""};
filename.append(name);
filename.append(".");
filename.append(ext);
std::ifstream f{ testfile(filename) };
bool result {f.good()};
f.close();
return result;
}
char** to_cstr_array(std::vector<std::string> in, char** argv) {
int i = 0;
for (auto& str : in) {
argv[i] = new char[str.size()];
strcpy(argv[i], str.c_str());
i++;
}
return argv;
}
void clean_array(size_t argc, char** argv) {
//for (size_t i = 0; i < argc; ++i) {
// delete[] argv[i];
//}
}
SCENARIO( "CLI Export Arguments", "[!mayfail]") {
char* args_cli[20];
std::vector<std::string> in_args{};
in_args.reserve(20);
in_args.emplace_back("gui_test"s);
in_args.emplace_back(testfile("test_cli/20mmbox.stl"s));
GIVEN( "Default configuration and a simple 3D model" ) {
WHEN ( "[ ACTION ] is export-gcode with long option") {
in_args.emplace(in_args.cend()-1, "--export-gcode");
CLI().run(in_args.size(), to_cstr_array(in_args, args_cli));
THEN ("GCode file is created.") {
REQUIRE(file_exists("test_cli/20mmbox"s, "gcode"s));
}
clean_array(in_args.size(), args_cli);
clean_file("test_cli/20mmbox", "gcode");
}
WHEN ( "[ ACTION ] is export-gcode with short option") {
in_args.emplace(in_args.cend()-1, "-g");
CLI().run(in_args.size(), to_cstr_array(in_args, args_cli));
THEN ("GCode file is created.") {
REQUIRE(file_exists("test_cli/20mmbox"s, "gcode"s));
}
clean_array(in_args.size(), args_cli);
clean_file("test_cli/20mmbox", "gcode");
}
// doesn't work anymore
//WHEN ( "[ ACTION ] is export-obj") {
// in_args.emplace(in_args.cend()-1, "--export-obj");
// CLI().run(in_args.size(), to_cstr_array(in_args, args_cli));
// THEN ("OBJ file is created.") {
// REQUIRE(file_exists("test_cli/20mmbox"s, "obj"s));
// }
// clean_array(in_args.size(), args_cli);
// clean_file("test_cli/20mmbox", "obj");
//}
//doesn't work
//WHEN ( "[ ACTION ] is export-pov") {
// in_args.emplace(in_args.cend()-1, "--export-pov");
// CLI().run(in_args.size(), to_cstr_array(in_args, args_cli));
// THEN ("POV file is created.") {
// REQUIRE(file_exists("test_cli/20mmbox", "pov"));
// }
// clean_array(in_args.size(), args_cli);
// clean_file("test_cli/20mmbox", "pov");
//}
WHEN ( "[ ACTION ] is export-amf") {
in_args.emplace(in_args.cend()-1, "--export-amf");
CLI().run(in_args.size(), to_cstr_array(in_args, args_cli));
THEN ("Compressed AMF file is created.") {
REQUIRE(file_exists("test_cli/20mmbox.zip", "amf"));
}
clean_array(in_args.size(), args_cli);
clean_file("test_cli/20mmbox.zip", "amf");
}
WHEN ( "[ ACTION ] is export-3mf") {
in_args.emplace(in_args.cend()-1, "--export-3mf");
CLI().run(in_args.size(), to_cstr_array(in_args, args_cli));
THEN ("3MF file is created.") {
REQUIRE(file_exists("test_cli/20mmbox", "3mf"));
}
clean_array(in_args.size(), args_cli);
clean_file("test_cli/20mmbox", "3mf");
}
// now export-sla
//WHEN ( "[ ACTION ] is export-svg") {
// in_args.emplace(in_args.cend()-1, "--export-svg");
// CLI().run(in_args.size(), to_cstr_array(in_args, args_cli));
// THEN ("SVG files are created.") {
// REQUIRE(file_exists("test_cli/20mmbox_0", "svg"));
// REQUIRE(file_exists("test_cli/20mmbox_1", "svg"));
// REQUIRE(file_exists("test_cli/20mmbox_2", "svg"));
// REQUIRE(file_exists("test_cli/20mmbox_3", "svg"));
// REQUIRE(file_exists("test_cli/20mmbox_4", "svg"));
// }
// clean_file("test_cli/20mmbox_0", "svg", true);
// clean_file("test_cli/20mmbox_1", "svg", true);
// clean_file("test_cli/20mmbox_2", "svg", true);
// clean_file("test_cli/20mmbox_3", "svg", true);
// clean_file("test_cli/20mmbox_4", "svg", true);
// clean_array(in_args.size(), args_cli);
//}
//WHEN ( "[ ACTION ] is export-sla-svg") {
// in_args.emplace(in_args.cend()-1, "--export-sla-svg");
// CLI().run(in_args.size(), to_cstr_array(in_args, args_cli));
// THEN ("SVG files are created.") {
// REQUIRE(file_exists("test_cli/20mmbox", "svg"));
// }
// clean_array(in_args.size(), args_cli);
// clean_file("test_cli/20mmbox", "svg", true);
//}
//WHEN("[ ACTION ] is sla") {
// in_args.emplace(in_args.cend() - 1, "--sla");
// CLI().run(in_args.size(), to_cstr_array(in_args, args_cli));
// THEN("SVG file is created.") {
// REQUIRE(file_exists("test_cli/20mmbox", "svg"));
// }
// clean_array(in_args.size(), args_cli);
// clean_file("test_cli/20mmbox", "svg", true);
//}
//WHEN("[ ACTION ] is sla for sl1") {
// in_args.emplace(in_args.cend() - 1, "--sla");
// CLI().run(in_args.size(), to_cstr_array(in_args, args_cli));
// THEN("SVG file is created.") {
// REQUIRE(file_exists("test_cli/20mmbox", "sl1"));
// }
// clean_array(in_args.size(), args_cli);
// clean_file("test_cli/20mmbox", "sl1", true);
//}
//WHEN ( "[ ACTION ] is sla and --output is output.svg") {
// in_args.emplace(in_args.cend()-1, "--sla");
// in_args.emplace(in_args.cend()-1, "--output");
// in_args.emplace(in_args.cend()-1, testfile("output.svg"));
// CLI().run(in_args.size(), to_cstr_array(in_args, args_cli));
// THEN ("SVG files are created.") {
// REQUIRE(file_exists("output", "svg"));
// }
// clean_array(in_args.size(), args_cli);
// clean_file("output", "svg", true);
//}
WHEN ( "[ ACTION ] is save") {
in_args.emplace(in_args.cend()-1, "--save");
in_args.emplace(in_args.cend()-1, testfile("cfg.ini"));
CLI().run(in_args.size(), to_cstr_array(in_args, args_cli));
THEN ("Configuration file is created.") {
REQUIRE(file_exists("cfg", "ini"));
}
clean_array(in_args.size(), args_cli);
clean_file("cfg", "ini");
}
WHEN ( "[ ACTION ] is export-stl and --output option is specified") {
in_args.emplace(in_args.cend()-1, "--export-stl");
in_args.emplace(in_args.cend()-1, "--output");
in_args.emplace(in_args.cend()-1, testfile("output.stl"));
CLI().run(in_args.size(), to_cstr_array(in_args, args_cli));
THEN ("STL file is created.") {
REQUIRE(file_exists("output", "stl"));
}
clean_array(in_args.size(), args_cli);
clean_file("output", "stl");
}
}
}
// ??
//SCENARIO("CLI Transform arguments", "[!shouldfail]") {
// char* args_cli[20];
// std::vector<std::string> in_args;
// in_args.reserve(20);
// in_args.emplace_back("gui_test"s);
// in_args.emplace_back(testfile("test_cli/20mmbox.stl"s));
// WHEN("Tests are implemented for CLI model transform") {
// THEN ("Tests should not fail :D") {
// REQUIRE(false);
// }
// }
//}
// Test the --center and --dont-arrange parameters.
SCENARIO("CLI positioning arguments") {
char* args_cli[20];
std::vector<std::string> in_args{};
in_args.reserve(20);
in_args.emplace_back("gui_test"s);
GIVEN( " 3D Model for a 20mm box, centered around 0,0 and gcode export" ) {
in_args.emplace_back(testfile("test_cli/20mmbox.stl"s));
in_args.emplace(in_args.cend()-1, "-g");
in_args.emplace(in_args.cend()-1, "--load"s);
in_args.emplace(in_args.cend()-1, testfile("test_cli/20mmbox_config.ini"));
CLI cut{};
WHEN("--center is supplied with 40,40") {
in_args.emplace(in_args.cend()-1, "--center");
in_args.emplace(in_args.cend()-1, "40,40");
cut.run(in_args.size(), to_cstr_array(in_args, args_cli));
THEN ("The first layer of the print should be centered around 0,0") {
std::string exported { read_to_string("test_cli/20mmbox.gcode"s)};
GCodeReader reader;
REQUIRE(exported != ""s);
double min_x = 50.0, max_x = -50.0, min_y = 50.0, max_y = -50.0;
reader.apply_config(cut.full_print_config());
reader.parse_buffer(exported, [&min_x, &min_y, &max_x, &max_y] (GCodeReader& self, const GCodeReader::GCodeLine& line)
{
if (self.x() != 0.0 && self.y() != 0.0) { // avoid the first pass
if (self.z() <= 0.6 && self.z() > 0.3) {
min_x = std::min(min_x, static_cast<double>(self.x()));
min_y = std::min(min_y, static_cast<double>(self.y()));
max_x = std::max(max_x, static_cast<double>(self.x()));
max_y = std::max(max_y, static_cast<double>(self.y()));
}
}
});
AND_THEN("Minimum X encountered is about 30.1") {
REQUIRE(min_x == Approx(30.1));
}
AND_THEN("Minimum Y encountered is about 30.1") {
REQUIRE(min_y == Approx(30.1));
}
AND_THEN("Maximum X encountered is about 49.9") {
REQUIRE(max_x == Approx(49.9));
}
AND_THEN("Maximum Y encountered is about 49.9") {
REQUIRE(max_y == Approx(49.9));
}
}
}
WHEN("--dont-arrange is supplied") {
in_args.emplace(in_args.cend()-1, "--dont-arrange");
cut.run(in_args.size(), to_cstr_array(in_args, args_cli));
THEN ("The first layer of the print should be centered around 0,0") {
auto reader {GCodeReader()};
std::string exported { read_to_string("test_cli/20mmbox.gcode"s)};
REQUIRE(exported != ""s);
double min_x = 50.0, max_x = -50.0, min_y = 50.0, max_y = -50.0;
reader.apply_config(cut.full_print_config());
reader.parse_buffer(exported, [&min_x, &min_y, &max_x, &max_y] (GCodeReader& self, const GCodeReader::GCodeLine& line)
{
if (self.z() < 0.6) {
min_x = std::min(min_x, static_cast<double>(self.x()));
min_y = std::min(min_y, static_cast<double>(self.y()));
max_x = std::max(max_x, static_cast<double>(self.x()));
max_y = std::max(max_y, static_cast<double>(self.y()));
}
});
AND_THEN("Minimum X encountered is about -9.9") {
REQUIRE(min_x == Approx(-9.9));
}
AND_THEN("Minimum Y encountered is about -9.9") {
REQUIRE(min_y == Approx(-9.9));
}
AND_THEN("Maximum X encountered is about 9.9") {
REQUIRE(max_x == Approx(9.9));
}
AND_THEN("Maximum Y encountered is about 9.9") {
REQUIRE(max_y == Approx(9.9));
}
}
}
clean_array(in_args.size(), args_cli);
clean_file("test_cli/20mmbox", "gcode");
}
}