feat: atcoder scraper update for :CP test
This commit is contained in:
parent
0fb247f18b
commit
c99cf8d4f0
5 changed files with 104 additions and 29 deletions
|
|
@ -206,11 +206,24 @@ local function toggle_test_panel()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if state.platform == "codeforces" then
|
||||||
|
logger.log("test panel not yet supported for codeforces", vim.log.levels.ERROR)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local problem_id = get_current_problem()
|
local problem_id = get_current_problem()
|
||||||
if not problem_id then
|
if not problem_id then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local ctx = problem.create_context(state.platform, state.contest_id, state.problem_id, config)
|
||||||
|
local test_module = require("cp.test")
|
||||||
|
|
||||||
|
if not test_module.load_test_cases(ctx, state) then
|
||||||
|
logger.log("no test cases found", vim.log.levels.WARN)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
state.saved_session = vim.fn.tempname()
|
state.saved_session = vim.fn.tempname()
|
||||||
vim.cmd(("mksession! %s"):format(state.saved_session))
|
vim.cmd(("mksession! %s"):format(state.saved_session))
|
||||||
|
|
||||||
|
|
@ -221,24 +234,59 @@ local function toggle_test_panel()
|
||||||
vim.bo.filetype = "cptest"
|
vim.bo.filetype = "cptest"
|
||||||
vim.bo.bufhidden = "wipe"
|
vim.bo.bufhidden = "wipe"
|
||||||
|
|
||||||
local test_lines = {
|
local test_state = test_module.get_test_panel_state()
|
||||||
" 1 ✓ PASS 12ms",
|
local test_lines = {}
|
||||||
" 2 ✗ FAIL 45ms",
|
|
||||||
"> 3 ✓ PASS 8ms",
|
for i, test_case in ipairs(test_state.test_cases) do
|
||||||
" 4 ? PENDING",
|
local status_icon = "?"
|
||||||
"",
|
local status_text = "PENDING"
|
||||||
"── Test 3 ──",
|
|
||||||
"Input: │ Expected: │ Actual:",
|
if test_case.status == "pass" then
|
||||||
"5 3 │ 8 │ 8",
|
status_icon = "✓"
|
||||||
"",
|
status_text = "PASS"
|
||||||
"j/k: navigate <space>: toggle <enter>: run q: quit",
|
elseif test_case.status == "fail" then
|
||||||
}
|
status_icon = "✗"
|
||||||
|
status_text = "FAIL"
|
||||||
|
end
|
||||||
|
|
||||||
|
local time_text = test_case.time_ms and string.format("%.0fms", test_case.time_ms) or ""
|
||||||
|
local prefix = i == test_state.current_index and "> " or " "
|
||||||
|
|
||||||
|
table.insert(test_lines, string.format("%s%d %s %s %s",
|
||||||
|
prefix, i, status_icon, status_text, time_text))
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(test_lines, "")
|
||||||
|
|
||||||
|
local current_test = test_state.test_cases[test_state.current_index]
|
||||||
|
if current_test then
|
||||||
|
table.insert(test_lines, string.format("── Test %d ──", test_state.current_index))
|
||||||
|
table.insert(test_lines, "Input:")
|
||||||
|
for line in current_test.input:gmatch("[^\n]*") do
|
||||||
|
table.insert(test_lines, " " .. line)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(test_lines, "Expected:")
|
||||||
|
for line in current_test.expected:gmatch("[^\n]*") do
|
||||||
|
table.insert(test_lines, " " .. line)
|
||||||
|
end
|
||||||
|
|
||||||
|
if current_test.actual then
|
||||||
|
table.insert(test_lines, "Actual:")
|
||||||
|
for line in current_test.actual:gmatch("[^\n]*") do
|
||||||
|
table.insert(test_lines, " " .. line)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(test_lines, "")
|
||||||
|
table.insert(test_lines, "j/k: navigate <space>: toggle <enter>: run q: quit")
|
||||||
|
|
||||||
vim.api.nvim_buf_set_lines(test_buf, 0, -1, false, test_lines)
|
vim.api.nvim_buf_set_lines(test_buf, 0, -1, false, test_lines)
|
||||||
vim.bo.modifiable = false
|
vim.bo.modifiable = false
|
||||||
|
|
||||||
state.test_panel_active = true
|
state.test_panel_active = true
|
||||||
logger.log("test panel opened")
|
logger.log(string.format("test panel opened (%d test cases)", #test_state.test_cases))
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param delta number 1 for next, -1 for prev
|
---@param delta number 1 for next, -1 for prev
|
||||||
|
|
|
||||||
|
|
@ -225,7 +225,13 @@ function M.scrape_problem(ctx)
|
||||||
return data
|
return data
|
||||||
end
|
end
|
||||||
|
|
||||||
if data.test_cases and #data.test_cases > 0 then
|
if data.combined then
|
||||||
|
local combined_input = data.combined.input:gsub("\r", "")
|
||||||
|
local combined_output = data.combined.output:gsub("\r", "")
|
||||||
|
|
||||||
|
vim.fn.writefile(vim.split(combined_input, "\n", true), ctx.input_file)
|
||||||
|
vim.fn.writefile(vim.split(combined_output, "\n", true), ctx.expected_file)
|
||||||
|
elseif data.test_cases and #data.test_cases > 0 then
|
||||||
local combined_input = data.test_cases[1].input:gsub("\r", "")
|
local combined_input = data.test_cases[1].input:gsub("\r", "")
|
||||||
local combined_output = data.test_cases[1].output:gsub("\r", "")
|
local combined_output = data.test_cases[1].output:gsub("\r", "")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,24 @@
|
||||||
|
---@class TestCase
|
||||||
|
---@field index number
|
||||||
|
---@field input string
|
||||||
|
---@field expected string
|
||||||
|
---@field status "pending"|"pass"|"fail"|"running"
|
||||||
|
---@field actual string?
|
||||||
|
---@field time_ms number?
|
||||||
|
---@field error string?
|
||||||
|
|
||||||
|
---@class TestPanelState
|
||||||
|
---@field test_cases TestCase[]
|
||||||
|
---@field current_index number
|
||||||
|
---@field buffer number?
|
||||||
|
---@field namespace number?
|
||||||
|
---@field is_active boolean
|
||||||
|
---@field saved_layout table?
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
local logger = require("cp.log")
|
local logger = require("cp.log")
|
||||||
local execute = require("cp.execute")
|
|
||||||
|
|
||||||
|
---@type TestPanelState
|
||||||
local test_panel_state = {
|
local test_panel_state = {
|
||||||
test_cases = {},
|
test_cases = {},
|
||||||
current_index = 1,
|
current_index = 1,
|
||||||
|
|
@ -33,8 +50,10 @@ local function parse_test_cases_from_cache(platform, contest_id, problem_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
local test_cases = {}
|
local test_cases = {}
|
||||||
|
|
||||||
for i, test_case in ipairs(cached_test_cases) do
|
for i, test_case in ipairs(cached_test_cases) do
|
||||||
table.insert(test_cases, create_test_case(i, test_case.input, test_case.output))
|
local index = test_case.index or i
|
||||||
|
table.insert(test_cases, create_test_case(index, test_case.input, test_case.output))
|
||||||
end
|
end
|
||||||
|
|
||||||
return test_cases
|
return test_cases
|
||||||
|
|
|
||||||
|
|
@ -45,10 +45,10 @@ end, {
|
||||||
|
|
||||||
if num_args == 2 then
|
if num_args == 2 then
|
||||||
local candidates = { "--lang" }
|
local candidates = { "--lang" }
|
||||||
vim.list_extend(candidates, actions)
|
|
||||||
local cp = require("cp")
|
local cp = require("cp")
|
||||||
local context = cp.get_current_context()
|
local context = cp.get_current_context()
|
||||||
if context.platform and context.contest_id then
|
if context.platform and context.contest_id then
|
||||||
|
vim.list_extend(candidates, actions)
|
||||||
local cache = require("cp.cache")
|
local cache = require("cp.cache")
|
||||||
cache.load()
|
cache.load()
|
||||||
local contest_data = cache.get_contest_data(context.platform, context.contest_id)
|
local contest_data = cache.get_contest_data(context.platform, context.contest_id)
|
||||||
|
|
|
||||||
|
|
@ -169,24 +169,26 @@ def main() -> None:
|
||||||
print(json.dumps(result))
|
print(json.dumps(result))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
test_cases: list[dict[str, str]] = []
|
individual_test_cases: list[dict[str, str]] = []
|
||||||
for input_data, output_data in tests:
|
for index, (input_data, output_data) in enumerate(tests, 1):
|
||||||
test_cases.append({"input": input_data, "output": output_data})
|
individual_test_cases.append({
|
||||||
|
"index": index,
|
||||||
|
"input": input_data,
|
||||||
|
"output": output_data
|
||||||
|
})
|
||||||
|
|
||||||
if test_cases:
|
combined_input = "\n".join(tc["input"] for tc in individual_test_cases)
|
||||||
combined_input: str = (
|
combined_output = "\n".join(tc["output"] for tc in individual_test_cases)
|
||||||
str(len(test_cases))
|
|
||||||
+ "\n"
|
|
||||||
+ "\n".join(tc["input"] for tc in test_cases)
|
|
||||||
)
|
|
||||||
combined_output: str = "\n".join(tc["output"] for tc in test_cases)
|
|
||||||
test_cases = [{"input": combined_input, "output": combined_output}]
|
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
"success": True,
|
"success": True,
|
||||||
"problem_id": problem_id,
|
"problem_id": problem_id,
|
||||||
"url": url,
|
"url": url,
|
||||||
"test_cases": test_cases,
|
"test_cases": individual_test_cases,
|
||||||
|
"combined": {
|
||||||
|
"input": combined_input,
|
||||||
|
"output": combined_output
|
||||||
|
}
|
||||||
}
|
}
|
||||||
print(json.dumps(result))
|
print(json.dumps(result))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue