-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cest-runner finds all tests and runs them
- Loading branch information
Showing
15 changed files
with
298 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
#include "directory.h" | ||
#include <filesystem> | ||
#include <algorithm> | ||
|
||
constexpr bool hasPerms(std::filesystem::perms target, std::filesystem::perms other) | ||
{ | ||
return std::filesystem::perms::none != (other & target); | ||
} | ||
|
||
constexpr bool isExecutable(std::filesystem::perms target) | ||
{ | ||
return hasPerms(std::filesystem::perms::owner_exec, target) || | ||
hasPerms(std::filesystem::perms::group_exec, target) || | ||
hasPerms(std::filesystem::perms::others_exec, target); | ||
} | ||
|
||
static std::vector<std::string> filterBy(const std::string& filter, const std::vector<std::string>& entries) | ||
{ | ||
std::vector<std::string> result; | ||
|
||
std::copy_if( | ||
entries.begin(), | ||
entries.end(), | ||
std::back_inserter(result), | ||
[&filter](std::string path) { | ||
return path.find(filter) != std::string::npos; | ||
} | ||
); | ||
|
||
return result; | ||
} | ||
|
||
std::vector<std::string> Directory::findExecutableFiles( | ||
const std::string& path, | ||
const std::string& filter | ||
) { | ||
std::vector<std::string> result; | ||
|
||
if (!std::filesystem::is_directory(path)) return result; | ||
|
||
for (const auto& entry : std::filesystem::directory_iterator(path)) | ||
{ | ||
const auto permissions = entry.status().permissions(); | ||
|
||
if (entry.is_regular_file() && isExecutable(permissions)) | ||
{ | ||
result.push_back(entry.path()); | ||
} | ||
else if (entry.is_directory()) | ||
{ | ||
const auto sub_files = Directory::findExecutableFiles(entry.path(), filter); | ||
result.insert(result.end(), sub_files.begin(), sub_files.end()); | ||
} | ||
} | ||
|
||
return filterBy(filter, result); | ||
} | ||
|
||
std::string Directory::cwd() | ||
{ | ||
return std::filesystem::current_path(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#pragma once | ||
#include <vector> | ||
#include <string> | ||
|
||
namespace Directory | ||
{ | ||
std::vector<std::string> findExecutableFiles(const std::string& path, const std::string& filter); | ||
std::string cwd(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#include "runner.h" | ||
|
||
int main(int argc, char *argv[]) | ||
{ | ||
Runner::runTestsInCurrentPath(); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#include "output.h" | ||
#include <iostream> | ||
|
||
void Output::print(std::stringstream& text) | ||
{ | ||
std::cout << text.str(); | ||
text.clear(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#pragma once | ||
#include <sstream> | ||
|
||
namespace Output | ||
{ | ||
void print(std::stringstream& text); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#include "process.h" | ||
#include <unistd.h> | ||
#include <sys/wait.h> | ||
|
||
static constexpr int MAX_ARGS = 32; | ||
static constexpr int MAX_BUFFER = 4096; | ||
|
||
static constexpr bool isChildProcess(pid_t pid) | ||
{ | ||
return pid == 0; | ||
} | ||
|
||
static void handleChildProcess(int pipe_fd[2], const std::string& path, std::vector<std::string> args) | ||
{ | ||
std::array<char *, MAX_ARGS> c_args; | ||
|
||
dup2(pipe_fd[1], STDOUT_FILENO); | ||
close(STDERR_FILENO); | ||
close(pipe_fd[0]); | ||
close(pipe_fd[1]); | ||
|
||
c_args.fill(NULL); | ||
|
||
for (int i=0; i<args.size(); ++i) | ||
{ | ||
c_args[i] = (char *)args[i].c_str(); | ||
} | ||
|
||
execv(path.c_str(), c_args.data()); | ||
} | ||
|
||
static void waitForChildren() | ||
{ | ||
pid_t pid; | ||
int status = 0; | ||
|
||
while ((pid = wait(&status)) > 0); | ||
} | ||
|
||
static void handleParentProcess(int pipe_fd[2], std::function<void(std::string)> on_output) | ||
{ | ||
std::array<char, MAX_BUFFER> buffer; | ||
|
||
buffer.fill('\0'); | ||
close(pipe_fd[1]); | ||
read(pipe_fd[0], buffer.data(), buffer.size()); | ||
|
||
on_output(std::string(buffer.data())); | ||
|
||
waitForChildren(); | ||
} | ||
|
||
void Process::runExecutable(const std::string& path, std::function<void(std::string)> on_output) | ||
{ | ||
int pipe_fd[2]; | ||
pipe(pipe_fd); | ||
|
||
const auto pid = fork(); | ||
|
||
if (isChildProcess(pid)) | ||
{ | ||
std::vector<std::string> args = { "-o" }; | ||
handleChildProcess(pipe_fd, path, args); | ||
} | ||
else | ||
{ | ||
handleParentProcess(pipe_fd, on_output); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#include <functional> | ||
#include <string> | ||
|
||
namespace Process | ||
{ | ||
void runExecutable(const std::string& path, std::function<void(std::string)> on_output); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#include "runner.h" | ||
#include "process.h" | ||
#include "directory.h" | ||
#include "output.h" | ||
|
||
void Runner::runTestsInCurrentPath() | ||
{ | ||
std::stringstream out; | ||
const auto executables = Directory::findExecutableFiles(Directory::cwd(), "test_"); | ||
|
||
for (const auto& test_file : executables) | ||
{ | ||
out << "Running test " << test_file << std::endl; | ||
Output::print(out); | ||
|
||
Process::runExecutable(test_file, [&out](const auto& output) { | ||
out << output; | ||
Output::print(out); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#pragma once | ||
|
||
namespace Runner | ||
{ | ||
void runTestsInCurrentPath(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
#include <sstream> | ||
#include <vector> | ||
#include <functional> | ||
#include "helpers.h" | ||
#include "../../output.h" | ||
#include "../../process.h" | ||
#include "../../directory.h" | ||
|
||
static std::vector<std::string> __mock_executable_files; | ||
static bool __find_executable_files_called = false; | ||
static std::string __find_executable_files_path; | ||
static std::string __find_executable_files_filter; | ||
|
||
static std::string __mock_run_executable_output; | ||
static bool __run_executable_has_been_called = false; | ||
static std::vector<std::string> __run_executable_path; | ||
|
||
void Output::print(std::stringstream& text) | ||
{ | ||
} | ||
|
||
void Directory::findExecutableFiles_mockFiles(std::vector<std::string> files) | ||
{ | ||
__mock_executable_files = files; | ||
} | ||
bool Directory::findExecutableFiles_hasBeenCalledWith(const std::string& path, const std::string& filter) | ||
{ | ||
return __find_executable_files_called && __find_executable_files_path == path && __find_executable_files_filter == filter; | ||
} | ||
std::vector<std::string> Directory::findExecutableFiles(const std::string& path, const std::string& filter) | ||
{ | ||
__find_executable_files_path = path; | ||
__find_executable_files_filter = filter; | ||
__find_executable_files_called = true; | ||
return __mock_executable_files; | ||
} | ||
std::string Directory::cwd() | ||
{ | ||
return "/cwd"; | ||
} | ||
|
||
void Process::runExecutable_mockOutput(const std::string& output) | ||
{ | ||
__mock_run_executable_output = output; | ||
} | ||
void Process::runExecutable(const std::string& path, std::function<void(std::string)> on_output) | ||
{ | ||
__run_executable_has_been_called = true; | ||
__run_executable_path.push_back(path); | ||
on_output(__mock_run_executable_output); | ||
} | ||
bool Process::runExecutable_hasBeenCalledWith(const std::string& path) | ||
{ | ||
auto it = std::find(__run_executable_path.cbegin(), __run_executable_path.cend(), path); | ||
return __run_executable_has_been_called && it != __run_executable_path.end(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#pragma once | ||
#include <sstream> | ||
#include <functional> | ||
#include <vector> | ||
|
||
namespace Directory | ||
{ | ||
void findExecutableFiles_mockFiles(std::vector<std::string> files); | ||
bool findExecutableFiles_hasBeenCalledWith(const std::string& path, const std::string& filter); | ||
} | ||
|
||
namespace Process | ||
{ | ||
void runExecutable_mockOutput(const std::string& output); | ||
bool runExecutable_hasBeenCalledWith(const std::string& path); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#include <cest> | ||
#include "../runner.h" | ||
#include "../directory.h" | ||
#include "helpers/helpers.h" | ||
|
||
describe("Runner", []() { | ||
it("executes all tests found in the current directory", []() { | ||
std::vector<std::string> test_files = { "first/test", "second/test" }; | ||
Directory::findExecutableFiles_mockFiles(test_files); | ||
|
||
Runner::runTestsInCurrentPath(); | ||
|
||
expect(Directory::findExecutableFiles_hasBeenCalledWith(Directory::cwd(), "test_")).toBeTruthy(); | ||
expect(Process::runExecutable_hasBeenCalledWith("first/test")).toBeTruthy(); | ||
expect(Process::runExecutable_hasBeenCalledWith("second/test")).toBeTruthy(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters