eval/vals: 0:0 and n:n are now valid string indicies.

Also expand the unit test.
This commit is contained in:
Qi Xiao 2018-10-14 10:58:52 +01:00
parent 754d5ce57e
commit 20c0eb1032
2 changed files with 39 additions and 7 deletions

View File

@ -20,15 +20,33 @@ func convertStringIndex(rawIndex interface{}, s string) (int, int, error) {
if err != nil {
return 0, 0, err
}
if index.Slice {
lower, upper := index.Lower, index.Upper
if startsWithRuneBoundary(s[lower:]) && endsWithRuneBoundary(s[:upper]) {
return lower, upper, nil
}
return 0, 0, errIndexNotAtRuneBoundary
}
// Not slice
r, size := utf8.DecodeRuneInString(s[index.Lower:])
if r == utf8.RuneError {
return 0, 0, errIndexNotAtRuneBoundary
}
if index.Slice {
if r, _ := utf8.DecodeLastRuneInString(s[:index.Upper]); r == utf8.RuneError {
return 0, 0, errIndexNotAtRuneBoundary
}
return index.Lower, index.Upper, nil
}
return index.Lower, index.Lower + size, nil
}
func startsWithRuneBoundary(s string) bool {
if s == "" {
return true
}
r, _ := utf8.DecodeRuneInString(s)
return r != utf8.RuneError
}
func endsWithRuneBoundary(s string) bool {
if s == "" {
return true
}
r, _ := utf8.DecodeLastRuneInString(s)
return r != utf8.RuneError
}

View File

@ -13,6 +13,17 @@ var (
)
var indexTests = tt.Table{
// String indicies
Args("abc", "0").Rets("a", nil),
Args("你好", "0").Rets("你", nil),
Args("你好", "3").Rets("好", nil),
Args("你好", "2").Rets(any, errIndexNotAtRuneBoundary),
Args("abc", "1:2").Rets("b", nil),
Args("abc", "1:").Rets("bc", nil),
Args("abc", ":").Rets("abc", nil),
Args("abc", ":0").Rets("", nil), // i == j == 0 is allowed
Args("abc", "3:").Rets("", nil), // i == j == n is allowed
// List indices
// ============
@ -32,7 +43,8 @@ var indexTests = tt.Table{
// Slice indicies: 0 <= i <= j <= n.
Args(li4, "1:3").Rets(eq(MakeList("bar", "lorem")), nil),
Args(li4, "3:4").Rets(eq(MakeList("ipsum")), nil),
Args(li4, "4:4").Rets(eq(EmptyList), nil), // i == j == n is allowed.
Args(li4, "0:0").Rets(eq(EmptyList), nil), // i == j == 0 is allowed
Args(li4, "4:4").Rets(eq(EmptyList), nil), // i == j == n is allowed
// i defaults to 0
Args(li4, ":2").Rets(eq(MakeList("foo", "bar")), nil),
Args(li4, ":-1").Rets(eq(MakeList("foo", "bar", "lorem")), nil),
@ -48,6 +60,8 @@ var indexTests = tt.Table{
Args(li4, "1:3:2").Rets(any, anyError),
// Map indicies
// ============
Args(m, "foo").Rets("bar", nil),
Args(m, "bad").Rets(any, anyError),
}