mirror of
				https://github.com/golang/go.git
				synced 2025-10-31 16:50:58 +00:00 
			
		
		
		
	bytes, strings: add TrimPrefix and TrimSuffix
Everybody either gets confused and thinks this is TrimLeft/TrimRight or does this by hand which gets repetitive looking. R=rsc, kevlar CC=golang-dev https://golang.org/cl/7239044
This commit is contained in:
		
							parent
							
								
									fe14ee52cc
								
							
						
					
					
						commit
						e515d80d5d
					
				
					 21 changed files with 117 additions and 54 deletions
				
			
		|  | @ -778,8 +778,7 @@ func (w *Walker) walkConst(vs *ast.ValueSpec) { | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		if strings.HasPrefix(litType, constDepPrefix) { | 		if dep := strings.TrimPrefix(litType, constDepPrefix); dep != litType { | ||||||
| 			dep := litType[len(constDepPrefix):] |  | ||||||
| 			w.constDep[ident.Name] = dep | 			w.constDep[ident.Name] = dep | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -1542,8 +1542,8 @@ func godefsFields(fld []*ast.Field) { | ||||||
| 	npad := 0 | 	npad := 0 | ||||||
| 	for _, f := range fld { | 	for _, f := range fld { | ||||||
| 		for _, n := range f.Names { | 		for _, n := range f.Names { | ||||||
| 			if strings.HasPrefix(n.Name, prefix) && n.Name != prefix { | 			if n.Name != prefix { | ||||||
| 				n.Name = n.Name[len(prefix):] | 				n.Name = strings.TrimPrefix(n.Name, prefix) | ||||||
| 			} | 			} | ||||||
| 			if n.Name == "_" { | 			if n.Name == "_" { | ||||||
| 				// Use exported name instead. | 				// Use exported name instead. | ||||||
|  |  | ||||||
|  | @ -180,7 +180,7 @@ func (p *Package) cdefs(f *File, srcfile string) string { | ||||||
| 			for _, line := range lines { | 			for _, line := range lines { | ||||||
| 				line = strings.TrimSpace(line) | 				line = strings.TrimSpace(line) | ||||||
| 				if strings.HasPrefix(line, "type ") && strings.HasSuffix(line, " struct {") { | 				if strings.HasPrefix(line, "type ") && strings.HasSuffix(line, " struct {") { | ||||||
| 					s := line[len("type ") : len(line)-len(" struct {")] | 					s := strings.TrimSuffix(strings.TrimPrefix(line, "type "), " struct {") | ||||||
| 					printf("typedef struct %s %s;\n", s, s) | 					printf("typedef struct %s %s;\n", s, s) | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | @ -395,9 +395,7 @@ func typecheck1(cfg *TypeConfig, f interface{}, typeof map[interface{}]string, a | ||||||
| 			// Field or method. | 			// Field or method. | ||||||
| 			name := n.Sel.Name | 			name := n.Sel.Name | ||||||
| 			if t := typeof[n.X]; t != "" { | 			if t := typeof[n.X]; t != "" { | ||||||
| 				if strings.HasPrefix(t, "*") { | 				t = strings.TrimPrefix(t, "*") // implicit * | ||||||
| 					t = t[1:] // implicit * |  | ||||||
| 				} |  | ||||||
| 				if typ := cfg.Type[t]; typ != nil { | 				if typ := cfg.Type[t]; typ != nil { | ||||||
| 					if t := typ.dot(cfg, name); t != "" { | 					if t := typ.dot(cfg, name); t != "" { | ||||||
| 						typeof[n] = t | 						typeof[n] = t | ||||||
|  |  | ||||||
|  | @ -195,9 +195,7 @@ func testFlag(args []string, i int) (f *testFlagSpec, value string, extra bool) | ||||||
| 	} | 	} | ||||||
| 	name := arg[1:] | 	name := arg[1:] | ||||||
| 	// If there's already "test.", drop it for now. | 	// If there's already "test.", drop it for now. | ||||||
| 	if strings.HasPrefix(name, "test.") { | 	name = strings.TrimPrefix(name, "test.") | ||||||
| 		name = name[5:] |  | ||||||
| 	} |  | ||||||
| 	equals := strings.Index(name, "=") | 	equals := strings.Index(name, "=") | ||||||
| 	if equals >= 0 { | 	if equals >= 0 { | ||||||
| 		value = name[equals+1:] | 		value = name[equals+1:] | ||||||
|  |  | ||||||
|  | @ -229,9 +229,7 @@ func (dir *Directory) lookupLocal(name string) *Directory { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func splitPath(p string) []string { | func splitPath(p string) []string { | ||||||
| 	if strings.HasPrefix(p, "/") { | 	p = strings.TrimPrefix(p, "/") | ||||||
| 		p = p[1:] |  | ||||||
| 	} |  | ||||||
| 	if p == "" { | 	if p == "" { | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  | @ -310,14 +308,9 @@ func (root *Directory) listing(skipRoot bool) *DirList { | ||||||
| 		// the path is relative to root.Path - remove the root.Path | 		// the path is relative to root.Path - remove the root.Path | ||||||
| 		// prefix (the prefix should always be present but avoid | 		// prefix (the prefix should always be present but avoid | ||||||
| 		// crashes and check) | 		// crashes and check) | ||||||
| 		path := d.Path | 		path := strings.TrimPrefix(d.Path, root.Path) | ||||||
| 		if strings.HasPrefix(d.Path, root.Path) { |  | ||||||
| 			path = d.Path[len(root.Path):] |  | ||||||
| 		} |  | ||||||
| 		// remove leading separator if any - path must be relative | 		// remove leading separator if any - path must be relative | ||||||
| 		if len(path) > 0 && path[0] == '/' { | 		path = strings.TrimPrefix(path, "/") | ||||||
| 			path = path[1:] |  | ||||||
| 		} |  | ||||||
| 		p.Path = path | 		p.Path = path | ||||||
| 		p.Name = d.Name | 		p.Name = d.Name | ||||||
| 		p.HasPkg = d.HasPkg | 		p.HasPkg = d.HasPkg | ||||||
|  |  | ||||||
|  | @ -459,9 +459,7 @@ func (ns nameSpace) ReadDir(path string) ([]os.FileInfo, error) { | ||||||
| 		if hasPathPrefix(old, path) && old != path { | 		if hasPathPrefix(old, path) && old != path { | ||||||
| 			// Find next element after path in old. | 			// Find next element after path in old. | ||||||
| 			elem := old[len(path):] | 			elem := old[len(path):] | ||||||
| 			if strings.HasPrefix(elem, "/") { | 			elem = strings.TrimPrefix(elem, "/") | ||||||
| 				elem = elem[1:] |  | ||||||
| 			} |  | ||||||
| 			if i := strings.Index(elem, "/"); i >= 0 { | 			if i := strings.Index(elem, "/"); i >= 0 { | ||||||
| 				elem = elem[:i] | 				elem = elem[:i] | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | @ -419,9 +419,7 @@ func pkgLinkFunc(path string) string { | ||||||
| 	relpath := path[1:] | 	relpath := path[1:] | ||||||
| 	// because of the irregular mapping under goroot | 	// because of the irregular mapping under goroot | ||||||
| 	// we need to correct certain relative paths | 	// we need to correct certain relative paths | ||||||
| 	if strings.HasPrefix(relpath, "src/pkg/") { | 	relpath = strings.TrimPrefix(relpath, "src/pkg/") | ||||||
| 		relpath = relpath[len("src/pkg/"):] |  | ||||||
| 	} |  | ||||||
| 	return pkgHandler.pattern[1:] + relpath // remove trailing '/' for relative URL | 	return pkgHandler.pattern[1:] + relpath // remove trailing '/' for relative URL | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -347,7 +347,7 @@ func main() { | ||||||
| 		fs.Bind(target, OS(path), "/", bindReplace) | 		fs.Bind(target, OS(path), "/", bindReplace) | ||||||
| 		abspath = target | 		abspath = target | ||||||
| 	} else if strings.HasPrefix(path, cmdPrefix) { | 	} else if strings.HasPrefix(path, cmdPrefix) { | ||||||
| 		path = path[len(cmdPrefix):] | 		path = strings.TrimPrefix(path, cmdPrefix) | ||||||
| 		forceCmd = true | 		forceCmd = true | ||||||
| 	} else if bp, _ := build.Import(path, "", build.FindOnly); bp.Dir != "" && bp.ImportPath != "" { | 	} else if bp, _ := build.Import(path, "", build.FindOnly); bp.Dir != "" && bp.ImportPath != "" { | ||||||
| 		fs.Bind(target, OS(bp.Dir), "/", bindReplace) | 		fs.Bind(target, OS(bp.Dir), "/", bindReplace) | ||||||
|  |  | ||||||
|  | @ -90,9 +90,7 @@ func (f *File) checkCanonicalMethod(id *ast.Ident, t *ast.FuncType) { | ||||||
| 			fmt.Fprintf(&f.b, "<%s>", err) | 			fmt.Fprintf(&f.b, "<%s>", err) | ||||||
| 		} | 		} | ||||||
| 		actual := f.b.String() | 		actual := f.b.String() | ||||||
| 		if strings.HasPrefix(actual, "func(") { | 		actual = strings.TrimPrefix(actual, "func(") | ||||||
| 			actual = actual[4:] |  | ||||||
| 		} |  | ||||||
| 		actual = id.Name + actual | 		actual = id.Name + actual | ||||||
| 
 | 
 | ||||||
| 		f.Warnf(id.Pos(), "method %s should have signature %s", actual, expectFmt) | 		f.Warnf(id.Pos(), "method %s should have signature %s", actual, expectFmt) | ||||||
|  |  | ||||||
|  | @ -515,6 +515,24 @@ func TrimFunc(s []byte, f func(r rune) bool) []byte { | ||||||
| 	return TrimRightFunc(TrimLeftFunc(s, f), f) | 	return TrimRightFunc(TrimLeftFunc(s, f), f) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // TrimPrefix returns s without the provided leading prefix string. | ||||||
|  | // If s doesn't start with prefix, s is returned unchanged. | ||||||
|  | func TrimPrefix(s, prefix []byte) []byte { | ||||||
|  | 	if HasPrefix(s, prefix) { | ||||||
|  | 		return s[len(prefix):] | ||||||
|  | 	} | ||||||
|  | 	return s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // TrimSuffix returns s without the provided trailing suffix string. | ||||||
|  | // If s doesn't end with suffix, s is returned unchanged. | ||||||
|  | func TrimSuffix(s, suffix []byte) []byte { | ||||||
|  | 	if HasSuffix(s, suffix) { | ||||||
|  | 		return s[:len(s)-len(suffix)] | ||||||
|  | 	} | ||||||
|  | 	return s | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // IndexFunc interprets s as a sequence of UTF-8-encoded Unicode code points. | // IndexFunc interprets s as a sequence of UTF-8-encoded Unicode code points. | ||||||
| // It returns the byte index in s of the first Unicode | // It returns the byte index in s of the first Unicode | ||||||
| // code point satisfying f(c), or -1 if none do. | // code point satisfying f(c), or -1 if none do. | ||||||
|  |  | ||||||
|  | @ -794,8 +794,8 @@ func TestRunes(t *testing.T) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type TrimTest struct { | type TrimTest struct { | ||||||
| 	f               string | 	f            string | ||||||
| 	in, cutset, out string | 	in, arg, out string | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var trimTests = []TrimTest{ | var trimTests = []TrimTest{ | ||||||
|  | @ -820,12 +820,17 @@ var trimTests = []TrimTest{ | ||||||
| 	{"TrimRight", "", "123", ""}, | 	{"TrimRight", "", "123", ""}, | ||||||
| 	{"TrimRight", "", "", ""}, | 	{"TrimRight", "", "", ""}, | ||||||
| 	{"TrimRight", "☺\xc0", "☺", "☺\xc0"}, | 	{"TrimRight", "☺\xc0", "☺", "☺\xc0"}, | ||||||
|  | 	{"TrimPrefix", "aabb", "a", "abb"}, | ||||||
|  | 	{"TrimPrefix", "aabb", "b", "aabb"}, | ||||||
|  | 	{"TrimSuffix", "aabb", "a", "aabb"}, | ||||||
|  | 	{"TrimSuffix", "aabb", "b", "aab"}, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestTrim(t *testing.T) { | func TestTrim(t *testing.T) { | ||||||
| 	for _, tc := range trimTests { | 	for _, tc := range trimTests { | ||||||
| 		name := tc.f | 		name := tc.f | ||||||
| 		var f func([]byte, string) []byte | 		var f func([]byte, string) []byte | ||||||
|  | 		var fb func([]byte, []byte) []byte | ||||||
| 		switch name { | 		switch name { | ||||||
| 		case "Trim": | 		case "Trim": | ||||||
| 			f = Trim | 			f = Trim | ||||||
|  | @ -833,12 +838,21 @@ func TestTrim(t *testing.T) { | ||||||
| 			f = TrimLeft | 			f = TrimLeft | ||||||
| 		case "TrimRight": | 		case "TrimRight": | ||||||
| 			f = TrimRight | 			f = TrimRight | ||||||
|  | 		case "TrimPrefix": | ||||||
|  | 			fb = TrimPrefix | ||||||
|  | 		case "TrimSuffix": | ||||||
|  | 			fb = TrimSuffix | ||||||
| 		default: | 		default: | ||||||
| 			t.Errorf("Undefined trim function %s", name) | 			t.Errorf("Undefined trim function %s", name) | ||||||
| 		} | 		} | ||||||
| 		actual := string(f([]byte(tc.in), tc.cutset)) | 		var actual string | ||||||
|  | 		if f != nil { | ||||||
|  | 			actual = string(f([]byte(tc.in), tc.arg)) | ||||||
|  | 		} else { | ||||||
|  | 			actual = string(fb([]byte(tc.in), []byte(tc.arg))) | ||||||
|  | 		} | ||||||
| 		if actual != tc.out { | 		if actual != tc.out { | ||||||
| 			t.Errorf("%s(%q, %q) = %q; want %q", name, tc.in, tc.cutset, actual, tc.out) | 			t.Errorf("%s(%q, %q) = %q; want %q", name, tc.in, tc.arg, actual, tc.out) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -66,3 +66,20 @@ func ExampleCompare_search() { | ||||||
| 		// Found it! | 		// Found it! | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func ExampleTrimSuffix() { | ||||||
|  | 	var b = []byte("Hello, goodbye, etc!") | ||||||
|  | 	b = bytes.TrimSuffix(b, []byte("goodbye, etc!")) | ||||||
|  | 	b = bytes.TrimSuffix(b, []byte("gopher")) | ||||||
|  | 	b = append(b, bytes.TrimSuffix([]byte("world!"), []byte("x!"))...) | ||||||
|  | 	os.Stdout.Write(b) | ||||||
|  | 	// Output: Hello, world! | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func ExampleTrimPrefix() { | ||||||
|  | 	var b = []byte("Goodbye,, world!") | ||||||
|  | 	b = bytes.TrimPrefix(b, []byte("Goodbye,")) | ||||||
|  | 	b = bytes.TrimPrefix(b, []byte("See ya,")) | ||||||
|  | 	fmt.Printf("Hello%s", b) | ||||||
|  | 	// Output: Hello, world! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -42,10 +42,7 @@ func readParseTest(r *bufio.Reader) (text, want, context string, err error) { | ||||||
| 		} | 		} | ||||||
| 		b = append(b, line...) | 		b = append(b, line...) | ||||||
| 	} | 	} | ||||||
| 	text = string(b) | 	text = strings.TrimSuffix(string(b), "\n") | ||||||
| 	if strings.HasSuffix(text, "\n") { |  | ||||||
| 		text = text[:len(text)-1] |  | ||||||
| 	} |  | ||||||
| 	b = b[:0] | 	b = b[:0] | ||||||
| 
 | 
 | ||||||
| 	// Skip the error list. | 	// Skip the error list. | ||||||
|  |  | ||||||
|  | @ -551,9 +551,7 @@ func stripCommonPrefix(lines []string) { | ||||||
| 			} | 			} | ||||||
| 			// Shorten the computed common prefix by the length of | 			// Shorten the computed common prefix by the length of | ||||||
| 			// suffix, if it is found as suffix of the prefix. | 			// suffix, if it is found as suffix of the prefix. | ||||||
| 			if strings.HasSuffix(prefix, string(suffix)) { | 			prefix = strings.TrimSuffix(prefix, string(suffix)) | ||||||
| 				prefix = prefix[0 : len(prefix)-len(suffix)] |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -44,10 +44,7 @@ func FindPkg(path, srcDir string) (filename, id string) { | ||||||
| 		if bp.PkgObj == "" { | 		if bp.PkgObj == "" { | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		noext = bp.PkgObj | 		noext = strings.TrimSuffix(bp.PkgObj, ".a") | ||||||
| 		if strings.HasSuffix(noext, ".a") { |  | ||||||
| 			noext = noext[:len(noext)-len(".a")] |  | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 	case build.IsLocalImport(path): | 	case build.IsLocalImport(path): | ||||||
| 		// "./x" -> "/this/directory/x.ext", "/this/directory/x" | 		// "./x" -> "/this/directory/x.ext", "/this/directory/x" | ||||||
|  |  | ||||||
|  | @ -172,7 +172,7 @@ func (name handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||||||
| // listing the available profiles. | // listing the available profiles. | ||||||
| func Index(w http.ResponseWriter, r *http.Request) { | func Index(w http.ResponseWriter, r *http.Request) { | ||||||
| 	if strings.HasPrefix(r.URL.Path, "/debug/pprof/") { | 	if strings.HasPrefix(r.URL.Path, "/debug/pprof/") { | ||||||
| 		name := r.URL.Path[len("/debug/pprof/"):] | 		name := strings.TrimPrefix(r.URL.Path, "/debug/pprof/") | ||||||
| 		if name != "" { | 		if name != "" { | ||||||
| 			handler(name).ServeHTTP(w, r) | 			handler(name).ServeHTTP(w, r) | ||||||
| 			return | 			return | ||||||
|  |  | ||||||
|  | @ -198,9 +198,7 @@ func (r *Response) Write(w io.Writer) error { | ||||||
| 	} | 	} | ||||||
| 	protoMajor, protoMinor := strconv.Itoa(r.ProtoMajor), strconv.Itoa(r.ProtoMinor) | 	protoMajor, protoMinor := strconv.Itoa(r.ProtoMajor), strconv.Itoa(r.ProtoMinor) | ||||||
| 	statusCode := strconv.Itoa(r.StatusCode) + " " | 	statusCode := strconv.Itoa(r.StatusCode) + " " | ||||||
| 	if strings.HasPrefix(text, statusCode) { | 	text = strings.TrimPrefix(text, statusCode) | ||||||
| 		text = text[len(statusCode):] |  | ||||||
| 	} |  | ||||||
| 	io.WriteString(w, "HTTP/"+protoMajor+"."+protoMinor+" "+statusCode+text+"\r\n") | 	io.WriteString(w, "HTTP/"+protoMajor+"."+protoMinor+" "+statusCode+text+"\r\n") | ||||||
| 
 | 
 | ||||||
| 	// Process Body,ContentLength,Close,Trailer | 	// Process Body,ContentLength,Close,Trailer | ||||||
|  |  | ||||||
|  | @ -179,3 +179,19 @@ func ExampleToLower() { | ||||||
| 	fmt.Println(strings.ToLower("Gopher")) | 	fmt.Println(strings.ToLower("Gopher")) | ||||||
| 	// Output: gopher | 	// Output: gopher | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func ExampleTrimSuffix() { | ||||||
|  | 	var s = "Hello, goodbye, etc!" | ||||||
|  | 	s = strings.TrimSuffix(s, "goodbye, etc!") | ||||||
|  | 	s = strings.TrimSuffix(s, "planet") | ||||||
|  | 	fmt.Print(s, "world!") | ||||||
|  | 	// Output: Hello, world! | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func ExampleTrimPrefix() { | ||||||
|  | 	var s = "Goodbye,, world!" | ||||||
|  | 	s = strings.TrimPrefix(s, "Goodbye,") | ||||||
|  | 	s = strings.TrimPrefix(s, "Howdy,") | ||||||
|  | 	fmt.Print("Hello" + s) | ||||||
|  | 	// Output: Hello, world! | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -558,6 +558,24 @@ func TrimSpace(s string) string { | ||||||
| 	return TrimFunc(s, unicode.IsSpace) | 	return TrimFunc(s, unicode.IsSpace) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // TrimPrefix returns s without the provided leading prefix string. | ||||||
|  | // If s doesn't start with prefix, s is returned unchanged. | ||||||
|  | func TrimPrefix(s, prefix string) string { | ||||||
|  | 	if HasPrefix(s, prefix) { | ||||||
|  | 		return s[len(prefix):] | ||||||
|  | 	} | ||||||
|  | 	return s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // TrimSuffix returns s without the provided trailing suffix string. | ||||||
|  | // If s doesn't end with suffix, s is returned unchanged. | ||||||
|  | func TrimSuffix(s, suffix string) string { | ||||||
|  | 	if HasSuffix(s, suffix) { | ||||||
|  | 		return s[:len(s)-len(suffix)] | ||||||
|  | 	} | ||||||
|  | 	return s | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Replace returns a copy of the string s with the first n | // Replace returns a copy of the string s with the first n | ||||||
| // non-overlapping instances of old replaced by new. | // non-overlapping instances of old replaced by new. | ||||||
| // If n < 0, there is no limit on the number of replacements. | // If n < 0, there is no limit on the number of replacements. | ||||||
|  |  | ||||||
|  | @ -496,8 +496,8 @@ func TestSpecialCase(t *testing.T) { | ||||||
| func TestTrimSpace(t *testing.T) { runStringTests(t, TrimSpace, "TrimSpace", trimSpaceTests) } | func TestTrimSpace(t *testing.T) { runStringTests(t, TrimSpace, "TrimSpace", trimSpaceTests) } | ||||||
| 
 | 
 | ||||||
| var trimTests = []struct { | var trimTests = []struct { | ||||||
| 	f               string | 	f            string | ||||||
| 	in, cutset, out string | 	in, arg, out string | ||||||
| }{ | }{ | ||||||
| 	{"Trim", "abba", "a", "bb"}, | 	{"Trim", "abba", "a", "bb"}, | ||||||
| 	{"Trim", "abba", "ab", ""}, | 	{"Trim", "abba", "ab", ""}, | ||||||
|  | @ -520,6 +520,10 @@ var trimTests = []struct { | ||||||
| 	{"TrimRight", "", "123", ""}, | 	{"TrimRight", "", "123", ""}, | ||||||
| 	{"TrimRight", "", "", ""}, | 	{"TrimRight", "", "", ""}, | ||||||
| 	{"TrimRight", "☺\xc0", "☺", "☺\xc0"}, | 	{"TrimRight", "☺\xc0", "☺", "☺\xc0"}, | ||||||
|  | 	{"TrimPrefix", "aabb", "a", "abb"}, | ||||||
|  | 	{"TrimPrefix", "aabb", "b", "aabb"}, | ||||||
|  | 	{"TrimSuffix", "aabb", "a", "aabb"}, | ||||||
|  | 	{"TrimSuffix", "aabb", "b", "aab"}, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestTrim(t *testing.T) { | func TestTrim(t *testing.T) { | ||||||
|  | @ -533,12 +537,16 @@ func TestTrim(t *testing.T) { | ||||||
| 			f = TrimLeft | 			f = TrimLeft | ||||||
| 		case "TrimRight": | 		case "TrimRight": | ||||||
| 			f = TrimRight | 			f = TrimRight | ||||||
|  | 		case "TrimPrefix": | ||||||
|  | 			f = TrimPrefix | ||||||
|  | 		case "TrimSuffix": | ||||||
|  | 			f = TrimSuffix | ||||||
| 		default: | 		default: | ||||||
| 			t.Errorf("Undefined trim function %s", name) | 			t.Errorf("Undefined trim function %s", name) | ||||||
| 		} | 		} | ||||||
| 		actual := f(tc.in, tc.cutset) | 		actual := f(tc.in, tc.arg) | ||||||
| 		if actual != tc.out { | 		if actual != tc.out { | ||||||
| 			t.Errorf("%s(%q, %q) = %q; want %q", name, tc.in, tc.cutset, actual, tc.out) | 			t.Errorf("%s(%q, %q) = %q; want %q", name, tc.in, tc.arg, actual, tc.out) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Brad Fitzpatrick
						Brad Fitzpatrick