Skip to content

Commit

Permalink
Merge pull request #110 from QuBenhao/105-node-reference-by-value
Browse files Browse the repository at this point in the history
105 node reference by value
  • Loading branch information
QuBenhao committed Jul 25, 2024
2 parents d620dfb + d675ac8 commit 44c25ef
Show file tree
Hide file tree
Showing 36 changed files with 710 additions and 283 deletions.
30 changes: 30 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ path = "rust/test_executor/tests/solutions_test.rs"
serde_json = "1.0"
rand = "0.8.4"
regex = "1.10.5"
assert_float_eq = "1"
test_executor = { path = "rust/test_executor", features = ["run_test"] }
solution_1 = { path = "problems/problems_1", features = ["solution_1"] }
solution_2 = { path = "problems/problems_2", features = ["solution_2"] }
Expand Down
21 changes: 21 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")


# Hedron's Compile Commands Extractor for Bazel
# https://github.com/hedronvision/bazel-compile-commands-extractor
http_archive(
name = "hedron_compile_commands",

# Replace the commit hash (0e990032f3c5a866e72615cf67e5ce22186dcb97) in both places (below) with the latest (https://github.com/hedronvision/bazel-compile-commands-extractor/commits/main), rather than using the stale one here.
# Even better, set up Renovate and let it do the work for you (see "Suggestion: Updates" in the README).
url = "https://github.com/hedronvision/bazel-compile-commands-extractor/archive/1e08f8e0507b6b6b1f4416a9a22cf5c28beaba93.tar.gz",
strip_prefix = "bazel-compile-commands-extractor-1e08f8e0507b6b6b1f4416a9a22cf5c28beaba93",
# When you first run this tool, it'll recommend a sha256 hash to put here with a message like: "DEBUG: Rule 'hedron_compile_commands' indicated that a canonical reproducible form can be obtained by modifying arguments sha256 = ..."
)
load("@hedron_compile_commands//:workspace_setup.bzl", "hedron_compile_commands_setup")
hedron_compile_commands_setup()
load("@hedron_compile_commands//:workspace_setup_transitive.bzl", "hedron_compile_commands_setup_transitive")
hedron_compile_commands_setup_transitive()
load("@hedron_compile_commands//:workspace_setup_transitive_transitive.bzl", "hedron_compile_commands_setup_transitive_transitive")
hedron_compile_commands_setup_transitive_transitive()
load("@hedron_compile_commands//:workspace_setup_transitive_transitive_transitive.bzl", "hedron_compile_commands_setup_transitive_transitive_transitive")
hedron_compile_commands_setup_transitive_transitive_transitive()

