github.com/agilebits/godog@v0.7.9/fmt_progress.go (about)

     1  package godog
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"math"
     7  	"strings"
     8  	"sync"
     9  
    10  	"github.com/DATA-DOG/godog/gherkin"
    11  )
    12  
    13  func init() {
    14  	Format("progress", "Prints a character per step.", progressFunc)
    15  }
    16  
    17  func progressFunc(suite string, out io.Writer) Formatter {
    18  	return &progress{
    19  		basefmt: basefmt{
    20  			started: timeNowFunc(),
    21  			indent:  2,
    22  			out:     out,
    23  		},
    24  		stepsPerRow: 70,
    25  	}
    26  }
    27  
    28  type progress struct {
    29  	basefmt
    30  	sync.Mutex
    31  	stepsPerRow int
    32  	steps       int
    33  }
    34  
    35  func (f *progress) Node(n interface{}) {
    36  	f.Lock()
    37  	defer f.Unlock()
    38  	f.basefmt.Node(n)
    39  }
    40  
    41  func (f *progress) Feature(ft *gherkin.Feature, p string, c []byte) {
    42  	f.Lock()
    43  	defer f.Unlock()
    44  	f.basefmt.Feature(ft, p, c)
    45  }
    46  
    47  func (f *progress) Summary() {
    48  	left := math.Mod(float64(f.steps), float64(f.stepsPerRow))
    49  	if left != 0 {
    50  		if f.steps > f.stepsPerRow {
    51  			fmt.Fprintf(f.out, s(f.stepsPerRow-int(left))+fmt.Sprintf(" %d\n", f.steps))
    52  		} else {
    53  			fmt.Fprintf(f.out, " %d\n", f.steps)
    54  		}
    55  	}
    56  	fmt.Fprintln(f.out, "")
    57  
    58  	if len(f.failed) > 0 {
    59  		fmt.Fprintln(f.out, "\n--- "+red("Failed steps:")+"\n")
    60  		for _, fail := range f.failed {
    61  			fmt.Fprintln(f.out, s(2)+red(fail.scenarioDesc())+black(" # "+fail.scenarioLine()))
    62  			fmt.Fprintln(f.out, s(4)+red(strings.TrimSpace(fail.step.Keyword)+" "+fail.step.Text)+black(" # "+fail.line()))
    63  			fmt.Fprintln(f.out, s(6)+red("Error: ")+redb(fmt.Sprintf("%+v", fail.err))+"\n")
    64  		}
    65  	}
    66  	f.basefmt.Summary()
    67  }
    68  
    69  func (f *progress) step(res *stepResult) {
    70  	switch res.typ {
    71  	case passed:
    72  		fmt.Fprint(f.out, green("."))
    73  	case skipped:
    74  		fmt.Fprint(f.out, cyan("-"))
    75  	case failed:
    76  		fmt.Fprint(f.out, red("F"))
    77  	case undefined:
    78  		fmt.Fprint(f.out, yellow("U"))
    79  	case pending:
    80  		fmt.Fprint(f.out, yellow("P"))
    81  	}
    82  	f.steps++
    83  	if math.Mod(float64(f.steps), float64(f.stepsPerRow)) == 0 {
    84  		fmt.Fprintf(f.out, " %d\n", f.steps)
    85  	}
    86  }
    87  
    88  func (f *progress) Passed(step *gherkin.Step, match *StepDef) {
    89  	f.Lock()
    90  	defer f.Unlock()
    91  	f.basefmt.Passed(step, match)
    92  	f.step(f.passed[len(f.passed)-1])
    93  }
    94  
    95  func (f *progress) Skipped(step *gherkin.Step, match *StepDef) {
    96  	f.Lock()
    97  	defer f.Unlock()
    98  	f.basefmt.Skipped(step, match)
    99  	f.step(f.skipped[len(f.skipped)-1])
   100  }
   101  
   102  func (f *progress) Undefined(step *gherkin.Step, match *StepDef) {
   103  	f.Lock()
   104  	defer f.Unlock()
   105  	f.basefmt.Undefined(step, match)
   106  	f.step(f.undefined[len(f.undefined)-1])
   107  }
   108  
   109  func (f *progress) Failed(step *gherkin.Step, match *StepDef, err error) {
   110  	f.Lock()
   111  	defer f.Unlock()
   112  	f.basefmt.Failed(step, match, err)
   113  	f.step(f.failed[len(f.failed)-1])
   114  }
   115  
   116  func (f *progress) Pending(step *gherkin.Step, match *StepDef) {
   117  	f.Lock()
   118  	defer f.Unlock()
   119  	f.basefmt.Pending(step, match)
   120  	f.step(f.pending[len(f.pending)-1])
   121  }