Repository: gavv/httpexpect
Pull request #224 (2023-01-05 16:22:58)

Add unit tests for chain cloning
Adding unit tests for constructors of all matcher structs (newValue, newArray, etc).

- chain field of constructed object point to different address
- chain of constructed object has same path

coveralls: 
[![Coverage Status](https://coveralls.io/builds/55678539/badge)](https://coveralls.io/builds/55678539)

Coverage: 95.43%. Remained the same when pulling **d90050d9a1c665d2f874000d2e1fd74bd041c92a on kairemor:mor/unit-test-chain-cloning** into **69c1ae446081de7b4d305213e459dcea58cad613 on gavv:master**.

gavv: Thanks for pr!

Instead of NotEqual with unsafe, I think we can just use NotSame?
gavv: Thanks for update. Could you please downgrade testify version to 1.5.0? It's the first version that has NotSame, according  to https://pkg.go.dev/github.com/stretchr/testify@v1.8.1/assert#NotSame

In this lib, I'm trying to keep dependency requirements as low as possible, because users may rely on older versions in some cases.

Patch:
diff --git a/go.mod b/go.mod
index 73c6bfe..023b91c 100644
--- a/go.mod
+++ b/go.mod
@@ -11,7 +11,7 @@ require (
 	github.com/imkira/go-interpol v1.1.0
 	github.com/mitchellh/go-wordwrap v1.0.1
 	github.com/sanity-io/litter v1.5.5
-	github.com/stretchr/testify v1.4.0
+	github.com/stretchr/testify v1.5.0
 	github.com/valyala/fasthttp v1.34.0
 	github.com/xeipuuv/gojsonschema v1.2.0
 	github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0
@@ -25,8 +25,10 @@ require (
 	github.com/mattn/go-colorable v0.1.2 // indirect
 	github.com/onsi/ginkgo v1.10.1 // indirect
 	github.com/onsi/gomega v1.7.0 // indirect
+	github.com/stretchr/objx v0.3.0 // indirect
 	github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
 	github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect
 	github.com/yudai/pp v2.0.1+incompatible // indirect
-	gopkg.in/yaml.v2 v2.2.8 // indirect
+	gopkg.in/yaml.v2 v2.4.0 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
diff --git a/go.sum b/go.sum
index f588cbc..e88a315 100644
--- a/go.sum
+++ b/go.sum
@@ -6,6 +6,8 @@ github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHG
 github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/fasthttp/websocket v1.4.3-rc.6 h1:omHqsl8j+KXpmzRjF8bmzOSYJ8GnS0E3efi1wYT+niY=
 github.com/fasthttp/websocket v1.4.3-rc.6/go.mod h1:43W9OM2T8FeXpCWMsBd9Cb7nE2CACNqNvCqQCoty/Lc=
 github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
@@ -53,10 +55,21 @@ github.com/savsgio/gotils v0.0.0-20210617111740-97865ed5a873/go.mod h1:dmPawKuiA
 github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
 github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As=
+github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
 github.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.5.0 h1:DMOzIV76tmoDNE9pX6RSN0aDtCYeCg5VueieJaAo1uw=
+github.com/stretchr/testify v1.5.0/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502/go.mod h1:p9lPsd+cx33L3H9nNoecRRxPssFKUwwI50I3pZ0yT+8=
 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
 github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
@@ -137,5 +150,10 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 moul.io/http2curl/v2 v2.3.0 h1:9r3JfDzWPcbIklMOs2TnIFzDYvfAZvjeavG6EzP7jYs=
 moul.io/http2curl/v2 v2.3.0/go.mod h1:RW4hyBjTWSYDOxapodpNEtX0g5Eb16sxklBqmd2RHcE=


Test patch:
diff --git a/array_test.go b/array_test.go
index 1b6c1a5..b7bdece 100644
--- a/array_test.go
+++ b/array_test.go
@@ -106,6 +106,13 @@ func TestArray_Constructors(t *testing.T) {
 		value.Equal(testValue)
 		value.chain.assertNotFailed(t)
 	})
+
+	t.Run("chain Constructor", func(t *testing.T) {
+		chain := newMockChain(t)
+		value := newArray(chain, testValue)
+		assert.NotSame(t, value.chain, chain)
+		assert.Equal(t, value.chain.context.Path, chain.context.Path)
+	})
 }
 
 func TestArray_Getters(t *testing.T) {
diff --git a/boolean_test.go b/boolean_test.go
index 19dd847..7b944e6 100644
--- a/boolean_test.go
+++ b/boolean_test.go
@@ -37,6 +37,13 @@ func TestBoolean_Constructors(t *testing.T) {
 		value.Equal(true)
 		value.chain.assertNotFailed(t)
 	})
+
+	t.Run("chain Constructor", func(t *testing.T) {
+		chain := newMockChain(t)
+		value := newBoolean(chain, true)
+		assert.NotSame(t, value.chain, &chain)
+		assert.Equal(t, value.chain.context.Path, chain.context.Path)
+	})
 }
 
 func TestBoolean_Getters(t *testing.T) {
diff --git a/cookie_test.go b/cookie_test.go
index 8ee2a58..8411226 100644
--- a/cookie_test.go
+++ b/cookie_test.go
@@ -89,6 +89,13 @@ func TestCookie_Constructors(t *testing.T) {
 		value.MaxAge().Equal(123 * time.Second)
 		value.chain.assertNotFailed(t)
 	})
+
+	t.Run("chain Constructor", func(t *testing.T) {
+		chain := newMockChain(t)
+		value := newCookie(chain, cookie)
+		assert.NotSame(t, value.chain, &chain)
+		assert.Equal(t, value.chain.context.Path, chain.context.Path)
+	})
 }
 
 func TestCookie_Getters(t *testing.T) {
diff --git a/datetime_test.go b/datetime_test.go
index e361797..5e7dde1 100644
--- a/datetime_test.go
+++ b/datetime_test.go
@@ -45,6 +45,13 @@ func TestDateTime_Constructors(t *testing.T) {
 		value.Equal(time)
 		value.chain.assertNotFailed(t)
 	})
