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