Source file src/internal/coverage/cformat/fmt_test.go

     1  // Copyright 2022 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package cformat_test
     6  
     7  import (
     8  	"internal/coverage"
     9  	"internal/coverage/cformat"
    10  	"slices"
    11  	"strings"
    12  	"testing"
    13  )
    14  
    15  func TestBasics(t *testing.T) {
    16  	fm := cformat.NewFormatter(coverage.CtrModeAtomic)
    17  
    18  	mku := func(stl, enl, nx uint32) coverage.CoverableUnit {
    19  		return coverage.CoverableUnit{
    20  			StLine:  stl,
    21  			EnLine:  enl,
    22  			NxStmts: nx,
    23  		}
    24  	}
    25  	fn1units := []coverage.CoverableUnit{
    26  		mku(10, 11, 2),
    27  		mku(15, 11, 1),
    28  	}
    29  	fn2units := []coverage.CoverableUnit{
    30  		mku(20, 25, 3),
    31  		mku(30, 31, 2),
    32  		mku(33, 40, 7),
    33  	}
    34  	fn3units := []coverage.CoverableUnit{
    35  		mku(99, 100, 1),
    36  	}
    37  	fm.SetPackage("my/pack1")
    38  	for k, u := range fn1units {
    39  		fm.AddUnit("p.go", "f1", false, u, uint32(k))
    40  	}
    41  	for k, u := range fn2units {
    42  		fm.AddUnit("q.go", "f2", false, u, 0)
    43  		fm.AddUnit("q.go", "f2", false, u, uint32(k))
    44  	}
    45  	fm.SetPackage("my/pack2")
    46  	for _, u := range fn3units {
    47  		fm.AddUnit("lit.go", "f3", true, u, 0)
    48  	}
    49  
    50  	var b1, b2, b3, b4 strings.Builder
    51  	if err := fm.EmitTextual(&b1); err != nil {
    52  		t.Fatalf("EmitTextual returned %v", err)
    53  	}
    54  	wantText := strings.TrimSpace(`
    55  mode: atomic
    56  p.go:10.0,11.0 2 0
    57  p.go:15.0,11.0 1 1
    58  q.go:20.0,25.0 3 0
    59  q.go:30.0,31.0 2 1
    60  q.go:33.0,40.0 7 2
    61  lit.go:99.0,100.0 1 0`)
    62  	gotText := strings.TrimSpace(b1.String())
    63  	if wantText != gotText {
    64  		t.Errorf("emit text: got:\n%s\nwant:\n%s\n", gotText, wantText)
    65  	}
    66  
    67  	// Percent output with no aggregation.
    68  	noCoverPkg := ""
    69  	if err := fm.EmitPercent(&b2, nil, noCoverPkg, false, false); err != nil {
    70  		t.Fatalf("EmitPercent returned %v", err)
    71  	}
    72  	wantPercent := strings.Fields(`
    73         	my/pack1		coverage: 66.7% of statements
    74          my/pack2		coverage: 0.0% of statements
    75  `)
    76  	gotPercent := strings.Fields(b2.String())
    77  	if !slices.Equal(wantPercent, gotPercent) {
    78  		t.Errorf("emit percent: got:\n%+v\nwant:\n%+v\n",
    79  			gotPercent, wantPercent)
    80  	}
    81  
    82  	// Percent mode with aggregation.
    83  	withCoverPkg := " in ./..."
    84  	if err := fm.EmitPercent(&b3, nil, withCoverPkg, false, true); err != nil {
    85  		t.Fatalf("EmitPercent returned %v", err)
    86  	}
    87  	wantPercent = strings.Fields(`
    88  		coverage: 62.5% of statements in ./...
    89  `)
    90  	gotPercent = strings.Fields(b3.String())
    91  	if !slices.Equal(wantPercent, gotPercent) {
    92  		t.Errorf("emit percent: got:\n%+v\nwant:\n%+v\n",
    93  			gotPercent, wantPercent)
    94  	}
    95  
    96  	if err := fm.EmitFuncs(&b4); err != nil {
    97  		t.Fatalf("EmitFuncs returned %v", err)
    98  	}
    99  	wantFuncs := strings.TrimSpace(`
   100  p.go:10:	f1		33.3%
   101  q.go:20:	f2		75.0%
   102  total		(statements)	62.5%`)
   103  	gotFuncs := strings.TrimSpace(b4.String())
   104  	if wantFuncs != gotFuncs {
   105  		t.Errorf("emit funcs: got:\n%s\nwant:\n%s\n", gotFuncs, wantFuncs)
   106  	}
   107  	if false {
   108  		t.Logf("text is %s\n", b1.String())
   109  		t.Logf("perc is %s\n", b2.String())
   110  		t.Logf("perc2 is %s\n", b3.String())
   111  		t.Logf("funcs is %s\n", b4.String())
   112  	}
   113  
   114  	// Percent output with specific packages selected.
   115  	{
   116  		var b strings.Builder
   117  		selpkgs := []string{"foo/bar", "my/pack1"}
   118  		if err := fm.EmitPercent(&b, selpkgs, noCoverPkg, false, false); err != nil {
   119  			t.Fatalf("EmitPercent returned %v", err)
   120  		}
   121  		wantPercent := strings.Fields(`
   122         	my/pack1		coverage: 66.7% of statements
   123  `)
   124  		gotPercent := strings.Fields(b.String())
   125  		if !slices.Equal(wantPercent, gotPercent) {
   126  			t.Errorf("emit percent: got:\n%+v\nwant:\n%+v\n",
   127  				gotPercent, wantPercent)
   128  		}
   129  	}
   130  
   131  }
   132  
   133  func TestEmptyPackages(t *testing.T) {
   134  
   135  	fm := cformat.NewFormatter(coverage.CtrModeAtomic)
   136  	fm.SetPackage("my/pack1")
   137  	fm.SetPackage("my/pack2")
   138  
   139  	// No aggregation.
   140  	{
   141  		var b strings.Builder
   142  		noCoverPkg := ""
   143  		if err := fm.EmitPercent(&b, nil, noCoverPkg, true, false); err != nil {
   144  			t.Fatalf("EmitPercent returned %v", err)
   145  		}
   146  		wantPercent := strings.Fields(`
   147         	my/pack1 coverage:	[no statements]
   148          my/pack2 coverage:	[no statements]
   149  `)
   150  		gotPercent := strings.Fields(b.String())
   151  		if !slices.Equal(wantPercent, gotPercent) {
   152  			t.Errorf("emit percent: got:\n%+v\nwant:\n%+v\n",
   153  				gotPercent, wantPercent)
   154  		}
   155  	}
   156  
   157  	// With aggregation.
   158  	{
   159  		var b strings.Builder
   160  		noCoverPkg := ""
   161  		if err := fm.EmitPercent(&b, nil, noCoverPkg, true, true); err != nil {
   162  			t.Fatalf("EmitPercent returned %v", err)
   163  		}
   164  		wantPercent := strings.Fields(`
   165         	coverage:	[no statements]
   166  `)
   167  		gotPercent := strings.Fields(b.String())
   168  		if !slices.Equal(wantPercent, gotPercent) {
   169  			t.Errorf("emit percent: got:\n%+v\nwant:\n%+v\n",
   170  				gotPercent, wantPercent)
   171  		}
   172  	}
   173  }
   174  

View as plain text