+
+	t.Run("chain Constructor", func(t *testing.T) {
+		chain := newMockChain(t)
+		value := newDateTime(chain, time)
+		assert.NotSame(t, value.chain, chain)
+		assert.Equal(t, value.chain.context.Path, chain.context.Path)
+	})
 }
 
 func TestDateTime_Equal(t *testing.T) {
diff --git a/duration_test.go b/duration_test.go
index 6e18cbb..0054b8a 100644
--- a/duration_test.go
+++ b/duration_test.go
@@ -42,6 +42,14 @@ func TestDuration_Constructors(t *testing.T) {
 		value.Equal(tm)
 		value.chain.assertNotFailed(t)
 	})
+
+	t.Run("chain Constructor", func(t *testing.T) {
+		chain := newMockChain(t)
+		value := newDuration(chain, &tm)
+		assert.NotSame(t, value.chain, chain)
+		assert.Equal(t, value.chain.context.Path, chain.context.Path)
+	})
+
 }
 
 func TestDuration_Set(t *testing.T) {
diff --git a/environment_test.go b/environment_test.go
index d156d35..abd6b09 100644
--- a/environment_test.go
+++ b/environment_test.go
@@ -23,6 +23,13 @@ func TestEnvironment_Constructors(t *testing.T) {
 		})
 		env.chain.assertNotFailed(t)
 	})
+
+	t.Run("chain Constructor", func(t *testing.T) {
+		chain := newMockChain(t)
+		value := newEnvironment(chain)
+		assert.NotSame(t, value.chain, chain)
+		assert.Equal(t, value.chain.context.Path, chain.context.Path)
+	})
 }
 
 func TestEnvironment_Generic(t *testing.T) {
diff --git a/match_test.go b/match_test.go
index 81b076c..c14a3d4 100644
--- a/match_test.go
+++ b/match_test.go
@@ -41,6 +41,13 @@ func TestMatch_Constructors(t *testing.T) {
 		assert.Equal(t, matches, value.Raw())
 		value.chain.assertNotFailed(t)
 	})
+
+	t.Run("chain Constructor", func(t *testing.T) {
+		chain := newMockChain(t)
+		value := newMatch(chain, matches, names)
+		assert.NotSame(t, value.chain, chain)
+		assert.Equal(t, value.chain.context.Path, chain.context.Path)
+	})
 }
 
 func TestMatch_Getters(t *testing.T) {
diff --git a/number_test.go b/number_test.go
index f6151b7..9980d02 100644
--- a/number_test.go
+++ b/number_test.go
@@ -44,6 +44,13 @@ func TestNumber_Constructors(t *testing.T) {
 		value.Equal(10.3)
 		value.chain.assertNotFailed(t)
 	})
