Repository: gavv/httpexpect
Pull request #221 (2023-01-02 12:42:36)

Extend fruits server example
Extend example add new test for matching functions

- Array.Iter
- Array.Every
- Array.ContainsAny
- Object.ContainsKey
- Object.ContainsValue
- Object.ContainsSubset
- String.HasPrefix and String.HasSuffix
- String.IsASCII


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

Coverage: 95.43%. Remained the same when pulling **e0e5752a1aea4c9630795d7d470d0c9279b78c37 on kairemor:mor/f_extend_fruis_example** into **69c1ae446081de7b4d305213e459dcea58cad613 on gavv:master**.


Patch:
diff --git a/_examples/echo.go b/_examples/echo.go
index ef28521..24bd51c 100644
--- a/_examples/echo.go
+++ b/_examples/echo.go
@@ -4,8 +4,8 @@ import (
 	"net/http"
 
 	"github.com/dgrijalva/jwt-go"
-	"github.com/labstack/echo"
-	"github.com/labstack/echo/middleware"
+	"github.com/labstack/echo/v4"
+	"github.com/labstack/echo/v4/middleware"
 )
 
 // EchoHandler creates http.Handler using echo framework.
diff --git a/_examples/go.mod b/_examples/go.mod
index baa8a44..d6f27dd 100644
--- a/_examples/go.mod
+++ b/_examples/go.mod
@@ -9,7 +9,7 @@ require (
 	github.com/gin-gonic/gin v1.8.1
 	github.com/gorilla/websocket v1.5.0
 	github.com/kataras/iris/v12 v12.1.8
-	github.com/labstack/echo v3.3.10+incompatible
+	github.com/labstack/echo/v4 v4.10.0
 	github.com/valyala/fasthttp v1.44.0
 	google.golang.org/appengine v1.6.7
 )
