Skip to content

Commit

Permalink
fix: non-operator Body bug + add CI tests
Browse files Browse the repository at this point in the history
Signed-off-by: Maxime Soulé <btik-git@scoubidou.com>
  • Loading branch information
maxatome committed Nov 8, 2022
1 parent 6256cc6 commit b587f3e
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 26 deletions.
66 changes: 66 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: Build

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
test:
strategy:
matrix:
go-version: [1.13.x, 1.14.x, 1.15.x, 1.16.x, 1.17.x, 1.18.x, tip]
full-tests: [false]
include:
- go-version: 1.19.x
full-tests: true

runs-on: ubuntu-latest

steps:
- name: Setup go
run: |
curl -sL https://raw.githubusercontent.com/maxatome/install-go/v3.3/install-go.pl |
perl - ${{ matrix.go-version }} $HOME/go
- name: Checkout code
uses: actions/checkout@v2

- name: Linting
if: matrix.full-tests
run: |
curl -sL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh |
sh -s -- -b $HOME/go/bin v1.50.1
$HOME/go/bin/golangci-lint run --max-issues-per-linter 0 \
--max-same-issues 0 \
-E bidichk \
-E exportloopref \
-E gocritic \
-E godot \
-E goimports \
-E maligned \
-E misspell \
-E prealloc \
-E revive \
-E unconvert \
-E whitespace \
./...
- name: Testing
continue-on-error: ${{ matrix.go-version == 'tip' }}
run: |
go version
if [ ${{ matrix.full-tests }} = true ]; then
GO_TEST_OPTS="-covermode=atomic -coverprofile=coverage.out"
fi
export GORACE="halt_on_error=1"
go test -race $GO_TEST_OPTS ./...
- name: Reporting
if: matrix.full-tests
env:
COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
go install github.com/mattn/goveralls@v0.0.11
goveralls -coverprofile=coverage.out -service=github
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# tdhttpmock