+
+	t.Run("chain Constructor", func(t *testing.T) {
+		chain := newMockChain(t)
+		value := newNumber(chain, 10.3)
+		assert.NotSame(t, value.chain, chain)
+		assert.Equal(t, value.chain.context.Path, chain.context.Path)
+	})
 }
 
 func TestNumber_Getters(t *testing.T) {
diff --git a/object_test.go b/object_test.go
index dc9b25b..d1d01c7 100644
--- a/object_test.go
+++ b/object_test.go
@@ -102,6 +102,12 @@ func TestObject_Constructors(t *testing.T) {
 		value.chain.assertNotFailed(t)
 	})
 
+	t.Run("chain Constructor", func(t *testing.T) {
+		chain := newMockChain(t)
+		value := newObject(chain, test)
+		assert.NotSame(t, value.chain, chain)
+		assert.Equal(t, value.chain.context.Path, chain.context.Path)
+	})
 }
 
 func TestObject_Getters(t *testing.T) {
diff --git a/response_test.go b/response_test.go
index 8d4114c..545ed28 100644
--- a/response_test.go
+++ b/response_test.go
@@ -110,6 +110,19 @@ func TestResponse_Constructors(t *testing.T) {
 		}, &http.Response{})
 		resp.chain.assertNotFailed(t)
 	})
+
+	t.Run("chain Constructor", func(t *testing.T) {
+		chain := newMockChain(t)
+		reporter := newMockReporter(t)
+		config := newMockConfig(reporter)
+		value := newResponse(responseOpts{
+			config:   config,
+			chain:    chain,
+			httpResp: &http.Response{},
+		})
+		assert.NotSame(t, value.chain, chain)
+		assert.Equal(t, value.chain.context.Path, chain.context.Path)
+	})
 }
 
 func TestResponse_RoundTripTime(t *testing.T) {
diff --git a/string_test.go b/string_test.go
index efd2c39..d6611ce 100644
--- a/string_test.go
+++ b/string_test.go
@@ -62,6 +62,13 @@ func TestString_Constructors(t *testing.T) {
 		value.Equal("Hello")
 		value.chain.assertNotFailed(t)
 	})
+
+	t.Run("chain Constructor", func(t *testing.T) {
+		chain := newMockChain(t)
+		value := newString(chain, "Hello")
+		assert.NotSame(t, value.chain, chain)
+		assert.Equal(t, value.chain.context.Path, chain.context.Path)
+	})
 }
 
 func TestString_Getters(t *testing.T) {
diff --git a/value_test.go b/value_test.go
index 861c00d..9e05d85 100644
--- a/value_test.go
+++ b/value_test.go
@@ -58,6 +58,13 @@ func TestValue_Constructors(t *testing.T) {
 		value.chain.assertNotFailed(t)
 		value.String().chain.assertNotFailed(t)
 	})
+
+	t.Run("chain Constructor", func(t *testing.T) {
+		chain := newMockChain(t)
+		value := newValue(chain, "Test")
+		assert.NotSame(t, value.chain, chain)
+		assert.Equal(t, value.chain.context.Path, chain.context.Path)
+	})
 }
 
 func TestValue_CastNull(t *testing.T) {
diff --git a/websocket_message_test.go b/websocket_message_test.go
index e7b564c..ae7fd76 100644
--- a/websocket_message_test.go
+++ b/websocket_message_test.go
@@ -4,6 +4,7 @@ import (
 	"testing"
 
 	"github.com/gorilla/websocket"
+	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
 
@@ -46,6 +47,13 @@ func TestWebsocketMessage_Constructors(t *testing.T) {
 		msg.CloseMessage()
 		msg.chain.assertNotFailed(t)
 	})
+
+	t.Run("chain Constructor", func(t *testing.T) {
+		chain := newMockChain(t)
+		value := newWebsocketMessage(chain, 0, nil)
+		assert.NotSame(t, value.chain, chain)
+		assert.Equal(t, value.chain.context.Path, chain.context.Path)
+	})
 }
 
 func TestWebsocketMessage_BadUsage(t *testing.T) {