@@ -31,6 +31,7 @@ require (
 	github.com/go-playground/universal-translator v0.18.0 // indirect
 	github.com/go-playground/validator/v10 v10.11.1 // indirect
 	github.com/goccy/go-json v0.9.11 // indirect
+	github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
 	github.com/golang/protobuf v1.5.2 // indirect
 	github.com/google/go-querystring v1.1.0 // indirect
 	github.com/gorilla/css v1.0.0 // indirect
@@ -60,7 +61,7 @@ require (
 	github.com/sanity-io/litter v1.5.5 // indirect
 	github.com/savsgio/gotils v0.0.0-20220530130905-52f3993e8d6d // indirect
 	github.com/schollz/closestmatch v2.1.0+incompatible // indirect
-	github.com/sergi/go-diff v1.2.0 // indirect
+	github.com/sergi/go-diff v1.3.1 // indirect
 	github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
 	github.com/stretchr/testify v1.8.1 // indirect
 	github.com/ugorji/go/codec v1.2.7 // indirect
@@ -76,6 +77,7 @@ require (
 	golang.org/x/net v0.5.0 // indirect
 	golang.org/x/sys v0.4.0 // indirect
 	golang.org/x/text v0.6.0 // indirect
+	golang.org/x/time v0.2.0 // indirect
 	google.golang.org/protobuf v1.28.1 // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
diff --git a/_examples/go.sum b/_examples/go.sum
index 64347df..2c1404b 100644
--- a/_examples/go.sum
+++ b/_examples/go.sum
@@ -70,6 +70,8 @@ github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/E
 github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
 github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk=
 github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
+github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
@@ -141,8 +143,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
-github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg=
-github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s=
+github.com/labstack/echo/v4 v4.10.0 h1:5CiyngihEO4HXsz3vVsJn7f8xAlWwRr3aY6Ih280ZKA=
+github.com/labstack/echo/v4 v4.10.0/go.mod h1:S/T/5fy/GigaXnHTkh0ZGe4LpkkQysvRjFMSUTkDRNQ=
 github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
 github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
 github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
@@ -209,8 +211,8 @@ github.com/savsgio/gotils v0.0.0-20220530130905-52f3993e8d6d/go.mod h1:Gy+0tqhJv
 github.com/schollz/closestmatch v2.1.0+incompatible h1:Uel2GXEpJqOWBrlyI+oY9LTiyyjYS17cCYRqP13/SHk=
 github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g=
 github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
-github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
-github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
+github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
+github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
 github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
 github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
 github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
@@ -280,6 +282,7 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
 golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.2.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
 golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A=
 golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@@ -304,6 +307,7 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
 golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
 golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
 golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
+golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
 golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=
 golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -335,11 +339,13 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
 golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
+golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
 golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@@ -347,8 +353,11 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=
 golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/time v0.2.0 h1:52I/1L54xyEQAYdtcSuxtiT84KGYTBGXwayxmIpNJhE=
+golang.org/x/time v0.2.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
@@ -383,7 +392,6 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkep
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
 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.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 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=
diff --git a/chain.go b/chain.go
index f705e82..a39ec88 100644
--- a/chain.go
+++ b/chain.go
@@ -37,11 +37,14 @@ import (
 //     subsequent failures will be ignored not only in parent chain, but also
 //     in all newly created child chains
 type chain struct {
+	noCopy noCopy
+
 	context  AssertionContext
 	handler  AssertionHandler
 	severity AssertionSeverity
-	failCb   func()
-	failBit  bool
+
+	failCb  func()
+	failBit bool
 }
 
 // Construct chain using config.
@@ -140,12 +143,10 @@ func (c *chain) setResponse(resp *Response) {
 // Create a clone of the chain.
 // Modifications of the clone wont affect the original.
 func (c *chain) clone() *chain {
-	ret := *c
-
-	ret.context.Path = nil
-	ret.context.Path = append(ret.context.Path, c.context.Path...)
+	copy := *c //nolint
+	copy.context.Path = append(([]string)(nil), c.context.Path...)
 
-	return &ret
+	return &copy
 }
 
 // Append string to chain path.
diff --git a/datetime.go b/datetime.go
index 51007a4..bddb543 100644
--- a/datetime.go
+++ b/datetime.go
@@ -57,15 +57,15 @@ func (dt *DateTime) Raw() time.Time {
 	return dt.value
 }
 
-// Zone returns a new String instance with datetime zone.
+// GetZone returns a new String instance with datetime zone.
 //
 // Example:
 //
 //	tm, _ := time.Parse(time.UnixDate, "Fri Dec 30 15:04:05 IST 2022")
 //	dt := NewDateTime(t, tm)
-//	dt.Zone().Equal("IST")
-func (dt *DateTime) Zone() *String {
-	dt.chain.enter("Zone()")
+//	dt.GetZone().Equal("IST")
+func (dt *DateTime) GetZone() *String {
+	dt.chain.enter("GetZone()")
 	defer dt.chain.leave()
 
 	if dt.chain.failed() {
@@ -76,16 +76,16 @@ func (dt *DateTime) Zone() *String {
 	return newString(dt.chain, zone)
 }
 
-// Year returns the year in which datetime occurs,
+// GetYear returns the year in which datetime occurs,
 // in the range [0, 9999]
 //
 // Example:
 //
 //	tm, _ := time.Parse(time.UnixDate, "Fri Dec 30 15:04:05 IST 2022")
 //	dt := NewDateTime(t, tm)
-//	dt.Year().Equal(2022)
-func (dt *DateTime) Year() *Number {
-	dt.chain.enter("Year()")
+//	dt.GetYear().Equal(2022)
+func (dt *DateTime) GetYear() *Number {
+	dt.chain.enter("GetYear()")
 	defer dt.chain.leave()
 
 	if dt.chain.failed() {
@@ -95,16 +95,16 @@ func (dt *DateTime) Year() *Number {
 	return newNumber(dt.chain, float64(dt.value.Year()))
 }
 
-// Month returns the month of the year specified by datetime,
+// GetMonth returns the month of the year specified by datetime,
 // in the range [1,12].
 //
 // Example:
 //
 //	tm, _ := time.Parse(time.UnixDate, "Fri Dec 30 15:04:05 IST 2022")
 //	dt := NewDateTime(t, tm)
-//	dt.Month().Equal(12)
-func (dt *DateTime) Month() *Number {
-	dt.chain.enter("Month()")
+//	dt.GetMonth().Equal(12)
+func (dt *DateTime) GetMonth() *Number {
+	dt.chain.enter("GetMonth()")
 	defer dt.chain.leave()
 
 	if dt.chain.failed() {
@@ -114,16 +114,16 @@ func (dt *DateTime) Month() *Number {
 	return newNumber(dt.chain, float64(dt.value.Month()))
 }
 
-// Day returns the day of the month specified datetime,
+// GetDay returns the day of the month specified datetime,
 // in the range [1,31].
 //
 // Example:
 //
 //	tm, _ := time.Parse(time.UnixDate, "Fri Dec 30 15:04:05 IST 2022")
 //	dt := NewDateTime(t, tm)
-//	dt.Day().Equal(30)
-func (dt *DateTime) Day() *Number {
-	dt.chain.enter("Day()")
+//	dt.GetDay().Equal(30)
+func (dt *DateTime) GetDay() *Number {
+	dt.chain.enter("GetDay()")
 	defer dt.chain.leave()
 
 	if dt.chain.failed() {
@@ -140,9 +140,9 @@ func (dt *DateTime) Day() *Number {
 //
 //	tm, _ := time.Parse(time.UnixDate, "Fri Dec 30 15:04:05 IST 2022")
 //	dt := NewDateTime(t, tm)
-//	dt.WeekDay().Equal(time.Friday)
-func (dt *DateTime) WeekDay() *Number {
-	dt.chain.enter("WeekDay()")
+//	dt.GetWeekDay().Equal(time.Friday)
+func (dt *DateTime) GetWeekDay() *Number {
+	dt.chain.enter("GetWeekDay()")
 	defer dt.chain.leave()
 
 	if dt.chain.failed() {
@@ -152,7 +152,7 @@ func (dt *DateTime) WeekDay() *Number {
 	return newNumber(dt.chain, float64(dt.value.Weekday()))
 }
 
-// YearDay returns the day of the year specified by datetime,
+// GetYearDay returns the day of the year specified by datetime,
 // in the range [1,365] for non-leap years,
 // and [1,366] in leap years.
 //
@@ -160,9 +160,9 @@ func (dt *DateTime) WeekDay() *Number {
 //
 //	tm, _ := time.Parse(time.UnixDate, "Fri Dec 30 15:04:05 IST 2022")
 //	dt := NewDateTime(t, tm)
-//	dt.YearDay().Equal(364)
-func (dt *DateTime) YearDay() *Number {
-	dt.chain.enter("YearDay()")
+//	dt.GetYearDay().Equal(364)
+func (dt *DateTime) GetYearDay() *Number {
+	dt.chain.enter("GetYearDay()")
 	defer dt.chain.leave()
 
 	if dt.chain.failed() {
@@ -172,16 +172,16 @@ func (dt *DateTime) YearDay() *Number {
 	return newNumber(dt.chain, float64(dt.value.YearDay()))
 }
 
-// Hour returns the hour within the day specified by datetime,
+// GetHour returns the hour within the day specified by datetime,
 // in the range [0, 23].
 //
 // Example:
 //
 //	tm, _ := time.Parse(time.UnixDate, "Fri Dec 30 15:04:05 IST 2022")
 //	dt := NewDateTime(t, tm)
-//	dt.Hour().Equal(15)
-func (dt *DateTime) Hour() *Number {
-	dt.chain.enter("Hour()")
+//	dt.GetHour().Equal(15)
+func (dt *DateTime) GetHour() *Number {
+	dt.chain.enter("GetHour()")
 	defer dt.chain.leave()
 
 	if dt.chain.failed() {
@@ -191,16 +191,16 @@ func (dt *DateTime) Hour() *Number {
 	return newNumber(dt.chain, float64(dt.value.Hour()))
 }
 
-// Minute returns the minute offset within the hour specified by datetime,
+// GetMinute returns the minute offset within the hour specified by datetime,
 // in the range [0, 59].
 //
 // Example:
 //
 //	tm, _ := time.Parse(time.UnixDate, "Fri Dec 30 15:04:05 IST 2022")
 //	dt := NewDateTime(t, tm)
-//	dt.Minute().Equal(4)
-func (dt *DateTime) Minute() *Number {
-	dt.chain.enter("Minute()")
+//	dt.GetMinute().Equal(4)
+func (dt *DateTime) GetMinute() *Number {
+	dt.chain.enter("GetMinute()")
 	defer dt.chain.leave()
 
 	if dt.chain.failed() {
@@ -210,16 +210,16 @@ func (dt *DateTime) Minute() *Number {
 	return newNumber(dt.chain, float64(dt.value.Minute()))
 }
 
-// Second returns the second offset within the minute specified by datetime,
+// GetSecond returns the second offset within the minute specified by datetime,
 // in the range [0, 59].
 //
 // Example:
 //
 //	tm, _ := time.Parse(time.UnixDate, "Fri Dec 30 15:04:05 IST 2022")
 //	dt := NewDateTime(t, tm)
-//	dt.Second().Equal(5)
-func (dt *DateTime) Second() *Number {
-	dt.chain.enter("Second()")
+//	dt.GetSecond().Equal(5)
+func (dt *DateTime) GetSecond() *Number {
+	dt.chain.enter("GetSecond()")
 	defer dt.chain.leave()
 
 	if dt.chain.failed() {
@@ -229,16 +229,16 @@ func (dt *DateTime) Second() *Number {
 	return newNumber(dt.chain, float64(dt.value.Second()))
 }
 
-// Nanosecond returns the nanosecond offset within the second specified by datetime,
+// GetNanosecond returns the nanosecond offset within the second specified by datetime,
 // in the range [0, 999999999].
 //
 // Example:
 //
 //	tm, _ := time.Parse(time.UnixDate, "Fri Dec 30 15:04:05 IST 2022")
 //	dt := NewDateTime(t, tm)
-//	dt.Nanosecond().Equal(0)
-func (dt *DateTime) Nanosecond() *Number {
-	dt.chain.enter("Nanosecond()")
+//	dt.GetNanosecond().Equal(0)
+func (dt *DateTime) GetNanosecond() *Number {
+	dt.chain.enter("GetNanosecond()")
 	defer dt.chain.leave()
 
 	if dt.chain.failed() {
@@ -304,27 +304,29 @@ func (dt *DateTime) NotEqual(value time.Time) *DateTime {
 	return dt
 }
 
-// Gt succeeds if DateTime is greater than given value.
+// InRange succeeds if DateTime is within given range [min; max].
 //
 // Example:
 //
 //	dt := NewDateTime(t, time.Unix(0, 2))
-//	dt.Gt(time.Unix(0, 1))
-func (dt *DateTime) Gt(value time.Time) *DateTime {
-	dt.chain.enter("Gt()")
+//	dt.InRange(time.Unix(0, 1), time.Unix(0, 3))
+//	dt.InRange(time.Unix(0, 2), time.Unix(0, 2))
+func (dt *DateTime) InRange(min, max time.Time) *DateTime {
+	dt.chain.enter("InRange()")
 	defer dt.chain.leave()
 
 	if dt.chain.failed() {
 		return dt
 	}
 
-	if !dt.value.After(value) {
+	if !((dt.value.After(min) || dt.value.Equal(min)) &&
+		(dt.value.Before(max) || dt.value.Equal(max))) {
 		dt.chain.fail(AssertionFailure{
-			Type:     AssertGt,
+			Type:     AssertInRange,
 			Actual:   &AssertionValue{dt.value},
-			Expected: &AssertionValue{value},
+			Expected: &AssertionValue{AssertionRange{min, max}},
 			Errors: []error{
-				errors.New("expected: time point is after given time"),
+				errors.New("expected: time point is within given range"),
 			},
 		})
 	}
@@ -332,27 +334,29 @@ func (dt *DateTime) Gt(value time.Time) *DateTime {
 	return dt
 }
 
-// Ge succeeds if DateTime is greater than or equal to given value.
+// NotInRange succeeds if DateTime is not within given range [min; max].
 //
 // Example:
 //
-//	dt := NewDateTime(t, time.Unix(0, 2))
-//	dt.Ge(time.Unix(0, 1))
-func (dt *DateTime) Ge(value time.Time) *DateTime {
-	dt.chain.enter("Ge()")
+//	dt := NewDateTime(t, time.Unix(0, 10))
+//	dt.NotInRange(time.Unix(0, 1), time.Unix(0, 9))
+//	dt.NotInRange(time.Unix(0, 11), time.Unix(0, 20))
+func (dt *DateTime) NotInRange(min, max time.Time) *DateTime {
+	dt.chain.enter("NotInRange()")
 	defer dt.chain.leave()
 
 	if dt.chain.failed() {
 		return dt
 	}
 
-	if !(dt.value.After(value) || dt.value.Equal(value)) {
+	if (dt.value.After(min) || dt.value.Equal(min)) &&
+		(dt.value.Before(max) || dt.value.Equal(max)) {
 		dt.chain.fail(AssertionFailure{
-			Type:     AssertGe,
+			Type:     AssertNotInRange,
 			Actual:   &AssertionValue{dt.value},
-			Expected: &AssertionValue{value},
+			Expected: &AssertionValue{AssertionRange{min, max}},
 			Errors: []error{
-				errors.New("expected: time point is after or equal to given time"),
+				errors.New("expected: time point is not within given range"),
 			},
 		})
 	}
@@ -360,27 +364,27 @@ func (dt *DateTime) Ge(value time.Time) *DateTime {
 	return dt
 }
 
-// Lt succeeds if DateTime is lesser than given value.
+// Gt succeeds if DateTime is greater than given value.
 //
 // Example:
 //
-//	dt := NewDateTime(t, time.Unix(0, 1))
-//	dt.Lt(time.Unix(0, 2))
-func (dt *DateTime) Lt(value time.Time) *DateTime {
-	dt.chain.enter("Lt()")
+//	dt := NewDateTime(t, time.Unix(0, 2))
+//	dt.Gt(time.Unix(0, 1))
+func (dt *DateTime) Gt(value time.Time) *DateTime {
+	dt.chain.enter("Gt()")
 	defer dt.chain.leave()
 
 	if dt.chain.failed() {
 		return dt
 	}
 
-	if !dt.value.Before(value) {
+	if !dt.value.After(value) {
 		dt.chain.fail(AssertionFailure{
-			Type:     AssertLt,
+			Type:     AssertGt,
 			Actual:   &AssertionValue{dt.value},
 			Expected: &AssertionValue{value},
 			Errors: []error{
-				errors.New("expected: time point is before given time"),
+				errors.New("expected: time point is after given time"),
 			},
 		})
 	}
@@ -388,27 +392,27 @@ func (dt *DateTime) Lt(value time.Time) *DateTime {
 	return dt
 }
 
-// Le succeeds if DateTime is lesser than or equal to given value.
+// Ge succeeds if DateTime is greater than or equal to given value.
 //
 // Example:
 //
-//	dt := NewDateTime(t, time.Unix(0, 1))
-//	dt.Le(time.Unix(0, 2))
-func (dt *DateTime) Le(value time.Time) *DateTime {
-	dt.chain.enter("Le()")
+//	dt := NewDateTime(t, time.Unix(0, 2))
+//	dt.Ge(time.Unix(0, 1))
+func (dt *DateTime) Ge(value time.Time) *DateTime {
+	dt.chain.enter("Ge()")
 	defer dt.chain.leave()
 
 	if dt.chain.failed() {
 		return dt
 	}
 
-	if !(dt.value.Before(value) || dt.value.Equal(value)) {
+	if !(dt.value.After(value) || dt.value.Equal(value)) {
 		dt.chain.fail(AssertionFailure{
-			Type:     AssertLe,
+			Type:     AssertGe,
 			Actual:   &AssertionValue{dt.value},
 			Expected: &AssertionValue{value},
 			Errors: []error{
-				errors.New("expected: time point is before or equal to given time"),
+				errors.New("expected: time point is after or equal to given time"),
 			},
 		})
 	}
@@ -416,29 +420,27 @@ func (dt *DateTime) Le(value time.Time) *DateTime {
 	return dt
 }
 
-// InRange succeeds if DateTime is within given range [min; max].
+// Lt succeeds if DateTime is lesser than given value.
 //
 // Example:
 //
-//	dt := NewDateTime(t, time.Unix(0, 2))
-//	dt.InRange(time.Unix(0, 1), time.Unix(0, 3))
-//	dt.InRange(time.Unix(0, 2), time.Unix(0, 2))
-func (dt *DateTime) InRange(min, max time.Time) *DateTime {
-	dt.chain.enter("InRange()")
+//	dt := NewDateTime(t, time.Unix(0, 1))
+//	dt.Lt(time.Unix(0, 2))
+func (dt *DateTime) Lt(value time.Time) *DateTime {
+	dt.chain.enter("Lt()")
 	defer dt.chain.leave()
 
 	if dt.chain.failed() {
 		return dt
 	}
 
-	if !((dt.value.After(min) || dt.value.Equal(min)) &&
-		(dt.value.Before(max) || dt.value.Equal(max))) {
+	if !dt.value.Before(value) {
 		dt.chain.fail(AssertionFailure{
-			Type:     AssertInRange,
+			Type:     AssertLt,
 			Actual:   &AssertionValue{dt.value},
-			Expected: &AssertionValue{AssertionRange{min, max}},
+			Expected: &AssertionValue{value},
 			Errors: []error{
-				errors.New("expected: time point is within given range"),
+				errors.New("expected: time point is before given time"),
 			},
 		})
 	}
@@ -446,29 +448,27 @@ func (dt *DateTime) InRange(min, max time.Time) *DateTime {
 	return dt
 }
 
-// NotInRange succeeds if DateTime is not within given range [min; max].
+// Le succeeds if DateTime is lesser than or equal to given value.
 //
 // Example:
 //
-//	dt := NewDateTime(t, time.Unix(0, 10))
-//	dt.NotInRange(time.Unix(0, 1), time.Unix(0, 9))
-//	dt.NotInRange(time.Unix(0, 11), time.Unix(0, 20))
-func (dt *DateTime) NotInRange(min, max time.Time) *DateTime {
-	dt.chain.enter("NotInRange()")
+//	dt := NewDateTime(t, time.Unix(0, 1))
+//	dt.Le(time.Unix(0, 2))
+func (dt *DateTime) Le(value time.Time) *DateTime {
+	dt.chain.enter("Le()")
 	defer dt.chain.leave()
 
 	if dt.chain.failed() {
 		return dt
 	}
 
-	if (dt.value.After(min) || dt.value.Equal(min)) &&
-		(dt.value.Before(max) || dt.value.Equal(max)) {
+	if !(dt.value.Before(value) || dt.value.Equal(value)) {
 		dt.chain.fail(AssertionFailure{
-			Type:     AssertNotInRange,
+			Type:     AssertLe,
 			Actual:   &AssertionValue{dt.value},
-			Expected: &AssertionValue{AssertionRange{min, max}},
+			Expected: &AssertionValue{value},
 			Errors: []error{
-				errors.New("expected: time point is not within given range"),
+				errors.New("expected: time point is before or equal to given time"),
 			},
 		})
 	}
diff --git a/expect.go b/expect.go
index 7d04ff6..d058e5c 100644
--- a/expect.go
+++ b/expect.go
@@ -432,14 +432,12 @@ func (e *Expect) Env() *Environment {
 }
 
 func (e *Expect) clone() *Expect {
-	var copy Expect
-
-	copy.config = e.config
-	copy.chain = e.chain.clone()
-	copy.builders = append(copy.builders, e.builders...)
-	copy.matchers = append(copy.matchers, e.matchers...)
-
-	return &copy
+	return &Expect{
+		config:   e.config,
+		chain:    e.chain.clone(),
+		builders: append(([]func(*Request))(nil), e.builders...),
+		matchers: append(([]func(*Response))(nil), e.matchers...),
+	}
 }
 
 // Builder returns a copy of Expect instance with given builder attached to it.
diff --git a/number.go b/number.go
index 1f8a2f7..6024d3b 100644
--- a/number.go
+++ b/number.go
@@ -141,14 +141,14 @@ func (n *Number) NotEqual(value interface{}) *Number {
 	return n
 }
 
-// EqualDelta succeeds if two numerals are within delta of each other.
+// InDelta succeeds if two numerals are within delta of each other.
 //
 // Example:
 //
 //	number := NewNumber(t, 123.0)
-//	number.EqualDelta(123.2, 0.3)
-func (n *Number) EqualDelta(value, delta float64) *Number {
-	n.chain.enter("EqualDelta()")
+//	number.InDelta(123.2, 0.3)
+func (n *Number) InDelta(value, delta float64) *Number {
+	n.chain.enter("InDelta()")
 	defer n.chain.leave()
 
 	if n.chain.failed() {
@@ -186,14 +186,14 @@ func (n *Number) EqualDelta(value, delta float64) *Number {
 	return n
 }
 
-// NotEqualDelta succeeds if two numerals are not within delta of each other.
+// NotInDelta succeeds if two numerals are not within delta of each other.
 //
 // Example:
 //
 //	number := NewNumber(t, 123.0)
-//	number.NotEqualDelta(123.2, 0.1)
-func (n *Number) NotEqualDelta(value, delta float64) *Number {
-	n.chain.enter("NotEqualDelta()")
+//	number.NotInDelta(123.2, 0.1)
+func (n *Number) NotInDelta(value, delta float64) *Number {
+	n.chain.enter("NotInDelta()")
 	defer n.chain.leave()
 
 	if n.chain.failed() {
@@ -231,36 +231,52 @@ func (n *Number) NotEqualDelta(value, delta float64) *Number {
 	return n
 }
 
-// Gt succeeds if number is greater than given value.
+// Deprecated: use InDelta instead.
+func (n *Number) EqualDelta(value, delta float64) *Number {
+	return n.InDelta(value, delta)
+}
+
+// Deprecated: use NotInDelta instead.
+func (n *Number) NotEqualDelta(value, delta float64) *Number {
+	return n.NotInDelta(value, delta)
+}
+
+// InRange succeeds if number is within given range [min; max].
 //
-// value should have numeric type convertible to float64. Before comparison,
-// it is converted to float64.
+// min and max should have numeric type convertible to float64. Before comparison,
+// they are converted to float64.
 //
 // Example:
 //
 //	number := NewNumber(t, 123)
-//	number.Gt(float64(122))
-//	number.Gt(int32(122))
-func (n *Number) Gt(value interface{}) *Number {
-	n.chain.enter("Gt()")
+//	number.InRange(float32(100), int32(200))  // success
+//	number.InRange(100, 200)                  // success
+//	number.InRange(123, 123)                  // success
+func (n *Number) InRange(min, max interface{}) *Number {
+	n.chain.enter("InRange()")
 	defer n.chain.leave()
 
 	if n.chain.failed() {
 		return n
 	}
 
-	num, ok := canonNumber(n.chain, value)
+	a, ok := canonNumber(n.chain, min)
 	if !ok {
 		return n
 	}
 
-	if !(n.value > num) {
+	b, ok := canonNumber(n.chain, max)
+	if !ok {
+		return n
+	}
+
+	if !(n.value >= a && n.value <= b) {
 		n.chain.fail(AssertionFailure{
-			Type:     AssertGt,
+			Type:     AssertInRange,
 			Actual:   &AssertionValue{n.value},
-			Expected: &AssertionValue{num},
+			Expected: &AssertionValue{AssertionRange{a, b}},
 			Errors: []error{
-				errors.New("expected: number is larger than given value"),
+				errors.New("expected: number is within given range"),
 			},
 		})
 	}
@@ -268,36 +284,41 @@ func (n *Number) Gt(value interface{}) *Number {
 	return n
 }
 
-// Ge succeeds if number is greater than or equal to given value.
+// NotInRange succeeds if number is not within given range [min; max].
 //
-// value should have numeric type convertible to float64. Before comparison,
-// it is converted to float64.
+// min and max should have numeric type convertible to float64. Before comparison,
+// they are converted to float64.
 //
 // Example:
 //
-//	number := NewNumber(t, 123)
-//	number.Ge(float64(122))
-//	number.Ge(int32(122))
-func (n *Number) Ge(value interface{}) *Number {
-	n.chain.enter("Ge()")
+//	number := NewNumber(t, 100)
+//	number.NotInRange(0, 99)
+//	number.NotInRange(101, 200)
+func (n *Number) NotInRange(min, max interface{}) *Number {
+	n.chain.enter("NotInRange()")
 	defer n.chain.leave()
 
 	if n.chain.failed() {
 		return n
 	}
 
-	num, ok := canonNumber(n.chain, value)
+	a, ok := canonNumber(n.chain, min)
 	if !ok {
 		return n
 	}
 
-	if !(n.value >= num) {
+	b, ok := canonNumber(n.chain, max)
+	if !ok {
+		return n
+	}
+
+	if n.value >= a && n.value <= b {
 		n.chain.fail(AssertionFailure{
-			Type:     AssertGe,
+			Type:     AssertNotInRange,
 			Actual:   &AssertionValue{n.value},
-			Expected: &AssertionValue{num},
+			Expected: &AssertionValue{AssertionRange{a, b}},
 			Errors: []error{
-				errors.New("expected: number is larger than or equal to given value"),
+				errors.New("expected: number is not within given range"),
 			},
 		})
 	}
@@ -305,7 +326,7 @@ func (n *Number) Ge(value interface{}) *Number {
 	return n
 }
 
-// Lt succeeds if number is lesser than given value.
+// Gt succeeds if number is greater than given value.
 //
 // value should have numeric type convertible to float64. Before comparison,
 // it is converted to float64.
@@ -313,10 +334,10 @@ func (n *Number) Ge(value interface{}) *Number {
 // Example:
 //
 //	number := NewNumber(t, 123)
-//	number.Lt(float64(124))
-//	number.Lt(int32(124))
-func (n *Number) Lt(value interface{}) *Number {
-	n.chain.enter("Lt()")
+//	number.Gt(float64(122))
+//	number.Gt(int32(122))
+func (n *Number) Gt(value interface{}) *Number {
+	n.chain.enter("Gt()")
 	defer n.chain.leave()
 
 	if n.chain.failed() {
@@ -328,13 +349,13 @@ func (n *Number) Lt(value interface{}) *Number {
 		return n
 	}
 
-	if !(n.value < num) {
+	if !(n.value > num) {
 		n.chain.fail(AssertionFailure{
-			Type:     AssertLt,
+			Type:     AssertGt,
 			Actual:   &AssertionValue{n.value},
 			Expected: &AssertionValue{num},
 			Errors: []error{
-				errors.New("expected: number is less than given value"),
+				errors.New("expected: number is larger than given value"),
 			},
 		})
 	}
@@ -342,7 +363,7 @@ func (n *Number) Lt(value interface{}) *Number {
 	return n
 }
 
-// Le succeeds if number is lesser than or equal to given value.
+// Ge succeeds if number is greater than or equal to given value.
 //
 // value should have numeric type convertible to float64. Before comparison,
 // it is converted to float64.
@@ -350,10 +371,10 @@ func (n *Number) Lt(value interface{}) *Number {
 // Example:
 //
 //	number := NewNumber(t, 123)
-//	number.Le(float64(124))
-//	number.Le(int32(124))
-func (n *Number) Le(value interface{}) *Number {
-	n.chain.enter("Le()")
+//	number.Ge(float64(122))
+//	number.Ge(int32(122))
+func (n *Number) Ge(value interface{}) *Number {
+	n.chain.enter("Ge()")
 	defer n.chain.leave()
 
 	if n.chain.failed() {
@@ -365,13 +386,13 @@ func (n *Number) Le(value interface{}) *Number {
 		return n
 	}
 
-	if !(n.value <= num) {
+	if !(n.value >= num) {
 		n.chain.fail(AssertionFailure{
-			Type:     AssertLe,
+			Type:     AssertGe,
 			Actual:   &AssertionValue{n.value},
 			Expected: &AssertionValue{num},
 			Errors: []error{
-				errors.New("expected: number is less than or equal to given value"),
+				errors.New("expected: number is larger than or equal to given value"),
 			},
 		})
 	}
@@ -379,42 +400,36 @@ func (n *Number) Le(value interface{}) *Number {
 	return n
 }
 
-// InRange succeeds if number is within given range [min; max].
+// Lt succeeds if number is lesser than given value.
 //
-// min and max should have numeric type convertible to float64. Before comparison,
-// they are converted to float64.
+// value should have numeric type convertible to float64. Before comparison,
+// it is converted to float64.
 //
 // Example:
 //
 //	number := NewNumber(t, 123)
-//	number.InRange(float32(100), int32(200))  // success
-//	number.InRange(100, 200)                  // success
-//	number.InRange(123, 123)                  // success
-func (n *Number) InRange(min, max interface{}) *Number {
-	n.chain.enter("InRange()")
+//	number.Lt(float64(124))
+//	number.Lt(int32(124))
+func (n *Number) Lt(value interface{}) *Number {
+	n.chain.enter("Lt()")
 	defer n.chain.leave()
 
 	if n.chain.failed() {
 		return n
 	}
 
-	a, ok := canonNumber(n.chain, min)
-	if !ok {
-		return n
-	}
-
-	b, ok := canonNumber(n.chain, max)
+	num, ok := canonNumber(n.chain, value)
 	if !ok {
 		return n
 	}
 
-	if !(n.value >= a && n.value <= b) {
+	if !(n.value < num) {
 		n.chain.fail(AssertionFailure{
-			Type:     AssertInRange,
+			Type:     AssertLt,
 			Actual:   &AssertionValue{n.value},
-			Expected: &AssertionValue{AssertionRange{a, b}},
+			Expected: &AssertionValue{num},
 			Errors: []error{
-				errors.New("expected: number is within given range"),
+				errors.New("expected: number is less than given value"),
 			},
 		})
 	}
@@ -422,41 +437,36 @@ func (n *Number) InRange(min, max interface{}) *Number {
 	return n
 }
 
-// NotInRange succeeds if number is not within given range [min; max].
+// Le succeeds if number is lesser than or equal to given value.
 //
-// min and max should have numeric type convertible to float64. Before comparison,
-// they are converted to float64.
+// value should have numeric type convertible to float64. Before comparison,
+// it is converted to float64.
 //
 // Example:
 //
-//	number := NewNumber(t, 100)
-//	number.NotInRange(0, 99)
-//	number.NotInRange(101, 200)
-func (n *Number) NotInRange(min, max interface{}) *Number {
-	n.chain.enter("NotInRange()")
+//	number := NewNumber(t, 123)
+//	number.Le(float64(124))
+//	number.Le(int32(124))
+func (n *Number) Le(value interface{}) *Number {
+	n.chain.enter("Le()")
 	defer n.chain.leave()
 
 	if n.chain.failed() {
 		return n
 	}
 
-	a, ok := canonNumber(n.chain, min)
-	if !ok {
-		return n
-	}
-
-	b, ok := canonNumber(n.chain, max)
+	num, ok := canonNumber(n.chain, value)
 	if !ok {
 		return n
 	}
 
-	if n.value >= a && n.value <= b {
+	if !(n.value <= num) {
 		n.chain.fail(AssertionFailure{
-			Type:     AssertNotInRange,
+			Type:     AssertLe,
 			Actual:   &AssertionValue{n.value},
-			Expected: &AssertionValue{AssertionRange{a, b}},
+			Expected: &AssertionValue{num},
 			Errors: []error{
-				errors.New("expected: number is not within given range"),
+				errors.New("expected: number is less than or equal to given value"),
 			},
 		})
 	}
diff --git a/string.go b/string.go
index 089f218..49a7b8e 100644
--- a/string.go
+++ b/string.go
@@ -795,14 +795,14 @@ func (s *String) IsASCII() *String {
 	return s
 }
 
-// NotIsASCII succeeds if at least one string character does not belong to ASCII.
+// NotASCII succeeds if at least one string character does not belong to ASCII.
 //
 // Example:
 //
 //	str := NewString(t, "こんにちは")
-//	str.NotIsASCII()
-func (s *String) NotIsASCII() *String {
-	s.chain.enter("NotIsASCII()")
+//	str.NotASCII()
+func (s *String) NotASCII() *String {
+	s.chain.enter("NotASCII()")
 	defer s.chain.leave()
 
 	if s.chain.failed() {
@@ -830,6 +830,11 @@ func (s *String) NotIsASCII() *String {
 	return s
 }
 
+// Deprecated: use NotASCII instead.
+func (s *String) NotIsASCII() *String {
+	return s.NotASCII()
+}
+
 // AsNumber parses float from string and returns a new Number instance
 // with result.
 //
diff --git a/websocket_message.go b/websocket_message.go
index 84ee9fe..e03f334 100644
--- a/websocket_message.go
+++ b/websocket_message.go
@@ -9,7 +9,9 @@ import (
 
 // WebsocketMessage provides methods to inspect message read from WebSocket connection.
 type WebsocketMessage struct {
-	chain     *chain
+	noCopy noCopy
+	chain  *chain
+
 	typ       int
 	content   []byte
 	closeCode int


Test patch:
diff --git a/_examples/fruits_test.go b/_examples/fruits_test.go
index 6e09f1e..68c2d6f 100644
--- a/_examples/fruits_test.go
+++ b/_examples/fruits_test.go
@@ -31,15 +31,33 @@ func TestFruits(t *testing.T) {
 	apple := map[string]interface{}{
 		"colors": []interface{}{"green", "red"},
 		"weight": 200,
+		"image": []map[string]string{
+			{
+				"id":   " 1",
+				"url":  "http://example.com",
+				"type": "fruit",
+			},
+			{
+				"id":   "2",
+				"url":  "http://example2.com",
+				"type": "fruit",
+			},
+		},
 	}
 
 	e.PUT("/fruits/apple").WithJSON(apple).
 		Expect().
 		Status(http.StatusNoContent).NoContent()
 
-	e.GET("/fruits").
+	fruits := e.GET("/fruits").
 		Expect().
-		Status(http.StatusOK).JSON().Array().ContainsOnly("orange", "apple")
+		Status(http.StatusOK).JSON().Array()
+
+	fruits.Every(func(index int, value *httpexpect.Value) {
+		value.String().NotEmpty()
+	})
+	fruits.ContainsAny("orange", "melon")
+	fruits.ContainsOnly("orange", "apple")
 
 	e.GET("/fruits/orange").
 		Expect().
@@ -54,14 +72,25 @@ func TestFruits(t *testing.T) {
 		Expect().
 		Status(http.StatusOK).JSON().Object()
 
-	obj.Keys().ContainsOnly("colors", "weight")
+	obj.Keys().ContainsOnly("colors", "weight", "image")
 
 	obj.Value("colors").Array().Elements("green", "red")
 	obj.Value("colors").Array().Element(0).String().Equal("green")
 	obj.Value("colors").Array().Element(1).String().Equal("red")
+	obj.Value("colors").Array().Element(1).String().IsASCII()
+	obj.Value("colors").Array().Element(1).String().HasPrefix("re")
+	obj.Value("colors").Array().Element(1).String().HasSuffix("ed")
 
 	obj.Value("weight").Number().Equal(200)
 
+	for _, element := range obj.Value("image").Array().Iter() {
+		element.Object().ContainsKey("id")
+		element.Object().ContainsValue("fruit")
+		element.Object().ContainsSubset(map[string]interface{}{
+			"type": "fruit",
+		})
+	}
+
 	e.GET("/fruits/melon").
 		Expect().
 		Status(http.StatusNotFound)
diff --git a/assertion_test.go b/assertion_test.go
index e36e7c5..765160b 100644
--- a/assertion_test.go
+++ b/assertion_test.go
@@ -195,7 +195,193 @@ func TestAssertion_HandlerPanics(t *testing.T) {
 	})
 }
 
-func TestAssertion_Validation(t *testing.T) {
+func TestAssertion_ValidateTraits(t *testing.T) {
+	tests := []struct {
+		testName          string
+		errorContainsText string
+		failure           AssertionFailure
+		traits            fieldTraits
+	}{
+		{
+			testName:          "bad Type",
+			errorContainsText: "AssertionType",
+			failure: AssertionFailure{
+				Type: AssertionType(9999),
+			},
+			traits: fieldTraits{
+				Actual: fieldRequired,
+			},
+		},
+		{
+			testName:          "required Actual",
+			errorContainsText: "Actual",
+			failure: AssertionFailure{
+				Actual: nil,
+			},
+			traits: fieldTraits{
+				Actual: fieldRequired,
+			},
+		},
+		{
+			testName:          "denied Actual",
+			errorContainsText: "Actual",
+			failure: AssertionFailure{
+				Actual: &AssertionValue{},
+			},
+			traits: fieldTraits{
+				Actual: fieldDenied,
+			},
+		},
+		{
+			testName:          "required Expected",
+			errorContainsText: "Expected",
+			failure: AssertionFailure{
+				Expected: nil,
+			},
+			traits: fieldTraits{
+				Expected: fieldRequired,
+			},
+		},
+		{
+			testName:          "denied Expected",
+			errorContainsText: "Expected",
+			failure: AssertionFailure{
+				Expected: &AssertionValue{},
+			},
+			traits: fieldTraits{
+				Expected: fieldDenied,
+			},
+		},
+		{
+			testName:          "required AssertionRange",
+			errorContainsText: "Expected",
+			failure: AssertionFailure{
+				Expected: nil,
+			},
+			traits: fieldTraits{
+				Range: fieldRequired,
+			},
+		},
+		{
+			testName:          "AssertionRange should not be pointer",
+			errorContainsText: "AssertionRange",
+			failure: AssertionFailure{
+				Expected: &AssertionValue{
+					Value: &AssertionRange{},
+				},
+			},
+			traits: fieldTraits{
+				Range: fieldRequired,
+			},
+		},
+		{
+			testName:          "AssertionRange.Min should not be nil",
+			errorContainsText: "AssertionRange",
+			failure: AssertionFailure{
+				Expected: &AssertionValue{
+					Value: AssertionRange{
+						Max: 1,
+					},
+				},
+			},
+			traits: fieldTraits{
+				Range: fieldRequired,
+			},
+		},
+		{
+			testName:          "AssertionRange.Max should not be nil",
+			errorContainsText: "AssertionRange",
+			failure: AssertionFailure{
+				Expected: &AssertionValue{
+					Value: AssertionRange{
+						Min: 1,
+					},
+				},
+			},
+			traits: fieldTraits{
+				Range: fieldRequired,
+			},
+		},
+		{
+			testName:          "required AssertionList",
+			errorContainsText: "Expected",
+			failure: AssertionFailure{
+				Expected: nil,
+			},
+			traits: fieldTraits{
+				List: fieldRequired,
+			},
+		},
+		{
+			testName:          "AssertionList should not be pointer",
+			errorContainsText: "AssertionValue",
+			failure: AssertionFailure{
+				Expected: &AssertionValue{
+					Value: &AssertionList{},
+				},
+			},
+			traits: fieldTraits{
+				List: fieldRequired,
+			},
+		},
+		{
+			testName:          "AssertionList should be not nil",
+			errorContainsText: "AssertionList",
+			failure: AssertionFailure{
+				Expected: &AssertionValue{
+					Value: AssertionList{},
+				},
+			},
+			traits: fieldTraits{
+				List: fieldRequired,
+			},
+		},
+		{
+			testName:          "AssertionList should not be slice of single element",
+			errorContainsText: "AssertionList",
+			failure: AssertionFailure{
+				Expected: &AssertionValue{
+					Value: AssertionList{[]int{1}},
+				},
+			},
+			traits: fieldTraits{
+				List: fieldRequired,
+			},
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.testName, func(t *testing.T) {
+			err := validateTraits(&test.failure, test.traits)
+			require.Error(t, err)
+			require.Contains(t, err.Error(), test.errorContainsText)
+		})
+	}
+
+	t.Run("no error", func(t *testing.T) {
+		err := validateTraits(&AssertionFailure{}, fieldTraits{})
+		require.Nil(t, err)
+	})
+
+	t.Run("panic unsupported", func(t *testing.T) {
+		assert.Panics(t, func() {
+			err := validateTraits(&AssertionFailure{}, fieldTraits{List: fieldDenied})
+			if err != nil {
+				return
+			}
+		})
+
+		assert.Panics(t, func() {
+			err := validateTraits(&AssertionFailure{}, fieldTraits{Range: fieldDenied})
+			if err != nil {
+				return
+			}
+		})
+	})
+
+}
+
+func TestAssertion_ValidateAssertion(t *testing.T) {
 	tests := []struct {
 		testName          string
 		errorContainsText string
diff --git a/datetime_test.go b/datetime_test.go
index 5c6aa3d..922418c 100644
--- a/datetime_test.go
+++ b/datetime_test.go
@@ -25,16 +25,16 @@ func TestDateTime_Failed(t *testing.T) {
 	value.Le(tm)
 	value.InRange(tm, tm)
 	value.NotInRange(tm, tm)
-	value.Zone()
-	value.Year()
-	value.Month()
-	value.Day()
-	value.WeekDay()
-	value.YearDay()
-	value.Hour()
-	value.Minute()
-	value.Second()
-	value.Nanosecond()
+	value.GetZone()
+	value.GetYear()
+	value.GetMonth()
+	value.GetDay()
+	value.GetWeekDay()
+	value.GetYearDay()
+	value.GetHour()
+	value.GetMinute()
+	value.GetSecond()
+	value.GetNanosecond()
 	value.AsUTC()
 	value.AsLocal()
 }
@@ -205,29 +205,29 @@ func TestDateTimeGetters(t *testing.T) {
 
 	value.chain.assertNotFailed(t)
 
-	value.Zone().chain.assertNotFailed(t)
-	value.Year().chain.assertNotFailed(t)
-	value.Month().chain.assertNotFailed(t)
-	value.Day().chain.assertNotFailed(t)
-	value.WeekDay().chain.assertNotFailed(t)
-	value.YearDay().chain.assertNotFailed(t)
-	value.Hour().chain.assertNotFailed(t)
-	value.Minute().chain.assertNotFailed(t)
-	value.Second().chain.assertNotFailed(t)
-	value.Nanosecond().chain.assertNotFailed(t)
+	value.GetZone().chain.assertNotFailed(t)
+	value.GetYear().chain.assertNotFailed(t)
+	value.GetMonth().chain.assertNotFailed(t)
+	value.GetDay().chain.assertNotFailed(t)
+	value.GetWeekDay().chain.assertNotFailed(t)
+	value.GetYearDay().chain.assertNotFailed(t)
+	value.GetHour().chain.assertNotFailed(t)
+	value.GetMinute().chain.assertNotFailed(t)
+	value.GetSecond().chain.assertNotFailed(t)
+	value.GetNanosecond().chain.assertNotFailed(t)
 	value.AsUTC().chain.assertNotFailed(t)
 	value.AsLocal().chain.assertNotFailed(t)
 
 	expectedTime := parsedTime
 	expectedZone, _ := expectedTime.Zone()
-	assert.Equal(t, expectedZone, value.Zone().Raw())
-	assert.Equal(t, float64(expectedTime.Year()), value.Year().Raw())
-	assert.Equal(t, float64(expectedTime.Month()), value.Month().Raw())
-	assert.Equal(t, float64(expectedTime.Day()), value.Day().Raw())
-	assert.Equal(t, float64(expectedTime.Weekday()), value.WeekDay().Raw())
-	assert.Equal(t, float64(expectedTime.YearDay()), value.YearDay().Raw())
-	assert.Equal(t, float64(expectedTime.Hour()), value.Hour().Raw())
-	assert.Equal(t, float64(expectedTime.Minute()), value.Minute().Raw())
-	assert.Equal(t, float64(expectedTime.Second()), value.Second().Raw())
-	assert.Equal(t, float64(expectedTime.Nanosecond()), value.Nanosecond().Raw())
+	assert.Equal(t, expectedZone, value.GetZone().Raw())
+	assert.Equal(t, float64(expectedTime.Year()), value.GetYear().Raw())
+	assert.Equal(t, float64(expectedTime.Month()), value.GetMonth().Raw())
+	assert.Equal(t, float64(expectedTime.Day()), value.GetDay().Raw())
+	assert.Equal(t, float64(expectedTime.Weekday()), value.GetWeekDay().Raw())
+	assert.Equal(t, float64(expectedTime.YearDay()), value.GetYearDay().Raw())
+	assert.Equal(t, float64(expectedTime.Hour()), value.GetHour().Raw())
+	assert.Equal(t, float64(expectedTime.Minute()), value.GetMinute().Raw())
+	assert.Equal(t, float64(expectedTime.Second()), value.GetSecond().Raw())
+	assert.Equal(t, float64(expectedTime.Nanosecond()), value.GetNanosecond().Raw())
 }
diff --git a/number_test.go b/number_test.go
index 9980d02..d6de178 100644
--- a/number_test.go
+++ b/number_test.go
@@ -18,8 +18,8 @@ func TestNumber_Failed(t *testing.T) {
 
 	value.Equal(0)
 	value.NotEqual(0)
-	value.EqualDelta(0, 0)
-	value.NotEqualDelta(0, 0)
+	value.InDelta(0, 0)
+	value.NotInDelta(0, 0)
 	value.Gt(0)
 	value.Ge(0)
 	value.Lt(0)
@@ -99,44 +99,6 @@ func TestNumber_Equal(t *testing.T) {
 	value.chain.clearFailed()
 }
 
-func TestNumber_EqualDelta(t *testing.T) {
-	reporter := newMockReporter(t)
-
-	value := NewNumber(reporter, 1234.5)
-
-	value.EqualDelta(1234.3, 0.3)
-	value.chain.assertNotFailed(t)
-	value.chain.clearFailed()
-
-	value.EqualDelta(1234.7, 0.3)
-	value.chain.assertNotFailed(t)
-	value.chain.clearFailed()
-
-	value.EqualDelta(1234.3, 0.1)
-	value.chain.assertFailed(t)
-	value.chain.clearFailed()
-
-	value.EqualDelta(1234.7, 0.1)
-	value.chain.assertFailed(t)
-	value.chain.clearFailed()
-
-	value.NotEqualDelta(1234.3, 0.3)
-	value.chain.assertFailed(t)
-	value.chain.clearFailed()
-
-	value.NotEqualDelta(1234.7, 0.3)
-	value.chain.assertFailed(t)
-	value.chain.clearFailed()
-
-	value.NotEqualDelta(1234.3, 0.1)
-	value.chain.assertNotFailed(t)
-	value.chain.clearFailed()
-
-	value.NotEqualDelta(1234.7, 0.1)
-	value.chain.assertNotFailed(t)
-	value.chain.clearFailed()
-}
-
 func TestNumber_EqualNaN(t *testing.T) {
 	reporter := newMockReporter(t)
 
@@ -149,80 +111,66 @@ func TestNumber_EqualNaN(t *testing.T) {
 	v2.chain.assertFailed(t)
 
 	v3 := NewNumber(reporter, math.NaN())
-	v3.EqualDelta(1234.0, 0.1)
+	v3.InDelta(1234.0, 0.1)
 	v3.chain.assertFailed(t)
 
 	v4 := NewNumber(reporter, 1234.5)
-	v4.EqualDelta(math.NaN(), 0.1)
+	v4.InDelta(math.NaN(), 0.1)
 	v4.chain.assertFailed(t)
 
 	v5 := NewNumber(reporter, 1234.5)
-	v5.EqualDelta(1234.5, math.NaN())
+	v5.InDelta(1234.5, math.NaN())
 	v5.chain.assertFailed(t)
 
 	v6 := NewNumber(reporter, math.NaN())
-	v6.NotEqualDelta(1234.0, 0.1)
+	v6.NotInDelta(1234.0, 0.1)
 	v6.chain.assertFailed(t)
 
 	v7 := NewNumber(reporter, 1234.5)
-	v7.NotEqualDelta(math.NaN(), 0.1)
+	v7.NotInDelta(math.NaN(), 0.1)
 	v7.chain.assertFailed(t)
 
 	v8 := NewNumber(reporter, 1234.5)
-	v8.NotEqualDelta(1234.5, math.NaN())
+	v8.NotInDelta(1234.5, math.NaN())
 	v8.chain.assertFailed(t)
 }
 
-func TestNumber_Greater(t *testing.T) {
+func TestNumber_InDelta(t *testing.T) {
 	reporter := newMockReporter(t)
 
-	value := NewNumber(reporter, 1234)
+	value := NewNumber(reporter, 1234.5)
 
-	value.Gt(1234 - 1)
+	value.InDelta(1234.3, 0.3)
 	value.chain.assertNotFailed(t)
 	value.chain.clearFailed()
 
-	value.Gt(1234)
-	value.chain.assertFailed(t)
-	value.chain.clearFailed()
-
-	value.Ge(1234 - 1)
+	value.InDelta(1234.7, 0.3)
 	value.chain.assertNotFailed(t)
 	value.chain.clearFailed()
 
-	value.Ge(1234)
-	value.chain.assertNotFailed(t)
+	value.InDelta(1234.3, 0.1)
+	value.chain.assertFailed(t)
 	value.chain.clearFailed()
 
-	value.Ge(1234 + 1)
+	value.InDelta(1234.7, 0.1)
 	value.chain.assertFailed(t)
 	value.chain.clearFailed()
-}
-
-func TestNumber_Lesser(t *testing.T) {
-	reporter := newMockReporter(t)
 
-	value := NewNumber(reporter, 1234)
-
-	value.Lt(1234 + 1)
-	value.chain.assertNotFailed(t)
+	value.NotInDelta(1234.3, 0.3)
+	value.chain.assertFailed(t)
 	value.chain.clearFailed()
 
-	value.Lt(1234)
+	value.NotInDelta(1234.7, 0.3)
 	value.chain.assertFailed(t)
 	value.chain.clearFailed()
 
-	value.Le(1234 + 1)
+	value.NotInDelta(1234.3, 0.1)
 	value.chain.assertNotFailed(t)
 	value.chain.clearFailed()
 
-	value.Le(1234)
+	value.NotInDelta(1234.7, 0.1)
 	value.chain.assertNotFailed(t)
 	value.chain.clearFailed()
-
-	value.Le(1234 - 1)
-	value.chain.assertFailed(t)
-	value.chain.clearFailed()
 }
 
 func TestNumber_InRange(t *testing.T) {
@@ -287,6 +235,58 @@ func TestNumber_InRange(t *testing.T) {
 	value.chain.clearFailed()
 }
 
+func TestNumber_Greater(t *testing.T) {
+	reporter := newMockReporter(t)
+
+	value := NewNumber(reporter, 1234)
+
+	value.Gt(1234 - 1)
+	value.chain.assertNotFailed(t)
+	value.chain.clearFailed()
+
+	value.Gt(1234)
+	value.chain.assertFailed(t)
+	value.chain.clearFailed()
+
+	value.Ge(1234 - 1)
+	value.chain.assertNotFailed(t)
+	value.chain.clearFailed()
+
+	value.Ge(1234)
+	value.chain.assertNotFailed(t)
+	value.chain.clearFailed()
+
+	value.Ge(1234 + 1)
+	value.chain.assertFailed(t)
+	value.chain.clearFailed()
+}
+
+func TestNumber_Lesser(t *testing.T) {
+	reporter := newMockReporter(t)
+
+	value := NewNumber(reporter, 1234)
+
+	value.Lt(1234 + 1)
+	value.chain.assertNotFailed(t)
+	value.chain.clearFailed()
+
+	value.Lt(1234)
+	value.chain.assertFailed(t)
+	value.chain.clearFailed()
+
+	value.Le(1234 + 1)
+	value.chain.assertNotFailed(t)
+	value.chain.clearFailed()
+
+	value.Le(1234)
+	value.chain.assertNotFailed(t)
+	value.chain.clearFailed()
+
+	value.Le(1234 - 1)
+	value.chain.assertFailed(t)
+	value.chain.clearFailed()
+}
+
 func TestNumber_ConvertEqual(t *testing.T) {
 	reporter := newMockReporter(t)
 
@@ -317,6 +317,24 @@ func TestNumber_ConvertEqual(t *testing.T) {
 	value.chain.clearFailed()
 }
 
+func TestNumber_ConvertInRange(t *testing.T) {
+	reporter := newMockReporter(t)
+
+	value := NewNumber(reporter, 1234)
+
+	value.InRange(int64(1233), float32(1235))
+	value.chain.assertNotFailed(t)
+	value.chain.clearFailed()
+
+	value.InRange(int64(1233), "1235")
+	value.chain.assertFailed(t)
+	value.chain.clearFailed()
+
+	value.InRange(nil, 1235)
+	value.chain.assertFailed(t)
+	value.chain.clearFailed()
+}
+
 func TestNumber_ConvertGreater(t *testing.T) {
 	reporter := newMockReporter(t)
 
@@ -376,21 +394,3 @@ func TestNumber_ConvertLesser(t *testing.T) {
 	value.chain.assertFailed(t)
 	value.chain.clearFailed()
 }
-
-func TestNumber_ConvertInRange(t *testing.T) {
-	reporter := newMockReporter(t)
-
-	value := NewNumber(reporter, 1234)
-
-	value.InRange(int64(1233), float32(1235))
-	value.chain.assertNotFailed(t)
-	value.chain.clearFailed()
-
-	value.InRange(int64(1233), "1235")
-	value.chain.assertFailed(t)
-	value.chain.clearFailed()
-
-	value.InRange(nil, 1235)
-	value.chain.assertFailed(t)
-	value.chain.clearFailed()
-}
diff --git a/string_test.go b/string_test.go
index d6611ce..89847c5 100644
--- a/string_test.go
+++ b/string_test.go
@@ -43,7 +43,7 @@ func TestString_Failed(t *testing.T) {
 	value.NotMatch("")
 	value.MatchAll("")
 	value.IsASCII()
-	value.NotIsASCII()
+	value.NotASCII()
 }
 
 func TestString_Constructors(t *testing.T) {
@@ -360,27 +360,27 @@ func TestString_IsNotAscii(t *testing.T) {
 	reporter := newMockReporter(t)
 
 	value1 := NewString(reporter, "Ascii")
-	value1.NotIsASCII()
+	value1.NotASCII()
 	value1.chain.assertFailed(t)
 	value1.chain.clearFailed()
 
 	value2 := NewString(reporter, "Ascii is アスキー")
-	value2.NotIsASCII()
+	value2.NotASCII()
 	value2.chain.assertNotFailed(t)
 	value2.chain.clearFailed()
 
 	value3 := NewString(reporter, "アスキー")
-	value3.NotIsASCII()
+	value3.NotASCII()
 	value3.chain.assertNotFailed(t)
 	value3.chain.clearFailed()
 
 	value4 := NewString(reporter, string(rune(127)))
-	value4.NotIsASCII()
+	value4.NotASCII()
 	value4.chain.assertFailed(t)
 	value4.chain.clearFailed()
 
 	value5 := NewString(reporter, string(rune(128)))
-	value5.NotIsASCII()
+	value5.NotASCII()
 	value5.chain.assertNotFailed(t)
 	value5.chain.clearFailed()
 }