diff --git a/README.md b/README.md
index f2b66e5..4427d42 100644
--- a/README.md
+++ b/README.md
@@ -60,7 +60,7 @@ Expect(req).To(be_http.Request(
)),
// Matching the HTTP method
- be_http.HavingMethod(http.MethodPost),
+ be_http.POST()
// Matching request's context
be_http.HavingCtx(be_ctx.Ctx(
@@ -92,7 +92,7 @@ Expect(req).To(be_http.Request(
be_strings.Var("jwt",
be_jwt.Token(
be_jwt.Valid(),
- be_jwt.HavingClaims("name", "John Doe"),
+ be_jwt.HavingClaim("name", "John Doe"),
),
),
),
@@ -109,7 +109,7 @@ Expect(req).To(be_http.Request(
#### Core matchers:
-`Always`, `Never`, `All`, `Any`, `Eq`, `Not`, `HaveLength`
+`Always`, `Never`, `All`, `Any`, `Eq`, `Not`, `HaveLength`, `Dive`, `DiveAny`, `DiveFirst`
### be_reflected
@@ -162,7 +162,11 @@ types.
[See detailed docs](be_reflected/README.md)
#### Time Matchers
-`LaterThan`, `LaterThanEqual`, `EarlierThan`, `EarlierThanEqual`, `Approx`, `Eq`, `SameExactSecond`, `SameExactMinute`, `SameExactHour`, `SameTimezone`, `SameOffset`, `IsDST`, `SameExactDay`, `SameExactWeekday`, `SameWeek`, `SameMonth`, `SameYear`
+`LaterThan`, `LaterThanEqual`, `EarlierThan`, `EarlierThanEqual`, `Eq`, `Approx`,
+`SameExactMilli`, `SameExactSecond`, `SameExactMinute`, `SameExactHour`,
+`SameExactDay`, `SameExactWeekday`, `SameExactWeek`, `SameExactMonth`,
+`SameSecond`, `SameMinute`, `SameHour`, `SameDay`, `SameYearDay`,
+`SameWeek`, `SameMonth`, `SameYear`, `SameTimzone`, `SameOffset`, `IsDST`
### be_jwt
@@ -176,7 +180,7 @@ golang [jwt implementation](https://github.com/golang-jwt/jwt/v5).
[See deta
#### Matchers on JWT:
-`Token`, `Valid`, `HavingClaims`, `HavingMethodAlg`, `SignedVia`
+`Token`, `Valid`, `HavingClaims`, `HavingClaim`, `HavingMethodAlg`, `SignedVia`
### be_url
@@ -212,7 +216,9 @@ golang [jwt implementation](https://github.com/golang-jwt/jwt/v5).
[See deta
#### Matchers on HTTP:
-`Request`, `HavingMethod`, `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `OPTIONS`, `HavingURL`, `HavingBody`, `HavingHost`, `HavingProto`, `HavingHeader`
+`Request`, `HavingMethod`,
+`GET`, `HEAD`, `POST`, `PUT`, `PATCH`, `DELETE`, `OPTIONS`, `CONNECT`, `TRACE`,
+`HavingURL`, `HavingBody`, `HavingHost`, `HavingProto`, `HavingHeader`, `HavingHeaders`
# Contributing
diff --git a/be_http/README.md b/be_http/README.md
index 007aec0..ea00113 100644
--- a/be_http/README.md
+++ b/be_http/README.md
@@ -2,26 +2,25 @@
--
import "github.com/expectto/be/be_http"
-Package be_http provides matchers for url.Request todo: more detailed
+Package be_http provides matchers for url.Request TODO: more detailed
documentation here is required
## Usage
-#### func DELETE
-
-```go
-func DELETE() types.BeMatcher
-```
-DELETE returns a matcher that succeeds if the actual *http.Request has a method
-"DELETE".
-
-#### func GET
-
```go
-func GET() types.BeMatcher
+var (
+ GET = func() types.BeMatcher { return HavingMethod(http.MethodGet) }
+ HEAD = func() types.BeMatcher { return HavingMethod(http.MethodHead) }
+ POST = func() types.BeMatcher { return HavingMethod(http.MethodPost) }
+ PUT = func() types.BeMatcher { return HavingMethod(http.MethodPut) }
+ PATCH = func() types.BeMatcher { return HavingMethod(http.MethodPatch) }
+ DELETE = func() types.BeMatcher { return HavingMethod(http.MethodDelete) }
+ OPTIONS = func() types.BeMatcher { return HavingMethod(http.MethodOptions) }
+ CONNECT = func() types.BeMatcher { return HavingMethod(http.MethodConnect) }
+ TRACE = func() types.BeMatcher { return HavingMethod(http.MethodTrace) }
+)
```
-GET returns a matcher that succeeds if the actual *http.Request has a method
-"GET".
+HavingMethod: Syntactic sugar
#### func HavingBody
@@ -37,16 +36,39 @@ after matching.
```go
func HavingHeader(key string, args ...any) types.BeMatcher
```
-HavingHeader matches requests that have header with a given key. (1) If no args
-are given, it simply matches a request with existed header by key. (2) If
-len(args) == 1 && args[0] is a stringish, it matches a request with header `Key:
-Args[0]` (3) if len(args) == 1 && args[0] is not stringish, it is considered to
-be matcher for header's value Examples: - HavingHeader("X-Header") matches
-request with non-empty X-Header header - HavingHeader("X-Header", "X-Value")
-matches request with X-Header: X-Value - HavingHeader("X-Header",
-HavePrefix("Bearer ")) matchers request with header(X-Header)'s value matching
-given HavePrefix matcher - todo: support multiple header values todo: fixme I'm
-ugly for now
+HavingHeader matches requests that have header with a given key. Key is a string
+key for a header, args can be nil or len(args)==1. Note: Golang's http.Header is
+`map[string][]string`, and matching is done on the FIRST value of the header in
+case if you have multiple-valued header that needs to be matched, use
+HavingHeaders() instead
+
+These are scenarios that can be handled here: (1) If no args are given, it
+simply matches a request with existed header by key. (2) If len(args) == 1 &&
+args[0] is a stringish, it matches a request with header `Key: Args[0]` (3) if
+len(args) == 1 && args[0] is not stringish, it is considered to be matcher for
+header's value Examples: - HavingHeader("X-Header") matches request with
+non-empty X-Header header - HavingHeader("X-Header", "X-Value") matches request
+with X-Header: X-Value - HavingHeader("X-Header", HavePrefix("Bearer "))
+matchers request with header(X-Header)'s value matching given HavePrefix matcher
+
+#### func HavingHeaders
+
+```go
+func HavingHeaders(key string, args ...any) types.BeMatcher
+```
+HavingHeaders matches requests that have header with a given key. Key is a
+string key for a header, args can be nil or len(args)==1. Note: Matching is done
+on the list of header values. In case if you have single-valued header that
+needs to be matched, use HavingHeader() instead
+
+These are scenarios that can be handled here: (1) If no args are given, it
+simply matches a request with existed header by key. (2) If len(args) == 1 &&
+args[0] is a stringish, it matches a request with header `Key: Args[0]` (3) if
+len(args) == 1 && args[0] is not stringish, it is considered to be matcher for
+header's value Examples: - HavingHeader("X-Header") matches request with
+non-empty X-Header header - HavingHeader("X-Header", "X-Value") matches request
+with X-Header: X-Value - HavingHeader("X-Header", Dive(HavePrefix("Foo ")))
+matchers request with multiple X-Header values, each of them having Foo prefix
#### func HavingHost
@@ -80,38 +102,6 @@ func HavingURL(args ...any) types.BeMatcher
HavingURL succeeds if the actual value is a *http.Request and its URL matches
the provided arguments.
-#### func OPTIONS
-
-```go
-func OPTIONS() types.BeMatcher
-```
-OPTIONS returns a matcher that succeeds if the actual *http.Request has a method
-"OPTIONS".
-
-#### func PATCH
-
-```go
-func PATCH() types.BeMatcher
-```
-PATCH returns a matcher that succeeds if the actual *http.Request has a method
-"PATCH".
-
-#### func POST
-
-```go
-func POST() types.BeMatcher
-```
-POST returns a matcher that succeeds if the actual *http.Request has a method
-"POST".
-
-#### func PUT
-
-```go
-func PUT() types.BeMatcher
-```
-PUT returns a matcher that succeeds if the actual *http.Request has a method
-"PUT".
-
#### func Request
```go
diff --git a/be_time/matchers_time.go b/be_time/matchers_time.go
index 7875f37..db13782 100644
--- a/be_time/matchers_time.go
+++ b/be_time/matchers_time.go
@@ -99,42 +99,42 @@ func SameExactDay(compareTo time.Time) types.BeMatcher {
}))
}
-// SameExactWeek succeeds if the actual time falls within the same ISO week as the specified time `compareTo`.
-func SameExactWeek(compareTo time.Time) types.BeMatcher {
+// SameExactWeekday succeeds if the weekday component of the actual time is equal to the weekday component
+// of the specified time `compareTo`.
+func SameExactWeekday(compareTo time.Time) types.BeMatcher {
return Psi(gcustom.MakeMatcher(func(actual any) (bool, error) {
if !cast.IsTime(actual) {
return false, fmt.Errorf("invalid time type")
}
actualTime := cast.AsTime(actual)
- compareToYear, compareToWeek := compareTo.ISOWeek()
- actualYear, actualWeek := actualTime.ISOWeek()
- return compareToYear == actualYear && compareToWeek == actualWeek, nil
+ return compareTo.Weekday() == actualTime.Weekday(), nil
}))
}
-// SameExactMonth succeeds if the actual time falls within the same month as the specified time `compareTo`.
-func SameExactMonth(compareTo time.Time) types.BeMatcher {
+// SameExactWeek succeeds if the actual time falls within the same ISO week as the specified time `compareTo`.
+func SameExactWeek(compareTo time.Time) types.BeMatcher {
return Psi(gcustom.MakeMatcher(func(actual any) (bool, error) {
if !cast.IsTime(actual) {
return false, fmt.Errorf("invalid time type")
}
actualTime := cast.AsTime(actual)
- return compareTo.Year() == actualTime.Year() && compareTo.Month() == actualTime.Month(), nil
+ compareToYear, compareToWeek := compareTo.ISOWeek()
+ actualYear, actualWeek := actualTime.ISOWeek()
+ return compareToYear == actualYear && compareToWeek == actualWeek, nil
}))
}
-// SameExactWeekday succeeds if the weekday component of the actual time is equal to the weekday component
-// of the specified time `compareTo`.
-func SameExactWeekday(compareTo time.Time) types.BeMatcher {
+// SameExactMonth succeeds if the actual time falls within the same month as the specified time `compareTo`.
+func SameExactMonth(compareTo time.Time) types.BeMatcher {
return Psi(gcustom.MakeMatcher(func(actual any) (bool, error) {
if !cast.IsTime(actual) {
return false, fmt.Errorf("invalid time type")
}
actualTime := cast.AsTime(actual)
- return compareTo.Weekday() == actualTime.Weekday(), nil
+ return compareTo.Year() == actualTime.Year() && compareTo.Month() == actualTime.Month(), nil
}))
}