+func TestReplaceGrow(t *testing.T) {
+ // When Replace needs to allocate a new slice, we want the original slice
+ // to not be changed.
+ a, b, c, d, e, f := 1, 2, 3, 4, 5, 6
+ mem := []*int{&a, &b, &c, &d, &e, &f}
+ memcopy := Clone(mem)
+ s := mem[0:5] // there is 1 element beyond len(s), within cap(s)
+ copy := Clone(s)
+ original := s
+
+ // The new elements don't fit within cap(s), so Replace will allocate.
+ z := 99
+ s = Replace(s, 1, 3, &z, &z, &z, &z)
+
+ if want := []*int{&a, &z, &z, &z, &z, &d, &e}; !Equal(s, want) {
+ t.Errorf("Replace(%v, 1, 3, %v, %v, %v, %v) = %v, want %v", copy, &z, &z, &z, &z, s, want)
+ }
+
+ if !Equal(original, copy) {
+ t.Errorf("original slice has changed, got %v, want %v", original, copy)
+ }
+
+ if !Equal(mem, memcopy) {
+ // Changing the original tail s[len(s):cap(s)] is unwanted
+ t.Errorf("original backing memory has changed, got %v, want %v", mem, memcopy)
+ }
+}
+
+func TestReplaceClearTail(t *testing.T) {
+ a, b, c, d, e, f := 1, 2, 3, 4, 5, 6
+ mem := []*int{&a, &b, &c, &d, &e, &f}
+ s := mem[0:5] // there is 1 element beyond len(s), within cap(s)
+ copy := Clone(s)
+
+ y, z := 8, 9
+ s = Replace(s, 1, 4, &y, &z)
+
+ if want := []*int{&a, &y, &z, &e}; !Equal(s, want) {
+ t.Errorf("Replace(%v) = %v, want %v", copy, s, want)
+ }
+
+ if mem[4] != nil {
+ // Check that potential memory leak is avoided
+ t.Errorf("Replace: want nil discarded element, got %v", mem[4])
+ }
+ if mem[5] != &f {
+ t.Errorf("Replace: want unchanged elements beyond original len, got %v", mem[5])
+ }
+}
+