diff --git a/README.md b/README.md index 019f3f7..a7bdc9c 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Problems are stored in a `problems` folder. This can be changed in the `settings Within each difficulty folder, there are the individual problems. Each of these folders will contain a `problem.md` which is the problem statement. There will be a `tests` folder for test cases and a `solutions` folder for reference solutions. -If a problem folder contains a `checker.py` next to `problem.md`, `aucpl problem test` will use it as a custom checker. The file must define `check(process_output, judge_output)` and return a boolean. +If a problem folder contains a `checker.py` next to `problem.md`, `aucpl problem test` will use it as a custom checker. The file must define `check(process_output, judge_output, **kwargs)` and return a boolean. The `judge_input` value is provided in `kwargs`. Lastly, there is a `problem-mappings.json` file that maps the problem names to its stored location. This is so that in the CLI, you do not have to specify things like the rating or whether it's a new or archived problem. You can also use `aucpl sync` to generate or update the mappings. diff --git a/crates/cli/src/problem/test.rs b/crates/cli/src/problem/test.rs index f9e8946..52b51dc 100644 --- a/crates/cli/src/problem/test.rs +++ b/crates/cli/src/problem/test.rs @@ -20,6 +20,8 @@ checker_path = sys.argv[1] process_output = sys.argv[2] judge_output = sys.argv[3] +judge_input = sys.stdin.read() + spec = importlib.util.spec_from_file_location("aucpl_checker", checker_path) if spec is None or spec.loader is None: print("Could not load checker.py", file=sys.stderr) @@ -32,7 +34,7 @@ if not hasattr(module, "check"): print("checker.py must define a `check` function", file=sys.stderr) sys.exit(2) -result = module.check(process_output, judge_output) +result = module.check(process_output, judge_output, judge_input=judge_input) print("true" if bool(result) else "false") "#; @@ -42,6 +44,7 @@ fn run_custom_checker( checker_path: &Path, process_output: &str, judge_output: &[u8], + input_file_path: &PathBuf, ) -> Result { let judge_output = String::from_utf8_lossy(judge_output).into_owned(); let python_cmd = get_python_executable(settings); @@ -59,9 +62,8 @@ fn run_custom_checker( ], ) .context("Failed to prepare checker command")?; - let checker_result = checker_run - .get_result(None) + .get_result(Some(input_file_path)) .context("Failed to run checker.py")? .output; @@ -130,7 +132,13 @@ pub fn test( output_file.read_to_end(expected)?; let passed = if use_custom_checker { - run_custom_checker(settings, &checker_path, &out_str, expected)? + run_custom_checker( + settings, + &checker_path, + &out_str, + expected, + &input_file_path, + )? } else { expected == out_str.as_bytes() };