Calculator verification
Live test-suite results · last run 2 May 2026 at 19:50
Every release of the calculator runs an automated regression suite against authoritative EU sources before it ships. This page surfaces the latest results so brokers, customs officers, and counterparties can verify the methodology themselves without taking our word for it.
Numeric precision matches Implementing Reg (EU) 2025/2547 Annex II §A.2: intensity values clamped to ≤5 decimal places (§A.2.8), per-shipment emission totals preserve all significant digits (§A.2.7), monetary totals to cent precision. Means our outputs round identically to the EU's own SAT and Communication Template Excels — the CBAM Registry won't reject submissions for precision drift.
Tests run
53
Passing
53
Failing
0
Cost-calculation reference cases
Each case is a (CN code, country, tonnage) tuple with an EXPECTED net cost computed by hand from the EU formula in Reg (EU) 2025/2620§3-§4 + Article 10a(1a) of Directive 2003/87/EC. If the calculator's output drifts by more than the case's tolerance, the test fails and the build doesn't ship.
Aluminium hollow profiles · CN 76042100 + Turkey + 100t (default data)
Expected: €20,044.74 ± €5
▶Derivation + sources
embedded = 4.11554 tCO₂e/t × 100 t = 411.554 tCO₂e | BMg(Column B, route K) = 1.493 tCO₂e/t | SEFA = 0.975 (CBAM factor 2026) × 1.00 (CSCF) × 1.493 × 100 = 145.5675 tCO₂e | net = 411.554 − 145.5675 = 265.9865 tCO₂e | cost = 265.9865 × €75.36 = €20,044.74
Hot-rolled flat steel · CN 72081000 + Turkey + 100t (default data, single EU route)
Expected: €10,056.89 ± €5
▶Derivation + sources
embedded = 2.670263 tCO₂e/t × 100 t = 267.0263 tCO₂e | BMg(Column B, route C) = 1.37 tCO₂e/t | SEFA = 0.975 × 1.00 × 1.37 × 100 = 133.575 tCO₂e | net = 267.0263 − 133.575 = 133.4513 tCO₂e | cost = 133.4513 × €75.36 = €10,056.89
Hydrogen · CN 28041000 + Egypt + 100t (single-route sector)
Expected: €0.00 ± €1
▶Derivation + sources
Hydrogen single-route sector — no Column A/B distinction. Test asserts the EU formula matches our calc for the (embedded, no-benchmark) case.
Cement · Grey clinker CN 25231000 + Algeria + 100t (multi-route, route A)
Expected: €5,717.19 ± €30
▶Derivation + sources
embedded(A) = 1.408 tCO₂e/t × 100 t = 140.8 | BMg(Column B) = 0.666 | SEFA = 0.975 × 1.00 × 0.666 × 100 = 64.935 | net = 75.865 × €75.36 = €5,717.19
Cement · White clinker CN 25231000 + Algeria + 100t (route B, higher intensity)
Expected: €6,500.00 ± €1500
▶Derivation + sources
embedded(B) = 1.474 tCO₂e/t × 100 t = 147.4 | Same benchmark formula as (A); net cost should be MEASURABLY higher than route (A) due to higher intensity.
Aluminium · Unwrought CN 76011000 + Algeria + 100t (single route L, country-specific)
Expected: €80.00 ± €100
▶Derivation + sources
DZA aluminium uses route (L) low intensity (0.396 tCO₂e/t). Net cost low because EU default for aluminium ingots is small and benchmark covers most of it.
Fertilisers · Urea aqueous low-N CN 31021012 + Macao + 300t
Expected: €13,849.66 ± €50
▶Derivation + sources
ZZZ value_2026 = 0.909 tCO₂e/t (Macao falls back to ZZZ via Reg 2025/2621 Annex I) | BMg(Column B, default-data path) = 0.304 tCO₂e/t | SEFA = 0.975 × 1.00 × 0.304 × 300 = 88.92 tCO₂e | net = (272.7 − 88.92) × €75.36 = €13,849.66
Fertilisers · Ammonia CN 28141000 + China + 100t (high-emissions origin)
Expected: €25,000.00 ± €5000
▶Derivation + sources
CHN value_2026 = 4.4036 tCO₂e/t (coal-route ammonia, high emissions) × 100 t = 440.36 tCO₂e. Net cost in €20k–€30k range after free-allocation deduction.
EU CBAM Self Assessment Tool cross-check
Every CN code the EU's SAT v1.0 (28 March 2025) marks as CBAM-applies is asserted to resolve as in-scope by our scope checker. The same suite verifies our sector mapping (cement / iron-steel / aluminium / fertilisers / electricity / hydrogen) matches the SAT's main-category column.
573 CN codes scoped correctly · 6 sectors mapped correctly
Raw test suite results
tests/cbam-calc-coverage.test.ts
- Per-sector calc-coverage sweep (573 CN codes) Cement: all 6 CN codes return status='ok' or 'needs_data' (no throws / no NaN)8141ms
- Per-sector calc-coverage sweep (573 CN codes) Cement: ok-status results stay within €30–€200/t sanity band2812ms
- Per-sector calc-coverage sweep (573 CN codes) Iron and steel: all 479 CN codes return status='ok' or 'needs_data' (no throws / no NaN)14681ms
- Per-sector calc-coverage sweep (573 CN codes) Iron and steel: ok-status results stay within €30–€350/t sanity band3571ms
- Per-sector calc-coverage sweep (573 CN codes) Electricity: all 1 CN codes return status='ok' or 'needs_data' (no throws / no NaN)3145ms
- Per-sector calc-coverage sweep (573 CN codes) Electricity: ok-status results stay within €1–€100/t sanity band1830ms
- Per-sector calc-coverage sweep (573 CN codes) Chemicals (hydrogen): all 1 CN codes return status='ok' or 'needs_data' (no throws / no NaN)1941ms
- Per-sector calc-coverage sweep (573 CN codes) Chemicals (hydrogen): ok-status results stay within €100–€2000/t sanity band1991ms
- Per-sector calc-coverage sweep (573 CN codes) Fertilisers: all 27 CN codes return status='ok' or 'needs_data' (no throws / no NaN)2157ms
- Per-sector calc-coverage sweep (573 CN codes) Fertilisers: ok-status results stay within €10–€500/t sanity band1951ms
- Per-sector calc-coverage sweep (573 CN codes) Aluminium: all 59 CN codes return status='ok' or 'needs_data' (no throws / no NaN)3255ms
- Per-sector calc-coverage sweep (573 CN codes) Aluminium: ok-status results stay within €50–€600/t sanity band2615ms
tests/cbam-calc-reference.test.ts
- CBAM cost-calculation reference cases Aluminium hollow profiles · CN 76042100 + Turkey + 100t (default data)6665ms
- CBAM cost-calculation reference cases Hot-rolled flat steel · CN 72081000 + Turkey + 100t (default data, single EU route)3239ms
- CBAM cost-calculation reference cases Hydrogen · CN 28041000 + Egypt + 100t (single-route sector)1921ms
- CBAM cost-calculation reference cases Cement · Grey clinker CN 25231000 + Algeria + 100t (multi-route, route A)3310ms
- CBAM cost-calculation reference cases Cement · White clinker CN 25231000 + Algeria + 100t (route B, higher intensity)1994ms
- CBAM cost-calculation reference cases Aluminium · Unwrought CN 76011000 + Algeria + 100t (single route L, country-specific)4490ms
- CBAM cost-calculation reference cases Fertilisers · Urea aqueous low-N CN 31021012 + Macao + 300t2725ms
- CBAM cost-calculation reference cases Fertilisers · Ammonia CN 28141000 + China + 100t (high-emissions origin)1740ms
tests/cbam-input-validation.test.ts
- Origin-country filter (Reg 2023/956 Annex III + EU SAT) CBAM_ORIGIN_COUNTRIES excludes all 27 EU member states7ms
- Origin-country filter (Reg 2023/956 Annex III + EU SAT) CBAM_ORIGIN_COUNTRIES excludes EFTA + UK (Norway/Iceland/Liechtenstein/Switzerland/UK)1ms
- Origin-country filter (Reg 2023/956 Annex III + EU SAT) CBAM_ORIGIN_COUNTRIES still contains the major CBAM origins1ms
- Origin-country filter (Reg 2023/956 Annex III + EU SAT) CBAM_ORIGIN_COUNTRIES is strictly smaller than ORIGIN_COUNTRIES1ms
- Inexact-CN fallback warning (Reg 2025/2547 §A.2.7) CN 31021000 (urea heading, no exact 8-digit row) emits a ⚠ note10245ms
- Inexact-CN fallback warning (Reg 2025/2547 §A.2.7) CN 72081000 (steel, exact match via chapter heading 7208) does NOT emit fallback warning2496ms
tests/cbam-pricing.test.ts
- pickPaygTier — band boundaries €0 → cbam_report_micro (zero tax (out-of-scope CN) still wants a PDF)5ms
- pickPaygTier — band boundaries €1 → cbam_report_micro (minimal exposure)1ms
- pickPaygTier — band boundaries €999.99 → cbam_report_micro (just under €1k boundary)0ms
- pickPaygTier — band boundaries €1000 → cbam_report_micro (exactly €1k — tie goes to cheaper tier (buyer-friendly))0ms
- pickPaygTier — band boundaries €1000.01 → cbam_report_standard (first cent above €1k)0ms
- pickPaygTier — band boundaries €5000 → cbam_report_standard (mid-Standard)1ms
- pickPaygTier — band boundaries €10000 → cbam_report_standard (exactly €10k boundary — cheaper tier wins)0ms
- pickPaygTier — band boundaries €10000.01 → cbam_report_heavy (first cent above €10k)0ms
- pickPaygTier — band boundaries €25000 → cbam_report_heavy (mid-Heavy)0ms
- pickPaygTier — band boundaries €50000 → cbam_report_heavy (exactly €50k boundary)1ms
- pickPaygTier — band boundaries €50000.01 → cbam_report_enterprise (first cent above €50k)0ms
- pickPaygTier — band boundaries €1000000 → cbam_report_enterprise (absurd value still resolves)0ms
- pickPaygTier — band boundaries €-10 → cbam_report_micro (negative cost (refund?) defaults to Micro)0ms
- pickPaygTier — band boundaries €NaN → cbam_report_micro (NaN guard — never crash the buy form)0ms
- PAYG tier metadata PAYG_TIER_IDS lists exactly 4 tiers in cheapest-first order2ms
- PAYG tier metadata paygTierLabel returns short and long forms1ms
- PAYG tier metadata formatUsd (kept as alias for formatEur) renders euros1ms
- PAYG tier metadata paygTierPrice handles missing tier and missing price safely1ms
tests/cbam-rounding.test.ts
- EU rounding helpers roundEmissionsTotal: preserves 4dp for per-shipment values (Reg 2025/2547 §A.2.7)5ms
- EU rounding helpers roundAnnualReportEmissions: full integer tonnes (Reg 2025/2547 §A.2.6)1ms
- EU rounding helpers roundIntensity: ≤5 decimal places (Reg 2025/2547 §A.2.8)1ms
- EU rounding helpers roundEur: 2 decimal places (cent precision)1ms
- EU rounding helpers roundPricePerTco2e: 4 decimal places (EU certificate-price format)1ms
- EU rounding helpers symmetry: helpers are pure functions1ms
- API boundaries clamp intensity to ≤5dp per Reg 2025/2547 §A.2.8 /api/v1/cbam/routes (lookupAvailableRoutes) — every value_for_year is ≤5dp9877ms
tests/cbam-sat-scope.test.ts
- EU SAT scope cross-check (573 CN codes) every SAT-listed CN code resolves as in-scope24294ms
- EU SAT scope cross-check (573 CN codes) scope sectors match SAT's main categories5056ms
How to read this page
- Cost-calculation cases are derived BY HAND from the EU formulas — independent of our calculator's implementation. A regression in the calculator changes the output but NOT the expected number, so the test fails immediately.
- Scope assertions cross-reference the EU's own published Self-Assessment Tool. If the EU adds CN codes or revises the SAT, we re-import + re-run the suite.
- Tests run before every release. A failing test blocks the build — the calculator can't go live with known-wrong outputs.
- Want to add a reference case? Open an issue with the input and the regulatory derivation; we'll add it to the suite.