github.com/tilt-dev/wat@v0.0.2-0.20180626175338-9349b638e250/cli/wat/plugins_test.go (about) 1 package wat 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "os" 8 "path/filepath" 9 "reflect" 10 "testing" 11 "time" 12 ) 13 14 type pluginAB struct{} 15 16 func (pluginAB) name() string { return "pluginAB" } 17 func (pluginAB) run(ctx context.Context, root string) ([]WatCommand, error) { 18 return []WatCommand{cmdA, cmdB}, nil 19 } 20 21 type pluginC struct{} 22 23 func (pluginC) name() string { return "pluginC" } 24 func (pluginC) run(ctx context.Context, root string) ([]WatCommand, error) { 25 return []WatCommand{cmdC}, nil 26 } 27 28 type pluginErr struct{} 29 30 func (pluginErr) name() string { return "pluginErr" } 31 func (pluginErr) run(ctx context.Context, root string) ([]WatCommand, error) { 32 return []WatCommand{}, errors.New("Oh noes!") 33 } 34 35 func TestBuiltinGoList(t *testing.T) { 36 f := newWatFixture(t) 37 defer f.tearDown() 38 39 f.write("src/github.com/fake/repo/repo.go", ` 40 package repo 41 42 func One() { return 1 } 43 `) 44 f.write("src/github.com/fake/repo/repo_test.go", ` 45 package repo 46 47 import "testing" 48 49 func TestOne(t *testing.T) {} 50 `) 51 52 os.Setenv("GOPATH", f.root.Path()) 53 54 cmds, err := PluginGo{}.run(context.Background(), f.root.Path()) 55 if err != nil { 56 f.t.Fatalf("populateAt: %v", err) 57 } 58 59 if len(cmds) != 1 { 60 f.t.Fatalf("Expected 1 command, got %d", len(cmds)) 61 } 62 63 expected := WatCommand{ 64 FilePattern: "src/github.com/fake/repo/*", 65 Command: "go test github.com/fake/repo", 66 } 67 if cmds[0] != expected { 68 f.t.Fatalf("Expected %+v. Actual: %+v", expected, cmds[0]) 69 } 70 } 71 72 func TestRunBuiltinPlugins(t *testing.T) { 73 f := newWatFixture(t) 74 defer f.tearDown() 75 ws := f.watInit() 76 77 actual := runPlugins(context.Background(), ws, 78 []plugin{pluginAB{}, pluginErr{}, pluginC{}}) 79 80 // NOTE: we expect to ignore the err thrown by pluginErr and continue running the rest 81 expected := []WatCommand{cmdA, cmdB, cmdC} 82 83 if !reflect.DeepEqual(actual, expected) { 84 f.t.Fatalf("Expected command list %+v. Actual: %+v", expected, actual) 85 } 86 } 87 88 func TestGetUserPlugins(t *testing.T) { 89 f := newWatFixture(t) 90 defer f.tearDown() 91 ws := f.watInit() 92 f.write(filepath.Join(kWatDirName, fnameUserPlugins), "foo\nbar\nbaz") 93 94 actual, err := getUserPlugins(ws) 95 if err != nil { 96 f.t.Fatal("getUserPlugins:", err) 97 } 98 99 expected := []plugin{ 100 userPlugin{cmd: "foo"}, 101 userPlugin{cmd: "bar"}, 102 userPlugin{cmd: "baz"}, 103 } 104 if !reflect.DeepEqual(actual, expected) { 105 f.t.Fatalf("Expected to retrieve user plugins %+v, got %+v", expected, actual) 106 } 107 } 108 109 func TestGetUserPluginsNoFile(t *testing.T) { 110 f := newWatFixture(t) 111 defer f.tearDown() 112 ws := f.watInit() 113 114 actual, err := getUserPlugins(ws) 115 if err != nil { 116 f.t.Fatal("getUserPlugins:", err) 117 } 118 119 if len(actual) != 0 { 120 f.t.Fatalf("Expected to retrieve 0 user plugins, instead got %d: %+v", len(actual), actual) 121 } 122 } 123 124 func TestRunUserPlugins(t *testing.T) { 125 f := newWatFixture(t) 126 defer f.tearDown() 127 ws := f.watInit() 128 129 // Instead of paths to executables, these "plugins" just echo results straight to stdout. 130 f.write(filepath.Join(kWatDirName, fnameUserPlugins), 131 fmt.Sprintf(`echo '%s' 132 echo 'not valid json' 133 echo '%s'`, MustJson([]WatCommand{cmdA}), MustJson([]WatCommand{cmdB, cmdC}))) 134 135 actual, err := RunUserPlugins(context.Background(), ws) 136 if err != nil { 137 f.t.Fatal("RunUserPlugins:", err) 138 } 139 140 // NOTE: we expect to ignore the err from invalid json and continue running the rest 141 expected := []WatCommand{cmdA, cmdB, cmdC} 142 if !reflect.DeepEqual(actual, expected) { 143 f.t.Fatalf("Expected to retrieve user plugins %+v, got %+v", expected, actual) 144 } 145 } 146 147 func TestRunUserPluginReturnsErr(t *testing.T) { 148 f := newWatFixture(t) 149 defer f.tearDown() 150 151 plugin := userPlugin{cmd: "not-a-valid-command"} 152 153 _, err := plugin.run(context.Background(), f.root.Path()) 154 if err == nil { 155 f.t.Fatal("Expected error b/c of bad command, but none returned") 156 } 157 } 158 159 func TestRunUserPluginReturnsTimeoutErr(t *testing.T) { 160 f := newWatFixture(t) 161 defer f.tearDown() 162 ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond) 163 defer cancel() 164 165 plugin := userPlugin{cmd: "sleep 2"} 166 167 _, err := plugin.run(ctx, f.root.Path()) 168 if err == nil { 169 f.t.Fatal("Expected error b/c of timeout, but none returned") 170 } 171 }