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  }