@@ -531,3 +531,117 @@ func TestSelected_UnknownTagDropped(t *testing.T) {
531531 t .Fatalf ("Selected([bogus]) returned %d rules, want 0" , len (got ))
532532 }
533533}
534+
535+ // TestCollapseWs_SecondPass exercises the second pass of the
536+ // double-space collapsor. With 4 consecutive spaces the first pass
537+ // leaves 2 spaces, so the loop body executes once.
538+ func TestCollapseWs_SecondPass (t * testing.T ) {
539+ in := "a b" // 4 spaces
540+ want := "a b"
541+ got := Normalize (in )
542+ if got != want {
543+ t .Fatalf ("Normalize(%q) = %q, want %q" , in , got , want )
544+ }
545+ }
546+
547+ // TestBytesSaved_ClampsNegative covers the defensive clamp in
548+ // bytesSaved when compressed length exceeds original length.
549+ func TestBytesSaved_ClampsNegative (t * testing.T ) {
550+ if got := bytesSaved ("short" , "loooonger" ); got != 0 {
551+ t .Fatalf ("bytesSaved('short','loooonger') = %d, want 0" , got )
552+ }
553+ }
554+
555+ // TestRatio_EmptyOrig and TestRatio_NonPositiveSaved cover the guard
556+ // branches in ratio.
557+ func TestRatio_EmptyOrig (t * testing.T ) {
558+ if got := ratio ("" , "anything" ); got != 0 {
559+ t .Fatalf ("ratio('','anything') = %f, want 0" , got )
560+ }
561+ }
562+
563+ func TestRatio_NonPositiveSaved (t * testing.T ) {
564+ if got := ratio ("short" , "loooonger" ); got != 0 {
565+ t .Fatalf ("ratio('short','loooonger') = %f, want 0" , got )
566+ }
567+ if got := ratio ("same" , "same" ); got != 0 {
568+ t .Fatalf ("ratio('same','same') = %f, want 0" , got )
569+ }
570+ }
571+
572+ // TestTagSet_ListEmpty covers List returning nil for an empty set.
573+ func TestTagSet_ListEmpty (t * testing.T ) {
574+ set := FromCSV ("invalid-tag" )
575+ if got := set .List (); got != nil {
576+ t .Fatalf ("List() on empty set = %v, want nil" , got )
577+ }
578+ }
579+
580+ // TestTagSet_Contains covers the O(n) membership check.
581+ func TestTagSet_Contains (t * testing.T ) {
582+ set := FromCSV ("delete,shrink" )
583+ if ! set .Contains (TagDelete ) {
584+ t .Fatalf ("expected set to contain %q" , TagDelete )
585+ }
586+ if ! set .Contains (TagShrink ) {
587+ t .Fatalf ("expected set to contain %q" , TagShrink )
588+ }
589+ if set .Contains (TagNative ) {
590+ t .Fatalf ("did not expect set to contain %q" , TagNative )
591+ }
592+ }
593+
594+ // TestTagSet_Size exercises the size accessor.
595+ func TestTagSet_Size (t * testing.T ) {
596+ if got := FromCSV ("delete,shrink" ).Size (); got != 2 {
597+ t .Fatalf ("Size() = %d, want 2" , got )
598+ }
599+ if got := FromCSV ("" ).Size (); got != 5 {
600+ t .Fatalf ("Size() of default set = %d, want 5" , got )
601+ }
602+ if got := FromCSV ("invalid" ).Size (); got != 0 {
603+ t .Fatalf ("Size() of empty set = %d, want 0" , got )
604+ }
605+ }
606+
607+ // TestTagSet_CSV exercises the canonical CSV round-trip string.
608+ func TestTagSet_CSV (t * testing.T ) {
609+ cases := []struct {
610+ in string
611+ want string
612+ }{
613+ {"delete,shrink" , "delete,shrink" },
614+ {" shrink , delete " , "delete,shrink" },
615+ {"invalid" , "" },
616+ }
617+ for _ , tc := range cases {
618+ t .Run (tc .in , func (t * testing.T ) {
619+ got := FromCSV (tc .in ).CSV ()
620+ if got != tc .want {
621+ t .Fatalf ("CSV(%q) = %q, want %q" , tc .in , got , tc .want )
622+ }
623+ })
624+ }
625+ }
626+
627+ // TestTagSet_Empty covers the empty predicate.
628+ func TestTagSet_Empty (t * testing.T ) {
629+ if ! FromCSV ("invalid" ).Empty () {
630+ t .Fatalf ("Empty() on empty set = false, want true" )
631+ }
632+ if FromCSV ("delete" ).Empty () {
633+ t .Fatalf ("Empty() on non-empty set = true, want false" )
634+ }
635+ }
636+
637+ // TestTagSet_Valid covers the canonical-tag predicate.
638+ func TestTagSet_Valid (t * testing.T ) {
639+ for _ , tag := range DefaultTags {
640+ if ! Valid (tag ) {
641+ t .Fatalf ("Valid(%q) = false, want true" , tag )
642+ }
643+ }
644+ if Valid (Tag ("nope" )) {
645+ t .Fatalf ("Valid('nope') = true, want false" )
646+ }
647+ }
0 commit comments