import json
from pathlib import Path
import subprocess
root = Path(__file__).parent
data_dir = root / "../mwapi_responses_derive/data"
test_dir = root / "tests"
def handle_file(data: dict):
params = {
"action": "query",
data["mode"]: data["name"][6:],
}
name = f"query_{data['name'][6:]}"
props = set([field["prop"] for field in data["fields"]])
test = """
// Autogenerated by gen_tests.py
use mwapi_responses::prelude::*;
mod test_client;
"""
counter = 0
for prop in sorted(props):
if "||" in prop:
continue
if prop == "=default":
prop = "default"
else:
params[data["prop"]] = prop
test += write_test(params, f"{name}_{prop}", counter, data["test_extra"])
counter += 1
fname = test_dir / f"{name}.rs"
fname.write_text(test)
print(f"Wrote {fname}")
def write_test(params: dict, name: str, counter: int, extra: dict) -> str:
macro = "#[query("
for key, val in params.items():
macro += f'{key}="{val}",'
macro += ")]"
extra_rs = ""
mut = "mut "
for key, value in sorted(extra["params"].items()):
extra_rs += f'params.push(("{key}", "{value}"));'
if not extra_rs:
mut = ""
if name in extra.get("ignore", {}):
ignore = "#[ignore] // " + extra["ignore"][name]
else:
ignore = ""
return f"""
{macro}
struct Response{counter};
{ignore}
#[tokio::test]
async fn {name}() {{
let {mut}params = Response{counter}::params(){".to_vec()" if mut else ""};
{extra_rs}
let resp: Response{counter} = test_client::test({"&" if mut else ""}params).await.unwrap();
assert_eq!(resp.items().len(), {extra['assert'].get('length', 10)});
assert!({"!" if extra["assert"].get("continue", True) else ""}resp.continue_.is_empty());
}}
"""
def main():
for fname in data_dir.iterdir():
print(f"Generating test for {fname}")
data = json.loads(fname.read_text())
handle_file(data)
subprocess.check_call(["cargo", "fmt"])
if __name__ == "__main__":
main()