diff options
-rw-r--r-- | Builder.cpp | 2 | ||||
-rw-r--r-- | Makefile | 25 | ||||
-rw-r--r-- | file.cpp | 2 | ||||
-rw-r--r-- | test-ymake.cpp | 151 |
4 files changed, 176 insertions, 4 deletions
diff --git a/Builder.cpp b/Builder.cpp index cbe6466..c59aec8 100644 --- a/Builder.cpp +++ b/Builder.cpp @@ -231,7 +231,7 @@ void Builder::build_file(const fs::path& p) { for (auto &i: objects) { command += fmt::format(" {}", i.string()); } - command += " -lfmt -lreichwein"; + command += " -lreichwein -lfmt"; command += fmt::format(" -o {}", p.string()); } @@ -7,10 +7,19 @@ YSCAN=yscan YSCAN_SRC=yscan-main.cpp yscan.cpp file.cpp YSCAN_OBJ=$(YSCAN_SRC:.cpp=.o) +TEST=test-ymake +TEST_SRC=test-ymake.cpp +TEST_OBJ=$(TEST_SRC:.cpp=.o) + all: $(PROJECTNAME) $(YSCAN) -LDLIBS += -lfmt -lreichwein -CXXFLAGS += -std=c++17 +LDLIBS += -lreichwein -lfmt +CXXFLAGS += \ + -std=c++17 \ + -I/usr/src/googletest/googletest/include \ + -I/usr/src/googletest/googlemock/include \ + -I/usr/src/googletest/googletest \ + -I/usr/src/googletest/googlemock $(PROJECTNAME): $(OBJ) $(CXX) $(LDFLAGS) $^ $(LDLIBS) $(LIBS) -o $@ @@ -18,9 +27,21 @@ $(PROJECTNAME): $(OBJ) $(YSCAN): $(YSCAN_OBJ) $(CXX) $(LDFLAGS) $^ $(LDLIBS) $(LIBS) -o $@ +$(TEST): libgmock.a $(TEST_OBJ) + $(CXX) $(LDFLAGS) $^ $(LDLIBS) $(LIBS) -o $@ + %.o: %.cpp $(CXX) $(CXXFLAGS) -c $< -o $@ +libgmock.a: + $(CXX) $(CXXFLAGS) -c /usr/src/googletest/googletest/src/gtest-all.cc + $(CXX) $(CXXFLAGS) -c /usr/src/googletest/googlemock/src/gmock-all.cc + $(CXX) $(CXXFLAGS) -c /usr/src/googletest/googlemock/src/gmock_main.cc + ar -rv libgmock.a gmock-all.o gtest-all.o gmock_main.o + +test: $(TEST) + ./$(TEST) + install: mkdir -p $(DESTDIR)/usr/bin cp $(PROJECTNAME) $(DESTDIR)/usr/bin/ @@ -13,7 +13,7 @@ bool is_buildable_by_extension(const fs::path& p) { } namespace { - std::unordered_set<fs::path> compile_unit_source_types{".cpp", ".c"}; + std::unordered_set<fs::path> compile_unit_source_types{".cpp", ".c", ".cc", ".S", ".rs"}; } // type of file is source of compile unit (no included types like headers) diff --git a/test-ymake.cpp b/test-ymake.cpp new file mode 100644 index 0000000..a4d9aa4 --- /dev/null +++ b/test-ymake.cpp @@ -0,0 +1,151 @@ +#include <filesystem> +#include <string> + +#include <boost/process.hpp> + +#include <gtest/gtest.h> + +#include <libreichwein/file.h> +#include <libreichwein/stringhelper.h> + +namespace fs = std::filesystem; +namespace bp = boost::process; + +namespace { + const fs::path testpath{"testdir1"}; +} + +class BuildTest: public ::testing::Test +{ +private: + fs::path original_path; + +protected: + BuildTest() { + } + + ~BuildTest() override { + } + + void SetUp() override { + original_path = fs::current_path(); + + fs::remove_all(testpath); + + fs::create_directory(testpath); + + fs::current_path(testpath); + } + + void TearDown() override { + fs::current_path(original_path); + + fs::remove_all(testpath); + } + +}; + +void create_file(const fs::path& path, const std::string& contents) +{ + Reichwein::File::setFile(path, contents); +} + +int run_command(const std::string& command) +{ + return bp::system(command, bp::std_out > bp::null, bp::std_err > bp::null); +} + +int run_command(const std::string& command, std::vector<std::string>& output) +{ + bp::ipstream is; + bp::ipstream es; + int result = bp::system(command, bp::std_out > is, bp::std_err > es); + std::string output_string(std::istreambuf_iterator<char>(is), {}); + output_string += std::string(std::istreambuf_iterator<char>(es), {}); + output = Reichwein::Stringhelper::split(output_string, "\r\n"); + + return result; +} + +TEST_F(BuildTest, build_one_cpp) +{ + create_file("hello.cpp", R"(int main(int argc, char* argv[]) +{ + return 0; +})"); + + create_file("YMakefile", R"( +<ymake> + <build> + <name>hello</name> + <source>hello.cpp</source> + </build> +</ymake> +)"); + + std::vector<std::string> output; + int result = run_command("../ymake", output); + EXPECT_EQ(result, 0); + + EXPECT_EQ(output.size(), 2); // compile, link +} + +TEST_F(BuildTest, build_one_cpp_compile_error) +{ + create_file("hello.cpp", R"(int main(int argc, char* argv[]) +{ + retrn 0; +})"); + + create_file("YMakefile", R"( +<ymake> + <build> + <name>hello</name> + <source>hello.cpp</source> + </build> +</ymake> +)"); + + int result = run_command("../ymake"); + EXPECT_NE(result, 0); +} + +TEST_F(BuildTest, clean_one_cpp) +{ + create_file("hello.cpp", R"(int main(int argc, char* argv[]) +{ + return 0; +})"); + + create_file("YMakefile", R"( +<ymake> + <build> + <name>hello</name> + <source>hello.cpp</source> + </build> +</ymake> +)"); + + std::vector<std::string> output; + int result = run_command("../ymake clean", output); + EXPECT_EQ(output.size(), 0); + ASSERT_EQ(result, 0); + + result = run_command("../ymake", output); + EXPECT_EQ(output.size(), 2); // compile, link + ASSERT_EQ(result, 0); + + result = run_command("../ymake clean", output); + EXPECT_EQ(output.size(), 3); // rm .o, .d, executable + ASSERT_EQ(result, 0); +} + +TEST_F(BuildTest, YMakefile_missing) +{ + int result = run_command("../ymake"); + EXPECT_NE(result, 0); + + result = run_command("../ymake clean"); + EXPECT_NE(result, 0); +} + |