Skip to content

Commit

Permalink
Add noCopy protection (#226)
Browse files Browse the repository at this point in the history
  • Loading branch information
kairemor committed Jan 13, 2023
1 parent 8bcd3f8 commit 0e9f69c
Show file tree
Hide file tree
Showing 14 changed files with 55 additions and 27 deletions.
7 changes: 4 additions & 3 deletions array.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import (
// Array provides methods to inspect attached []interface{} object
// (Go representation of JSON array).
type Array struct {
chain *chain
value []interface{}
noCopy noCopy
chain *chain
value []interface{}
}

// NewArray returns a new Array instance.
Expand Down Expand Up @@ -38,7 +39,7 @@ func NewArrayC(config Config, value []interface{}) *Array {
}

func newArray(parent *chain, val []interface{}) *Array {
a := &Array{parent.clone(), nil}
a := &Array{chain: parent.clone(), value: nil}

if val == nil {
a.chain.fail(AssertionFailure{
Expand Down
7 changes: 4 additions & 3 deletions boolean.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import (
// Boolean provides methods to inspect attached bool value
// (Go representation of JSON boolean).
type Boolean struct {
chain *chain
value bool
noCopy noCopy
chain *chain
value bool
}

// NewBoolean returns a new Boolean instance.
Expand All @@ -34,7 +35,7 @@ func NewBooleanC(config Config, value bool) *Boolean {
}

func newBoolean(parent *chain, val bool) *Boolean {
return &Boolean{parent.clone(), val}
return &Boolean{chain: parent.clone(), value: val}
}

// Raw returns underlying value attached to Boolean.
Expand Down
7 changes: 4 additions & 3 deletions cookie.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import (

// Cookie provides methods to inspect attached http.Cookie value.
type Cookie struct {
chain *chain
value *http.Cookie
noCopy noCopy
chain *chain
value *http.Cookie
}

// NewCookie returns a new Cookie instance.
Expand Down Expand Up @@ -45,7 +46,7 @@ func NewCookieC(config Config, value *http.Cookie) *Cookie {
}

func newCookie(parent *chain, val *http.Cookie) *Cookie {
c := &Cookie{parent.clone(), nil}
c := &Cookie{chain: parent.clone(), value: nil}

if val == nil {
c.chain.fail(AssertionFailure{
Expand Down
7 changes: 4 additions & 3 deletions datetime.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import (

// DateTime provides methods to inspect attached time.Time value.
type DateTime struct {
chain *chain
value time.Time
noCopy noCopy
chain *chain
value time.Time
}

// NewDateTime returns a new DateTime instance.
Expand Down Expand Up @@ -42,7 +43,7 @@ func NewDateTimeC(config Config, value time.Time) *DateTime {
}

func newDateTime(parent *chain, val time.Time) *DateTime {
return &DateTime{parent.clone(), val}
return &DateTime{chain: parent.clone(), value: val}
}

// Raw returns underlying time.Time value attached to DateTime.
Expand Down
7 changes: 4 additions & 3 deletions duration.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import (

// Duration provides methods to inspect attached time.Duration value.
type Duration struct {
chain *chain
value *time.Duration
noCopy noCopy
chain *chain
value *time.Duration
}

// NewDuration returns a new Duration instance.
Expand Down Expand Up @@ -36,7 +37,7 @@ func NewDurationC(config Config, value time.Duration) *Duration {
}

func newDuration(parent *chain, val *time.Duration) *Duration {
return &Duration{parent.clone(), val}
return &Duration{chain: parent.clone(), value: val}
}

// Raw returns underlying time.Duration value attached to Duration.
Expand Down
5 changes: 3 additions & 2 deletions environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import (
// env.Put("key", "value")
// value := env.GetString("key")
type Environment struct {
chain *chain
data map[string]interface{}
noCopy noCopy
chain *chain
data map[string]interface{}
}

// NewEnvironment returns a new Environment.
Expand Down
3 changes: 2 additions & 1 deletion expect.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ import (
// Expect is a toplevel object that contains user Config and allows
// to construct Request objects.
type Expect struct {
noCopy noCopy
config Config
chain *chain
builders []func(*Request)
Expand Down Expand Up @@ -431,7 +432,7 @@ func (e *Expect) Env() *Environment {
}

func (e *Expect) clone() *Expect {
ret := *e
ret := *e //nolint

ret.builders = nil
ret.builders = append(ret.builders, e.builders...)
Expand Down
15 changes: 15 additions & 0 deletions nocopy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package httpexpect

// noCopy struct is a special type that is used to prevent a value from being copied.
// `go vet` gives a warning if it finds that a struct with a field of
// this type is being copied.
// To enable this behavior, this struct provides two methods `Lock` and `Unlock,
// that do not do anything.
// See more details here:
// https://github.com/golang/go/issues/8005
// https://stackoverflow.com/questions/52494458

type noCopy struct{}

func (*noCopy) Lock() {}
func (*noCopy) Unlock() {}
7 changes: 4 additions & 3 deletions number.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import (
// Number provides methods to inspect attached float64 value
// (Go representation of JSON number).
type Number struct {
chain *chain
value float64
noCopy noCopy
chain *chain
value float64
}

// NewNumber returns a new Number instance.
Expand All @@ -35,7 +36,7 @@ func NewNumberC(config Config, value float64) *Number {
}

func newNumber(parent *chain, val float64) *Number {
return &Number{parent.clone(), val}
return &Number{chain: parent.clone(), value: val}
}

// Raw returns underlying value attached to Number.
Expand Down
7 changes: 4 additions & 3 deletions object.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ import (
// Object provides methods to inspect attached map[string]interface{} object
// (Go representation of JSON object).
type Object struct {
chain *chain
value map[string]interface{}
noCopy noCopy
chain *chain
value map[string]interface{}
}

// NewObject returns a new Object instance.
Expand Down Expand Up @@ -39,7 +40,7 @@ func NewObjectC(config Config, value map[string]interface{}) *Object {
}

func newObject(parent *chain, val map[string]interface{}) *Object {
o := &Object{parent.clone(), nil}
o := &Object{chain: parent.clone(), value: nil}

if val == nil {
o.chain.fail(AssertionFailure{
Expand Down
1 change: 1 addition & 0 deletions request.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
// Request provides methods to incrementally build http.Request object,
// send it, and receive response.
type Request struct {
noCopy noCopy
config Config
chain *chain

Expand Down
1 change: 1 addition & 0 deletions response.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (

// Response provides methods to inspect attached http.Response object.
type Response struct {
noCopy noCopy
config Config
chain *chain

Expand Down
7 changes: 4 additions & 3 deletions string.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ import (
// String provides methods to inspect attached string value
// (Go representation of JSON string).
type String struct {
chain *chain
value string
noCopy noCopy
chain *chain
value string
}

// NewString returns a new String instance.
Expand All @@ -41,7 +42,7 @@ func NewStringC(config Config, value string) *String {
}

func newString(parent *chain, val string) *String {
return &String{parent.clone(), val}
return &String{chain: parent.clone(), value: val}
}

// Raw returns underlying value attached to String.
Expand Down
1 change: 1 addition & 0 deletions websocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type WebsocketConn interface {
// Websocket provides methods to read from, write into and close WebSocket
// connection.
type Websocket struct {
noCopy noCopy
config Config
chain *chain

Expand Down

0 comments on commit 0e9f69c

Please sign in to comment.