http_archive(
name = "com_google_googletest",
strip_prefix = "googletest-5ab508a01f9eb089207ee87fd547d290da39d015",
Expand Down
5 changes: 4 additions & 1 deletion cpp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@ or if you want to run more than one questions,
**change problem and path in `new_local_repository(name = "problem0", path = "problems/problems_1/"` in [WORKSPACE](../WORKSPACE)** and maybe add the name ref `@problem0` in [BUILD](tests/BUILD), and try:
```shell
bazel test --cxxopt=-std=c++20 --test_timeout=10 --test_output=all //cpp/tests:all
```
```

## Environment setup for idea:
[bazel-compile-commands-extractor](https://github.com/hedronvision/bazel-compile-commands-extractor)
211 changes: 124 additions & 87 deletions cpp/TestMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,110 +2,147 @@
// Created by 曲本豪 on 2024/5/21.
//

#include "TestMain.h"
#include <fstream>
#include <sstream>
#include <utility>
#include "TestMain.h"
#include <memory>
#include <vector>
#include "cpp/common/Solution.h"
#include "tools/cpp/runfiles/runfiles.h"

using namespace std;

using std::string;
using std::ifstream;
using std::stringstream;
using std::runtime_error;
using std::vector;
using std::size_t;
using std::endl;
using std::cerr;
using json = nlohmann::json;
using bazel::tools::cpp::runfiles::Runfiles;

namespace LeetCode {
namespace qubh {

vector<TestCase> LoadTestCases(const string &path) {
string error;
unique_ptr<Runfiles> runfiles(Runfiles::Create("LeetCode Solution Test", &error));

if (runfiles == nullptr) {
// error handling
throw runtime_error("Could not open file: " + error);
namespace qubh {

vector<TestCase> LoadTestCases(const string &path) {
string error;
unique_ptr<Runfiles> runfiles(
Runfiles::Create("LeetCode Solution Test", &error));

if (runfiles == nullptr) {
// error handling
throw runtime_error("Could not open file: " + error);
}

string filePath = runfiles->Rlocation(path);
ifstream fileStream(filePath);
if (!fileStream) {
throw runtime_error("Could not open file: " + filePath);
}

stringstream buffer;
buffer << fileStream.rdbuf();

string input = buffer.str();
vector<string> splits;
size_t pos = input.find('\n');
while (pos != string::npos) {
splits.push_back(input.substr(0, pos));
input = input.substr(pos + 1);
pos = input.find('\n');
}
splits.push_back(input);
if (splits.size() != 2) {
throw runtime_error("Invalid test case format");
}
vector<string> inputs = json::parse(splits[0]);
vector<json> outputs = json::parse(splits[1]);
vector<TestCase> testCases;
for (size_t i = 0; i < inputs.size(); i++) {
testCases.push_back(TestCase(inputs[i], outputs[i]));
}
return testCases;
}

class LeetCodeSuiteSet : public testing::Test {
public:
// All of these optional, just like in regular macro usage.
static void SetUpTestSuite() {}

static void TearDownTestSuite() {}

void SetUp() {}

void TearDown() {}
};

class LeetCodeTest : public LeetCodeSuiteSet {
public:
explicit LeetCodeTest(TestCase data) : data_(std::move(data)) {}

void TestBody() override {
bool isEqual = false;
int retries = 0;
const int maxRetries = 1e5; // Set the maximum number of retries
auto output = leetcode::qubh::Solve(data_.GetInput());
while (!isEqual && retries < maxRetries) {
if (data_.GetExpected().is_number_float()) {
isEqual = std::abs(output.get<double>() - data_.GetExpected().get<double>()) < 1e-6;
} else if (output.is_array() && !data_.GetExpected().is_array()) {
isEqual = (output[0] == data_.GetExpected());
} else {
isEqual = (output == data_.GetExpected());
}

string filePath = runfiles->Rlocation(path);
ifstream fileStream(filePath);
if (!fileStream) {
throw runtime_error("Could not open file: " + filePath);
}

stringstream buffer;
buffer << fileStream.rdbuf();

string input = buffer.str();
vector<string> splits;
size_t pos = input.find('\n');
while (pos != string::npos) {
splits.push_back(input.substr(0, pos));
input = input.substr(pos + 1);
pos = input.find('\n');
}
splits.push_back(input);
if (splits.size() != 2) {
throw runtime_error("Invalid test case format");
}
vector<string> inputs = json::parse(splits[0]);
vector<json> outputs = json::parse(splits[1]);
vector<TestCase> testCases;
for (size_t i = 0; i < inputs.size(); i++) {
testCases.push_back(TestCase(inputs[i], outputs[i]));
}
return testCases;
}

class LeetCodeSuiteSet : public testing::Test {
public:
// All of these optional, just like in regular macro usage.
static void SetUpTestSuite() {}

static void TearDownTestSuite() {}

void SetUp() override {}

void TearDown() override {}
};

class LeetCodeTest : public LeetCodeSuiteSet {
public:
explicit LeetCodeTest(TestCase data) : data_(std::move(data)) {}

void TestBody() override {
if (data_.GetExpected().is_number_float()) {
ASSERT_DOUBLE_EQ(leetcode::qubh::Solve(data_.GetInput()), data_.GetExpected());
} else {
ASSERT_EQ(leetcode::qubh::Solve(data_.GetInput()), data_.GetExpected());
if (!isEqual) {
auto secondOutput = leetcode::qubh::Solve(data_.GetInput());
if (retries == 0 && secondOutput == output) {
break;
}
output = secondOutput;
retries++;
}
}

private:
TestCase data_;
};

void RegisterMyTests(const vector<TestCase> &values) {
for (size_t i = 0; i < values.size(); i++) {
testing::RegisterTest(
"LeetCode Solution Test", ("Testcase" + to_string(i)).c_str(), nullptr,
"LeetCode::qubh::Testcase",
__FILE__, __LINE__,
// Important to use the fixture type as the return type here.
[=]() -> LeetCodeSuiteSet * { return new LeetCodeTest(values[i]); });
if (data_.GetExpected().is_number_float()) {
ASSERT_DOUBLE_EQ(output.get<double>(), data_.GetExpected().get<double>());
} else {
if (output.is_array() && !data_.GetExpected().is_array()) {
ASSERT_EQ(output[0], data_.GetExpected());
} else {
ASSERT_EQ(output, data_.GetExpected());
}
}
} // qubh
} // LeetCode
}

private:
TestCase data_;
};

void RegisterMyTests(const vector<TestCase> &values) {
for (size_t i = 0; i < values.size(); i++) {
testing::RegisterTest(
"LeetCode Solution Test", ("Testcase" + to_string(i)).c_str(), nullptr,
"LeetCode::qubh::Testcase", __FILE__, __LINE__,
// Important to use the fixture type as the return type here.
[=]() -> LeetCodeSuiteSet * { return new LeetCodeTest(values[i]); });
}
}
} // namespace qubh
} // namespace LeetCode

int main(int argc, char **argv) {
try {
// Run the tests.
vector<LeetCode::qubh::TestCase> testcases = LeetCode::qubh::LoadTestCases(argv[1]);
testing::InitGoogleTest(&argc, argv);
LeetCode::qubh::RegisterMyTests(testcases);
return RUN_ALL_TESTS();
}
catch (const exception &e) {
cerr << e.what() << endl;
return 1;
}
try {
// Run the tests.
vector<LeetCode::qubh::TestCase> testcases =
LeetCode::qubh::LoadTestCases(argv[1]);
testing::InitGoogleTest(&argc, argv);
LeetCode::qubh::RegisterMyTests(testcases);
return RUN_ALL_TESTS();
} catch (const exception &e) {
cerr << e.what() << endl;
return 1;
}
}
Loading

0 comments on commit 44c25ef

Please sign in to comment.