blogex: coverage floor (74) + test-scaffolding exclusions
`test_coverage` sets the floor the Lens pass enforces, measured first: 74.53% with test/support excluded (`mix test --cover` and the exported sample give the same number). The rule — a FLOOR, ratcheted up as behavior yaks land, never lowered — is written next to the config, along with why each module is excluded (test scaffolding only: fixtures measure the tests, not the library). Wiring, per the fast/push split: `test.coverage` runs the suite once with `--cover --export-coverage default`; the `coverage` sensor then enforces the floor from that export via `mix test.coverage` (no second suite run). So `verify` runs the suite first and the sensors after it. The sensor guards on the export existing: `mix test.coverage` exits 0 when it finds no .coverdata, and a floor check that did not run must not report success. blogex/.gitignore: cover/ (generated).
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
/_build/
|
/_build/
|
||||||
/deps/
|
/deps/
|
||||||
/doc/
|
/doc/
|
||||||
|
/cover/
|
||||||
*.ez
|
*.ez
|
||||||
*.beam
|
*.beam
|
||||||
.elixir_ls/
|
.elixir_ls/
|
||||||
|
|||||||
+26
-5
@@ -3,7 +3,7 @@
|
|||||||
MISE_BIN ?= mise
|
MISE_BIN ?= mise
|
||||||
MISE_EXEC = $(MISE_BIN) exec --
|
MISE_EXEC = $(MISE_BIN) exec --
|
||||||
|
|
||||||
.PHONY: check precommit deps compile test format verify
|
.PHONY: check precommit deps compile test test.coverage coverage format verify
|
||||||
|
|
||||||
# Cheap static gate for this library (no database, no coverage). Runs from the
|
# Cheap static gate for this library (no database, no coverage). Runs from the
|
||||||
# root `make check`, which loops app then blogex.
|
# root `make check`, which loops app then blogex.
|
||||||
@@ -30,6 +30,20 @@ compile:
|
|||||||
test: deps
|
test: deps
|
||||||
$(MISE_EXEC) mix test
|
$(MISE_EXEC) mix test
|
||||||
|
|
||||||
|
# Run the suite once with coverage exported, so the coverage floor check (and,
|
||||||
|
# later, CRAP) reads the export instead of running the suite a second time.
|
||||||
|
# Stale exports are removed first: the floor must never report an older run.
|
||||||
|
test.coverage: deps
|
||||||
|
rm -f cover/*.coverdata
|
||||||
|
$(MISE_EXEC) mix test --cover --export-coverage default
|
||||||
|
|
||||||
|
# Enforce the coverage floor (mix.exs -> test_coverage) from that export. No
|
||||||
|
# test run. `mix test.coverage` exits 0 when it finds no export at all, so the
|
||||||
|
# guard below is load-bearing: a floor check that did not run must not pass.
|
||||||
|
coverage:
|
||||||
|
@test -f cover/default.coverdata || { echo "coverage: no exported coverage - run 'make test.coverage' first" >&2; exit 1; }
|
||||||
|
$(MISE_EXEC) mix test.coverage
|
||||||
|
|
||||||
# Format code
|
# Format code
|
||||||
format:
|
format:
|
||||||
$(MISE_EXEC) mix format
|
$(MISE_EXEC) mix format
|
||||||
@@ -42,11 +56,18 @@ format:
|
|||||||
# and to VERIFY_SENSORS — that variable is the single source of truth for what
|
# and to VERIFY_SENSORS — that variable is the single source of truth for what
|
||||||
# this target reports as wired.
|
# this target reports as wired.
|
||||||
# - coverage (yak: coverage floors + framework-glue exclusions policy)
|
# - coverage (yak: coverage floors + framework-glue exclusions policy)
|
||||||
|
# WIRED below (test.coverage + coverage).
|
||||||
# - crap (yak: CRAP scores with ex_crap (both apps))
|
# - crap (yak: CRAP scores with ex_crap (both apps))
|
||||||
# - mutation (yak: mutation testing with muex — a sensor, not a gate)
|
# - mutation (yak: mutation testing with muex — a sensor, not a gate)
|
||||||
VERIFY_SENSORS :=
|
#
|
||||||
|
# The suite runs FIRST: it is what produces the coverage export that the
|
||||||
|
# sensors below read. (Sampling and reporting are separate steps because
|
||||||
|
# `mix test --cover --export-coverage` exports instead of printing a summary,
|
||||||
|
# and reporting through `mix test.coverage` keeps it to one suite run.) Sensors
|
||||||
|
# still run cheapest-first among themselves.
|
||||||
|
VERIFY_SENSORS := coverage
|
||||||
|
|
||||||
verify:
|
verify:
|
||||||
@echo "==> verify(blogex): sensors [$(if $(VERIFY_SENSORS),$(VERIFY_SENSORS),none wired yet)]"
|
@echo "==> verify(blogex): suite (coverage exported), then sensors [$(VERIFY_SENSORS)]"
|
||||||
@for sensor in $(VERIFY_SENSORS); do $(MAKE) $$sensor || exit 1; done
|
@$(MAKE) test.coverage
|
||||||
@$(MAKE) test
|
@for sensor in $(VERIFY_SENSORS); do echo "==> verify(blogex): sensor $$sensor"; $(MAKE) $$sensor || exit 1; done
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ defmodule Blogex.MixProject do
|
|||||||
start_permanent: Mix.env() == :prod,
|
start_permanent: Mix.env() == :prod,
|
||||||
aliases: aliases(),
|
aliases: aliases(),
|
||||||
deps: deps(),
|
deps: deps(),
|
||||||
|
test_coverage: test_coverage(),
|
||||||
docs: docs(),
|
docs: docs(),
|
||||||
package: package(),
|
package: package(),
|
||||||
description: "A multi-blog engine powered by NimblePublisher for Phoenix apps"
|
description: "A multi-blog engine powered by NimblePublisher for Phoenix apps"
|
||||||
@@ -49,6 +50,30 @@ defmodule Blogex.MixProject do
|
|||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The coverage floor the Lens pass enforces (`make verify` -> `make coverage`
|
||||||
|
# in blogex/). Rule: the threshold is a FLOOR. Raise it as behavior-test yaks
|
||||||
|
# land; never lower it. A drop means the change (or an exclusion) is wrong.
|
||||||
|
#
|
||||||
|
# Measured 2026-10-26, with the test scaffolding below excluded: 74.53% — the
|
||||||
|
# same via `mix test --cover` and via `mix test --cover --export-coverage
|
||||||
|
# default` + `mix test.coverage`. Floor is the integer below that.
|
||||||
|
#
|
||||||
|
# Excluded: the test scaffolding (Blogex.Test.*) only. Fixtures measure the
|
||||||
|
# tests, not the library. Everything in lib/blogex counts, and today's gaps
|
||||||
|
# are real: Blogex (the delegating facade), Blogex.Components and
|
||||||
|
# Blogex.Layout are at 0% because the router tests only exercise the JSON
|
||||||
|
# responses — moving this floor up is the behavior-test work.
|
||||||
|
defp test_coverage do
|
||||||
|
[
|
||||||
|
summary: [threshold: 74],
|
||||||
|
ignore_modules: [
|
||||||
|
Blogex.Test.FakeBlog,
|
||||||
|
Blogex.Test.PostBuilder,
|
||||||
|
Blogex.Test.Setup
|
||||||
|
]
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
defp docs do
|
defp docs do
|
||||||
[
|
[
|
||||||
main: "readme",
|
main: "readme",
|
||||||
|
|||||||
Reference in New Issue
Block a user