mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
fix bug in bytes.Map and add test cases for Map in both strings and bytes packages.
thanks to ulrik.sverdrup for the test case. Fixes #191. R=rsc CC=golang-dev https://golang.org/cl/155056
This commit is contained in:
parent
13ad5d40c4
commit
27779dd6cb
3 changed files with 56 additions and 3 deletions
|
|
@ -220,9 +220,7 @@ func Map(mapping func(rune int) int, s []byte) []byte {
|
||||||
for i := 0; i < len(s); {
|
for i := 0; i < len(s); {
|
||||||
wid := 1;
|
wid := 1;
|
||||||
rune := int(s[i]);
|
rune := int(s[i]);
|
||||||
if rune < utf8.RuneSelf {
|
if rune >= utf8.RuneSelf {
|
||||||
rune = mapping(rune)
|
|
||||||
} else {
|
|
||||||
rune, wid = utf8.DecodeRune(s[i:len(s)])
|
rune, wid = utf8.DecodeRune(s[i:len(s)])
|
||||||
}
|
}
|
||||||
rune = mapping(rune);
|
rune = mapping(rune);
|
||||||
|
|
|
||||||
|
|
@ -268,9 +268,22 @@ func tenRunes(rune int) string {
|
||||||
return string(r);
|
return string(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// User-defined self-inverse mapping function
|
||||||
|
func rot13(rune int) int {
|
||||||
|
step := 13;
|
||||||
|
if rune >= 'a' && rune <= 'z' {
|
||||||
|
return ((rune - 'a' + step) % 26) + 'a'
|
||||||
|
}
|
||||||
|
if rune >= 'A' && rune <= 'Z' {
|
||||||
|
return ((rune - 'A' + step) % 26) + 'A'
|
||||||
|
}
|
||||||
|
return rune;
|
||||||
|
}
|
||||||
|
|
||||||
func TestMap(t *testing.T) {
|
func TestMap(t *testing.T) {
|
||||||
// Run a couple of awful growth/shrinkage tests
|
// Run a couple of awful growth/shrinkage tests
|
||||||
a := tenRunes('a');
|
a := tenRunes('a');
|
||||||
|
|
||||||
// 1. Grow. This triggers two reallocations in Map.
|
// 1. Grow. This triggers two reallocations in Map.
|
||||||
maxRune := func(rune int) int { return unicode.MaxRune };
|
maxRune := func(rune int) int { return unicode.MaxRune };
|
||||||
m := Map(maxRune, Bytes(a));
|
m := Map(maxRune, Bytes(a));
|
||||||
|
|
@ -278,6 +291,7 @@ func TestMap(t *testing.T) {
|
||||||
if string(m) != expect {
|
if string(m) != expect {
|
||||||
t.Errorf("growing: expected %q got %q", expect, m)
|
t.Errorf("growing: expected %q got %q", expect, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Shrink
|
// 2. Shrink
|
||||||
minRune := func(rune int) int { return 'a' };
|
minRune := func(rune int) int { return 'a' };
|
||||||
m = Map(minRune, Bytes(tenRunes(unicode.MaxRune)));
|
m = Map(minRune, Bytes(tenRunes(unicode.MaxRune)));
|
||||||
|
|
@ -285,6 +299,20 @@ func TestMap(t *testing.T) {
|
||||||
if string(m) != expect {
|
if string(m) != expect {
|
||||||
t.Errorf("shrinking: expected %q got %q", expect, m)
|
t.Errorf("shrinking: expected %q got %q", expect, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3. Rot13
|
||||||
|
m = Map(rot13, Bytes("a to zed"));
|
||||||
|
expect = "n gb mrq";
|
||||||
|
if string(m) != expect {
|
||||||
|
t.Errorf("rot13: expected %q got %q", expect, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Rot13^2
|
||||||
|
m = Map(rot13, Map(rot13, Bytes("a to zed")));
|
||||||
|
expect = "a to zed";
|
||||||
|
if string(m) != expect {
|
||||||
|
t.Errorf("rot13: expected %q got %q", expect, m)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToUpper(t *testing.T) { runStringTests(t, ToUpper, "ToUpper", upperTests) }
|
func TestToUpper(t *testing.T) { runStringTests(t, ToUpper, "ToUpper", upperTests) }
|
||||||
|
|
|
||||||
|
|
@ -226,6 +226,18 @@ func tenRunes(rune int) string {
|
||||||
return string(r);
|
return string(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// User-defined self-inverse mapping function
|
||||||
|
func rot13(rune int) int {
|
||||||
|
step := 13;
|
||||||
|
if rune >= 'a' && rune <= 'z' {
|
||||||
|
return ((rune - 'a' + step) % 26) + 'a'
|
||||||
|
}
|
||||||
|
if rune >= 'A' && rune <= 'Z' {
|
||||||
|
return ((rune - 'A' + step) % 26) + 'A'
|
||||||
|
}
|
||||||
|
return rune;
|
||||||
|
}
|
||||||
|
|
||||||
func TestMap(t *testing.T) {
|
func TestMap(t *testing.T) {
|
||||||
// Run a couple of awful growth/shrinkage tests
|
// Run a couple of awful growth/shrinkage tests
|
||||||
a := tenRunes('a');
|
a := tenRunes('a');
|
||||||
|
|
@ -236,6 +248,7 @@ func TestMap(t *testing.T) {
|
||||||
if m != expect {
|
if m != expect {
|
||||||
t.Errorf("growing: expected %q got %q", expect, m)
|
t.Errorf("growing: expected %q got %q", expect, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Shrink
|
// 2. Shrink
|
||||||
minRune := func(rune int) int { return 'a' };
|
minRune := func(rune int) int { return 'a' };
|
||||||
m = Map(minRune, tenRunes(unicode.MaxRune));
|
m = Map(minRune, tenRunes(unicode.MaxRune));
|
||||||
|
|
@ -243,6 +256,20 @@ func TestMap(t *testing.T) {
|
||||||
if m != expect {
|
if m != expect {
|
||||||
t.Errorf("shrinking: expected %q got %q", expect, m)
|
t.Errorf("shrinking: expected %q got %q", expect, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3. Rot13
|
||||||
|
m = Map(rot13, "a to zed");
|
||||||
|
expect = "n gb mrq";
|
||||||
|
if m != expect {
|
||||||
|
t.Errorf("rot13: expected %q got %q", expect, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Rot13^2
|
||||||
|
m = Map(rot13, Map(rot13, "a to zed"));
|
||||||
|
expect = "a to zed";
|
||||||
|
if m != expect {
|
||||||
|
t.Errorf("rot13: expected %q got %q", expect, m)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToUpper(t *testing.T) { runStringTests(t, ToUpper, "ToUpper", upperTests) }
|
func TestToUpper(t *testing.T) { runStringTests(t, ToUpper, "ToUpper", upperTests) }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue