| // Copyright 2015 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| // string_ssa.go tests string operations. |
| package main |
| |
| import "testing" |
| |
| //go:noinline |
| func testStringSlice1_ssa(a string, i, j int) string { |
| return a[i:] |
| } |
| |
| //go:noinline |
| func testStringSlice2_ssa(a string, i, j int) string { |
| return a[:j] |
| } |
| |
| //go:noinline |
| func testStringSlice12_ssa(a string, i, j int) string { |
| return a[i:j] |
| } |
| |
| func testStringSlice(t *testing.T) { |
| tests := [...]struct { |
| fn func(string, int, int) string |
| s string |
| low, high int |
| want string |
| }{ |
| // -1 means the value is not used. |
| {testStringSlice1_ssa, "foobar", 0, -1, "foobar"}, |
| {testStringSlice1_ssa, "foobar", 3, -1, "bar"}, |
| {testStringSlice1_ssa, "foobar", 6, -1, ""}, |
| {testStringSlice2_ssa, "foobar", -1, 0, ""}, |
| {testStringSlice2_ssa, "foobar", -1, 3, "foo"}, |
| {testStringSlice2_ssa, "foobar", -1, 6, "foobar"}, |
| {testStringSlice12_ssa, "foobar", 0, 6, "foobar"}, |
| {testStringSlice12_ssa, "foobar", 0, 0, ""}, |
| {testStringSlice12_ssa, "foobar", 6, 6, ""}, |
| {testStringSlice12_ssa, "foobar", 1, 5, "ooba"}, |
| {testStringSlice12_ssa, "foobar", 3, 3, ""}, |
| {testStringSlice12_ssa, "", 0, 0, ""}, |
| } |
| |
| for i, test := range tests { |
| if got := test.fn(test.s, test.low, test.high); test.want != got { |
| t.Errorf("#%d %s[%d,%d] = %s, want %s", i, test.s, test.low, test.high, got, test.want) |
| } |
| } |
| } |
| |
| type prefix struct { |
| prefix string |
| } |
| |
| func (p *prefix) slice_ssa() { |
| p.prefix = p.prefix[:3] |
| } |
| |
| //go:noinline |
| func testStructSlice(t *testing.T) { |
| p := &prefix{"prefix"} |
| p.slice_ssa() |
| if "pre" != p.prefix { |
| t.Errorf("wrong field slice: wanted %s got %s", "pre", p.prefix) |
| } |
| } |
| |
| func testStringSlicePanic(t *testing.T) { |
| defer func() { |
| if r := recover(); r != nil { |
| //println("panicked as expected") |
| } |
| }() |
| |
| str := "foobar" |
| t.Errorf("got %s and expected to panic, but didn't", testStringSlice12_ssa(str, 3, 9)) |
| } |
| |
| const _Accuracy_name = "BelowExactAbove" |
| |
| var _Accuracy_index = [...]uint8{0, 5, 10, 15} |
| |
| //go:noinline |
| func testSmallIndexType_ssa(i int) string { |
| return _Accuracy_name[_Accuracy_index[i]:_Accuracy_index[i+1]] |
| } |
| |
| func testSmallIndexType(t *testing.T) { |
| tests := []struct { |
| i int |
| want string |
| }{ |
| {0, "Below"}, |
| {1, "Exact"}, |
| {2, "Above"}, |
| } |
| |
| for i, test := range tests { |
| if got := testSmallIndexType_ssa(test.i); got != test.want { |
| t.Errorf("#%d got %s wanted %s", i, got, test.want) |
| } |
| } |
| } |
| |
| //go:noinline |
| func testInt64Index_ssa(s string, i int64) byte { |
| return s[i] |
| } |
| |
| //go:noinline |
| func testInt64Slice_ssa(s string, i, j int64) string { |
| return s[i:j] |
| } |
| |
| func testInt64Index(t *testing.T) { |
| tests := []struct { |
| i int64 |
| j int64 |
| b byte |
| s string |
| }{ |
| {0, 5, 'B', "Below"}, |
| {5, 10, 'E', "Exact"}, |
| {10, 15, 'A', "Above"}, |
| } |
| |
| str := "BelowExactAbove" |
| for i, test := range tests { |
| if got := testInt64Index_ssa(str, test.i); got != test.b { |
| t.Errorf("#%d got %d wanted %d", i, got, test.b) |
| } |
| if got := testInt64Slice_ssa(str, test.i, test.j); got != test.s { |
| t.Errorf("#%d got %s wanted %s", i, got, test.s) |
| } |
| } |
| } |
| |
| func testInt64IndexPanic(t *testing.T) { |
| defer func() { |
| if r := recover(); r != nil { |
| //println("panicked as expected") |
| } |
| }() |
| |
| str := "foobar" |
| t.Errorf("got %d and expected to panic, but didn't", testInt64Index_ssa(str, 1<<32+1)) |
| } |
| |
| func testInt64SlicePanic(t *testing.T) { |
| defer func() { |
| if r := recover(); r != nil { |
| //println("panicked as expected") |
| } |
| }() |
| |
| str := "foobar" |
| t.Errorf("got %s and expected to panic, but didn't", testInt64Slice_ssa(str, 1<<32, 1<<32+1)) |
| } |
| |
| //go:noinline |
| func testStringElem_ssa(s string, i int) byte { |
| return s[i] |
| } |
| |
| func testStringElem(t *testing.T) { |
| tests := []struct { |
| s string |
| i int |
| n byte |
| }{ |
| {"foobar", 3, 98}, |
| {"foobar", 0, 102}, |
| {"foobar", 5, 114}, |
| } |
| for _, test := range tests { |
| if got := testStringElem_ssa(test.s, test.i); got != test.n { |
| t.Errorf("testStringElem \"%s\"[%d] = %d, wanted %d", test.s, test.i, got, test.n) |
| } |
| } |
| } |
| |
| //go:noinline |
| func testStringElemConst_ssa(i int) byte { |
| s := "foobar" |
| return s[i] |
| } |
| |
| func testStringElemConst(t *testing.T) { |
| if got := testStringElemConst_ssa(3); got != 98 { |
| t.Errorf("testStringElemConst= %d, wanted 98", got) |
| } |
| } |
| |
| func TestString(t *testing.T) { |
| testStringSlice(t) |
| testStringSlicePanic(t) |
| testStructSlice(t) |
| testSmallIndexType(t) |
| testStringElem(t) |
| testStringElemConst(t) |
| testInt64Index(t) |
| testInt64IndexPanic(t) |
| testInt64SlicePanic(t) |
| } |