1package fsm_test 2 3import ( 4 "testing" 5 6 "github.com/jawher/mow.cli/internal/container" 7 "github.com/jawher/mow.cli/internal/fsm" 8 "github.com/jawher/mow.cli/internal/fsm/fsmtest" 9 "github.com/jawher/mow.cli/internal/matcher" 10 "github.com/jawher/mow.cli/internal/values" 11 "github.com/stretchr/testify/require" 12) 13 14func TestApplyTerminalStateNoArgs(t *testing.T) { 15 s := fsm.NewState() 16 s.Terminal = true 17 18 err := s.Parse(nil) 19 20 require.NoError(t, err) 21} 22 23func TestApply(t *testing.T) { 24 var ( 25 testArgs = []string{"1", "2", "3"} 26 optStrs []string 27 optCon = &container.Container{ 28 Value: values.NewStrings(&optStrs, nil), 29 } 30 argStrs []string 31 argCon = &container.Container{ 32 Value: values.NewStrings(&argStrs, nil), 33 } 34 calls []string 35 ) 36 matchers := map[string]matcher.Matcher{ 37 "a": fsmtest.TestMatcher{ 38 TestPriority: 2, 39 MatchFunc: func(args []string, c *matcher.ParseContext) (bool, []string) { 40 require.Equal(t, testArgs, args) 41 42 calls = append(calls, "a") 43 44 c.Opts[optCon] = []string{"a.opt"} 45 c.Args[argCon] = []string{"a.arg"} 46 return true, args[1:] 47 }, 48 }, 49 "b": fsmtest.TestMatcher{ 50 TestPriority: 1, 51 MatchFunc: func(args []string, c *matcher.ParseContext) (bool, []string) { 52 require.Equal(t, testArgs, args) 53 54 calls = append(calls, "b") 55 56 c.Opts[optCon] = []string{"b.opt"} 57 c.Args[argCon] = []string{"b.arg"} 58 return true, args[1:] 59 }, 60 }, 61 "c": fsmtest.TestMatcher{ 62 TestPriority: 1, 63 MatchFunc: func(args []string, c *matcher.ParseContext) (bool, []string) { 64 require.Equal(t, testArgs[1:], args, "second stage matchers should be called with the rem args") 65 66 calls = append(calls, "c") 67 68 c.Opts[optCon] = []string{"c.opt"} 69 c.Args[argCon] = []string{"c.arg"} 70 return true, args[1:] 71 }, 72 }, 73 "d": fsmtest.TestMatcher{ 74 TestPriority: 1, 75 MatchFunc: func(args []string, c *matcher.ParseContext) (bool, []string) { 76 require.Equal(t, testArgs[1:], args, "second stage matchers should be called with the rem args") 77 78 calls = append(calls, "d") 79 80 c.Opts[optCon] = []string{"d.opt"} 81 c.Args[argCon] = []string{"d.arg"} 82 return false, args[1:] 83 }, 84 }, 85 "e": fsmtest.TestMatcher{ 86 TestPriority: 1, 87 MatchFunc: func(args []string, c *matcher.ParseContext) (bool, []string) { 88 require.Equal(t, testArgs[2:], args, "third stage matchers should be called with the rem args") 89 90 calls = append(calls, "e") 91 92 c.Opts[optCon] = []string{"e.opt"} 93 c.Args[argCon] = []string{"e.arg"} 94 return true, nil 95 }, 96 }, 97 } 98 s := fsmtest.NewFsm(` 99 S1 a S2 100 S1 b S3 101 102 S2 c S4 103 S3 d S4 104 105 S4 e (S5) 106 `, matchers) 107 108 s.Prepare() 109 110 err := s.Parse(testArgs) 111 112 require.Equal(t, []string{"b", "a", "d", "c", "e"}, calls) 113 114 require.NoError(t, err) 115 116 require.Equal(t, []string{"a.opt", "c.opt", "e.opt"}, optStrs) 117 require.Equal(t, []string{"a.arg", "c.arg", "e.arg"}, argStrs) 118} 119 120func TestApplyRejectOptions(t *testing.T) { 121 var ( 122 testArgs = []string{"1", "--", "2"} 123 calls []string 124 ) 125 matchers := map[string]matcher.Matcher{ 126 "a": fsmtest.TestMatcher{ 127 MatchFunc: func(args []string, c *matcher.ParseContext) (bool, []string) { 128 require.Equal(t, testArgs, args) 129 require.False(t, c.RejectOptions) 130 131 calls = append(calls, "a") 132 return true, args[1:] 133 }, 134 }, 135 "b": fsmtest.TestMatcher{ 136 MatchFunc: func(args []string, c *matcher.ParseContext) (bool, []string) { 137 require.Equal(t, []string{"2"}, args) 138 require.True(t, c.RejectOptions) 139 140 calls = append(calls, "b") 141 return true, args[1:] 142 }, 143 }, 144 } 145 s := fsmtest.NewFsm(` 146 S1 a S2 147 S2 b (S3) 148 `, matchers) 149 150 s.Prepare() 151 152 err := s.Parse(testArgs) 153 154 require.NoError(t, err) 155 156 require.Equal(t, []string{"a", "b"}, calls) 157 158} 159