github.com/neugram/ng@v0.0.0-20180309130942-d472ff93d872/ngcore/complete_test.go (about) 1 // Copyright 2016 The Neugram Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package ngcore 6 7 import ( 8 "context" 9 "io/ioutil" 10 "os" 11 "path/filepath" 12 "reflect" 13 "testing" 14 15 "neugram.io/ng/eval/environ" 16 "neugram.io/ng/eval/shell" 17 ) 18 19 type file struct { 20 name string 21 linkto string 22 dir, exec bool 23 } 24 25 type completeTest struct { 26 env map[string]string 27 line string 28 wantPrefix string 29 want []string 30 } 31 32 var emptyDir = []file{} 33 34 var emptyTests = []completeTest{ 35 {line: "", want: nil}, 36 {line: "ls ", wantPrefix: "ls ", want: nil}, 37 } 38 39 var justFilesDir = []file{ 40 {name: "unique"}, 41 {name: "file1"}, 42 {name: "file2"}, 43 {name: "cats"}, 44 {name: "more_cats", linkto: "cats"}, 45 } 46 47 var justFilesTests = []completeTest{ 48 { 49 line: "ls u", 50 wantPrefix: "ls ", 51 want: []string{"unique "}, 52 }, 53 { 54 line: "ls file1", 55 wantPrefix: "ls ", 56 want: []string{"file1 "}, 57 }, 58 { 59 line: "ls f", 60 wantPrefix: "ls ", 61 want: []string{"file1", "file2"}, 62 }, 63 { 64 line: "find . -name=un", 65 wantPrefix: "find . -name=", 66 want: []string{"unique "}, 67 }, 68 {line: "cat"}, 69 { 70 line: "ls more_", 71 wantPrefix: "ls ", 72 want: []string{"more_cats "}, 73 }, 74 } 75 76 var hierarchyDir = []file{ 77 {name: "hierarchy", dir: true}, 78 {name: "hierarchy/d1", dir: true}, 79 {name: "hierarchy/d2", dir: true}, 80 {name: "hierarchy/d2/d2d1", dir: true}, 81 {name: "hierarchy/d2/d2f1"}, 82 {name: "hierarchy/f1"}, 83 {name: "hierarchy/f2"}, 84 {name: "hierarchy/and1"}, 85 {name: "hierarchy/and2", dir: true}, 86 {name: "hierarchy/e1", exec: true}, 87 {name: "hierarchy/e2", exec: true}, 88 {name: "more_h", linkto: "hierarchy"}, 89 } 90 91 var hierarchyTests = []completeTest{ 92 { 93 line: "ls h", 94 wantPrefix: "ls ", 95 want: []string{"hierarchy/"}, 96 }, 97 { 98 line: "ls more_", 99 wantPrefix: "ls ", 100 want: []string{"more_h/"}, 101 }, 102 { 103 line: "ls hierarchy", 104 wantPrefix: "ls ", 105 want: []string{"hierarchy/"}, 106 }, 107 { 108 line: "ls hierarchy/", 109 wantPrefix: "ls hierarchy/", 110 want: []string{ 111 "and1", 112 "and2/", 113 "d1/", 114 "d2/", 115 "e1", 116 "e2", 117 "f1", 118 "f2", 119 }, 120 }, 121 { 122 line: "ls hierarchy/d", 123 wantPrefix: "ls hierarchy/", 124 want: []string{ 125 "d1/", 126 "d2/", 127 }, 128 }, 129 { 130 env: map[string]string{"H": "hierarchy"}, 131 line: "ls $H/d", 132 wantPrefix: "ls $H/", 133 want: []string{ 134 "d1/", 135 "d2/", 136 }, 137 }, 138 { 139 line: "ls hierarchy/f", 140 wantPrefix: "ls hierarchy/", 141 want: []string{ 142 "f1", 143 "f2", 144 }, 145 }, 146 { 147 line: "ls hierarchy/an", 148 wantPrefix: "ls hierarchy/", 149 want: []string{ 150 "and1", 151 "and2/", 152 }, 153 }, 154 { 155 line: "./hierarchy/f", 156 wantPrefix: "./hierarchy/", 157 }, 158 { 159 line: "./h", 160 wantPrefix: "./", 161 want: []string{"hierarchy/"}, 162 }, 163 { 164 line: "./hierarchy/e", 165 wantPrefix: "./hierarchy/", 166 want: []string{ 167 "e1", 168 "e2", 169 }, 170 }, 171 { 172 line: "hierarchy/f1 ", 173 wantPrefix: "hierarchy/f1 ", 174 want: []string{ 175 "hierarchy/", 176 "more_h/", 177 }, 178 }, 179 } 180 181 func testCompleteSh(t *testing.T, testName string, files []file, tests []completeTest) { 182 oldwd, err := os.Getwd() 183 if err != nil { 184 t.Fatalf("%s: %v", testName, err) 185 } 186 defer os.Chdir(oldwd) 187 dir, err := ioutil.TempDir("", "ngcompletetest") 188 if err != nil { 189 t.Fatalf("%s: %v", testName, err) 190 } 191 defer os.RemoveAll(dir) 192 if err := os.Chdir(dir); err != nil { 193 t.Fatalf("%s: %v", testName, err) 194 } 195 for _, f := range files { 196 if f.dir { 197 if err := os.MkdirAll(filepath.Join(dir, f.name), 0755); err != nil { 198 t.Fatalf("%s: %v", testName, err) 199 } 200 } 201 } 202 for _, f := range files { 203 if f.dir { 204 continue 205 } 206 if f.linkto != "" { 207 if err := os.Symlink(f.linkto, f.name); err != nil { 208 t.Fatalf("%s: %v", testName, err) 209 } 210 continue 211 } 212 perm := os.FileMode(0644) 213 if f.exec { 214 perm = os.FileMode(0755) 215 } 216 path := filepath.Join(dir, f.name) 217 name := []byte(f.name + " contents") 218 if err := ioutil.WriteFile(path, name, perm); err != nil { 219 t.Fatalf("%s: %v", testName, err) 220 } 221 } 222 223 ng := New() 224 defer ng.Close() 225 226 session, err := ng.NewSession(context.Background(), "test", nil) 227 if err != nil { 228 t.Fatal(err) 229 } 230 defer session.Close() 231 232 for _, test := range tests { 233 session.ShellState = &shell.State{ 234 Env: environ.New(), 235 Alias: environ.New(), 236 } 237 for k, v := range test.env { 238 session.ShellState.Env.Set(k, v) 239 } 240 gotPrefix, got, _ := session.completerSh(test.line, len(test.line)) 241 if gotPrefix != test.wantPrefix { 242 t.Errorf("%s: %q: gotPrefix=%v, wantPrefix=%v", testName, test.line, gotPrefix, test.wantPrefix) 243 } 244 if !reflect.DeepEqual(got, test.want) { 245 t.Errorf("%s: %q: got=%v, want=%v", testName, test.line, got, test.want) 246 } 247 } 248 } 249 250 func TestCompleteShell(t *testing.T) { 251 testCompleteSh(t, "empty", emptyDir, emptyTests) 252 testCompleteSh(t, "justFiles", justFilesDir, justFilesTests) 253 testCompleteSh(t, "hierarchy", hierarchyDir, hierarchyTests) 254 }