carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package runs
2
3import (
4 "errors"
5 "reflect"
6 "strings"
7 "testing"
8)
9
10// TestCommandGranted is Review Focus 4's pin among others: a prefix matches
11// word for word and exactly, never as a substring, never case-folded, and a
12// zero-word prefix matches nothing.
13func TestCommandGranted(t *testing.T) {
14 ic := [][]string{{"import", "classic"}}
15 for _, tc := range []struct {
16 name string
17 argv []string
18 prefixes [][]string
19 want bool
20 }{
21 {"prefix then more words", []string{"import", "classic", "--slug", "x"}, ic, true},
22 {"exactly the prefix", []string{"import", "classic"}, ic, true},
23 {"shorter than the prefix", []string{"import"}, ic, false},
24 {"a word that only starts with the prefix word", []string{"importer", "classic"}, ic, false},
25 {"a word the prefix word only starts", []string{"imp", "classic"}, ic, false},
26 {"case differs", []string{"Import", "classic"}, ic, false},
27 {"empty argv", []string{}, ic, false},
28 {"nil argv", nil, ic, false},
29 {"empty argv under a zero-word prefix", []string{}, [][]string{{}}, false},
30 {"second of two prefixes", []string{"import", "sync", "--all"}, [][]string{{"import", "classic"}, {"import", "sync"}}, true},
31 {"neither of two prefixes", []string{"export", "sync"}, [][]string{{"import", "classic"}, {"import", "sync"}}, false},
32 {"zero-word prefix", []string{"anything"}, [][]string{{}}, false},
33 {"nil prefix", []string{"anything"}, [][]string{nil}, false},
34 {"no prefixes", []string{"anything"}, nil, false},
35 {"zero-word prefix beside a real one does not widen it", []string{"rm", "-rf"}, [][]string{nil, {"import"}}, false},
36 } {
37 if got := CommandGranted(tc.argv, tc.prefixes); got != tc.want {
38 t.Errorf("%s: CommandGranted(%q, %q) = %v, want %v", tc.name, tc.argv, tc.prefixes, got, tc.want)
39 }
40 }
41}
42
43func TestCheckCommandPrefixes(t *testing.T) {
44 if err := CheckCommandPrefixes(nil); !errors.Is(err, ErrNoCommands) {
45 t.Errorf("nil: err = %v, want ErrNoCommands", err)
46 }
47 if err := CheckCommandPrefixes([][]string{}); !errors.Is(err, ErrNoCommands) {
48 t.Errorf("empty: err = %v, want ErrNoCommands", err)
49 }
50 word128 := strings.Repeat("a", MaxCommandWordBytes)
51 many := func(n int) [][]string {
52 out := make([][]string, n)
53 for i := range out {
54 out[i] = []string{word128}
55 }
56 return out
57 }
58 for name, bad := range map[string][][]string{
59 "zero-word prefix": {{"import"}, {}},
60 "nil prefix": {nil},
61 "empty word": {{"import", ""}},
62 "129-byte word": {{"import", word128 + "a"}},
63 "33 prefixes": many(MaxCommandPrefixes + 1),
64 "zero-word prefix only": {{}},
65 "a word with a space": {{"import classic"}},
66 "a word with a comma": {{"import,classic"}},
67 "a word with a tab": {{"import\tclassic"}},
68 "a word with ESC": {{"import", "\x1b[8mclassic"}},
69 "a word with NUL": {{"import", "a\x00"}},
70 "invalid UTF-8": {{"import", "\xff"}},
71 "U+FFFD": {{"import", "\ufffd"}},
72 "a no-break space": {{"import\u00a0classic"}},
73 "a zero-width space": {{"import\u200bclassic"}},
74 "a newline": {{"import\n"}},
75 } {
76 if err := CheckCommandPrefixes(bad); err == nil {
77 t.Errorf("%s: accepted; want refused", name)
78 }
79 }
80 if err := CheckCommandPrefixes(many(MaxCommandPrefixes)); err != nil {
81 t.Errorf("32 prefixes of 128-byte words: %v; want accepted", err)
82 }
83 if err := CheckCommandPrefixes([][]string{{"import", "classic"}, {"import", "sync"}}); err != nil {
84 t.Errorf("two prefixes: %v", err)
85 }
86 if err := CheckCommandPrefixes([][]string{{"import", "--slug=café", "über/ü", "a:b;c"}}); err != nil {
87 t.Errorf("printable non-ASCII and punctuation: %v; want accepted", err)
88 }
89 if err := CheckCommandPrefixes([][]string{{"import", "\x1b"}}); !errors.Is(err, ErrCommandWordChars) {
90 t.Errorf("ESC: err = %v, want ErrCommandWordChars", err)
91 }
92}
93
94// TestParseCommandList is the one text form both the CLI flag and the
95// console form take: prefixes split on commas, words on spaces, empty
96// entries dropped.
97func TestParseCommandList(t *testing.T) {
98 for _, tc := range []struct {
99 in string
100 want [][]string
101 }{
102 {"", nil},
103 {" , ,", nil},
104 {"import classic", [][]string{{"import", "classic"}}},
105 {"import classic,import sync", [][]string{{"import", "classic"}, {"import", "sync"}}},
106 {" import classic , import sync ,", [][]string{{"import", "classic"}, {"import", "sync"}}},
107 } {
108 if got := ParseCommandList(tc.in); !reflect.DeepEqual(got, tc.want) {
109 t.Errorf("ParseCommandList(%q) = %q, want %q", tc.in, got, tc.want)
110 }
111 }
112 if got := FormatCommandList([][]string{{"import", "classic"}, {"import", "sync"}}); got != "import classic, import sync" {
113 t.Errorf("FormatCommandList = %q", got)
114 }
115}
116
117// TestCommandListRoundTrips: every accepted list survives being written out
118// as text and read back, so a listing copied into a new mint grants exactly
119// what it showed.
120func TestCommandListRoundTrips(t *testing.T) {
121 word128 := strings.Repeat("ü", MaxCommandWordBytes/2)
122 max := make([][]string, MaxCommandPrefixes)
123 for i := range max {
124 max[i] = []string{word128, "x"}
125 }
126 for _, p := range [][][]string{
127 {{"import"}},
128 {{"import", "classic"}, {"import", "sync", "--all"}},
129 {{"--slug=café"}, {"a:b;c", "[x]", "\"q\""}},
130 max,
131 } {
132 if err := CheckCommandPrefixes(p); err != nil {
133 t.Fatalf("fixture %q is not accepted: %v", p, err)
134 }
135 if got := ParseCommandList(FormatCommandList(p)); !reflect.DeepEqual(got, p) {
136 t.Errorf("round trip of %q gave %q", p, got)
137 }
138 }
139}
140
141// FuzzCommandListRoundTrip: whatever text is typed, if the list it parses
142// to is accepted, formatting and parsing it again gives the same list.
143func FuzzCommandListRoundTrip(f *testing.F) {
144 for _, s := range []string{"import classic,import sync", " a ,, b c ", "a\u00a0b", "x\x1b", "\xff", "café, über"} {
145 f.Add(s)
146 }
147 f.Fuzz(func(t *testing.T, s string) {
148 p := ParseCommandList(s)
149 if CheckCommandPrefixes(p) != nil {
150 return
151 }
152 if got := ParseCommandList(FormatCommandList(p)); !reflect.DeepEqual(got, p) {
153 t.Fatalf("round trip of %q (from %q) gave %q", p, s, got)
154 }
155 })
156}
157