code.cestus.io/tools/fabricator@v0.4.3/pkg/cmd/cmd_test.go (about) 1 package cmd 2 3 import ( 4 "context" 5 "fmt" 6 "os" 7 "testing" 8 9 "code.cestus.io/tools/fabricator/internal/pkg/util" 10 "code.cestus.io/tools/fabricator/pkg/fabricator" 11 "code.cestus.io/tools/fabricator/pkg/helpers" 12 ) 13 14 func TestFabricatorCommandHandlesPlugins(t *testing.T) { 15 tests := []struct { 16 name string 17 args []string 18 expectPlugin string 19 expectPluginArgs []string 20 expectError string 21 }{ 22 { 23 name: "test that a plugin executable is found based on command args", 24 args: []string{"fabricator", "foo", "--bar"}, 25 expectPlugin: "plugin/testdata/fabricator-foo", 26 expectPluginArgs: []string{"--bar"}, 27 }, 28 { 29 name: "test that a plugin does not execute over an existing command by the same name", 30 args: []string{"fabricator", "version"}, 31 }, 32 } 33 34 for _, test := range tests { 35 t.Run(test.name, func(t *testing.T) { 36 ctx := context.Background() 37 pluginsHandler := &testPluginHandler{ 38 pluginsDirectory: "plugin/testdata", 39 } 40 io, _, _, errOut := fabricator.NewTestIOStreams() 41 42 util.BehaviorOnFatal(func(str string, code int) { 43 errOut.Write([]byte(str)) 44 }) 45 46 root := NewDefaultFabricatorCommandWithArgs(ctx, pluginsHandler, test.args, io, helpers.DefaultFlagParser) 47 48 root.SetArgs(test.args[1:]) 49 if err := root.Execute(); err != nil { 50 t.Fatalf("unexpected error: %v", err) 51 } 52 53 if pluginsHandler.err != nil && pluginsHandler.err.Error() != test.expectError { 54 t.Fatalf("unexpected error: expected %q to occur, but got %q", test.expectError, pluginsHandler.err) 55 } 56 57 if pluginsHandler.executedPlugin != test.expectPlugin { 58 t.Fatalf("unexpected plugin execution: expected %q, got %q", test.expectPlugin, pluginsHandler.executedPlugin) 59 } 60 61 if len(pluginsHandler.withArgs) != len(test.expectPluginArgs) { 62 t.Fatalf("unexpected plugin execution args: expected %q, got %q", test.expectPluginArgs, pluginsHandler.withArgs) 63 } 64 }) 65 } 66 } 67 68 type testPluginHandler struct { 69 pluginsDirectory string 70 71 // execution results 72 executedPlugin string 73 withArgs []string 74 withEnv fabricator.Environment 75 76 err error 77 } 78 79 func (h *testPluginHandler) Lookup(ctx context.Context, filename string, paths []string) (string, bool) { 80 // append supported plugin prefix to the filename 81 filename = fmt.Sprintf("%s-%s", "fabricator", filename) 82 83 dir, err := os.Stat(h.pluginsDirectory) 84 if err != nil { 85 h.err = err 86 return "", false 87 } 88 89 if !dir.IsDir() { 90 h.err = fmt.Errorf("expected %q to be a directory", h.pluginsDirectory) 91 return "", false 92 } 93 94 plugins, err := os.ReadDir(h.pluginsDirectory) 95 if err != nil { 96 h.err = err 97 return "", false 98 } 99 100 for _, p := range plugins { 101 if p.Name() == filename { 102 h.err = nil 103 return fmt.Sprintf("%s/%s", h.pluginsDirectory, p.Name()), true 104 } 105 } 106 107 h.err = fmt.Errorf("unable to find a plugin executable %q", filename) 108 return "", false 109 } 110 111 func (h *testPluginHandler) Execute(ctx context.Context, executablePath string, cmdArgs []string, env fabricator.Environment) error { 112 h.executedPlugin = executablePath 113 h.withArgs = cmdArgs 114 h.withEnv = env 115 return nil 116 }