github.com/mpwalkerdine/elicit@v0.1.0/elicit_test.go (about)

     1  package elicit_test
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"os/exec"
     8  	"path/filepath"
     9  	"regexp"
    10  	"strings"
    11  	"testing"
    12  
    13  	"github.com/mpwalkerdine/elicit"
    14  )
    15  
    16  var startdir, tempdir string
    17  
    18  func init() {
    19  	wd, err := os.Getwd()
    20  	if err != nil {
    21  		panic(fmt.Errorf("os.Getwd(): %s", err))
    22  	}
    23  	startdir = wd
    24  }
    25  
    26  func Test(t *testing.T) {
    27  	elicit.New().
    28  		WithSpecsFolder("./specs").
    29  		WithTransforms(transforms).
    30  		WithSteps(steps).
    31  		BeforeScenarios(createTempDir).
    32  		AfterScenarios(removeTempDir).
    33  		RunTests(t)
    34  }
    35  
    36  var steps = elicit.Steps{}
    37  var transforms = elicit.Transforms{}
    38  
    39  func init() {
    40  	steps["Create a temporary environment"] =
    41  		func(t *testing.T) {
    42  			createFile(t, false, "specs_test.go", testfile)
    43  			createFile(t, false, "go.mod", fmt.Sprintf(modfile, startdir))
    44  		}
    45  
    46  	steps["Create a module file"] =
    47  		func(t *testing.T) {
    48  			createFile(t, false, "go.mod", fmt.Sprintf(modfile, startdir))
    49  		}
    50  
    51  	steps["(Create an?|Replace the) `(.*)` file:"] =
    52  		func(t *testing.T, createorReplace, filename string, text elicit.TextBlock) {
    53  			replace := strings.HasPrefix(createorReplace, "Replace")
    54  			createFile(t, replace, filename, text.Content)
    55  		}
    56  
    57  	steps["Create (?:a step definition|step definitions|transform definitions):"] =
    58  		func(t *testing.T, text elicit.TextBlock) {
    59  			createFile(t, false, "steps_test.go", fmt.Sprintf(stepFileFmt, "", text.Content))
    60  		}
    61  
    62  	steps["Create (?:a step definition|step definitions) using (.+):"] =
    63  		func(t *testing.T, imports []string, text elicit.TextBlock) {
    64  			createFile(t, false, "steps_test.go", fmt.Sprintf(stepFileFmt, strings.Join(imports, "\n"), text.Content))
    65  		}
    66  
    67  	steps["Running `(go test.*)` will output:"] =
    68  		func(t *testing.T, command string, text elicit.TextBlock) {
    69  			output := runGoTest(t, command)
    70  
    71  			expected, actual := quoteOutput(text.Content), quoteOutput(output)
    72  			if !strings.Contains(actual, expected) {
    73  				t.Errorf("\n\nExpected:\n\n%s\n\n to contain:\n\n%s\n", actual, expected)
    74  			}
    75  		}
    76  
    77  	steps["Running `(go test.*)` will output the following lines:"] =
    78  		func(t *testing.T, command string, text elicit.TextBlock) {
    79  			output := runGoTest(t, command)
    80  
    81  			missingLines := []string{}
    82  			for _, line := range strings.Split(text.Content, "\n") {
    83  				if !strings.Contains(output, line) {
    84  					missingLines = append(missingLines, line)
    85  				}
    86  			}
    87  
    88  			if len(missingLines) > 0 {
    89  				t.Errorf("\n\nExpected:\n\n%s\n\n to contain the lines:\n\n%s\n",
    90  					quoteOutput(output),
    91  					quoteOutput(strings.Join(missingLines, "\n")))
    92  			}
    93  		}
    94  
    95  	steps["`(.+)` will contain:"] =
    96  		func(t *testing.T, filename string, text elicit.TextBlock) {
    97  			path := filepath.Join(tempdir, filename)
    98  
    99  			if _, err := os.Stat(path); os.IsNotExist(err) {
   100  				t.Error(filename, err)
   101  			}
   102  
   103  			if contents, err := ioutil.ReadFile(path); err != nil {
   104  				t.Error("reading", filename, err)
   105  			} else {
   106  				actual := string(contents)
   107  				expected := strings.TrimSpace(text.Content)
   108  				if actual != expected {
   109  					t.Errorf("\n\nExpected:\n\n%s\n\n to equal:\n\n%s\n", quoteOutput(actual), quoteOutput(expected))
   110  				}
   111  			}
   112  		}
   113  }
   114  
   115  func createTempDir() {
   116  	var err error
   117  	tempdir, err = ioutil.TempDir("", "elicit_test")
   118  
   119  	if err != nil {
   120  		panic(fmt.Errorf("creating tempdir: %s", err))
   121  	}
   122  }
   123  
   124  func removeTempDir() {
   125  	if err := os.RemoveAll(tempdir); err != nil {
   126  		panic(fmt.Errorf("removing tempdir %q: %s", tempdir, err))
   127  	}
   128  	if err := os.Chdir(startdir); err != nil {
   129  		panic(fmt.Errorf("reverting wd to %q: %s", startdir, err))
   130  	}
   131  }
   132  
   133  func createFile(t *testing.T, replace bool, filename, contents string) {
   134  	if tempdir == "" || tempdir == startdir {
   135  		t.Fatal("creating file: tempdir not set")
   136  	}
   137  
   138  	outpath := filepath.Join(tempdir, filename)
   139  
   140  	if _, err := os.Stat(outpath); os.IsNotExist(err) || replace {
   141  		ioutil.WriteFile(outpath, []byte(contents), 0777)
   142  	} else {
   143  		t.Fatal("creating file:", outpath, "already exists")
   144  	}
   145  }
   146  
   147  func runGoTest(t *testing.T, command string) string {
   148  	if err := os.Chdir(tempdir); err != nil {
   149  		t.Fatalf("switching to tempdir %s: %s", tempdir, err)
   150  	}
   151  
   152  	parts := strings.Split(command, " ")
   153  	output, _ := exec.Command(parts[0], parts[1:]...).CombinedOutput()
   154  
   155  	return string(output)
   156  }
   157  
   158  func quoteOutput(s string) string {
   159  	s = strings.TrimSpace(s)
   160  	s = regexp.MustCompile(`\033\[\d+(;\d+)?m`).ReplaceAllString(s, "")
   161  	s = regexp.MustCompile(` $`).ReplaceAllString(s, "·")
   162  	s = strings.Replace(s, "\t", "  ➟ ", -1)
   163  	s = "  | " + strings.Join(strings.Split(s, "\n"), "\n  | ")
   164  	return s
   165  }
   166  
   167  const modfile = `
   168  module github.com/mpwalkerdine/elicit/testmod
   169  
   170  require github.com/mpwalkerdine/elicit latest
   171  
   172  replace github.com/mpwalkerdine/elicit latest => %s
   173  `
   174  
   175  const testfile = `
   176  package elicit_test
   177  
   178  import (
   179      "github.com/mpwalkerdine/elicit"
   180      "testing"
   181  )
   182  
   183  func Test(t *testing.T) {
   184      elicit.New().
   185          WithSpecsFolder(".").
   186          WithSteps(steps).
   187          WithTransforms(transforms).
   188          RunTests(t)
   189  }
   190  
   191  var steps = elicit.Steps{}
   192  var transforms = elicit.Transforms{}
   193  `
   194  
   195  const stepFileFmt = `
   196  package elicit_test
   197  
   198  import (
   199  	"testing"
   200  	%s
   201  )
   202  
   203  func init() {
   204  	%s
   205  }
   206  `