Home | History | Annotate | Download | only in path
      1 // Copyright 2009 The Go 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 path
      6 
      7 import (
      8 	"runtime"
      9 	"testing"
     10 )
     11 
     12 type PathTest struct {
     13 	path, result string
     14 }
     15 
     16 var cleantests = []PathTest{
     17 	// Already clean
     18 	{"", "."},
     19 	{"abc", "abc"},
     20 	{"abc/def", "abc/def"},
     21 	{"a/b/c", "a/b/c"},
     22 	{".", "."},
     23 	{"..", ".."},
     24 	{"../..", "../.."},
     25 	{"../../abc", "../../abc"},
     26 	{"/abc", "/abc"},
     27 	{"/", "/"},
     28 
     29 	// Remove trailing slash
     30 	{"abc/", "abc"},
     31 	{"abc/def/", "abc/def"},
     32 	{"a/b/c/", "a/b/c"},
     33 	{"./", "."},
     34 	{"../", ".."},
     35 	{"../../", "../.."},
     36 	{"/abc/", "/abc"},
     37 
     38 	// Remove doubled slash
     39 	{"abc//def//ghi", "abc/def/ghi"},
     40 	{"//abc", "/abc"},
     41 	{"///abc", "/abc"},
     42 	{"//abc//", "/abc"},
     43 	{"abc//", "abc"},
     44 
     45 	// Remove . elements
     46 	{"abc/./def", "abc/def"},
     47 	{"/./abc/def", "/abc/def"},
     48 	{"abc/.", "abc"},
     49 
     50 	// Remove .. elements
     51 	{"abc/def/ghi/../jkl", "abc/def/jkl"},
     52 	{"abc/def/../ghi/../jkl", "abc/jkl"},
     53 	{"abc/def/..", "abc"},
     54 	{"abc/def/../..", "."},
     55 	{"/abc/def/../..", "/"},
     56 	{"abc/def/../../..", ".."},
     57 	{"/abc/def/../../..", "/"},
     58 	{"abc/def/../../../ghi/jkl/../../../mno", "../../mno"},
     59 
     60 	// Combinations
     61 	{"abc/./../def", "def"},
     62 	{"abc//./../def", "def"},
     63 	{"abc/../../././../def", "../../def"},
     64 }
     65 
     66 func TestClean(t *testing.T) {
     67 	for _, test := range cleantests {
     68 		if s := Clean(test.path); s != test.result {
     69 			t.Errorf("Clean(%q) = %q, want %q", test.path, s, test.result)
     70 		}
     71 		if s := Clean(test.result); s != test.result {
     72 			t.Errorf("Clean(%q) = %q, want %q", test.result, s, test.result)
     73 		}
     74 	}
     75 }
     76 
     77 func TestCleanMallocs(t *testing.T) {
     78 	if testing.Short() {
     79 		t.Skip("skipping malloc count in short mode")
     80 	}
     81 	if runtime.GOMAXPROCS(0) > 1 {
     82 		t.Log("skipping AllocsPerRun checks; GOMAXPROCS>1")
     83 		return
     84 	}
     85 
     86 	for _, test := range cleantests {
     87 		allocs := testing.AllocsPerRun(100, func() { Clean(test.result) })
     88 		if allocs > 0 {
     89 			t.Errorf("Clean(%q): %v allocs, want zero", test.result, allocs)
     90 		}
     91 	}
     92 }
     93 
     94 type SplitTest struct {
     95 	path, dir, file string
     96 }
     97 
     98 var splittests = []SplitTest{
     99 	{"a/b", "a/", "b"},
    100 	{"a/b/", "a/b/", ""},
    101 	{"a/", "a/", ""},
    102 	{"a", "", "a"},
    103 	{"/", "/", ""},
    104 }
    105 
    106 func TestSplit(t *testing.T) {
    107 	for _, test := range splittests {
    108 		if d, f := Split(test.path); d != test.dir || f != test.file {
    109 			t.Errorf("Split(%q) = %q, %q, want %q, %q", test.path, d, f, test.dir, test.file)
    110 		}
    111 	}
    112 }
    113 
    114 type JoinTest struct {
    115 	elem []string
    116 	path string
    117 }
    118 
    119 var jointests = []JoinTest{
    120 	// zero parameters
    121 	{[]string{}, ""},
    122 
    123 	// one parameter
    124 	{[]string{""}, ""},
    125 	{[]string{"a"}, "a"},
    126 
    127 	// two parameters
    128 	{[]string{"a", "b"}, "a/b"},
    129 	{[]string{"a", ""}, "a"},
    130 	{[]string{"", "b"}, "b"},
    131 	{[]string{"/", "a"}, "/a"},
    132 	{[]string{"/", ""}, "/"},
    133 	{[]string{"a/", "b"}, "a/b"},
    134 	{[]string{"a/", ""}, "a"},
    135 	{[]string{"", ""}, ""},
    136 }
    137 
    138 // join takes a []string and passes it to Join.
    139 func join(elem []string, args ...string) string {
    140 	args = elem
    141 	return Join(args...)
    142 }
    143 
    144 func TestJoin(t *testing.T) {
    145 	for _, test := range jointests {
    146 		if p := join(test.elem); p != test.path {
    147 			t.Errorf("join(%q) = %q, want %q", test.elem, p, test.path)
    148 		}
    149 	}
    150 }
    151 
    152 type ExtTest struct {
    153 	path, ext string
    154 }
    155 
    156 var exttests = []ExtTest{
    157 	{"path.go", ".go"},
    158 	{"path.pb.go", ".go"},
    159 	{"a.dir/b", ""},
    160 	{"a.dir/b.go", ".go"},
    161 	{"a.dir/", ""},
    162 }
    163 
    164 func TestExt(t *testing.T) {
    165 	for _, test := range exttests {
    166 		if x := Ext(test.path); x != test.ext {
    167 			t.Errorf("Ext(%q) = %q, want %q", test.path, x, test.ext)
    168 		}
    169 	}
    170 }
    171 
    172 var basetests = []PathTest{
    173 	// Already clean
    174 	{"", "."},
    175 	{".", "."},
    176 	{"/.", "."},
    177 	{"/", "/"},
    178 	{"////", "/"},
    179 	{"x/", "x"},
    180 	{"abc", "abc"},
    181 	{"abc/def", "def"},
    182 	{"a/b/.x", ".x"},
    183 	{"a/b/c.", "c."},
    184 	{"a/b/c.x", "c.x"},
    185 }
    186 
    187 func TestBase(t *testing.T) {
    188 	for _, test := range basetests {
    189 		if s := Base(test.path); s != test.result {
    190 			t.Errorf("Base(%q) = %q, want %q", test.path, s, test.result)
    191 		}
    192 	}
    193 }
    194 
    195 var dirtests = []PathTest{
    196 	{"", "."},
    197 	{".", "."},
    198 	{"/.", "/"},
    199 	{"/", "/"},
    200 	{"////", "/"},
    201 	{"/foo", "/"},
    202 	{"x/", "x"},
    203 	{"abc", "."},
    204 	{"abc/def", "abc"},
    205 	{"abc////def", "abc"},
    206 	{"a/b/.x", "a/b"},
    207 	{"a/b/c.", "a/b"},
    208 	{"a/b/c.x", "a/b"},
    209 }
    210 
    211 func TestDir(t *testing.T) {
    212 	for _, test := range dirtests {
    213 		if s := Dir(test.path); s != test.result {
    214 			t.Errorf("Dir(%q) = %q, want %q", test.path, s, test.result)
    215 		}
    216 	}
    217 }
    218 
    219 type IsAbsTest struct {
    220 	path  string
    221 	isAbs bool
    222 }
    223 
    224 var isAbsTests = []IsAbsTest{
    225 	{"", false},
    226 	{"/", true},
    227 	{"/usr/bin/gcc", true},
    228 	{"..", false},
    229 	{"/a/../bb", true},
    230 	{".", false},
    231 	{"./", false},
    232 	{"lala", false},
    233 }
    234 
    235 func TestIsAbs(t *testing.T) {
    236 	for _, test := range isAbsTests {
    237 		if r := IsAbs(test.path); r != test.isAbs {
    238 			t.Errorf("IsAbs(%q) = %v, want %v", test.path, r, test.isAbs)
    239 		}
    240 	}
    241 }
    242