diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Conf.cpp | 6 | ||||
-rw-r--r-- | src/main.cpp | 94 |
2 files changed, 90 insertions, 10 deletions
diff --git a/src/Conf.cpp b/src/Conf.cpp index 6a8de19..695bc9e 100644 --- a/src/Conf.cpp +++ b/src/Conf.cpp @@ -508,12 +508,6 @@ namespace sibs buildPath += TINYDIR_STRING("release"); break; } - - if(sibsConfig.shouldBuildTests() && sibsConfig.getTestPath().empty()) - { - printf("Project is missing package.tests config. No tests to build\n"); - exit(0); - } } const char* asString(Platform platform) diff --git a/src/main.cpp b/src/main.cpp index d8ce41c..6c9df97 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -93,6 +93,8 @@ using namespace std::chrono; // TODO: Make Process::exec safe to use. Currently you pass an argument and it's run as a command, but the string can be escaped to perform malicious acts. // Process::exec should be modified to take a list of arguments to execute command with. +// TODO: Verify paths (test path, ignore dirs, include dirs, expose include dir, sibs test --file dir) are sub directory of the project + #if OS_FAMILY == OS_FAMILY_POSIX #define fout std::cout #define ferr std::cerr @@ -139,7 +141,7 @@ void usageBuild() void usageNew() { - printf("Usage: sibs new <project_name> <--exec|--static|--dynamic> <--lang [c|c++|zig]>\n\n"); + printf("Usage: sibs new <project_name> <--exec|--static|--dynamic> [--lang c|c++|zig]\n\n"); printf("Create a new sibs project\n\n"); printf("Options:\n"); printf(" project_name\t\tThe name of the project you want to create\n"); @@ -154,11 +156,13 @@ void usageNew() void usageTest() { - printf("Usage: sibs test [project_path] [--no-sanitize]\n\n"); + printf("Usage: sibs test [project_path] [--no-sanitize] [--file filepath...|--all-files]\n\n"); printf("Build and run tests for a sibs project\n\n"); printf("Options:\n"); printf(" project_path\t\tThe directory containing a project.conf file - Optional (default: current directory)\n"); - printf(" --no-sanitize\t\tDisable runtime address/undefined behavior - Optional\n"); + printf(" --no-sanitize\t\tDisable runtime address/undefined behavior - Optional (default: enabled), Only applicable for C and C++\n"); + printf(" --file\t\t\tSpecify file to test, path to test file should be defined after this. Can be defined multiple times to test multiple files - Optional (default: not used), Only applicable for Zig\n"); + printf(" --all-files\t\t\tTest all files - Optional (default: not used), Only applicable for Zig\n"); printf("Examples:\n"); printf(" sibs test\n"); printf(" sibs test dirA/dirB\n"); @@ -167,7 +171,7 @@ void usageTest() void usageInit() { - printf("Usage: sibs init [project_path] <--exec|--static|--dynamic> <--lang [c|c++|zig]>\n\n"); + printf("Usage: sibs init [project_path] <--exec|--static|--dynamic> [--lang c|c++|zig]\n\n"); printf("Create sibs project structure in an existing directory\n\n"); printf("Options:\n"); printf(" project_path\t\tThe directory where you want to initialize sibs project - Optional (default: current directory)\n"); @@ -390,6 +394,8 @@ int testProject(int argc, const _tinydir_char_t **argv) usageTest(); FileString projectPath; + vector<FileString> filesToTest; + bool testAllFiles = false; bool sanitize = true; for(int i = 0; i < argc; ++i) @@ -399,6 +405,39 @@ int testProject(int argc, const _tinydir_char_t **argv) { sanitize = false; } + else if(_tinydir_strcmp(arg, TINYDIR_STRING("--file")) == 0) + { + if(i == argc - 1) + { + ferr << "Error: Expected path to file to test after --file " << endl; + usageTest(); + } + + ++i; + arg = argv[i]; + filesToTest.push_back(arg); + + if(testAllFiles) + { + ferr << "Error: --file can't be used together with --all-files " << endl; + usageTest(); + } + } + else if(_tinydir_strcmp(arg, TINYDIR_STRING("--all-files")) == 0) + { + if(testAllFiles) + { + ferr << "Error: --all-files defined twice " << endl; + usageTest(); + } + testAllFiles = true; + + if(!filesToTest.empty()) + { + ferr << "Error: --all-files can't be used together with --file " << endl; + usageTest(); + } + } else if(_tinydir_strncmp(arg, TINYDIR_STRING("--"), 2) == 0) { ferr << "Error: Invalid argument " << arg << endl; @@ -431,6 +470,44 @@ int testProject(int argc, const _tinydir_char_t **argv) } projectPath = projectRealPathResult.unwrap(); + for(const FileString &testFile : filesToTest) + { + if(testFile.empty()) + { + ferr << "Error: Test filepath can't be empty" << endl; + exit(20); + } + + FileType fileType = getFileType(testFile.c_str()); + switch(fileType) + { + case FileType::FILE_NOT_FOUND: + { + ferr << "Error: Test file not found: " << testFile << endl; + exit(20); + break; + } + case FileType::DIRECTORY: + { + ferr << "Error: Test file " << testFile << " is a directory, expected to be a file" << endl; + exit(20); + break; + } + case FileType::REGULAR: + { + // TODO: This can be optimized, there is no need to create a copy to check file extension + FileString fileExtension = backend::BackendUtils::getFileExtension(testFile); + sibs::Language fileLanguage = backend::BackendUtils::getFileLanguage(fileExtension.c_str()); + if(fileLanguage != sibs::Language::ZIG) + { + ferr << "Error: file specific testing can only be done on zig files. " << testFile << " is not a zig file" << endl; + exit(42); + } + break; + } + } + } + FileString projectConfFilePath = projectPath; projectConfFilePath += TINYDIR_STRING("/project.conf"); validateFilePath(projectConfFilePath.c_str()); @@ -446,6 +523,15 @@ int testProject(int argc, const _tinydir_char_t **argv) SibsConfig sibsConfig(compiler, projectPath, OPT_LEV_DEBUG, true); sibsConfig.showWarnings = true; sibsConfig.setSanitize(sanitize); + sibsConfig.zigTestFiles = move(filesToTest); + sibsConfig.zigTestAllFiles = testAllFiles; + + if(sibsConfig.getTestPath().empty() && !sibsConfig.zigTestAllFiles && sibsConfig.zigTestFiles.empty()) + { + printf("Project is missing package.tests config. No tests to build\n"); + exit(50); + } + return buildProject(projectPath, projectConfFilePath, sibsConfig); } |