From 5bb9deb0ca11807aed27aa4cd8e537f43e22db83 Mon Sep 17 00:00:00 2001 From: Jono Prest Date: Wed, 10 Jun 2026 14:25:51 +0000 Subject: [PATCH 1/5] coverage: include gentype and analysis test suites The coverage suite previously only ran `node scripts/test.js -all` (mocha/build/ounit/docstrings), leaving compiler/gentype and the whole analysis/ tree uninstrumented in the report. Run the additional suites under the same BISECT_FILE env so their instrumented binaries accumulate counters: - gentype tests compile via the instrumented bsc in BIN_DIR - analysis tests run the instrumented rescript-editor-analysis - tools tests run the instrumented rescript-tools (links analysis + reanalyze) Use the analysis suite's test-analysis-binary target rather than its full test: the reanalyze tests invoke the binary via `dune exec`, which rebuilds it uninstrumented and strips instrumentation from the shared _build artifacts, so they produce no coverage and would corrupt the build for later suites. --- Makefile | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 9b096b7c00e..dcf1de89252 100644 --- a/Makefile +++ b/Makefile @@ -237,6 +237,12 @@ checkformat: | $(YARN_INSTALL_STAMP) # make coverage # run full test suite, generate report # make clean-coverage # remove coverage artifacts # +# Suites covered: the `scripts/test.js -all` suites (mocha/build/ounit/ +# docstrings) plus the gentype tests (compiler/gentype, via the instrumented +# bsc) and the analysis + tools tests (analysis/, via the instrumented +# rescript-editor-analysis and rescript-tools). The reanalyze tests are +# excluded — see the coverage-run target for why. +# # Outputs (under _coverage/): # html/index.html — human-browsable line-level report # coverage.json — Coveralls-format JSON, queryable with jq: @@ -253,6 +259,10 @@ COVERAGE_FILES_DIR := $(COVERAGE_DIR)/files COVERAGE_HTML_DIR := $(COVERAGE_DIR)/html COVERAGE_JSON := $(COVERAGE_DIR)/coverage.json COVERAGE_BISECT_PREFIX := $(abspath $(COVERAGE_FILES_DIR))/bisect +# Env that makes instrumented binaries append their counters to the shared +# coverage prefix. bisect_ppx adds a unique per-process suffix, so many +# concurrent `bsc` / analysis processes accumulate without colliding. +COVERAGE_TEST_ENV := BISECT_FILE=$(COVERAGE_BISECT_PREFIX) BISECT_SILENT=YES # Re-builds the toolchain with bisect_ppx instrumentation and swaps the # instrumented binaries into BIN_DIR so any test runner that shells out to @@ -278,10 +288,26 @@ coverage-lib: coverage-prepare yarn workspace @rescript/runtime build rm -f $(COVERAGE_BISECT_PREFIX)-discard*.coverage +# Run the test suites that exercise the instrumented toolchain. Each suite +# shells out to a binary that `coverage-build` instrumented: +# - `node scripts/test.js -all` drives bsc (mocha/build/ounit/docstrings). +# - gentype tests compile via `rescript build`, i.e. the instrumented bsc in +# BIN_DIR, so they add coverage for compiler/gentype. +# - analysis tests run the instrumented `rescript-editor-analysis` and tools +# tests the instrumented `rescript-tools` (which links analysis + reanalyze), +# both from _build/install/default/bin — adding coverage for analysis/. +# We deliberately run the analysis suite's `test-analysis-binary` target rather +# than its full `test`: the reanalyze tests invoke the binary via `dune exec`, +# which would rebuild it *uninstrumented* (and strip instrumentation from the +# shared _build artifacts mid-run), so they produce no coverage and would +# corrupt the instrumented build for later suites. .PHONY: coverage-run coverage-run: coverage-lib - BISECT_FILE=$(COVERAGE_BISECT_PREFIX) BISECT_SILENT=YES \ - node scripts/test.js -all + $(COVERAGE_TEST_ENV) node scripts/test.js -all + $(COVERAGE_TEST_ENV) make -C tests/gentype_tests/typescript-react-example clean test + $(COVERAGE_TEST_ENV) make -C tests/gentype_tests/stdlib-no-shims clean test + $(COVERAGE_TEST_ENV) make -C tests/analysis_tests clean test-analysis-binary + $(COVERAGE_TEST_ENV) make -C tests/tools_tests clean test .PHONY: coverage-report coverage-report: From 8c8448c9cf116c06c1b4048edb3cf0434283dc2f Mon Sep 17 00:00:00 2001 From: Jono Prest Date: Wed, 10 Jun 2026 14:53:59 +0000 Subject: [PATCH 2/5] coverage: include syntax tests The syntax suite (scripts/test_syntax.sh) is a merge-gating test on all platforms but contributed no coverage: it drives the res_parser binary, which is instrumented (it carries the bisect_ppx stanza and links the instrumented compiler/syntax lib) and is invoked from _build/install/default/bin, the same pattern as the analysis tests. Run it under BISECT_FILE so compiler/syntax is no longer a blind spot. ROUNDTRIP_TEST=1 matches Linux CI and also exercises the printer paths. --- Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index dcf1de89252..9eade0f235b 100644 --- a/Makefile +++ b/Makefile @@ -238,7 +238,8 @@ checkformat: | $(YARN_INSTALL_STAMP) # make clean-coverage # remove coverage artifacts # # Suites covered: the `scripts/test.js -all` suites (mocha/build/ounit/ -# docstrings) plus the gentype tests (compiler/gentype, via the instrumented +# docstrings), the syntax tests (compiler/syntax, via the instrumented +# res_parser), the gentype tests (compiler/gentype, via the instrumented # bsc) and the analysis + tools tests (analysis/, via the instrumented # rescript-editor-analysis and rescript-tools). The reanalyze tests are # excluded — see the coverage-run target for why. @@ -291,6 +292,9 @@ coverage-lib: coverage-prepare # Run the test suites that exercise the instrumented toolchain. Each suite # shells out to a binary that `coverage-build` instrumented: # - `node scripts/test.js -all` drives bsc (mocha/build/ounit/docstrings). +# - the syntax tests drive the instrumented `res_parser` from +# _build/install/default/bin, adding coverage for compiler/syntax. +# ROUNDTRIP_TEST=1 matches Linux CI and also exercises the printer paths. # - gentype tests compile via `rescript build`, i.e. the instrumented bsc in # BIN_DIR, so they add coverage for compiler/gentype. # - analysis tests run the instrumented `rescript-editor-analysis` and tools @@ -304,6 +308,7 @@ coverage-lib: coverage-prepare .PHONY: coverage-run coverage-run: coverage-lib $(COVERAGE_TEST_ENV) node scripts/test.js -all + $(COVERAGE_TEST_ENV) ROUNDTRIP_TEST=1 ./scripts/test_syntax.sh $(COVERAGE_TEST_ENV) make -C tests/gentype_tests/typescript-react-example clean test $(COVERAGE_TEST_ENV) make -C tests/gentype_tests/stdlib-no-shims clean test $(COVERAGE_TEST_ENV) make -C tests/analysis_tests clean test-analysis-binary From 8f9fdb65f3f44a05330cec825951ff9b717f189d Mon Sep 17 00:00:00 2001 From: Jono Prest Date: Wed, 10 Jun 2026 14:58:35 +0000 Subject: [PATCH 3/5] coverage: include reanalyze tests via DUNE_INSTRUMENT_WITH The reanalyze tests invoke rescript-tools through `dune exec`, so they ran an uninstrumented binary and produced no coverage (and a plain `dune exec` would rebuild the shared _build artifacts uninstrumented). Set DUNE_INSTRUMENT_WITH=bisect_ppx (the env-var form of `--instrument-with`) for the analysis suite so that `dune exec` matches the instrumentation config coverage-build already used. dune finds the build up to date, runs the instrumented binary, and reanalyze now contributes coverage for analysis/reanalyze without any test-script changes. Switch the analysis line from test-analysis-binary to the full test target to pull reanalyze in. --- Makefile | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 9eade0f235b..a99e21bd2be 100644 --- a/Makefile +++ b/Makefile @@ -240,9 +240,8 @@ checkformat: | $(YARN_INSTALL_STAMP) # Suites covered: the `scripts/test.js -all` suites (mocha/build/ounit/ # docstrings), the syntax tests (compiler/syntax, via the instrumented # res_parser), the gentype tests (compiler/gentype, via the instrumented -# bsc) and the analysis + tools tests (analysis/, via the instrumented -# rescript-editor-analysis and rescript-tools). The reanalyze tests are -# excluded — see the coverage-run target for why. +# bsc) and the analysis + tools tests, including reanalyze (analysis/, via +# the instrumented rescript-editor-analysis and rescript-tools). # # Outputs (under _coverage/): # html/index.html — human-browsable line-level report @@ -300,18 +299,19 @@ coverage-lib: coverage-prepare # - analysis tests run the instrumented `rescript-editor-analysis` and tools # tests the instrumented `rescript-tools` (which links analysis + reanalyze), # both from _build/install/default/bin — adding coverage for analysis/. -# We deliberately run the analysis suite's `test-analysis-binary` target rather -# than its full `test`: the reanalyze tests invoke the binary via `dune exec`, -# which would rebuild it *uninstrumented* (and strip instrumentation from the -# shared _build artifacts mid-run), so they produce no coverage and would -# corrupt the instrumented build for later suites. +# The reanalyze tests (run by the analysis suite's full `test`) invoke the +# binary via `dune exec`, which would otherwise rebuild it *uninstrumented*. +# Setting DUNE_INSTRUMENT_WITH=bisect_ppx (the env-var form of +# `--instrument-with`) makes that `dune exec` match the config coverage-build +# already used, so it runs the instrumented binary — no rebuild, no coverage +# gap, and no de-instrumentation of the shared _build artifacts. .PHONY: coverage-run coverage-run: coverage-lib $(COVERAGE_TEST_ENV) node scripts/test.js -all $(COVERAGE_TEST_ENV) ROUNDTRIP_TEST=1 ./scripts/test_syntax.sh $(COVERAGE_TEST_ENV) make -C tests/gentype_tests/typescript-react-example clean test $(COVERAGE_TEST_ENV) make -C tests/gentype_tests/stdlib-no-shims clean test - $(COVERAGE_TEST_ENV) make -C tests/analysis_tests clean test-analysis-binary + $(COVERAGE_TEST_ENV) DUNE_INSTRUMENT_WITH=bisect_ppx make -C tests/analysis_tests clean test $(COVERAGE_TEST_ENV) make -C tests/tools_tests clean test .PHONY: coverage-report From 6803ce09d7510e131208775bffa83f6f6c1a7027 Mon Sep 17 00:00:00 2001 From: Jono Prest Date: Wed, 10 Jun 2026 15:21:39 +0000 Subject: [PATCH 4/5] coverage: instrument the reanalyze library MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The DUNE_INSTRUMENT_WITH change alone routed the reanalyze tests to an instrumented rescript-tools, but the reanalyze library itself declared no instrumentation backend, so its own 58 source files recorded zero coverage (only the analysis/tools code it links was counted). Add the (instrumentation (backend bisect_ppx)) stanza — matching every other analysis/* and tools/* library — so analysis/reanalyze/src is measured. Verified locally: reanalyze goes from 0 to ~61% line coverage in the report. The stanza is a no-op for normal builds (it only activates under --instrument-with / DUNE_INSTRUMENT_WITH). --- Makefile | 6 ++++-- analysis/reanalyze/src/dune | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index a99e21bd2be..bec611f7661 100644 --- a/Makefile +++ b/Makefile @@ -303,8 +303,10 @@ coverage-lib: coverage-prepare # binary via `dune exec`, which would otherwise rebuild it *uninstrumented*. # Setting DUNE_INSTRUMENT_WITH=bisect_ppx (the env-var form of # `--instrument-with`) makes that `dune exec` match the config coverage-build -# already used, so it runs the instrumented binary — no rebuild, no coverage -# gap, and no de-instrumentation of the shared _build artifacts. +# already used, so it runs the instrumented binary — no rebuild, no +# de-instrumentation of the shared _build artifacts. (The reanalyze library +# also carries its own bisect_ppx instrumentation stanza so its source is +# counted, not just the analysis/tools code it links.) .PHONY: coverage-run coverage-run: coverage-lib $(COVERAGE_TEST_ENV) node scripts/test.js -all diff --git a/analysis/reanalyze/src/dune b/analysis/reanalyze/src/dune index 7573766dfb3..e3ffbf08966 100644 --- a/analysis/reanalyze/src/dune +++ b/analysis/reanalyze/src/dune @@ -1,5 +1,7 @@ (library (name reanalyze) + (instrumentation + (backend bisect_ppx)) (flags (-w "+6+26+27+32+33+39")) (libraries reactive yojson ml str unix)) From 4e80945df6edfb84964eee49c1c8150fad032121 Mon Sep 17 00:00:00 2001 From: Jono Prest Date: Wed, 10 Jun 2026 19:31:41 +0200 Subject: [PATCH 5/5] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 824fb890a03..7add39a3417 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,7 @@ - Convert OCaml codebase to snake case format. https://github.com/rescript-lang/rescript/pull/8456 - Analysis refactor: remove global state `Shared_types.state`. https://github.com/rescript-lang/rescript/pull/8465 - Refactor analysis CLI helpers to use source input. https://github.com/rescript-lang/rescript/pull/8466 +- Include syntax, gentype, analysis, tools, and reanalyze tests in coverage reports. https://github.com/rescript-lang/rescript/pull/8467 # 13.0.0-alpha.4