/ dispatcher_test.go
dispatcher_test.go
  1  package dispatch2_test
  2  
  3  import (
  4  	"context"
  5  	"fmt"
  6  	"testing"
  7  
  8  	"codeberg.org/vlbeaudoin/dispatch2"
  9  )
 10  
 11  func TestSimple(t *testing.T) {
 12  	type Config struct {
 13  		Verbose bool
 14  	}
 15  
 16  	d := dispatch2.NewDispatcher[Config]()
 17  
 18  	if err := d.RegisterFunc("basic", "basic command", "", []string{"b"}, func(ctx context.Context, cfg *Config, args []string) error {
 19  		select {
 20  		case <-ctx.Done():
 21  			return ctx.Err()
 22  		default:
 23  			t.Log("inside basic executer")
 24  			if cfg.Verbose {
 25  				t.Log("basic: verbose mode is on")
 26  			}
 27  			return nil
 28  		}
 29  	}); err != nil {
 30  		t.Error(err)
 31  	}
 32  
 33  	for _, command := range d.Commands() {
 34  		t.Run(
 35  			fmt.Sprintf("exec: %q", command),
 36  			func(t *testing.T) {
 37  				if err := command.Execute(context.TODO(), d.Config(), []string{}); err != nil {
 38  					t.Error(err)
 39  				}
 40  			})
 41  	}
 42  
 43  	t.Run("dispatch basic", func(t *testing.T) {
 44  		if err := d.Dispatch(context.TODO(), []string{"basic"}); err != nil {
 45  			t.Error(err)
 46  		}
 47  	})
 48  
 49  	t.Run("dispatch empty string", func(t *testing.T) {
 50  		if err := d.Dispatch(context.TODO(), nil); err != nil {
 51  			if err != dispatch2.ErrCommandRequired {
 52  				t.Error(err)
 53  			}
 54  		}
 55  	})
 56  
 57  	t.Run("dispatch invalid", func(t *testing.T) {
 58  		if err := d.Dispatch(context.TODO(), []string{"invalid"}); err != nil {
 59  			if err != dispatch2.ErrCommandNotFound {
 60  				t.Error(err)
 61  			}
 62  		}
 63  	})
 64  
 65  	t.Run("help", func(t *testing.T) {
 66  		if err := d.RegisterFunc(
 67  			"help",
 68  			"show help",
 69  			"help COMMAND [SUBCOMMAND...]",
 70  			nil,
 71  			func(ctx context.Context, cfg *Config, args []string) error {
 72  				t.Log("help command executed")
 73  				return nil
 74  			},
 75  		); err != nil {
 76  			t.Error(err)
 77  		}
 78  
 79  		if err := d.Dispatch(context.TODO(), []string{"help"}); err != nil {
 80  			t.Error(err)
 81  		}
 82  
 83  		if err := d.Dispatch(context.TODO(), []string{"help", "invalid"}); err != nil {
 84  			t.Error(err)
 85  		}
 86  	})
 87  
 88  	t.Run("subcommand", func(t *testing.T) {
 89  		deepCmd := dispatch2.NewCommandFunc(
 90  			"deep",
 91  			"deep command",
 92  			"deep SUBCOMMAND...",
 93  			nil,
 94  			func(ctx context.Context, cfg *Config, args []string) error {
 95  				t.Log("executed 'deep' command")
 96  				t.Log("remaining args:", args)
 97  				return nil
 98  			})
 99  
100  		if err := deepCmd.RegisterFunc(
101  			"deeper",
102  			"deeper command",
103  			"deeper SUBCOMMAND...",
104  			nil,
105  			func(ctx context.Context, cfg *Config, args []string) error {
106  				t.Log("executed 'deep deeper' command")
107  				return nil
108  			},
109  		); err != nil {
110  			t.Error(err)
111  		}
112  
113  		if err := d.RegisterCommand(deepCmd); err != nil {
114  			t.Error(err)
115  		}
116  
117  		t.Run("deep deeper", func(t *testing.T) {
118  			if err := d.Dispatch(context.TODO(), []string{"deep", "deeper"}); err != nil {
119  				t.Log(d.Commands())
120  				for _, cmd := range d.Commands() {
121  					t.Logf("%s subcommands: %d", cmd.Name(), cmd.NSubcommands())
122  					if cmd.NSubcommands() != 0 {
123  						for _, cmd := range cmd.Subcommands() {
124  							t.Log("inner command: ", cmd)
125  						}
126  					}
127  				}
128  				t.Error(err)
129  			}
130  		})
131  
132  		t.Run("deep", func(t *testing.T) {
133  			if err := d.Dispatch(context.TODO(), []string{"deep"}); err != nil {
134  				t.Error(err)
135  			}
136  		})
137  
138  		t.Run("deep invalid", func(t *testing.T) {
139  			if err := d.Dispatch(context.TODO(), []string{"deep", "invalid"}); err != nil {
140  				t.Error(err)
141  			}
142  		})
143  
144  		t.Run("deep with helloworld middleware", func(t *testing.T) {
145  			/*
146  				f := dispatch2.MiddlewareHelloWorld[Config]()(dispatch2.WrapExecuter(deepCmd.Executer()))
147  				if err := f(); err != nil {
148  					t.Error(err)
149  				}
150  			*/
151  
152  			/*
153  				mw := dispatch2.WrapMiddleware(func(e dispatch2.Executer[Config]) dispatch2.Executer[Config] {
154  					//	return dispatch2.ExecuterFunc[Config](func(ctx context.Context, cfg *Config, args []string) error {
155  					//		return e.Execute(ctx, cfg, args)
156  					//	})
157  					return deepCmd
158  				})
159  
160  				executer := mw(deepCmd.Execute)
161  
162  				if err := executer(context.TODO(), &Config{}, []string{}); err != nil {
163  					t.Error(err)
164  				}
165  			*/
166  
167  			if err := dispatch2.MiddlewareHelloWorld[Config]()(
168  				dispatch2.ExecuterFunc[Config](deepCmd.Execute))(
169  				context.TODO(), d.Config(), []string{}); err != nil {
170  				t.Error(err)
171  			}
172  		})
173  	})
174  }
175  
176  func TestDispatcherMiddleware(t *testing.T) {
177  	type Config struct{}
178  
179  	d := dispatch2.NewDispatcher[Config]()
180  
181  	d.Before(dispatch2.MiddlewarePrinter[Config]("dispatch middleware before 1"))
182  	d.Before(dispatch2.MiddlewarePrinter[Config]("dispatch middleware before 2"))
183  	d.After(dispatch2.MiddlewarePrinter[Config]("dispatch middleware after 1"))
184  	d.After(dispatch2.MiddlewarePrinter[Config]("dispatch middleware after 2"))
185  
186  	c := dispatch2.NewCommand(
187  		"foo",
188  		"foo command for TestDispatcherMiddleware",
189  		"foo",
190  		nil,
191  		dispatch2.EmptyExecuter[Config]())
192  
193  	c.Before(dispatch2.MiddlewarePrinter[Config]("command middleware before 1"))
194  	c.Before(dispatch2.MiddlewarePrinter[Config]("command middleware before 2"))
195  	c.After(dispatch2.MiddlewarePrinter[Config]("command middleware after 1"))
196  	c.After(dispatch2.MiddlewarePrinter[Config]("command middleware after 2"))
197  
198  	if err := d.RegisterCommand(c); err != nil {
199  		t.Error(err)
200  	}
201  
202  	if err := d.Dispatch(context.TODO(), []string{"foo"}); err != nil {
203  		t.Error(err)
204  	}
205  }