11PYTHON_TEMPLATE = r"""import json
22import traceback
3+ import io
4+ import sys
35from typing import *
46
57{code}
@@ -10,23 +12,26 @@ def __init__(
1012 expected: str,
1113 passed: bool,
1214 output: Any = None,
15+ logs: str = None,
1316 error: str = None,
1417 input: str = None,
1518 ):
1619 self.expected = expected
1720 self.output = str(output) if output is not None else None
1821 self.passed = passed
22+ self.logs = logs
1923 self.error = error
2024 self.input = input
2125
22- def to_dict(self, include_input : bool = True):
26+ def to_dict(self, is_sample : bool = True):
2327 result = {{
2428 "expected": self.expected,
2529 "output": self.output,
2630 "passed": self.passed,
2731 "error": self.error,
2832 }}
29- if include_input:
33+ if is_sample:
34+ result["logs"] = self.logs
3035 result["input"] = self.input
3136 return result
3237
@@ -47,22 +52,30 @@ def run_tests(solution, method_name, test_data, is_sample: bool = False):
4752 results = []
4853
4954 for test in test_data:
55+ old_stdout = sys.stdout
56+ new_stdout = io.StringIO()
57+ sys.stdout = new_stdout
58+
5059 try:
5160 result = eval(f"solution.{{format_test_data(method_name, test['input'])}}")
5261 passed = compare_results(result, test['expected'])
5362 results.append(TestResult(
5463 expected=test['expected'],
5564 output=result,
5665 passed=passed,
66+ logs=new_stdout.getvalue(),
5767 input=test['input'],
58- ).to_dict(include_input =is_sample))
68+ ).to_dict(is_sample =is_sample))
5969 except Exception as e:
6070 results.append(TestResult(
6171 expected=test['expected'],
6272 passed=False,
73+ logs=new_stdout.getvalue(),
6374 error=traceback.format_exc(),
6475 input=test['input'],
65- ).to_dict(include_input=is_sample))
76+ ).to_dict(is_sample=is_sample))
77+ finally:
78+ sys.stdout = old_stdout
6679
6780 return {{
6881 "test_results": results,
@@ -94,6 +107,7 @@ def run_tests(solution, method_name, test_data, is_sample: bool = False):
94107import com.google.gson.*;
95108import java.lang.reflect.*;
96109import java.util.*;
110+ import java.io.*;
97111
98112{code}
99113
@@ -115,11 +129,32 @@ def run_tests(solution, method_name, test_data, is_sample: bool = False):
115129 }}
116130 }}
117131
132+ private static class LogCapture {{
133+ private final ByteArrayOutputStream baos;
134+ private final PrintStream original;
135+ private final PrintStream capture;
136+
137+ public LogCapture() {{
138+ this.baos = new ByteArrayOutputStream();
139+ this.original = System.out;
140+ this.capture = new PrintStream(baos);
141+ }}
142+
143+ public void start() {{
144+ System.setOut(capture);
145+ }}
146+
147+ public String stop() {{
148+ System.setOut(original);
149+ return baos.toString().trim();
150+ }}
151+ }}
152+
118153 private static boolean compare(Object result, Object expected) {{
119154 {compare_func}
120155 }}
121156
122- public static JsonArray runTests(Solution solution, JsonArray testData, boolean showInput ) {{
157+ public static JsonArray runTests(Solution solution, JsonArray testData, boolean isSample ) {{
123158 JsonArray results = new JsonArray();
124159 Gson gson = new Gson();
125160
@@ -146,21 +181,28 @@ def run_tests(solution, method_name, test_data, is_sample: bool = False):
146181 for (JsonElement testElement : testData) {{
147182 JsonObject test = testElement.getAsJsonObject();
148183 JsonObject result = new JsonObject();
184+ LogCapture logCapture = new LogCapture();
149185
150186 try {{
151187 String inputStr = test.get("input").getAsString();
152188 Object[] args = parseArguments(inputStr, paramTypes);
189+
190+ logCapture.start();
153191 Object output = targetMethod.invoke(solution, args);
192+ String logs = logCapture.stop();
193+
154194 Object expected = parseValue(test.get("expected").getAsString(), returnType);
155195
156196 boolean passed = compare(output, expected);
157197 result.addProperty("passed", passed);
158198 result.addProperty("output", gson.toJson(output));
159199 result.addProperty("expected", test.get("expected").getAsString());
160- if (showInput) {{
200+ if (isSample) {{
201+ result.addProperty("logs", logs);
161202 result.addProperty("input", inputStr);
162203 }}
163204 }} catch (Exception e) {{
205+ logCapture.stop();
164206 Throwable cause = e;
165207 if (e instanceof InvocationTargetException && e.getCause() != null) {{
166208 cause = e.getCause();
@@ -459,6 +501,7 @@ def run_tests(solution, method_name, test_data, is_sample: bool = False):
459501#include <type_traits>
460502#include <bits/stdc++.h>
461503#include <vector>
504+ #include <streambuf>
462505
463506using namespace std;
464507
@@ -585,14 +628,19 @@ def run_tests(solution, method_name, test_data, is_sample: bool = False):
585628 {compare_func}
586629}}
587630
588- Json::Value runTests(Solution& solution, const Json::Value& testData, bool showInput ) {{
631+ Json::Value runTests(Solution& solution, const Json::Value& testData, bool isSample ) {{
589632 Json::Value results(Json::arrayValue);
590633 Json::CharReaderBuilder builder;
591634 Json::CharReader* reader = builder.newCharReader();
592635 string errors;
593636
594637 for (const auto &test : testData) {{
595638 Json::Value testResult;
639+
640+ stringstream logStream;
641+ streambuf* oldCout = cout.rdbuf();
642+ cout.rdbuf(logStream.rdbuf());
643+
596644 try {{
597645 auto args = parseArguments(test["input"].asString());
598646
@@ -615,13 +663,15 @@ def run_tests(solution, method_name, test_data, is_sample: bool = False):
615663 writer["indentation"] = "";
616664 testResult["output"] = Json::writeString(writer, output_json);
617665 testResult["expected"] = Json::writeString(writer, expected);
618- if (showInput) {{
666+ if (isSample) {{
667+ testResult["logs"] = logStream.str();
619668 testResult["input"] = test["input"];
620669 }}
621670 }} catch (const exception &e) {{
622671 testResult["error"] = e.what();
623672 testResult["passed"] = false;
624673 }}
674+ cout.rdbuf(oldCout);
625675 results.append(testResult);
626676 }}
627677 delete reader;
0 commit comments