Source file src/testing/example.go

Documentation: testing

     1  // Copyright 2009 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 testing
     6  
     7  import (
     8  	"fmt"
     9  	"os"
    10  	"sort"
    11  	"strings"
    12  	"time"
    13  )
    14  
    15  type InternalExample struct {
    16  	Name      string
    17  	F         func()
    18  	Output    string
    19  	Unordered bool
    20  }
    21  
    22  // An internal function but exported because it is cross-package; part of the implementation
    23  // of the "go test" command.
    24  func RunExamples(matchString func(pat, str string) (bool, error), examples []InternalExample) (ok bool) {
    25  	_, ok = runExamples(matchString, examples)
    26  	return ok
    27  }
    28  
    29  func runExamples(matchString func(pat, str string) (bool, error), examples []InternalExample) (ran, ok bool) {
    30  	ok = true
    31  
    32  	var eg InternalExample
    33  
    34  	for _, eg = range examples {
    35  		matched, err := matchString(*match, eg.Name)
    36  		if err != nil {
    37  			fmt.Fprintf(os.Stderr, "testing: invalid regexp for -test.run: %s\n", err)
    38  			os.Exit(1)
    39  		}
    40  		if !matched {
    41  			continue
    42  		}
    43  		ran = true
    44  		if !runExample(eg) {
    45  			ok = false
    46  		}
    47  	}
    48  
    49  	return ran, ok
    50  }
    51  
    52  func sortLines(output string) string {
    53  	lines := strings.Split(output, "\n")
    54  	sort.Strings(lines)
    55  	return strings.Join(lines, "\n")
    56  }
    57  
    58  // processRunResult computes a summary and status of the result of running an example test.
    59  // stdout is the captured output from stdout of the test.
    60  // recovered is the result of invoking recover after running the test, in case it panicked.
    61  //
    62  // If stdout doesn't match the expected output or if recovered is non-nil, it'll print the cause of failure to stdout.
    63  // If the test is chatty/verbose, it'll print a success message to stdout.
    64  // If recovered is non-nil, it'll panic with that value.
    65  func (eg *InternalExample) processRunResult(stdout string, timeSpent time.Duration, recovered interface{}) (passed bool) {
    66  	passed = true
    67  
    68  	dstr := fmtDuration(timeSpent)
    69  	var fail string
    70  	got := strings.TrimSpace(stdout)
    71  	want := strings.TrimSpace(eg.Output)
    72  	if eg.Unordered {
    73  		if sortLines(got) != sortLines(want) && recovered == nil {
    74  			fail = fmt.Sprintf("got:\n%s\nwant (unordered):\n%s\n", stdout, eg.Output)
    75  		}
    76  	} else {
    77  		if got != want && recovered == nil {
    78  			fail = fmt.Sprintf("got:\n%s\nwant:\n%s\n", got, want)
    79  		}
    80  	}
    81  	if fail != "" || recovered != nil {
    82  		fmt.Printf("--- FAIL: %s (%s)\n%s", eg.Name, dstr, fail)
    83  		passed = false
    84  	} else if *chatty {
    85  		fmt.Printf("--- PASS: %s (%s)\n", eg.Name, dstr)
    86  	}
    87  	if recovered != nil {
    88  		// Propagate the previously recovered result, by panicking.
    89  		panic(recovered)
    90  	}
    91  
    92  	return
    93  }
    94  

View as plain text