feat(config): add language version selection with setup-time validation

Problem: users cannot choose which C++ standard (e.g. C++17 vs C++20
vs C++23) to submit with — the plugin hardcodes a single platform ID
per language with no discoverability or override mechanism.

Solution: add `LANGUAGE_VERSIONS` and `DEFAULT_VERSIONS` tables in
`constants.lua` as the single source of truth. `config.lua` gains
`version` and `submit_id` fields on `CpLanguage`/`CpPlatformOverrides`,
validated at setup time. `submit.lua` resolves the effective config to
a platform ID (priority: `submit_id` > `version` > default). Helpdocs
document the new `*cp-submit-language*` section with per-platform
available versions and the `submit_id` escape hatch. Tests cover
`LANGUAGE_IDS` completeness and `get_language_id` lookups.
This commit is contained in:
Barrett Ruth 2026-03-06 18:04:04 -05:00
parent 4e709c8470
commit b90ac67826
Signed by: barrett
GPG key ID: A6C96C9349D2FC81
5 changed files with 153 additions and 11 deletions

View file

@ -1,5 +1,6 @@
import pytest
from scrapers.language_ids import LANGUAGE_IDS, get_language_id
from scrapers.models import (
ContestListResult,
MetadataResult,
@ -137,3 +138,28 @@ def test_scraper_metadata_error(run_scraper_offline, scraper, contest_id):
assert objs
assert objs[-1].get("success") is False
assert objs[-1].get("error")
EXPECTED_PLATFORMS = {"atcoder", "codeforces", "cses", "usaco", "kattis", "codechef"}
EXPECTED_LANGUAGES = {"cpp", "python"}
def test_language_ids_coverage():
assert set(LANGUAGE_IDS.keys()) == EXPECTED_PLATFORMS
for platform, langs in LANGUAGE_IDS.items():
assert set(langs.keys()) == EXPECTED_LANGUAGES, f"{platform} missing languages"
for lang, lid in langs.items():
assert isinstance(lid, str) and lid, f"{platform}/{lang} empty ID"
@pytest.mark.parametrize("platform", EXPECTED_PLATFORMS)
@pytest.mark.parametrize("language", EXPECTED_LANGUAGES)
def test_get_language_id(platform, language):
result = get_language_id(platform, language)
assert result is not None, f"No ID for {platform}/{language}"
assert result == LANGUAGE_IDS[platform][language]
def test_get_language_id_unknown():
assert get_language_id("nonexistent", "cpp") is None
assert get_language_id("codeforces", "rust") is None