github.com/kcmerrill/alfred@v0.0.0-20180727171036-06445dcb5e3d/alfred_test.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"os/exec"
     7  	"regexp"
     8  	"strings"
     9  	"testing"
    10  )
    11  
    12  func TestAlfredComponents(t *testing.T) {
    13  	tt := map[string]TestComponent{
    14  		"|show.tasks":                  TestComponent{expectedOutput: []string{" summary            | TESTING SUMMARY"}, failWithOutput: []string{"hidden.task"}},
    15  		"invalid.task":                 TestComponent{shouldFail: true},
    16  		"invalid.task|formatted":       TestComponent{shouldFail: true, expectedOutput: []string{"0s"}},
    17  		"invalid.task|not.formatted":   TestComponent{args: "--no-formatting", shouldFail: true, failWithOutput: []string{"0s"}},
    18  		"summary":                      TestComponent{expectedOutput: []string{"TESTING SUMMARY"}},
    19  		"hidden.task":                  TestComponent{expectedOutput: []string{"Testing a hidden task"}},
    20  		"command":                      TestComponent{expectedOutput: []string{"HELLO ALFRED", "HELLO NEWLINE"}},
    21  		"commands":                     TestComponent{shouldFail: true, expectedOutput: []string{"HELLO ALFRED"}, failWithOutput: []string{"THIS LINE NOT SHOWN"}},
    22  		"exit":                         TestComponent{shouldFail: true},
    23  		"arguments|without":            TestComponent{shouldFail: true},
    24  		"arguments":                    TestComponent{params: "ARG1", expectedOutput: []string{"ARG::ARG1"}},
    25  		"default.arguments":            TestComponent{expectedOutput: []string{"ARG::ARG1"}},
    26  		"required.arguments":           TestComponent{shouldFail: true, failWithOutput: []string{"ARG::ARG2"}},
    27  		"required.arguments|with_args": TestComponent{params: "ARG1", expectedOutput: []string{"ARG::ARG1 ARG::ARG2"}},
    28  		"ok":                TestComponent{expectedOutput: []string{"TEST::OK", "ARG::ARG1", "ARG::OKTEST"}},
    29  		"ok|witharg":        TestComponent{params: "DEFAULTARG", expectedOutput: []string{"TEST::OK", "ARG::DEFAULTARG", "ARG::OKTEST"}},
    30  		"fail":              TestComponent{expectedOutput: []string{"TEST::FAIL", "ARG::ARG1", "ARG::FAILTEST"}},
    31  		"tasks":             TestComponent{expectedOutput: []string{"ARG::ARG1", "ARG::TASKTEST"}},
    32  		"multitask":         TestComponent{expectedOutput: []string{"ARG::ARG1", "ARG::MULTITASKTEST"}},
    33  		"check|should_skip": TestComponent{params: "alfred.yml", expectedOutput: []string{"skipped"}, failWithOutput: []string{"TEST::CHECK"}},
    34  		"check|should_run":  TestComponent{params: "doesnotexist", expectedOutput: []string{"TEST::CHECK"}},
    35  		"config|file":       TestComponent{params: "config.yml", expectedOutput: []string{"FOO::BAR", "FIZZ::BUZZ"}},
    36  		"config|text":       TestComponent{params: "'foo: BAR\nfizz: BUZZ'", expectedOutput: []string{"FOO::BAR", "FIZZ::BUZZ"}},
    37  		"dir":               TestComponent{params: "/tmp/", expectedOutput: []string{"PWD::/private/tmp|PWD::/tmp"}},
    38  		"dir|with_alfred_folder": TestComponent{dir: "catalog2", failWithOutput: []string{"tests/catalog2/alfred"}},
    39  		"wait":           TestComponent{expectedOutput: []string{"wait wait 2s"}},
    40  		"template|sprig": TestComponent{expectedOutput: []string{"HELLO!HELLO!HELLO!HELLO!HELLO!"}},
    41  		"for":            TestComponent{expectedOutput: []string{"ARG::0", "ARG::1", "ARG::2", "ARG::3", "ARG::4"}, failWithOutput: []string{"ARG::5"}},
    42  		"include":        TestComponent{expectedOutput: []string{"taska.alfred.yml", "taskb.alfred.yml"}},
    43  		"@catalog":       TestComponent{expectedOutput: []string{"taska"}, failWithOutput: []string{"taskb"}},
    44  		"@catalog:taska": TestComponent{expectedOutput: []string{"taska.alfred.yml"}},
    45  		"env":            TestComponent{expectedOutput: []string{"ARG::TESTENV"}},
    46  		"register":       TestComponent{expectedOutput: []string{"REGISTER::var", "WHOAMI::(kcmerrill|root)"}},
    47  
    48  		// Tests that _should_ be working(read: bugs)
    49  		"arguments|empty_log":   TestComponent{skip: true, shouldFail: true, args: "--log scratch/test_empty.log", filesExist: []string{"scratch/"}},
    50  		"arguments|log_written": TestComponent{skip: true, args: "--log scratch/test.log", filesExist: []string{"scratch/test.log"}},
    51  	}
    52  
    53  	/* SHOULD NOT HAVE TO CHANGE TOO MUCH BELOW. Add tests above ^^^^ */
    54  
    55  	// lets be in the correct directory
    56  	err := os.Chdir("tests/")
    57  	if err != nil {
    58  		t.Fatalf("Could not switch directories. Bailing ...")
    59  	}
    60  
    61  	// lets clean up our scratch directory
    62  	testCommand("rm -rf scratch/", ".")
    63  
    64  	// lets cycle through our test map and get to testing!
    65  	for task, tc := range tt {
    66  		if tc.skip {
    67  			// we should skip this test
    68  			continue
    69  		}
    70  		taskBits := strings.Split(task, "|")
    71  		taskName := taskBits[0]
    72  		output, ok := runAlfredCommand(taskName, tc)
    73  
    74  		if tc.shouldFail && tc.shouldFail != !ok {
    75  			fmt.Println(output)
    76  			t.Fatalf("[" + task + "] Expected task failure ...")
    77  		}
    78  
    79  		if !tc.shouldFail && !ok {
    80  			fmt.Println(output)
    81  			t.Fatalf("[" + task + "] Expected task success ...")
    82  		}
    83  
    84  		for _, expectedOutput := range tc.expectedOutput {
    85  			found := false
    86  			for _, actualOutput := range strings.Split(output, "\n") {
    87  
    88  				if matched, _ := regexp.MatchString(expectedOutput, actualOutput); matched {
    89  					found = true
    90  					break
    91  				}
    92  			}
    93  
    94  			if !found {
    95  				t.Fatalf("["+task+"]Output: Expected to find '%s' in: \n\n%s", expectedOutput, output)
    96  			}
    97  		}
    98  
    99  		for _, ignoreOutput := range tc.failWithOutput {
   100  			found := false
   101  			for _, actualOutput := range strings.Split(output, "\n") {
   102  				if strings.Contains(actualOutput, ignoreOutput) {
   103  					found = true
   104  					break
   105  				}
   106  			}
   107  
   108  			if found {
   109  				t.Fatalf("["+task+"]Output: Expected to _NOT_ find '%s' in: \n\n%s", ignoreOutput, output)
   110  			}
   111  		}
   112  
   113  		for _, file := range tc.filesExist {
   114  			if _, exists := os.Stat(file); exists != nil {
   115  				t.Fatalf("["+task+"]File: Expected the file '%s' to exist ...", file)
   116  			}
   117  		}
   118  	}
   119  }
   120  
   121  type TestComponent struct {
   122  	filesExist     []string
   123  	fileContents   map[string]string
   124  	tasksStarted   []string
   125  	expectedOutput []string
   126  	failWithOutput []string
   127  	params         string
   128  	args           string
   129  	shouldFail     bool
   130  	skip           bool
   131  	dir            string
   132  }
   133  
   134  func testCommand(command, dir string) (string, bool) {
   135  	cmd := exec.Command("bash", "-c", command)
   136  	cmd.Dir = dir
   137  	cmdOutput, error := cmd.CombinedOutput()
   138  	if error != nil {
   139  		return string(cmdOutput), false
   140  	}
   141  	return string(cmdOutput), true
   142  }
   143  
   144  func runAlfredCommand(task string, tc TestComponent) (string, bool) {
   145  	cmd := "alfred --no-colors"
   146  	if tc.args != "" {
   147  		cmd += " " + tc.args
   148  	}
   149  
   150  	cmd += " " + task
   151  
   152  	if tc.params != "" {
   153  		cmd += " " + tc.params
   154  	}
   155  
   156  	dir := "."
   157  	if tc.dir != "" {
   158  		dir = tc.dir
   159  	}
   160  	return testCommand(cmd, dir)
   161  }