From 43121f1d8f1906babdfd429d8955e85f4918fc03 Mon Sep 17 00:00:00 2001 From: chichuan Date: Mon, 10 Aug 2026 15:02:08 +0800 Subject: [PATCH] test(interface): cover the merge-path bundled-regression branches mergedFlagContractOtherwiseChanged was only ever exercised on the path where every condition holds still, because `||` short-circuits: with no reviewed entry the first operand already decides the outcome and the function is never called at all. That left its five regression branches uncovered and put changed-code coverage at 88.0952% against a 100% target. Add the merge-path counterpart of the checkCompatibility bundled-regression table, pairing each of shorthand / required / hidden / no-opt / scope with the reviewed type change and requiring the type failure to reappear. Changed-code coverage is now 100%. --- .../interface-baseline/contract_test.go | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/scripts/policy/interface-baseline/contract_test.go b/scripts/policy/interface-baseline/contract_test.go index 4d7a9657..c2838d5f 100644 --- a/scripts/policy/interface-baseline/contract_test.go +++ b/scripts/policy/interface-baseline/contract_test.go @@ -401,6 +401,66 @@ func TestMergeAcceptsReviewedFlagTypeChangeAndKeepsHistoricalType(t *testing.T) } } +// mergeContracts applies the same "nothing else moved" condition as +// checkCompatibility, but against two recorded contracts rather than a live +// pflag definition. Each case bundles one unrelated regression with the reviewed +// type change and requires the type failure to reappear, anchoring +// mergedFlagContractOtherwiseChanged against the checks it mirrors. +func TestMergeRejectsReviewedFlagTypeChangeWithBundledRegression(t *testing.T) { + registerReviewedFixture(t, flagTypeChange{CommandPath: "dws old", Flag: "policy", From: "string", To: "int"}) + + tests := []struct { + name string + historical func(*cobra.Command) + current func(*cobra.Command) + }{ + { + name: "lost shorthand", + historical: func(command *cobra.Command) { command.Flags().StringP("policy", "p", "", "policy") }, + current: func(command *cobra.Command) { command.Flags().Int("policy", 0, "policy") }, + }, + { + name: "became required", + historical: func(command *cobra.Command) { command.Flags().String("policy", "", "policy") }, + current: func(command *cobra.Command) { + command.Flags().Int("policy", 0, "policy") + _ = command.MarkFlagRequired("policy") + }, + }, + { + name: "became hidden", + historical: func(command *cobra.Command) { command.Flags().String("policy", "", "policy") }, + current: func(command *cobra.Command) { + command.Flags().Int("policy", 0, "policy") + _ = command.Flags().MarkHidden("policy") + }, + }, + { + name: "changed no-opt value", + historical: func(command *cobra.Command) { command.Flags().String("policy", "", "policy") }, + current: func(command *cobra.Command) { + command.Flags().Int("policy", 0, "policy") + command.Flags().Lookup("policy").NoOptDefVal = "4" + }, + }, + { + name: "narrowed persistent scope", + historical: func(command *cobra.Command) { command.PersistentFlags().String("policy", "", "policy") }, + current: func(command *cobra.Command) { command.Flags().Int("policy", 0, "policy") }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + _, failures := mergeContracts( + snapshot(policyRoot(test.historical)), + snapshot(policyRoot(test.current)), + ) + assertFailureContains(t, failures, typeChangedFailure) + }) + } +} + // The behaviour tests above register their own fixtures, so they cannot catch a // production entry whose key is spelled in the wrong form — that mistake // disables the exemption silently and only a real gate run reports it. Recompute