diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 51fbc24..f118ccd 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -21,7 +21,7 @@ env: GO111MODULE: "on" CACHE_BENCHMARK: "off" # Enables benchmark result reuse between runs, may skew latency results. RUN_BASE_BENCHMARK: "on" # Runs benchmark for PR base in case benchmark result is missing. - GO_VERSION: 1.21.x + GO_VERSION: 1.22.x jobs: bench: runs-on: ubuntu-latest diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index d2e4b61..6239219 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -21,13 +21,13 @@ jobs: steps: - uses: actions/setup-go@v3 with: - go-version: 1.21.x + go-version: 1.22.x - uses: actions/checkout@v2 - name: golangci-lint - uses: golangci/golangci-lint-action@v3.7.0 + uses: golangci/golangci-lint-action@v4.0.0 with: # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version. - version: v1.54.1 + version: v1.56.2 # Optional: working directory, useful for monorepos # working-directory: somedir diff --git a/.github/workflows/gorelease.yml b/.github/workflows/gorelease.yml index 97ebe87..6356a9d 100644 --- a/.github/workflows/gorelease.yml +++ b/.github/workflows/gorelease.yml @@ -9,7 +9,7 @@ concurrency: cancel-in-progress: true env: - GO_VERSION: 1.21.x + GO_VERSION: 1.22.x jobs: gorelease: runs-on: ubuntu-latest diff --git a/.github/workflows/test-unit.yml b/.github/workflows/test-unit.yml index 1f61fb8..7eb27c9 100644 --- a/.github/workflows/test-unit.yml +++ b/.github/workflows/test-unit.yml @@ -15,13 +15,13 @@ concurrency: env: GO111MODULE: "on" RUN_BASE_COVERAGE: "on" # Runs test for PR base in case base test coverage is missing. - COV_GO_VERSION: 1.21.x # Version of Go to collect coverage + COV_GO_VERSION: 1.22.x # Version of Go to collect coverage TARGET_DELTA_COV: 90 # Target coverage of changed lines, in percents jobs: test: strategy: matrix: - go-version: [ 1.13.x, 1.20.x, 1.21.x ] + go-version: [ 1.13.x, 1.21.x, 1.22.x ] runs-on: ubuntu-latest steps: - name: Install Go stable @@ -88,9 +88,9 @@ jobs: id: annotate if: matrix.go-version == env.COV_GO_VERSION && github.event.pull_request.base.sha != '' run: | - curl -sLO https://github.com/vearutop/gocovdiff/releases/download/v1.4.0/linux_amd64.tar.gz && tar xf linux_amd64.tar.gz && rm linux_amd64.tar.gz + curl -sLO https://github.com/vearutop/gocovdiff/releases/download/v1.4.2/linux_amd64.tar.gz && tar xf linux_amd64.tar.gz && rm linux_amd64.tar.gz gocovdiff_hash=$(git hash-object ./gocovdiff) - [ "$gocovdiff_hash" == "f191b45548bb65ec2c7d88909679a57116ff1ba1" ] || (echo "::error::unexpected hash for gocovdiff, possible tampering: $gocovdiff_hash" && exit 1) + [ "$gocovdiff_hash" == "c37862c73a677e5a9c069470287823ab5bbf0244" ] || (echo "::error::unexpected hash for gocovdiff, possible tampering: $gocovdiff_hash" && exit 1) git fetch origin master ${{ github.event.pull_request.base.sha }} REP=$(./gocovdiff -mod github.com/$GITHUB_REPOSITORY -cov unit.coverprofile -gha-annotations gha-unit.txt -delta-cov-file delta-cov-unit.txt -target-delta-cov ${TARGET_DELTA_COV}) echo "${REP}" diff --git a/.golangci.yml b/.golangci.yml index a035208..19232d9 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -20,6 +20,7 @@ linters-settings: linters: enable-all: true disable: + - musttag - lll - maligned - gochecknoglobals diff --git a/Makefile b/Makefile index e820993..79a4626 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -#GOLANGCI_LINT_VERSION := "v1.54.1" # Optional configuration to pinpoint golangci-lint version. +#GOLANGCI_LINT_VERSION := "v1.56.2" # Optional configuration to pinpoint golangci-lint version. # The head of Makefile determines location of dev-go to include standard targets. GO ?= go diff --git a/example_test.go b/example_test.go index f11b346..7559c05 100644 --- a/example_test.go +++ b/example_test.go @@ -78,7 +78,7 @@ func ExampleStorage_InTx() { ctx context.Context ) - err := s.InTx(ctx, func(ctx context.Context) error { + err := s.InTx(ctx, func(_ context.Context) error { return nil }) if err != nil { diff --git a/go.mod b/go.mod index 0326e4a..72d9a95 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,10 @@ module github.com/bool64/sqluct go 1.18 require ( - github.com/DATA-DOG/go-sqlmock v1.5.0 + github.com/DATA-DOG/go-sqlmock v1.5.2 github.com/Masterminds/squirrel v1.5.4 github.com/bool64/ctxd v1.2.1 - github.com/bool64/dev v0.2.31 + github.com/bool64/dev v0.2.34 github.com/jmoiron/sqlx v1.3.5 github.com/stretchr/testify v1.8.2 ) diff --git a/go.sum b/go.sum index 6be31ae..0b23c1d 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,11 @@ -github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= -github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= +github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM= github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= github.com/bool64/ctxd v1.2.1 h1:hARFteq0zdn4bwfmxLhak3fXFuvtJVKDH2X29VV/2ls= github.com/bool64/ctxd v1.2.1/go.mod h1:ZG6QkeGVLTiUl2mxPpyHmFhDzFZCyocr9hluBV3LYuc= -github.com/bool64/dev v0.2.31 h1:OS57EqYaYe2M/2bw9uhDCIFiZZwywKFS/4qMLN6JUmQ= -github.com/bool64/dev v0.2.31/go.mod h1:iJbh1y/HkunEPhgebWRNcs8wfGq7sjvJ6W5iabL8ACg= +github.com/bool64/dev v0.2.34 h1:P9n315P8LdpxusnYQ0X7MP1CZXwBK5ae5RZrd+GdSZE= +github.com/bool64/dev v0.2.34/go.mod h1:iJbh1y/HkunEPhgebWRNcs8wfGq7sjvJ6W5iabL8ACg= 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= @@ -13,6 +13,7 @@ github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfC github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= +github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE= github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw= github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o= github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk= diff --git a/mapper_test.go b/mapper_test.go index c1d2269..9389a68 100644 --- a/mapper_test.go +++ b/mapper_test.go @@ -7,6 +7,7 @@ import ( "github.com/Masterminds/squirrel" "github.com/bool64/sqluct" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) type ( @@ -48,7 +49,7 @@ func TestInsertValue(t *testing.T) { sm := sqluct.Mapper{} q := sm.Insert(ps.Insert("sample"), z) query, args, err := q.ToSql() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "INSERT INTO sample (a,meta,e,b,c) VALUES ($1,$2,$3,$4,$5)", query) assert.Equal(t, []interface{}{1, AnotherRow{SampleEmbedded: SampleEmbedded{B: 0, C: ""}, D: ""}, "e!", 2.2, "3"}, args) } @@ -88,7 +89,7 @@ func TestInsertValue_omitempty(t *testing.T) { sm := sqluct.Mapper{} q := sm.Insert(ps.Insert("sample"), z) query, args, err := q.ToSql() - assert.NoError(t, err) + require.NoError(t, err) // a and e are missing for `omitempty` assert.Equal(t, "INSERT INTO sample (meta,b,c) VALUES ($1,$2,$3)", query) assert.Equal(t, []interface{}{AnotherRow{SampleEmbedded: SampleEmbedded{B: 0, C: ""}, D: ""}, 0.0, ""}, args) @@ -120,7 +121,7 @@ func TestInsertValue_IgnoreOmitEmpty(t *testing.T) { sm := sqluct.Mapper{} q := sm.Insert(ps.Insert("sample"), z, sqluct.IgnoreOmitEmpty) query, args, err := q.ToSql() - assert.NoError(t, err) + require.NoError(t, err) // a and e are missing for `omitempty` assert.Equal(t, "INSERT INTO sample (a,meta,e,b,c) VALUES ($1,$2,$3,$4,$5)", query) assert.Equal(t, []interface{}{0, AnotherRow{SampleEmbedded: SampleEmbedded{B: 0, C: ""}, D: ""}, "", 0.0, ""}, args) @@ -174,7 +175,7 @@ func TestInsertValueSlice_heterogeneous(t *testing.T) { assert.Equal(t, q, sm.Insert(q, nil)) q = sm.Insert(q, z) query, args, err := q.ToSql() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "INSERT INTO sample (a,meta,e,b,c) VALUES ($1,$2,$3,$4,$5),($6,$7,$8,$9,$10)", query) assert.Equal(t, []interface{}{ 0, @@ -216,7 +217,7 @@ func TestInsertValueSlice_homogeneous(t *testing.T) { assert.Equal(t, q, sm.Insert(q, nil)) q = sm.Insert(q, z) query, args, err := q.ToSql() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "INSERT INTO sample (a,meta,e,b,c) VALUES ($1,$2,$3,$4,$5),($6,$7,$8,$9,$10)", query) assert.Equal(t, []interface{}{ 1, @@ -338,7 +339,7 @@ func TestInsertValueSlicePtr(t *testing.T) { sm := sqluct.Mapper{} q := sm.Insert(ps.Insert("sample"), z) query, args, err := q.ToSql() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "INSERT INTO sample (a,meta,e,b,c) VALUES ($1,$2,$3,$4,$5),($6,$7,$8,$9,$10)", query) assert.Equal(t, []interface{}{ 1, @@ -369,7 +370,7 @@ func TestMapper_Update(t *testing.T) { q := sm.Update(ps.Update("sample"), z) q = q.Where(sm.WhereEq(condition)) query, args, err := q.ToSql() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "UPDATE sample SET b = $1, c = $2 WHERE a = $3 AND b IN ($4,$5)", query) assert.Equal(t, []interface{}{2.2, "3", 1, "b1", "b2"}, args) } @@ -382,7 +383,7 @@ func TestMapper_Select_struct(t *testing.T) { q = q.From("sample") query, args, err := q.ToSql() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "SELECT a, meta, e, b, c FROM sample", query) assert.Equal(t, []interface{}(nil), args) } @@ -421,7 +422,7 @@ func TestMapper_Select_slice(t *testing.T) { q = q.Where(sm.WhereEq(condition)) q = q.From("sample") query, args, err := q.ToSql() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "SELECT b, c FROM sample WHERE a = $1 AND b IN ($2,$3)", query) assert.Equal(t, []interface{}{1, "b1", "b2"}, args) } @@ -453,7 +454,7 @@ func TestMapper_WhereEq(t *testing.T) { q = q.Where(sm.WhereEq(filter, sqluct.SkipZeroValues)) query, args, err := q.ToSql() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "SELECT campaign, variation, fk_customer, created_at FROM sample WHERE fk_customer = $1", query) assert.Equal(t, []interface{}{uint64(123)}, args) @@ -462,7 +463,7 @@ func TestMapper_WhereEq(t *testing.T) { q = sm.Select(q, rows) q = q.Where(sm.WhereEq(filter, sqluct.SkipZeroValues)) query, args, err = q.ToSql() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "SELECT campaign, variation, fk_customer, created_at FROM sample WHERE campaign IN ($1,$2) AND fk_customer = $3", query) assert.Equal(t, []interface{}{"k1", "k2", uint64(123)}, args) @@ -471,7 +472,7 @@ func TestMapper_WhereEq(t *testing.T) { q = sm.Select(q, rows) q = q.Where(sm.WhereEq(filter, sqluct.SkipZeroValues)) query, args, err = q.ToSql() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "SELECT campaign, variation, fk_customer, created_at FROM sample WHERE campaign IN ($1,$2)", query) assert.Equal(t, []interface{}{"k1", "k2"}, args) @@ -480,7 +481,7 @@ func TestMapper_WhereEq(t *testing.T) { q = sm.Select(q, rows) q = q.Where(sm.WhereEq(filter, sqluct.SkipZeroValues)) query, args, err = q.ToSql() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "SELECT campaign, variation, fk_customer, created_at FROM sample WHERE (1=1)", query) assert.Equal(t, []interface{}(nil), args) } @@ -499,7 +500,7 @@ func TestMapper_Delete(t *testing.T) { sm := sqluct.Mapper{} q := ps.Delete("sample").Where(sm.WhereEq(condition, sqluct.SkipZeroValues)) query, args, err := q.ToSql() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "DELETE FROM sample WHERE a = $1 AND b IN ($2,$3)", query) assert.Equal(t, []interface{}{1, "b1", "b2"}, args) } @@ -541,10 +542,11 @@ func TestMapper_FindColumnName(t *testing.T) { t.Run("", func(t *testing.T) { tagValue, err := sm.FindColumnName(tc.structPtr, tc.fieldPtr) assert.Equal(t, tc.tagValue, tagValue) + if tc.err == "" { - assert.NoError(t, err) + require.NoError(t, err) } else { - assert.EqualError(t, err, tc.err) + require.EqualError(t, err, tc.err) } }) } @@ -628,6 +630,6 @@ func assertStatement(t *testing.T, s string, qb sqluct.ToSQL) { t.Helper() stmt, _, err := qb.ToSql() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, s, stmt) } diff --git a/referencer_test.go b/referencer_test.go index f09808a..279ffe2 100644 --- a/referencer_test.go +++ b/referencer_test.go @@ -6,6 +6,7 @@ import ( "github.com/Masterminds/squirrel" "github.com/bool64/sqluct" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestReferencer_Fmt(t *testing.T) { @@ -46,7 +47,7 @@ func TestReferencer_Fmt(t *testing.T) { Where(squirrel.NotEq(m.WhereEq(User{FirstName: "Sergey", LastName: "Brin"}, rf.ColumnsOf("manager")))) stmt, args, err := qb.ToSql() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, `SELECT dr.manager_id, dr.employee_id `+ `FROM users AS manager `+ `INNER JOIN direct_reports AS dr ON dr.manager_id = manager.id AND dr.employee_id = employee.id `+ diff --git a/storage.go b/storage.go index 0313fdd..65feeb0 100644 --- a/storage.go +++ b/storage.go @@ -138,8 +138,8 @@ func (s *Storage) InTx(ctx context.Context, fn func(context.Context) error) (err ctx = TxToContext(ctx, tx) } else { // Do nothing because parent tx is still running and - // this is not the beginner so it can't be the finisher. - finish = func(ctx context.Context, err error) error { + // this is not the beginner, so it can't be the finisher. + finish = func(_ context.Context, err error) error { return err } } diff --git a/storage_go1.18.go b/storage_go1.18.go index 5a65f34..ca7a26c 100644 --- a/storage_go1.18.go +++ b/storage_go1.18.go @@ -161,6 +161,16 @@ type JSON[V any] struct { Val V } +// UnmarshalJSON decodes JSON into container. +func (s *JSON[V]) UnmarshalJSON(bytes []byte) error { + return json.Unmarshal(bytes, &s.Val) +} + +// MarshalJSON encodes container value as JSON. +func (s JSON[V]) MarshalJSON() ([]byte, error) { + return json.Marshal(s.Val) +} + // Scan decodes json value from a db column. func (s *JSON[V]) Scan(src any) error { if src == nil { diff --git a/storage_go1.18_test.go b/storage_go1.18_test.go index 0ff3a3c..b4d1543 100644 --- a/storage_go1.18_test.go +++ b/storage_go1.18_test.go @@ -5,12 +5,14 @@ package sqluct_test import ( "context" + "encoding/json" "testing" "github.com/DATA-DOG/go-sqlmock" "github.com/bool64/sqluct" "github.com/jmoiron/sqlx" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestList(t *testing.T) { @@ -21,7 +23,7 @@ func TestList(t *testing.T) { } db, mock, err := sqlmock.New() - assert.NoError(t, err) + require.NoError(t, err) traceStarted := false traceFinished := false @@ -36,7 +38,7 @@ func TestList(t *testing.T) { return ctx, func(err error) { traceFinished = true - assert.NoError(t, err) + require.NoError(t, err) } } @@ -51,12 +53,13 @@ func TestList(t *testing.T) { mock.ExpectQuery("SELECT one, two, three FROM table").WillReturnRows(mockedRows) rows, err := sqluct.List[row](ctx, st, qb) - assert.NoError(t, err) + require.NoError(t, err) i := 0 for _, item := range rows { assert.Equal(t, row{One: i, Two: 2 * i, Three: 3 * i}, item) + i++ } @@ -73,7 +76,7 @@ func TestGet(t *testing.T) { } db, mock, err := sqlmock.New() - assert.NoError(t, err) + require.NoError(t, err) st := sqluct.NewStorage(sqlx.NewDb(db, "mock")) @@ -85,7 +88,57 @@ func TestGet(t *testing.T) { mock.ExpectQuery("SELECT one, two, three FROM table").WillReturnRows(mockedRows) item, err := sqluct.Get[row](ctx, st, qb) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, row{One: 1, Two: 2, Three: 3}, item) } + +func TestJSON_Value(t *testing.T) { + type nested struct { + A int `json:"a"` + B bool `json:"b"` + } + + type row struct { + One int `db:"one" json:"one"` + Two int `db:"two" json:"two"` + Three int `db:"three" json:"three"` + Four sqluct.JSON[nested] `db:"four" json:"four"` + } + + db, mock, err := sqlmock.New() + require.NoError(t, err) + + st := sqluct.NewStorage(sqlx.NewDb(db, "mock")) + + qb := st.SelectStmt("table", row{}) + ctx := context.Background() + + mockedRows := sqlmock.NewRows([]string{"one", "two", "three", "four"}) + mockedRows.AddRow(1, 2, 3, `{"a":123,"b":true}`) + mock.ExpectQuery("SELECT one, two, three, four FROM table").WillReturnRows(mockedRows) + + item, err := sqluct.Get[row](ctx, st, qb) + require.NoError(t, err) + + expected := row{One: 1, Two: 2, Three: 3} + expected.Four.Val = nested{A: 123, B: true} + assert.Equal(t, expected, item) + + j, err := json.Marshal(item) + require.NoError(t, err) + + assert.Equal(t, `{"one":1,"two":2,"three":3,"four":{"a":123,"b":true}}`, string(j)) + + var r row + + require.NoError(t, json.Unmarshal(j, &r)) + assert.Equal(t, expected, r) + + mock.ExpectExec("INSERT INTO table \\(one,two,three,four\\) VALUES \\(\\$1,\\$2\\,\\$3,\\$4\\)"). + WithArgs(1, 2, 3, `{"a":123,"b":true}`). + WillReturnResult(sqlmock.NewResult(0, 1)) + + _, err = st.InsertStmt("table", r).ExecContext(ctx) + require.NoError(t, err) +} diff --git a/storage_test.go b/storage_test.go index 8537ffe..e4d36c9 100644 --- a/storage_test.go +++ b/storage_test.go @@ -2,7 +2,7 @@ package sqluct_test import ( "context" - "fmt" + "errors" "testing" sqlmock "github.com/DATA-DOG/go-sqlmock" @@ -15,7 +15,7 @@ import ( func TestStorage_InTx_FailToStart(t *testing.T) { db, mock, err := sqlmock.New() - assert.NoError(t, err) + require.NoError(t, err) type ctxKey struct{} @@ -27,38 +27,38 @@ func TestStorage_InTx_FailToStart(t *testing.T) { errReceived = true assert.Equal(t, "a", ctx.Value(ctxKey{})) - assert.EqualError(t, err, "failed to begin tx: begin error") + require.EqualError(t, err, "failed to begin tx: begin error") } - mock.ExpectBegin().WillReturnError(fmt.Errorf("begin error")) + mock.ExpectBegin().WillReturnError(errors.New("begin error")) err = st.InTx(ctx, nil) - assert.EqualError(t, err, "failed to begin tx: begin error") - assert.NoError(t, mock.ExpectationsWereMet()) + require.EqualError(t, err, "failed to begin tx: begin error") + require.NoError(t, mock.ExpectationsWereMet()) assert.True(t, errReceived) } func TestStorage_InTx_Success(t *testing.T) { db, mock, err := sqlmock.New() - assert.NoError(t, err) + require.NoError(t, err) st := sqluct.NewStorage(sqlx.NewDb(db, "mock")) mock.ExpectBegin() mock.ExpectCommit() - err = st.InTx(context.TODO(), func(ctx context.Context) error { + err = st.InTx(context.TODO(), func(_ context.Context) error { return nil }) - assert.Nil(t, err) - assert.NoError(t, mock.ExpectationsWereMet()) + require.NoError(t, err) + require.NoError(t, mock.ExpectationsWereMet()) } func TestStorage_InTx_ReuseTx(t *testing.T) { db, mock, err := sqlmock.New() - assert.NoError(t, err) + require.NoError(t, err) dbx := sqlx.NewDb(db, "mock") st := sqluct.NewStorage(dbx) @@ -68,26 +68,26 @@ func TestStorage_InTx_ReuseTx(t *testing.T) { // Manually start a transaction. tx, err := dbx.BeginTxx(context.TODO(), nil) - assert.NoError(t, err) + require.NoError(t, err) ctx := sqluct.TxToContext(context.TODO(), tx) counter := 0 // Start using transaction. - err = st.InTx(ctx, func(ctx context.Context) error { + err = st.InTx(ctx, func(_ context.Context) error { counter++ return nil }) assert.Equal(t, 1, counter) - assert.Nil(t, err) - assert.NoError(t, mock.ExpectationsWereMet()) + require.NoError(t, err) + require.NoError(t, mock.ExpectationsWereMet()) } func TestStorage_InTx_RollbackOnError(t *testing.T) { db, mock, err := sqlmock.New() - assert.NoError(t, err) + require.NoError(t, err) st := sqluct.NewStorage(sqlx.NewDb(db, "mock")) @@ -95,48 +95,48 @@ func TestStorage_InTx_RollbackOnError(t *testing.T) { mock.ExpectRollback() // Start using transaction. - err = st.InTx(context.TODO(), func(ctx context.Context) error { - return fmt.Errorf("error") + err = st.InTx(context.TODO(), func(_ context.Context) error { + return errors.New("error") }) - assert.EqualError(t, err, "error") - assert.NoError(t, mock.ExpectationsWereMet()) + require.EqualError(t, err, "error") + require.NoError(t, mock.ExpectationsWereMet()) } func TestStorage_InTx_ErrorOnRollback(t *testing.T) { db, mock, err := sqlmock.New() - assert.NoError(t, err) + require.NoError(t, err) st := sqluct.NewStorage(sqlx.NewDb(db, "mock")) mock.ExpectBegin() - mock.ExpectRollback().WillReturnError(fmt.Errorf("rollback error")) + mock.ExpectRollback().WillReturnError(errors.New("rollback error")) // Start using transaction. - err = st.InTx(context.TODO(), func(ctx context.Context) error { - return fmt.Errorf("error") + err = st.InTx(context.TODO(), func(_ context.Context) error { + return errors.New("error") }) - assert.EqualError(t, err, "failed to rollback: rollback error") - assert.NoError(t, mock.ExpectationsWereMet()) + require.EqualError(t, err, "failed to rollback: rollback error") + require.NoError(t, mock.ExpectationsWereMet()) } func TestStorage_InTx_FailToCommit(t *testing.T) { db, mock, err := sqlmock.New() - assert.NoError(t, err) + require.NoError(t, err) st := sqluct.NewStorage(sqlx.NewDb(db, "mock")) mock.ExpectBegin() - mock.ExpectCommit().WillReturnError(fmt.Errorf("commit error")) + mock.ExpectCommit().WillReturnError(errors.New("commit error")) // Start using transaction. - err = st.InTx(context.TODO(), func(ctx context.Context) error { + err = st.InTx(context.TODO(), func(_ context.Context) error { return nil }) - assert.EqualError(t, err, "failed to commit: commit error") - assert.NoError(t, mock.ExpectationsWereMet()) + require.EqualError(t, err, "failed to commit: commit error") + require.NoError(t, mock.ExpectationsWereMet()) } func TestStorage_SelectContext_slice(t *testing.T) { @@ -147,7 +147,7 @@ func TestStorage_SelectContext_slice(t *testing.T) { } db, mock, err := sqlmock.New() - assert.NoError(t, err) + require.NoError(t, err) traceStarted := false traceFinished := false @@ -162,7 +162,7 @@ func TestStorage_SelectContext_slice(t *testing.T) { return ctx, func(err error) { traceFinished = true - assert.NoError(t, err) + require.NoError(t, err) } } @@ -178,12 +178,13 @@ func TestStorage_SelectContext_slice(t *testing.T) { mock.ExpectQuery("SELECT one, two, three FROM table").WillReturnRows(mockedRows) err = st.Select(ctx, qb, &rows) - assert.NoError(t, err) + require.NoError(t, err) i := 0 for _, item := range rows { assert.Equal(t, row{One: i, Two: 2 * i, Three: 3 * i}, item) + i++ } @@ -200,7 +201,7 @@ func TestStorage_SelectContext_row(t *testing.T) { } db, mock, err := sqlmock.New() - assert.NoError(t, err) + require.NoError(t, err) st := sqluct.NewStorage(sqlx.NewDb(db, "mock")) @@ -215,7 +216,7 @@ func TestStorage_SelectContext_row(t *testing.T) { mock.ExpectQuery("SELECT one, two, three FROM table").WillReturnRows(mockedRows) err = st.Select(ctx, qb, &item) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, row{One: 1, Two: 2, Three: 3}, item) } @@ -237,7 +238,7 @@ func TestStorage_ExecContext(t *testing.T) { return ctx, func(err error) { traceFinished = true - assert.NoError(t, err) + require.NoError(t, err) } } @@ -246,7 +247,7 @@ func TestStorage_ExecContext(t *testing.T) { qb := st.DeleteStmt("table") _, err = st.Exec(context.Background(), qb) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, traceStarted) assert.True(t, traceFinished) } @@ -263,8 +264,8 @@ func TestStorage_DeleteStmt_backticks(t *testing.T) { WillReturnResult(sqlmock.NewResult(0, 1)) _, err = st.DeleteStmt("table").Exec() - assert.NoError(t, err) - assert.NoError(t, mock.ExpectationsWereMet()) + require.NoError(t, err) + require.NoError(t, mock.ExpectationsWereMet()) } func TestStorage_InsertStmt_backticks(t *testing.T) { @@ -282,8 +283,8 @@ func TestStorage_InsertStmt_backticks(t *testing.T) { OrderID int `db:"order_id"` Amount int `db:"amount"` }{10, 20}).Exec() - assert.NoError(t, err) - assert.NoError(t, mock.ExpectationsWereMet()) + require.NoError(t, err) + require.NoError(t, mock.ExpectationsWereMet()) } func TestStorage_UpdateStmt(t *testing.T) { @@ -295,8 +296,8 @@ func TestStorage_UpdateStmt(t *testing.T) { OrderID int `db:"order_id"` Amount int `db:"amount"` }{10, 20}).ToSql() - assert.NoError(t, err) - assert.Equal(t, query, "UPDATE table SET order_id = $1, amount = $2") + require.NoError(t, err) + assert.Equal(t, "UPDATE table SET order_id = $1, amount = $2", query) assert.Equal(t, []interface{}{10, 20}, args) } @@ -310,8 +311,8 @@ func TestStorage_UpdateStmt_ansi(t *testing.T) { OrderID int `db:"order_id"` Amount int `db:"amount"` }{10, 20}).ToSql() - assert.NoError(t, err) - assert.Equal(t, query, `UPDATE "table" SET "order_id" = $1, "amount" = $2`) + require.NoError(t, err) + assert.Equal(t, `UPDATE "table" SET "order_id" = $1, "amount" = $2`, query) assert.Equal(t, []interface{}{10, 20}, args) } @@ -322,8 +323,8 @@ func TestStorage_SelectStmt(t *testing.T) { OrderID int `db:"order_id"` Amount int `db:"amount"` }{}).ToSql() - assert.NoError(t, err) - assert.Equal(t, query, "SELECT order_id, amount FROM table") + require.NoError(t, err) + assert.Equal(t, "SELECT order_id, amount FROM table", query) } func TestStorage_SelectStmt_backticks(t *testing.T) { @@ -334,13 +335,13 @@ func TestStorage_SelectStmt_backticks(t *testing.T) { OrderID int `db:"order_id"` Amount int `db:"amount"` }{}).ToSql() - assert.NoError(t, err) - assert.Equal(t, query, "SELECT `order_id`, `amount` FROM `table`") + require.NoError(t, err) + assert.Equal(t, "SELECT `order_id`, `amount` FROM `table`", query) } func TestStorage_DB(t *testing.T) { db, _, err := sqlmock.New() - assert.NoError(t, err) + require.NoError(t, err) dbx := sqlx.NewDb(db, "test") st := sqluct.NewStorage(dbx) @@ -352,12 +353,12 @@ func TestStmt_ToSql(t *testing.T) { s, a, err := sqluct.Stmt("SELECT * FROM foo WHERE id=? AND name=?", 1, "bar").ToSql() assert.Equal(t, "SELECT * FROM foo WHERE id=? AND name=?", s) assert.Equal(t, []interface{}{1, "bar"}, a) - assert.NoError(t, err) + require.NoError(t, err) } func TestPlain_ToSql(t *testing.T) { s, a, err := sqluct.Plain("SELECT * FROM foo WHERE id=1 AND name='bar'").ToSql() assert.Equal(t, "SELECT * FROM foo WHERE id=1 AND name='bar'", s) assert.Nil(t, a) - assert.NoError(t, err) + require.NoError(t, err) }