Repository: elliotchance/pie
Pull request #144 (2019-05-16 12:19:28)

Issue24: add SubSlice func
see [issue24](https://github.com/elliotchance/pie/issues/24)

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/elliotchance/pie/144)
<!-- Reviewable:end -->


codecov-io: # [Codecov](https://codecov.io/gh/elliotchance/pie/pull/144?src=pr&el=h1) Report
> :exclamation: No coverage uploaded for pull request base (`master@da458e3`). [Click here to learn what that means](https://docs.codecov.io/docs/error-reference#section-missing-base-commit).
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/elliotchance/pie/pull/144/graphs/tree.svg?width=650&token=OvugwUQGM3&height=150&src=pr)](https://codecov.io/gh/elliotchance/pie/pull/144?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##             master   #144   +/-   ##
=======================================
  Coverage          ?   100%           
=======================================
  Files             ?      8           
  Lines             ?   1428           
  Branches          ?      0           
=======================================
  Hits              ?   1428           
  Misses            ?      0           
  Partials          ?      0
```


| [Impacted Files](https://codecov.io/gh/elliotchance/pie/pull/144?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pie/float64s\_pie.go](https://codecov.io/gh/elliotchance/pie/pull/144/diff?src=pr&el=tree#diff-cGllL2Zsb2F0NjRzX3BpZS5nbw==) | `100% <100%> (ø)` | |
| [pie/carpointers\_pie.go](https://codecov.io/gh/elliotchance/pie/pull/144/diff?src=pr&el=tree#diff-cGllL2NhcnBvaW50ZXJzX3BpZS5nbw==) | `100% <100%> (ø)` | |
| [pie/cars\_pie.go](https://codecov.io/gh/elliotchance/pie/pull/144/diff?src=pr&el=tree#diff-cGllL2NhcnNfcGllLmdv) | `100% <100%> (ø)` | |
| [pie/ints\_pie.go](https://codecov.io/gh/elliotchance/pie/pull/144/diff?src=pr&el=tree#diff-cGllL2ludHNfcGllLmdv) | `100% <100%> (ø)` | |
| [pie/strings\_pie.go](https://codecov.io/gh/elliotchance/pie/pull/144/diff?src=pr&el=tree#diff-cGllL3N0cmluZ3NfcGllLmdv) | `100% <100%> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/elliotchance/pie/pull/144?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/elliotchance/pie/pull/144?src=pr&el=footer). Last update [da458e3...3147869](https://codecov.io/gh/elliotchance/pie/pull/144?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/README.md b/README.md
index f0a6671..587100c 100644
--- a/README.md
+++ b/README.md
@@ -217,6 +217,7 @@ The letters in brackets indicate:
 | `SortStableUsing` | ✓      |        | ✓      |      | n⋅log(n) | Return a new sorted slice, using custom comparator, keeping the original order of equal elements. |
 | `SortUsing`       | ✓      |        | ✓      |      | n⋅log(n) | Return a new sorted slice, using custom comparator. |
 | `Strings` (S)     | ✓      | ✓      | ✓      |      | n        | Transforms each element into a string. |
+| `SubSlice`        | ✓      | ✓      | ✓      |      | n        | Return the subSlice from start to end(excluded). |
 | `Sum`             |        | ✓      |        |      | n        | Sum (total) of all elements. |
 | `Top`             | ✓      | ✓      | ✓      |      | n        | Gets several elements from top(head of slice).|
 | `ToStrings`       | ✓      | ✓      | ✓      |      | n        | Transforms each element to a string. |
diff --git a/functions/main.go b/functions/main.go
index 53f7570..767072d 100644
--- a/functions/main.go
+++ b/functions/main.go
@@ -64,6 +64,7 @@ var Functions = []struct {
 	{"SortStableUsing", "sort_stable_using.go", ForStrings | ForStructs},
 	{"SortUsing", "sort_using.go", ForStrings | ForStructs},
 	{"Strings", "strings.go", ForAll},
+	{"SubSlice", "sub_slice.go", ForAll},
 	{"Sum", "sum.go", ForNumbers},
 	{"Top", "top.go", ForAll},
 	{"ToStrings", "to_strings.go", ForAll},
diff --git a/functions/sub_slice.go b/functions/sub_slice.go
new file mode 100644
index 0000000..1bd8d33
--- /dev/null
+++ b/functions/sub_slice.go
@@ -0,0 +1,32 @@
+package functions
+
+// SubSlice will return the subSlice from start to end(excluded)
+//
+// Condition 1: If start < 0 or end < 0, nil is returned.
+// Condition 2: If start >= end, nil is returned.
+// Condition 3: Return all elements that exist in the range provided,
+// if start or end is out of bounds, zero items will be placed.
+func (ss SliceType) SubSlice(start int, end int) (subSlice SliceType) {
+	if start < 0 || end < 0 {
+		return
+	}
+
+	if start >= end {
+		return
+	}
+
+	length := ss.Len()
+	if start < length {
+		if end <= length {
+			subSlice = ss[start:end]
+		} else {
+			zeroArray := make([]ElementType, end-length)
+			subSlice = ss[start:length].Append(zeroArray[:]...)
+		}
+	} else {
+		zeroArray := make([]ElementType, end-start)
+		subSlice = zeroArray[:]
+	}
+
+	return
+}
diff --git a/pie/carpointers_pie.go b/pie/carpointers_pie.go
index 33c0dad..2df30d0 100755
--- a/pie/carpointers_pie.go
+++ b/pie/carpointers_pie.go
@@ -509,6 +509,37 @@ func (ss carPointers) Strings() Strings {
 	return result
 }
 
+// SubSlice will return the subSlice from start to end(excluded)
+//
+// Condition 1: If start < 0 or end < 0, nil is returned.
+// Condition 2: If start >= end, nil is returned.
+// Condition 3: Return all elements that exist in the range provided,
+// if start or end is out of bounds, zero items will be placed.
+func (ss carPointers) SubSlice(start int, end int) (subSlice carPointers) {
+	if start < 0 || end < 0 {
+		return
+	}
+
+	if start >= end {
+		return
+	}
+
+	length := ss.Len()
+	if start < length {
+		if end <= length {
+			subSlice = ss[start:end]
+		} else {
+			zeroArray := make([]*car, end-length)
+			subSlice = ss[start:length].Append(zeroArray[:]...)
+		}
+	} else {
+		zeroArray := make([]*car, end-start)
+		subSlice = zeroArray[:]
+	}
+
+	return
+}
+
 // Top will return n elements from head of the slice
 // if the slice has less elements then n that'll return all elements
 // if n < 0 it'll return empty slice.
diff --git a/pie/cars_pie.go b/pie/cars_pie.go
index 315ce55..71bea5d 100755
--- a/pie/cars_pie.go
+++ b/pie/cars_pie.go
@@ -509,6 +509,37 @@ func (ss cars) Strings() Strings {
 	return result
 }
 
+// SubSlice will return the subSlice from start to end(excluded)
+//
+// Condition 1: If start < 0 or end < 0, nil is returned.
+// Condition 2: If start >= end, nil is returned.
+// Condition 3: Return all elements that exist in the range provided,
+// if start or end is out of bounds, zero items will be placed.
+func (ss cars) SubSlice(start int, end int) (subSlice cars) {
+	if start < 0 || end < 0 {
+		return
+	}
+
+	if start >= end {
+		return
+	}
+
+	length := ss.Len()
+	if start < length {
+		if end <= length {
+			subSlice = ss[start:end]
+		} else {
+			zeroArray := make([]car, end-length)
+			subSlice = ss[start:length].Append(zeroArray[:]...)
+		}
+	} else {
+		zeroArray := make([]car, end-start)
+		subSlice = zeroArray[:]
+	}
+
+	return
+}
+
 // Top will return n elements from head of the slice
 // if the slice has less elements then n that'll return all elements
 // if n < 0 it'll return empty slice.
diff --git a/pie/float64s_pie.go b/pie/float64s_pie.go
index 1066398..37230c8 100755
--- a/pie/float64s_pie.go
+++ b/pie/float64s_pie.go
@@ -673,6 +673,37 @@ func (ss Float64s) Strings() Strings {
 	return result
 }
 
+// SubSlice will return the subSlice from start to end(excluded)
+//
+// Condition 1: If start < 0 or end < 0, nil is returned.
+// Condition 2: If start >= end, nil is returned.
+// Condition 3: Return all elements that exist in the range provided,
+// if start or end is out of bounds, zero items will be placed.
+func (ss Float64s) SubSlice(start int, end int) (subSlice Float64s) {
+	if start < 0 || end < 0 {
+		return
+	}
+
+	if start >= end {
+		return
+	}
+
+	length := ss.Len()
+	if start < length {
+		if end <= length {
+			subSlice = ss[start:end]
+		} else {
+			zeroArray := make([]float64, end-length)
+			subSlice = ss[start:length].Append(zeroArray[:]...)
+		}
+	} else {
+		zeroArray := make([]float64, end-start)
+		subSlice = zeroArray[:]
+	}
+
+	return
+}
+
 // Sum is the sum of all of the elements.
 func (ss Float64s) Sum() (sum float64) {
 	for _, s := range ss {
diff --git a/pie/ints_pie.go b/pie/ints_pie.go
index 7710fd9..8c537ca 100755
--- a/pie/ints_pie.go
+++ b/pie/ints_pie.go
@@ -673,6 +673,37 @@ func (ss Ints) Strings() Strings {
 	return result
 }
 
+// SubSlice will return the subSlice from start to end(excluded)
+//
+// Condition 1: If start < 0 or end < 0, nil is returned.
+// Condition 2: If start >= end, nil is returned.
+// Condition 3: Return all elements that exist in the range provided,
+// if start or end is out of bounds, zero items will be placed.
+func (ss Ints) SubSlice(start int, end int) (subSlice Ints) {
+	if start < 0 || end < 0 {
+		return
+	}
+
+	if start >= end {
+		return
+	}
+
+	length := ss.Len()
+	if start < length {
+		if end <= length {
+			subSlice = ss[start:end]
+		} else {
+			zeroArray := make([]int, end-length)
+			subSlice = ss[start:length].Append(zeroArray[:]...)
+		}
+	} else {
+		zeroArray := make([]int, end-start)
+		subSlice = zeroArray[:]
+	}
+
+	return
+}
+
 // Sum is the sum of all of the elements.
 func (ss Ints) Sum() (sum int) {
 	for _, s := range ss {
diff --git a/pie/strings_pie.go b/pie/strings_pie.go
index e379a38..687c5cc 100755
--- a/pie/strings_pie.go
+++ b/pie/strings_pie.go
@@ -639,6 +639,37 @@ func (ss Strings) Strings() Strings {
 	return result
 }
 
+// SubSlice will return the subSlice from start to end(excluded)
+//
+// Condition 1: If start < 0 or end < 0, nil is returned.
+// Condition 2: If start >= end, nil is returned.
+// Condition 3: Return all elements that exist in the range provided,
+// if start or end is out of bounds, zero items will be placed.
+func (ss Strings) SubSlice(start int, end int) (subSlice Strings) {
+	if start < 0 || end < 0 {
+		return
+	}
+
+	if start >= end {
+		return
+	}
+
+	length := ss.Len()
+	if start < length {
+		if end <= length {
+			subSlice = ss[start:end]
+		} else {
+			zeroArray := make([]string, end-length)
+			subSlice = ss[start:length].Append(zeroArray[:]...)
+		}
+	} else {
+		zeroArray := make([]string, end-start)
+		subSlice = zeroArray[:]
+	}
+
+	return
+}
+
 // Top will return n elements from head of the slice
 // if the slice has less elements then n that'll return all elements
 // if n < 0 it'll return empty slice.
diff --git a/template.go b/template.go
index 9b944bb..0187144 100644
--- a/template.go
+++ b/template.go
@@ -874,6 +874,39 @@ func (ss SliceType) Strings() pie.Strings {
 
 	return result
 }
+`,
+	"SubSlice": `package functions
+
+// SubSlice will return the subSlice from start to end(excluded)
+//
+// Condition 1: If start < 0 or end < 0, nil is returned.
+// Condition 2: If start >= end, nil is returned.
+// Condition 3: Return all elements that exist in the range provided,
+// if start or end is out of bounds, zero items will be placed.
+func (ss SliceType) SubSlice(start int, end int) (subSlice SliceType) {
+	if start < 0 || end < 0 {
+		return
+	}
+
+	if start >= end {
+		return
+	}
+
+	length := ss.Len()
+	if start < length {
+		if end <= length {
+			subSlice = ss[start:end]
+		} else {
+			zeroArray := make([]ElementType, end-length)
+			subSlice = ss[start:length].Append(zeroArray[:]...)
+		}
+	} else {
+		zeroArray := make([]ElementType, end-start)
+		subSlice = zeroArray[:]
+	}
+
+	return
+}
 `,
 	"Sum": `package functions
 


Test patch:
diff --git a/pie/carpointers_test.go b/pie/carpointers_test.go
index b7c55a5..c44ae69 100644
--- a/pie/carpointers_test.go
+++ b/pie/carpointers_test.go
@@ -1000,6 +1000,109 @@ func TestCarPointers_DropTop(t *testing.T) {
 	}
 }
 
+var carPointersSubSliceTests = []struct {
+	ss       carPointers
+	start    int
+	end      int
+	subSlice carPointers
+}{
+	{
+		// start:1 ,end: 2
+		nil,
+		1,
+		1,
+		nil,
+	},
+	{
+		// start:1 ,end: 2
+		nil,
+		1,
+		2,
+		carPointers{nil},
+	},
+	{
+		carPointers{},
+		1,
+		1,
+		nil,
+	},
+	{
+		carPointers{},
+		1,
+		2,
+		carPointers{nil},
+	},
+	{
+		carPointers{carPointerA, carPointerB},
+		-1,
+		-1,
+		nil,
+	},
+	{
+		carPointers{carPointerA, carPointerB},
+		-1,
+		1,
+		nil,
+	},
+	{
+		carPointers{carPointerA, carPointerB},
+		1,
+		-1,
+		nil,
+	},
+	{
+		carPointers{carPointerA, carPointerB},
+		2,
+		0,
+		nil,
+	},
+	{
+		carPointers{carPointerA, carPointerB},
+		1,
+		1,
+		nil,
+	},
+	{
+		carPointers{carPointerA, carPointerB},
+		1,
+		2,
+		carPointers{carPointerB},
+	},
+	{
+		carPointers{carPointerA, carPointerB},
+		1,
+		3,
+		carPointers{carPointerB, nil},
+	},
+	{
+		carPointers{carPointerA, carPointerB},
+		2,
+		2,
+		nil,
+	},
+	{
+		carPointers{carPointerA, carPointerB},
+		2,
+		3,
+		carPointers{nil},
+	},
+	{
+		carPointers{carPointerA, carPointerB, nil},
+		2,
+		3,
+		carPointers{nil},
+	},
+}
+
+func TestCarPointers_SubSlice(t *testing.T) {
+	for _, test := range carPointersSubSliceTests {
+		t.Run("", func(t *testing.T) {
+			defer assertImmutableCarPointers(t, &test.ss)()
+			assert.Equal(t, test.subSlice, test.ss.SubSlice(test.start, test.end))
+		})
+	}
+}
+
 var carsPointerFindFirstUsingTests = []struct {
 	ss         carPointers
 	expression func(value *car) bool
diff --git a/pie/cars_test.go b/pie/cars_test.go
index 3fc2542..51deef3 100644
--- a/pie/cars_test.go
+++ b/pie/cars_test.go
@@ -974,6 +974,107 @@ func TestCars_DropTop(t *testing.T) {
 	}
 }
 
+var carsSubSliceTests = []struct {
+	ss       cars
+	start    int
+	end      int
+	subSlice cars
+}{
+	{
+		nil,
+		1,
+		1,
+		nil,
+	},
+	{
+		nil,
+		1,
+		2,
+		cars{car{}},
+	},
+	{
+		cars{},
+		1,
+		1,
+		nil,
+	},
+	{
+		cars{},
+		1,
+		2,
+		cars{car{}},
+	},
+	{
+		cars{car{"bar", "yellow"}, car{"Baz", "black"}},
+		-1,
+		-1,
+		nil,
+	},
+	{
+		cars{car{"bar", "yellow"}, car{"Baz", "black"}},
+		-1,
+		1,
+		nil,
+	},
+	{
+		cars{car{"bar", "yellow"}, car{"Baz", "black"}},
+		1,
+		-1,
+		nil,
+	},
+	{
+		cars{car{"bar", "yellow"}, car{"Baz", "black"}},
+		2,
+		0,
+		nil,
+	},
+	{
+		cars{car{"bar", "yellow"}, car{"Baz", "black"}},
+		1,
+		1,
+		nil,
+	},
+	{
+		cars{car{"bar", "yellow"}, car{"Baz", "black"}},
+		1,
+		2,
+		cars{car{"Baz", "black"}},
+	},
+	{
+		cars{car{"bar", "yellow"}, car{"Baz", "black"}},
+		1,
+		3,
+		cars{car{"Baz", "black"}, car{}},
+	},
+	{
+		cars{car{"bar", "yellow"}, car{"Baz", "black"}},
+		2,
+		2,
+		nil,
+	},
+	{
+		cars{car{"bar", "yellow"}, car{"Baz", "black"}},
+		2,
+		3,
+		cars{car{}},
+	},
+	{
+		cars{car{"bar", "yellow"}, car{"Baz", "black"}, car{}},
+		2,
+		3,
+		cars{car{}},
+	},
+}
+
+func TestCars_SubSlice(t *testing.T) {
+	for _, test := range carsSubSliceTests {
+		t.Run("", func(t *testing.T) {
+			defer assertImmutableCars(t, &test.ss)()
+			assert.Equal(t, test.subSlice, test.ss.SubSlice(test.start, test.end))
+		})
+	}
+}
+
 var carsFindFirstUsingTests = []struct {
 	ss         cars
 	expression func(value car) bool
diff --git a/pie/float64s_test.go b/pie/float64s_test.go
index e7b878d..e680eef 100644
--- a/pie/float64s_test.go
+++ b/pie/float64s_test.go
@@ -1162,6 +1162,108 @@ func TestFloat64s_DropTop(t *testing.T) {
 	}
 }
 
+var float64sSubSliceTests = []struct {
+	ss       Float64s
+	start    int
+	end      int
+	subSlice Float64s
+}{
+	{
+		nil,
+		1,
+		1,
+		nil,
+	},
+	{
+		nil,
+		1,
+		2,
+		Float64s{0},
+	},
+	{
+		Float64s{},
+		1,
+		1,
+		nil,
+	},
+	{
+		Float64s{},
+		1,
+		2,
+		Float64s{0},
+	},
+	{
+		Float64s{1.23, 2.34},
+		-1,
+		-1,
+		nil,
+	},
+	{
+		Float64s{1.23, 2.34},
+		-1,
+		1,
+		nil,
+	},
+	{
+		Float64s{1.23, 2.34},
+		1,
+		-1,
+		nil,
+	},
+	{
+		Float64s{1.23, 2.34},
+		2,
+		0,
+		nil,
+	},
+
+	{
+		Float64s{1.23, 2.34},
+		1,
+		1,
+		nil,
+	},
+	{
+		Float64s{1.23, 2.34},
+		1,
+		2,
+		Float64s{2.34},
+	},
+	{
+		Float64s{1.23, 2.34},
+		1,
+		3,
+		Float64s{2.34, 0},
+	},
+	{
+		Float64s{1.23, 2.34},
+		2,
+		2,
+		nil,
+	},
+	{
+		Float64s{1.23, 2.34},
+		2,
+		3,
+		Float64s{0},
+	},
+	{
+		Float64s{1.23, 2.34, 0},
+		2,
+		3,
+		Float64s{0},
+	},
+}
+
+func TestFloat64s_SubSlice(t *testing.T) {
+	for _, test := range float64sSubSliceTests {
+		t.Run("", func(t *testing.T) {
+			defer assertImmutableFloat64s(t, &test.ss)()
+			assert.Equal(t, test.subSlice, test.ss.SubSlice(test.start, test.end))
+		})
+	}
+}
+
 var floatFindFirstUsingTests = []struct {
 	ss         Float64s
 	expression func(value float64) bool
diff --git a/pie/ints_test.go b/pie/ints_test.go
index 1a6aae4..9294f79 100644
--- a/pie/ints_test.go
+++ b/pie/ints_test.go
@@ -1144,6 +1144,108 @@ func TestInts_DropTop(t *testing.T) {
 	}
 }
 
+var intsSubSliceTests = []struct {
+	ss       Ints
+	start    int
+	end      int
+	subSlice Ints
+}{
+	{
+		nil,
+		1,
+		1,
+		nil,
+	},
+	{
+		nil,
+		1,
+		2,
+		Ints{0},
+	},
+	{
+		Ints{},
+		1,
+		1,
+		nil,
+	},
+	{
+		Ints{},
+		1,
+		2,
+		Ints{0},
+	},
+	{
+		Ints{1, 2},
+		-1,
+		-1,
+		nil,
+	},
+	{
+		Ints{1, 2},
+		-1,
+		1,
+		nil,
+	},
+	{
+		Ints{1, 2},
+		1,
+		-1,
+		nil,
+	},
+	{
+		Ints{1, 2},
+		2,
+		0,
+		nil,
+	},
+
+	{
+		Ints{1, 2},
+		1,
+		1,
+		nil,
+	},
+	{
+		Ints{1, 2},
+		1,
+		2,
+		Ints{2},
+	},
+	{
+		Ints{1, 2},
+		1,
+		3,
+		Ints{2, 0},
+	},
+	{
+		Ints{1, 2},
+		2,
+		2,
+		nil,
+	},
+	{
+		Ints{1, 2},
+		2,
+		3,
+		Ints{0},
+	},
+	{
+		Ints{1, 2, 0},
+		2,
+		3,
+		Ints{0},
+	},
+}
+
+func TestInts_SubSlice(t *testing.T) {
+	for _, test := range intsSubSliceTests {
+		t.Run("", func(t *testing.T) {
+			defer assertImmutableInts(t, &test.ss)()
+			assert.Equal(t, test.subSlice, test.ss.SubSlice(test.start, test.end))
+		})
+	}
+}
+
 var intsFindFirstUsingTests = []struct {
 	ss         Ints
 	expression func(value int) bool
diff --git a/pie/strings_test.go b/pie/strings_test.go
index c616129..c59a5e1 100644
--- a/pie/strings_test.go
+++ b/pie/strings_test.go
@@ -1156,6 +1156,108 @@ func TestStrings_DropTop(t *testing.T) {
 	}
 }
 
+var stringsSubSliceTests = []struct {
+	ss       Strings
+	start    int
+	end      int
+	subSlice Strings
+}{
+	{
+		nil,
+		1,
+		1,
+		nil,
+	},
+	{
+		nil,
+		1,
+		2,
+		Strings{""},
+	},
+	{
+		Strings{},
+		1,
+		1,
+		nil,
+	},
+	{
+		Strings{},
+		1,
+		2,
+		Strings{""},
+	},
+	{
+		Strings{"foo", "bar"},
+		-1,
+		-1,
+		nil,
+	},
+	{
+		Strings{"foo", "bar"},
+		-1,
+		1,
+		nil,
+	},
+	{
+		Strings{"foo", "bar"},
+		1,
+		-1,
+		nil,
+	},
+	{
+		Strings{"foo", "bar"},
+		2,
+		0,
+		nil,
+	},
+
+	{
+		Strings{"foo", "bar"},
+		1,
+		1,
+		nil,
+	},
+	{
+		Strings{"foo", "bar"},
+		1,
+		2,
+		Strings{"bar"},
+	},
+	{
+		Strings{"foo", "bar"},
+		1,
+		3,
+		Strings{"bar", ""},
+	},
+	{
+		Strings{"foo", "bar"},
+		2,
+		2,
+		nil,
+	},
+	{
+		Strings{"foo", "bar"},
+		2,
+		3,
+		Strings{""},
+	},
+	{
+		Strings{"foo", "bar", ""},
+		2,
+		3,
+		Strings{""},
+	},
+}
+
+func TestStrings_SubSlice(t *testing.T) {
+	for _, test := range stringsSubSliceTests {
+		t.Run("", func(t *testing.T) {
+			defer assertImmutableStrings(t, &test.ss)()
+			assert.Equal(t, test.subSlice, test.ss.SubSlice(test.start, test.end))
+		})
+	}
+}
+
 var stringsFindFirstUsingTests = []struct {
 	ss         Strings
 	expression func(value string) bool