summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2009-11-15 12:07:27 -0800
committerRob Pike <r@golang.org>2009-11-15 12:07:27 -0800
commit505e65563af267c6911981d54ab61914bab4f3a0 (patch)
treeab55ac2067df79f29579aaade24cc02ce769cfa5
parentc2bb73dc6c450bd22abe56838ec06bf90369d206 (diff)
downloadgolang-505e65563af267c6911981d54ab61914bab4f3a0.tar.gz
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 issue 191. R=rsc CC=golang-dev http://codereview.appspot.com/155056
-rw-r--r--src/pkg/bytes/bytes.go4
-rw-r--r--src/pkg/bytes/bytes_test.go28
-rw-r--r--src/pkg/strings/strings_test.go27
3 files changed, 56 insertions, 3 deletions
diff --git a/src/pkg/bytes/bytes.go b/src/pkg/bytes/bytes.go
index ccaa71a93..f6cae7353 100644
--- a/src/pkg/bytes/bytes.go
+++ b/src/pkg/bytes/bytes.go
@@ -220,9 +220,7 @@ func Map(mapping func(rune int) int, s []byte) []byte {
for i := 0; i < len(s); {
wid := 1;
rune := int(s[i]);
- if rune < utf8.RuneSelf {
- rune = mapping(rune)
- } else {
+ if rune >= utf8.RuneSelf {
rune, wid = utf8.DecodeRune(s[i:len(s)])
}
rune = mapping(rune);
diff --git a/src/pkg/bytes/bytes_test.go b/src/pkg/bytes/bytes_test.go
index 20d6b25f7..dddaf5064 100644
--- a/src/pkg/bytes/bytes_test.go
+++ b/src/pkg/bytes/bytes_test.go
@@ -268,9 +268,22 @@ func tenRunes(rune int) string {
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) {
// Run a couple of awful growth/shrinkage tests
a := tenRunes('a');
+
// 1. Grow. This triggers two reallocations in Map.
maxRune := func(rune int) int { return unicode.MaxRune };
m := Map(maxRune, Bytes(a));
@@ -278,6 +291,7 @@ func TestMap(t *testing.T) {
if string(m) != expect {
t.Errorf("growing: expected %q got %q", expect, m)
}
+
// 2. Shrink
minRune := func(rune int) int { return 'a' };
m = Map(minRune, Bytes(tenRunes(unicode.MaxRune)));
@@ -285,6 +299,20 @@ func TestMap(t *testing.T) {
if string(m) != expect {
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) }
diff --git a/src/pkg/strings/strings_test.go b/src/pkg/strings/strings_test.go
index 2281458ea..732da4242 100644
--- a/src/pkg/strings/strings_test.go
+++ b/src/pkg/strings/strings_test.go
@@ -226,6 +226,18 @@ func tenRunes(rune int) string {
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) {
// Run a couple of awful growth/shrinkage tests
a := tenRunes('a');
@@ -236,6 +248,7 @@ func TestMap(t *testing.T) {
if m != expect {
t.Errorf("growing: expected %q got %q", expect, m)
}
+
// 2. Shrink
minRune := func(rune int) int { return 'a' };
m = Map(minRune, tenRunes(unicode.MaxRune));
@@ -243,6 +256,20 @@ func TestMap(t *testing.T) {
if m != expect {
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) }