diff --git a/.github/workflows/openkal-compat.yml b/.github/workflows/openkal-compat.yml index 22eb99e9..fff25af4 100644 --- a/.github/workflows/openkal-compat.yml +++ b/.github/workflows/openkal-compat.yml @@ -108,7 +108,7 @@ jobs: shell: bash run: | archive="mcpp-${MCPP_VERSION}-linux-x86_64.tar.gz" - curl -L -fsS -o "$archive" \ + curl -L -fsS --retry 5 --retry-all-errors --retry-delay 10 -o "$archive" \ "https://github.com/mcpp-community/mcpp/releases/download/v${MCPP_VERSION}/${archive}" tar -xzf "$archive" root="$PWD/mcpp-${MCPP_VERSION}-linux-x86_64" diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index fb5006fa..be01d306 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -577,7 +577,7 @@ jobs: # needing a newer grammar cannot pass a lint pinned to an older mcpp. - name: Download pinned mcpp run: | - curl -L -fsS -o mcpp.tar.gz \ + curl -L -fsS --retry 5 --retry-all-errors --retry-delay 10 -o mcpp.tar.gz \ "https://github.com/mcpp-community/mcpp/releases/download/v${MCPP_VERSION}/mcpp-${MCPP_VERSION}-linux-x86_64.tar.gz" tar -xzf mcpp.tar.gz echo "MCPP=$PWD/mcpp-${MCPP_VERSION}-linux-x86_64/bin/mcpp" >> "$GITHUB_ENV" @@ -1210,7 +1210,7 @@ jobs: MCPP_ARCHIVE: mcpp-${{ env.MCPP_VERSION }}-linux-x86_64.tar.gz MCPP_ROOT: mcpp-${{ env.MCPP_VERSION }}-linux-x86_64 run: | - curl -L -fsS -o "$MCPP_ARCHIVE" \ + curl -L -fsS --retry 5 --retry-all-errors --retry-delay 10 -o "$MCPP_ARCHIVE" \ "https://github.com/mcpp-community/mcpp/releases/download/v${MCPP_VERSION}/${MCPP_ARCHIVE}" tar -xzf "$MCPP_ARCHIVE" root="$PWD/$MCPP_ROOT" @@ -1257,7 +1257,7 @@ jobs: shell: bash run: | archive="mcpp-${MCPP_VERSION}-${{ matrix.suffix }}.tar.gz" - curl -L -fsS -o "$archive" "https://github.com/mcpp-community/mcpp/releases/download/v${MCPP_VERSION}/$archive" + curl -L -fsS --retry 5 --retry-all-errors --retry-delay 10 -o "$archive" "https://github.com/mcpp-community/mcpp/releases/download/v${MCPP_VERSION}/$archive" tar -xzf "$archive" echo "MCPP=$PWD/mcpp-${MCPP_VERSION}-${{ matrix.suffix }}/bin/mcpp" >> "$GITHUB_ENV" - name: Immutable archive, default scaffold, strict build and loopback RPC @@ -1380,7 +1380,7 @@ jobs: MCPP_ARCHIVE: mcpp-${{ env.MCPP_VERSION }}-${{ matrix.suffix }}.${{ matrix.ext }} MCPP_ROOT: mcpp-${{ env.MCPP_VERSION }}-${{ matrix.suffix }} run: | - curl -L -fsS -o "$MCPP_ARCHIVE" \ + curl -L -fsS --retry 5 --retry-all-errors --retry-delay 10 -o "$MCPP_ARCHIVE" \ "https://github.com/mcpp-community/mcpp/releases/download/v${MCPP_VERSION}/${MCPP_ARCHIVE}" case "$MCPP_ARCHIVE" in *.zip) powershell -NoProfile -Command "Expand-Archive -Force -Path '${MCPP_ARCHIVE}' -DestinationPath '.'" ;; diff --git a/CHANGELOG.md b/CHANGELOG.md index cf445a1d..3b3f25df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,14 @@ ### Added +- **mtest 0.3.0.** `mcpplibs.mtest`、`mcpplibs.mtest.gtest`、`mcpplibs.mtest.capi` 的 0.3.0 与新包 + `mcpplibs.mtest.manifest`(同一标签、同一归档):一个对象即一个用例,类型即类别(`UTest`、`CTS`、`E2E`、`Bench`, + `Suite` 不声明类别),名字之后的属性说明它如何运行(资源、时限、隔离、重试、诊断)并由其声明的用例继承;静态用例 + 清单成为独立的包,读测试的工具不必链接测试库。测试成员 `mtest`、`mtest-gtest`、`mtest-capi` 移到 0.3.0,新成员 + `mtest-manifest` 检验清单。 +- **mtest 0.2.0.** `mcpplibs.mtest`、`mcpplibs.mtest.gtest`、`mcpplibs.mtest.capi` 的 0.2.0(同一标签、同一归档): + `mcpplibs.mtest.manifest` 从源文本读出测试文件声明的用例(静态用例清单);引擎增加 `[discover.]` 组、 + 用例属性、`--shard`、覆盖映射与 `list --static`。测试成员 `mtest`、`mtest-gtest`、`mtest-capi` 随之移到 0.2.0。 - **mcpp.plugins 0.21.0。** CMake 交叉构建在动作运行时使用引擎给出的编译器、标志、归档器与目标约定(链接可执行文件或共享库的 交叉子项目需要 mcpp 2026.11.7.1);加速器规则拥有各自的代码目标,SYCL 在一个请求中给出多个 NVIDIA 架构与 SPIR-V (mcpp#887);`plugins-progress` 写出动作的可选进度;各成员经 mcpplibs.os 0.4.0 访问系统,不包含头文件。包的下限为 diff --git a/mcpp.toml b/mcpp.toml index f7a027cc..25050548 100644 --- a/mcpp.toml +++ b/mcpp.toml @@ -126,6 +126,7 @@ members = [ "tests/examples/mtest", "tests/examples/mtest-capi", "tests/examples/mtest-gtest", + "tests/examples/mtest-manifest", "tests/examples/muduo", "tests/examples/libmysqlclient", "tests/examples/mysql-connector-cpp", diff --git a/pkgs/m/mcpplibs.mtest.capi.lua b/pkgs/m/mcpplibs.mtest.capi.lua index 1d3f2d0d..cfa14345 100644 --- a/pkgs/m/mcpplibs.mtest.capi.lua +++ b/pkgs/m/mcpplibs.mtest.capi.lua @@ -21,6 +21,20 @@ package = { xpm = { linux = { + ["0.3.0"] = { + url = { + GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.3.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/mtest/releases/download/v0.3.0/mtest-v0.3.0.tar.gz", + }, + sha256 = "b695022706d5fac107918c1d9461b953a8f462c63b78acacf52ea427e7009187", + }, + ["0.2.0"] = { + url = { + GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.2.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/mtest/releases/download/v0.2.0/mtest-v0.2.0.tar.gz", + }, + sha256 = "600f52ff1b55489b012c16174fcded3dc9b9aea112377c783a2c9425072e03d2", + }, ["0.1.0"] = { url = { GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.1.0.tar.gz", @@ -30,6 +44,20 @@ package = { }, }, macosx = { + ["0.3.0"] = { + url = { + GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.3.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/mtest/releases/download/v0.3.0/mtest-v0.3.0.tar.gz", + }, + sha256 = "b695022706d5fac107918c1d9461b953a8f462c63b78acacf52ea427e7009187", + }, + ["0.2.0"] = { + url = { + GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.2.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/mtest/releases/download/v0.2.0/mtest-v0.2.0.tar.gz", + }, + sha256 = "600f52ff1b55489b012c16174fcded3dc9b9aea112377c783a2c9425072e03d2", + }, ["0.1.0"] = { url = { GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.1.0.tar.gz", @@ -39,6 +67,20 @@ package = { }, }, windows = { + ["0.3.0"] = { + url = { + GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.3.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/mtest/releases/download/v0.3.0/mtest-v0.3.0.tar.gz", + }, + sha256 = "b695022706d5fac107918c1d9461b953a8f462c63b78acacf52ea427e7009187", + }, + ["0.2.0"] = { + url = { + GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.2.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/mtest/releases/download/v0.2.0/mtest-v0.2.0.tar.gz", + }, + sha256 = "600f52ff1b55489b012c16174fcded3dc9b9aea112377c783a2c9425072e03d2", + }, ["0.1.0"] = { url = { GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.1.0.tar.gz", diff --git a/pkgs/m/mcpplibs.mtest.gtest.lua b/pkgs/m/mcpplibs.mtest.gtest.lua index 96ec17a5..a83a296f 100644 --- a/pkgs/m/mcpplibs.mtest.gtest.lua +++ b/pkgs/m/mcpplibs.mtest.gtest.lua @@ -20,6 +20,20 @@ package = { xpm = { linux = { + ["0.3.0"] = { + url = { + GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.3.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/mtest/releases/download/v0.3.0/mtest-v0.3.0.tar.gz", + }, + sha256 = "b695022706d5fac107918c1d9461b953a8f462c63b78acacf52ea427e7009187", + }, + ["0.2.0"] = { + url = { + GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.2.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/mtest/releases/download/v0.2.0/mtest-v0.2.0.tar.gz", + }, + sha256 = "600f52ff1b55489b012c16174fcded3dc9b9aea112377c783a2c9425072e03d2", + }, ["0.1.0"] = { url = { GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.1.0.tar.gz", @@ -29,6 +43,20 @@ package = { }, }, macosx = { + ["0.3.0"] = { + url = { + GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.3.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/mtest/releases/download/v0.3.0/mtest-v0.3.0.tar.gz", + }, + sha256 = "b695022706d5fac107918c1d9461b953a8f462c63b78acacf52ea427e7009187", + }, + ["0.2.0"] = { + url = { + GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.2.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/mtest/releases/download/v0.2.0/mtest-v0.2.0.tar.gz", + }, + sha256 = "600f52ff1b55489b012c16174fcded3dc9b9aea112377c783a2c9425072e03d2", + }, ["0.1.0"] = { url = { GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.1.0.tar.gz", @@ -38,6 +66,20 @@ package = { }, }, windows = { + ["0.3.0"] = { + url = { + GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.3.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/mtest/releases/download/v0.3.0/mtest-v0.3.0.tar.gz", + }, + sha256 = "b695022706d5fac107918c1d9461b953a8f462c63b78acacf52ea427e7009187", + }, + ["0.2.0"] = { + url = { + GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.2.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/mtest/releases/download/v0.2.0/mtest-v0.2.0.tar.gz", + }, + sha256 = "600f52ff1b55489b012c16174fcded3dc9b9aea112377c783a2c9425072e03d2", + }, ["0.1.0"] = { url = { GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.1.0.tar.gz", diff --git a/pkgs/m/mcpplibs.mtest.manifest.lua b/pkgs/m/mcpplibs.mtest.manifest.lua new file mode 100644 index 00000000..d2956a5e --- /dev/null +++ b/pkgs/m/mcpplibs.mtest.manifest.lua @@ -0,0 +1,54 @@ +-- mcpplibs.mtest.manifest --- mtest's static case manifest. +-- +-- A package of mcpp-community/mtest (one tag, one archive): the cases a source +-- file declares with mcpplibs.mtest -- objects, the cases they declare, their +-- kinds and attributes -- read from its text without building it. A tool that +-- reads tests (mtest's engine, an editor) depends on it alone. +package = { + spec = "1", + namespace = "mcpplibs.mtest", + name = "manifest", + description = "mtest's static case manifest: the cases a source file declares, with their kinds and attributes, read without building it", + licenses = {"Apache-2.0"}, + repo = "https://github.com/mcpp-community/mtest", + type = "package", + + extensions = { + autoupdate = { + tag = "v${version}", + url = "https://github.com/mcpp-community/mtest/archive/refs/tags/${tag}.tar.gz", + }, + }, + + xpm = { + linux = { + ["0.3.0"] = { + url = { + GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.3.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/mtest/releases/download/v0.3.0/mtest-v0.3.0.tar.gz", + }, + sha256 = "b695022706d5fac107918c1d9461b953a8f462c63b78acacf52ea427e7009187", + }, + }, + macosx = { + ["0.3.0"] = { + url = { + GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.3.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/mtest/releases/download/v0.3.0/mtest-v0.3.0.tar.gz", + }, + sha256 = "b695022706d5fac107918c1d9461b953a8f462c63b78acacf52ea427e7009187", + }, + }, + windows = { + ["0.3.0"] = { + url = { + GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.3.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/mtest/releases/download/v0.3.0/mtest-v0.3.0.tar.gz", + }, + sha256 = "b695022706d5fac107918c1d9461b953a8f462c63b78acacf52ea427e7009187", + }, + }, + }, + + mcpp = "*/manifest/mcpp.toml", +} diff --git a/pkgs/m/mtest.lua b/pkgs/m/mtest.lua index ffe5e9ba..49a2b73d 100644 --- a/pkgs/m/mtest.lua +++ b/pkgs/m/mtest.lua @@ -23,6 +23,20 @@ package = { xpm = { linux = { + ["0.3.0"] = { + url = { + GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.3.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/mtest/releases/download/v0.3.0/mtest-v0.3.0.tar.gz", + }, + sha256 = "b695022706d5fac107918c1d9461b953a8f462c63b78acacf52ea427e7009187", + }, + ["0.2.0"] = { + url = { + GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.2.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/mtest/releases/download/v0.2.0/mtest-v0.2.0.tar.gz", + }, + sha256 = "600f52ff1b55489b012c16174fcded3dc9b9aea112377c783a2c9425072e03d2", + }, ["0.1.0"] = { url = { GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.1.0.tar.gz", @@ -32,6 +46,20 @@ package = { }, }, macosx = { + ["0.3.0"] = { + url = { + GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.3.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/mtest/releases/download/v0.3.0/mtest-v0.3.0.tar.gz", + }, + sha256 = "b695022706d5fac107918c1d9461b953a8f462c63b78acacf52ea427e7009187", + }, + ["0.2.0"] = { + url = { + GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.2.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/mtest/releases/download/v0.2.0/mtest-v0.2.0.tar.gz", + }, + sha256 = "600f52ff1b55489b012c16174fcded3dc9b9aea112377c783a2c9425072e03d2", + }, ["0.1.0"] = { url = { GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.1.0.tar.gz", @@ -41,6 +69,20 @@ package = { }, }, windows = { + ["0.3.0"] = { + url = { + GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.3.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/mtest/releases/download/v0.3.0/mtest-v0.3.0.tar.gz", + }, + sha256 = "b695022706d5fac107918c1d9461b953a8f462c63b78acacf52ea427e7009187", + }, + ["0.2.0"] = { + url = { + GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.2.0.tar.gz", + CN = "https://gitcode.com/mcpp-res/mtest/releases/download/v0.2.0/mtest-v0.2.0.tar.gz", + }, + sha256 = "600f52ff1b55489b012c16174fcded3dc9b9aea112377c783a2c9425072e03d2", + }, ["0.1.0"] = { url = { GLOBAL = "https://github.com/mcpp-community/mtest/archive/refs/tags/v0.1.0.tar.gz", diff --git a/tests/autoupdate/ci.py b/tests/autoupdate/ci.py index e8b0b62d..4cdf6c49 100644 --- a/tests/autoupdate/ci.py +++ b/tests/autoupdate/ci.py @@ -151,10 +151,7 @@ def dependency_tables(table): candidates.append((category, path.parent.name)) continue for deps in dependency_tables(manifest): - nested = deps - for part in namespace.split("."): - nested = nested.get(part, {}) if isinstance(nested, dict) else {} - if (f"{namespace}.{name}" in deps or name in deps.get(namespace, {}) or name in nested): + if names_dependency(deps, namespace, name): candidates.append((category, path.parent.name)) break if not candidates: @@ -172,12 +169,24 @@ def member_manifest(member: str) -> Path: raise FileNotFoundError(f"consumer manifest not found: {member}") +SPEC_KEYS = {"version", "path", "git", "branch", "tag", "rev", "features", "default-features", + "optional", "host-module", "tools", "artifacts", "visibility", "linkage", "embed"} + + +def is_spec(value) -> bool: + """A dependency's specification, as opposed to the table of a namespace below it: a version + string, or a table of a specification's keys (`mcpplibs.mtest.capi = "0.2.0"` makes + `mcpplibs.mtest` the table `{capi = "0.2.0"}`, which names no dependency).""" + return isinstance(value, str) or (isinstance(value, dict) and bool(SPEC_KEYS & value.keys())) + + def names_dependency(deps: dict, namespace: str, name: str) -> bool: nested = deps for part in namespace.split("."): nested = nested.get(part, {}) if isinstance(nested, dict) else {} - return (f"{namespace}.{name}" in deps - or name in deps.get(namespace, {}) or name in nested) + return (is_spec(deps.get(f"{namespace}.{name}")) + or is_spec(deps.get(namespace, {}).get(name) if isinstance(deps.get(namespace), dict) else None) + or (isinstance(nested, dict) and is_spec(nested.get(name)))) # The runner platforms, by the spelling a member's `cfg(os = ...)` uses. @@ -232,6 +241,16 @@ def condition_platforms(condition: str) -> set[str]: return out +def version_key(version: str) -> tuple: + """A dotted version's order: its numeric parts as numbers, any other part + after them as text (`0.10.0` after `0.9.0`).""" + return tuple((0, int(p), "") if p.isdigit() else (1, 0, p) for p in re.split(r"[.+-]", version)) + + +def newest(versions: set[str]) -> str: + return max(versions, key=version_key) + + def matrix(plan: Path, output: Path, base: str): build_plan = json.loads(plan.read_text(encoding="utf-8")) # A normal bump PR already contains its candidate, so discovery says up-to-date. @@ -247,9 +266,10 @@ def matrix(plan: Path, output: Path, base: str): added = {v for plat, entries in new.items() for v in entries if v not in old.get(plat, {})} if not added: continue - if len(added) != 1: - raise RuntimeError(f"expected one added candidate for {info['id']}: {added}") - candidate = added.pop() + # A change that adds several releases of one package (two releases cut + # while its pull request was open) is proven at the newest: the one + # consumers are moved to, and whose archive the older ones precede. + candidate = newest(added) assets = [] for plat, platform in info["platforms"].items(): if candidate not in platform["entries"]: @@ -301,9 +321,12 @@ def archive_of(record): def replace_candidate(text: str, identity: str, version: str) -> str: + # The key as a consumer writes it: the bare name under the namespace's + # table, or the identity key, quoted or not (`mcpplibs.mtest.capi = ...`, + # the form mcpp recommends since 2026.11.8.1). namespace, name = identity.split(":", 1) text, replacements = re.subn( - rf'(?m)^(\s*(?:{re.escape(name)}|"{re.escape(namespace)}\.{re.escape(name)}")\s*=\s*(?:\{{\s*version\s*=\s*)?")[^"]+(".*)$', + rf'(?m)^(\s*(?:{re.escape(name)}|"?{re.escape(namespace)}\.{re.escape(name)}"?)\s*=\s*(?:\{{\s*version\s*=\s*)?")[^"]+(".*)$', lambda m: m[1] + version + m[2], text) if not replacements: # A platform the member selects (mcpp SPEC-013). diff --git a/tests/autoupdate/test_ci.py b/tests/autoupdate/test_ci.py index d2b68d09..e746dcd9 100644 --- a/tests/autoupdate/test_ci.py +++ b/tests/autoupdate/test_ci.py @@ -25,6 +25,11 @@ def descriptor(name): class BaselineTests(unittest.TestCase): + def test_several_added_releases_are_proven_at_the_newest(self): + self.assertEqual(ci.newest({"0.2.0", "0.3.0"}), "0.3.0") + self.assertEqual(ci.newest({"0.9.0", "0.10.0"}), "0.10.0") + self.assertEqual(ci.newest({"2026.11.7.2", "2026.11.10.1"}), "2026.11.10.1") + def test_one_consumer_uses_all_and_only_its_planned_candidates(self): with tempfile.TemporaryDirectory() as directory: root = Path(directory) @@ -113,6 +118,24 @@ def test_mwrap_candidate_uses_its_actual_member_and_qualified_dependency(self): self.assertEqual(result["dependencies"]["mcpplibs.mwrap.example"], "1.0.1") self.assertEqual((dest / "tests/probe.cpp").read_text(), 'int main() { return 0; }\n') + def test_an_unquoted_identity_key_is_replaced(self): + # The key mcpp recommends (2026.11.8.1): the identity, dotted and unquoted, which TOML + # reads as nested tables. + text = '[dev-dependencies]\nmcpplibs.mtest.capi = "0.2.0"\nmcpplibs.mtest = "0.2.0"\n' + replaced = ci.replace_candidate(text, "mcpplibs.mtest:capi", "0.3.0") + self.assertIn('mcpplibs.mtest.capi = "0.3.0"', replaced) + self.assertIn('mcpplibs.mtest = "0.2.0"', replaced) + replaced = ci.replace_candidate(text, "mcpplibs:mtest", "0.3.0") + self.assertIn('mcpplibs.mtest = "0.3.0"', replaced) + self.assertIn('mcpplibs.mtest.capi = "0.2.0"', replaced) + + def test_a_package_below_a_namespace_does_not_name_the_namespace_package(self): + # `mcpplibs.mtest.capi = ...` reads as the table mcpplibs.mtest = {capi = ...}, which names + # mcpplibs.mtest:capi and not mcpplibs:mtest. + deps = tomllib.loads('[dependencies]\nmcpplibs.mtest.capi = "0.2.0"\n')["dependencies"] + self.assertTrue(ci.names_dependency(deps, "mcpplibs.mtest", "capi")) + self.assertFalse(ci.names_dependency(deps, "mcpplibs", "mtest")) + def test_candidate_discovers_target_and_build_dependencies(self): with tempfile.TemporaryDirectory() as directory: root = Path(directory) diff --git a/tests/examples/mtest-capi/mcpp.toml b/tests/examples/mtest-capi/mcpp.toml index 83594271..d5e325c4 100644 --- a/tests/examples/mtest-capi/mcpp.toml +++ b/tests/examples/mtest-capi/mcpp.toml @@ -8,4 +8,4 @@ version = "0.1.0" # Use the complete candidate built-in index prepared by tests/run_members.sh. [dependencies] -mcpplibs.mtest.capi = "0.1.0" +mcpplibs.mtest.capi = "0.3.0" diff --git a/tests/examples/mtest-gtest/mcpp.toml b/tests/examples/mtest-gtest/mcpp.toml index 9d31f3a3..b099c332 100644 --- a/tests/examples/mtest-gtest/mcpp.toml +++ b/tests/examples/mtest-gtest/mcpp.toml @@ -10,7 +10,7 @@ version = "0.1.0" [dev-dependencies] compat.gtest = "1.18.0" -mcpplibs.mtest.gtest = "0.1.0" +mcpplibs.mtest.gtest = "0.3.0" [test] main = { from = "mcpplibs.mtest.gtest/main" } diff --git a/tests/examples/mtest-manifest/mcpp.toml b/tests/examples/mtest-manifest/mcpp.toml new file mode 100644 index 00000000..5bf95643 --- /dev/null +++ b/tests/examples/mtest-manifest/mcpp.toml @@ -0,0 +1,11 @@ +# mcpplibs.mtest.manifest test project: the cases a source file declares, read from its text -- +# an object, the cases it declares, their kinds and attributes -- through the published index. +[package] +name = "mtest-manifest-tests" +version = "0.1.0" + +[indices] +# Use the complete candidate built-in index prepared by tests/run_members.sh. + +[dependencies] +mcpplibs.mtest.manifest = "0.3.0" diff --git a/tests/examples/mtest-manifest/tests/scan.cpp b/tests/examples/mtest-manifest/tests/scan.cpp new file mode 100644 index 00000000..abfd3cba --- /dev/null +++ b/tests/examples/mtest-manifest/tests/scan.cpp @@ -0,0 +1,14 @@ +import std; +import mcpplibs.mtest.manifest; + +int main() { + const auto cases = mcpplibs::mtest::manifest::scan( + "E2E cli{\"cli\", resource{\"serial:home\"}, [] {\n" + " \"prints its version\"_test[tag{\"fast\"}] = [] {};\n" + "}};\n"); + if (cases.size() != 2) return 1; + if (cases[0].id != "cli" || cases[0].kind != "e2e" || cases[0].resources != std::vector{"serial:home"}) return 2; + if (cases[1].id != "cli/prints its version" || cases[1].tags != std::vector{"fast"}) return 3; + std::println("mtest-manifest: {} cases, {} of kind {}", cases.size(), cases[0].id, cases[0].kind); + return 0; +} diff --git a/tests/examples/mtest/mcpp.toml b/tests/examples/mtest/mcpp.toml index 3f1a09f0..9d72d501 100644 --- a/tests/examples/mtest/mcpp.toml +++ b/tests/examples/mtest/mcpp.toml @@ -1,5 +1,6 @@ -# mcpplibs.mtest test project: cases, expectations, an expected failure and parameters through the -# published index, reported by the library's own `report()`. +# mcpplibs.mtest test project: objects that are cases, the cases they declare, attributes, an +# expected failure and parameters through the published index, reported by the library's own +# `report()`. [package] name = "mtest-tests" version = "0.1.0" @@ -8,4 +9,4 @@ version = "0.1.0" # Use the complete candidate built-in index prepared by tests/run_members.sh. [dev-dependencies] -mcpplibs.mtest = "0.1.0" +mcpplibs.mtest = "0.3.0" diff --git a/tests/examples/mtest/tests/cases.cpp b/tests/examples/mtest/tests/cases.cpp index e5d3935f..25222bf7 100644 --- a/tests/examples/mtest/tests/cases.cpp +++ b/tests/examples/mtest/tests/cases.cpp @@ -1,9 +1,14 @@ import std; import mcpplibs.mtest; using namespace mcpplibs::mtest; -int main() { + +UTest parsing{"parsing", tag{"fast"}, [] { "a comparison holds"_test = [] { expect(eq(1 + 1, 2)); }; "a failure reports both sides"_test[expect_failure{"shown"}] = [] { expect(eq(std::string("a"), std::string("b"))); }; +}}; +E2E timed{"a case with a time limit", timeout{std::chrono::seconds{30}}, [] { expect(true); }}; + +int main() { "parameters"_test = values{2, 4, 6} | [](int v) { expect(eq(v % 2, 0)); }; return report(); }