[![Build Status](https://github.com/maxatome/tdhttpmock/workflows/Build/badge.svg?branch=master)](https://github.com/maxatome/tdhttpmock/actions?query=workflow%3ABuild)
[![Coverage Status](https://coveralls.io/repos/github/maxatome/tdhttpmock/badge.svg?branch=master)](https://coveralls.io/github/maxatome/tdhttpmock?branch=master)
[![GoDoc](https://pkg.go.dev/badge/github.com/maxatome/tdhttpmock)](https://pkg.go.dev/github.com/maxatome/tdhttpmock)

The marriage of [go-testdeep](github.com/maxatome/go-testdeep) and
[httpmock](github.com/jarcoal/httpmock).
2 changes: 1 addition & 1 deletion any.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
//go:build !go1.18
// +build !go1.18

package testdeep
package tdhttpmock

type any = interface{}
2 changes: 1 addition & 1 deletion any_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
//go:build !go1.18
// +build !go1.18

package testdeep_test
package tdhttpmock_test

type any = interface{}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/maxatome/tdhttpmock
go 1.19

require (
github.com/jarcoal/httpmock v1.2.1-0.20221107220010-e78b81264f6c
github.com/jarcoal/httpmock v1.2.1-0.20221108221151-f69cd5e7f9cf
github.com/maxatome/go-testdeep v1.12.0
)

Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,11 @@ github.com/jarcoal/httpmock v1.2.1-0.20221022183827-0f002063db7c h1:+mS3pcUxRC8S
github.com/jarcoal/httpmock v1.2.1-0.20221022183827-0f002063db7c/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg=
github.com/jarcoal/httpmock v1.2.1-0.20221107220010-e78b81264f6c h1:6Qw5Ud4Z7d8XJVF37IMuxIuih2qXON/EsmL0E8ChMGw=
github.com/jarcoal/httpmock v1.2.1-0.20221107220010-e78b81264f6c/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg=
github.com/jarcoal/httpmock v1.2.1-0.20221108194521-59c197c7f946 h1:UClGvrWCX/mONL2go7lHpRKbalHLCVShBKNJMw+gOIM=
github.com/jarcoal/httpmock v1.2.1-0.20221108194521-59c197c7f946/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg=
github.com/jarcoal/httpmock v1.2.1-0.20221108215555-dfc8f19478d9 h1:GgZh18Who8XtSTJMO2rUitmauwcX6Nq1+RslSOpJgKc=
github.com/jarcoal/httpmock v1.2.1-0.20221108215555-dfc8f19478d9/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg=
github.com/jarcoal/httpmock v1.2.1-0.20221108221151-f69cd5e7f9cf h1:lnt1bDQ8h9pBdDyaQ+V9ipXF1HvyzRdZ0LDABmrmthM=
github.com/jarcoal/httpmock v1.2.1-0.20221108221151-f69cd5e7f9cf/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg=
github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g=
github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM=
31 changes: 14 additions & 17 deletions tdhttpmock.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,16 @@ func marshaledBody(

// If expectedBody is a TestDeep operator, try to ask it the type
// behind it.
op, ok := expectedBody.(td.TestDeep)
if ok {
if op, ok := expectedBody.(td.TestDeep); ok {
bodyType = op.TypeBehind()
if bodyType == nil {
// As the expected body type cannot be guessed, try to
// unmarshal in an any
bodyType = interfaceType
} else {
bodyType = reflect.TypeOf(expectedBody)
if bodyType == nil {
bodyType = interfaceType
}
}
} else {
bodyType = reflect.TypeOf(expectedBody)
}

// As the expected body type cannot be guessed, try to
// unmarshal in an any
if bodyType == nil {
bodyType = interfaceType
}

bodyPtr := reflect.New(bodyType)
Expand Down Expand Up @@ -81,7 +78,7 @@ func marshaledBody(
// httpmock.NewStringResponder(200, "OK test"))
//
// The name of the returned [httpmock.Matcher] is auto-generated (see
// [httpmock.NewMatcher]). To name it explicitely, use
// [httpmock.NewMatcher]). To name it explicitly, use
// [httpmock.Matcher.WithName] as in:
//
// tdhttpmock.Body("OK!\n").WithName("01-body-OK")
Expand Down Expand Up @@ -144,7 +141,7 @@ func Body(expectedBody any) httpmock.Matcher {
// httpmock.NewStringResponder(200, "OK bob"))
//
// The name of the returned [httpmock.Matcher] is auto-generated (see
// [httpmock.NewMatcher]). To name it explicitely, use
// [httpmock.NewMatcher]). To name it explicitly, use
// [httpmock.Matcher.WithName] as in:
//
// tdhttpmock.JSONBody(td.JSONPointer("/name", "Bob")).WithName("01-bob")
Expand Down Expand Up @@ -182,7 +179,7 @@ func JSONBody(expectedBody any) httpmock.Matcher {
// httpmock.NewStringResponder(200, "OK bob"))
//
// The name of the returned [httpmock.Matcher] is auto-generated (see
// [httpmock.NewMatcher]). To name it explicitely, use
// [httpmock.NewMatcher]). To name it explicitly, use
// [httpmock.Matcher.WithName] as in:
//
// tdhttpmock.XMLBody(td.Struct(Person{Name: "Bob"})).WithName("01-bob")
Expand Down Expand Up @@ -219,7 +216,7 @@ func XMLBody(expectedBody any) httpmock.Matcher {
// httpmock.NewStringResponder(200, "OK account"))
//
// The name of the returned [httpmock.Matcher] is auto-generated (see
// [httpmock.NewMatcher]). To name it explicitely, use
// [httpmock.NewMatcher]). To name it explicitly, use
// [httpmock.Matcher.WithName] as in:
//
// tdhttpmock.Header(td.ContainsKey("X-Custom")).WithName("01-header-custom")
Expand Down Expand Up @@ -256,7 +253,7 @@ func Header(expectedHader any) httpmock.Matcher {
// httpmock.NewStringResponder(200, "OK cookies"))
//
// The name of the returned [httpmock.Matcher] is auto-generated (see
// [httpmock.NewMatcher]). To name it explicitely, use
// [httpmock.NewMatcher]). To name it explicitly, use
// [httpmock.Matcher.WithName] as in:
//
// tdhttpmock.Cookies([]*http.Cookies{}).WithName("01-cookies")
Expand Down
76 changes: 70 additions & 6 deletions tdhttpmock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
package tdhttpmock_test

import (
"io"
"io/ioutil" //nolint: staticcheck
"net/http"
"strings"
"testing"
Expand All @@ -18,9 +18,9 @@ import (
"github.com/maxatome/tdhttpmock"
)

func TestTdhttpmock(t *testing.T) {
func TestBodyHeader(t *testing.T) {
httpmock.Activate()
t.Cleanup(httpmock.DeactivateAndReset)
defer httpmock.DeactivateAndReset()

httpmock.RegisterNoResponder(httpmock.NewStringResponder(404, "Not found"))

Expand All @@ -40,20 +40,56 @@ func TestTdhttpmock(t *testing.T) {
httpmock.NewStringResponder(200, "OK-10"),
)

httpmock.RegisterMatcherResponder(
http.MethodPost,
"/test",
tdhttpmock.Body("STRING").WithName("50-body-STRING"),
httpmock.NewStringResponder(200, "OK-50"),
)

httpmock.RegisterMatcherResponder(
http.MethodPost,
"/test",
tdhttpmock.Body([]byte("BYTES")).WithName("40-body-BYTES"),
httpmock.NewStringResponder(200, "OK-40"),
)

httpmock.RegisterMatcherResponder(
http.MethodPost,
"/test",
tdhttpmock.Body(td.All(td.Contains("FOO"), td.Contains("BAR"))).
WithName("60-body-FOO-BAR"),
httpmock.NewStringResponder(200, "OK-60"),
)

httpmock.RegisterMatcherResponder(
http.MethodPost,
"/test",
tdhttpmock.Body(td.Empty()).WithName("70-body-empty"),
httpmock.NewStringResponder(200, "OK-70"),
)

httpmock.RegisterMatcherResponder(
http.MethodPost,
"/test",
tdhttpmock.Body(666).WithName("00-never-match"),
httpmock.NewStringResponder(200, "BAD-00"),
)

assert := td.Assert(t)

assert.RunAssertRequire("20-body", func(assert, require *td.T) {
resp, err := http.Post("/test", "text/plain", strings.NewReader("42 test"))
require.CmpNoError(err)
assert.Cmp(resp.StatusCode, 200)
assert.Cmp(resp.Body, td.Smuggle(io.ReadAll, td.String("OK-20")))
assert.Cmp(resp.Body, td.Smuggle(ioutil.ReadAll, td.String("OK-20")))
})

assert.RunAssertRequire("not found", func(assert, require *td.T) {
resp, err := http.Post("/test", "text/plain", strings.NewReader("x test"))
require.CmpNoError(err)
assert.Cmp(resp.StatusCode, 404)
assert.Cmp(resp.Body, td.Smuggle(io.ReadAll, td.String("Not found")))
assert.Cmp(resp.Body, td.Smuggle(ioutil.ReadAll, td.String("Not found")))
})

assert.RunAssertRequire("10-body+header", func(assert, require *td.T) {
Expand All @@ -66,6 +102,34 @@ func TestTdhttpmock(t *testing.T) {
resp, err := http.DefaultClient.Do(req)
require.CmpNoError(err)
assert.Cmp(resp.StatusCode, 200)
assert.Cmp(resp.Body, td.Smuggle(io.ReadAll, td.String("OK-10")))
assert.Cmp(resp.Body, td.Smuggle(ioutil.ReadAll, td.String("OK-10")))
})

assert.RunAssertRequire("40-body-BYTES", func(assert, require *td.T) {
resp, err := http.Post("/test", "text/plain", strings.NewReader("BYTES"))
require.CmpNoError(err)
assert.Cmp(resp.StatusCode, 200)
assert.Cmp(resp.Body, td.Smuggle(ioutil.ReadAll, td.String("OK-40")))
})

assert.RunAssertRequire("50-body-STRING", func(assert, require *td.T) {
resp, err := http.Post("/test", "text/plain", strings.NewReader("STRING"))
require.CmpNoError(err)
assert.Cmp(resp.StatusCode, 200)
assert.Cmp(resp.Body, td.Smuggle(ioutil.ReadAll, td.String("OK-50")))
})

assert.RunAssertRequire("60-body-FOO-BAR", func(assert, require *td.T) {
resp, err := http.Post("/test", "text/plain", strings.NewReader("--FOO--BAR--"))
require.CmpNoError(err)
assert.Cmp(resp.StatusCode, 200)
assert.Cmp(resp.Body, td.Smuggle(ioutil.ReadAll, td.String("OK-60")))
})

assert.RunAssertRequire("70-body-empty", func(assert, require *td.T) {
resp, err := http.Post("/test", "", nil)
require.CmpNoError(err)
assert.Cmp(resp.StatusCode, 200)
assert.Cmp(resp.Body, td.Smuggle(ioutil.ReadAll, td.String("OK-70")))
})
}

0 comments on commit b587f3e

Please sign in to comment.