Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
- name: Run golangci-lint
uses: golangci/golangci-lint-action@v9
with:
version: v2.6.1
version: v2.13.2

- name: Run tests
run: go test -race -v ./...
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ jobs:
- name: Lint
uses: golangci/golangci-lint-action@v9
with:
version: v2.6.1
version: v2.13.2

- name: Full release validation
run: bash scripts/test-all.sh
Expand Down
3 changes: 2 additions & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ linters:
- gocyclo
- godot
- godox
- gomodguard
- gomodguard_v2
- goprintffuncname
- gosec
- importas
Expand Down Expand Up @@ -75,6 +75,7 @@ linters:
- err113
- errcheck
- funlen
- goconst
- gochecknoglobals
- gocyclo
- gosec
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,16 @@ this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
- JWT assertion callbacks use `assertjson` types instead of `github.com/golang-jwt/jwt/v5`.
- Module dependencies (`github.com/gofrs/uuid/v5`, `github.com/stretchr/testify`,
`golang.org/x/net`) and minimum Go version (`1.26`).
- CI and local lint use golangci-lint `v2.13.2` (`gomodguard_v2`, test exclusions for
`goconst`).

### Removed

- Direct dependency on `github.com/golang-jwt/jwt/v5`.
- Deprecated `assertjson` APIs: legacy `AssertNode` helpers (`EqualToTheString`,
`IsNumberGreaterThan`, and similar), `Nodef` / `Atf`, UUID chain aliases
(`Nil`, `Version`, …), and JSON Pointer strings passed as a single path
argument to `Node` / `At`.

## [0.11.0] - 2026-02-07

Expand Down
14 changes: 7 additions & 7 deletions EXAMPLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -272,22 +272,22 @@ assertjson.IsJWT(t, rawJWTString, keyFunc).WithPayload(func(json *assertjson.Ass
```go
// Пакетная функция (аналог Has для одного JSON)
assertjson.LinesHas(t, body, func(lines *assertjson.AssertJSONLines) {
lines.At(0).Node("id").EqualToTheInteger(1)
lines.At(0).Node("name").EqualToTheString("Alice")
lines.At(1).Node("id").EqualToTheInteger(2)
lines.At(1).Node("role").EqualToTheString("admin")
lines.At(0).Node("id").IsInteger().EqualTo(1)
lines.At(0).Node("name").IsString().EqualTo("Alice")
lines.At(1).Node("id").IsInteger().EqualTo(2)
lines.At(1).Node("role").IsString().EqualTo("admin")
lines.WithLength(2)
})

// Метод на результате Lines
assertjson.Lines(t, body).Has(func(lines *assertjson.AssertJSONLines) {
lines.At(0).Node("event").EqualToTheString("created")
lines.At(1).Node("event").EqualToTheString("updated")
lines.At(0).Node("event").IsString().EqualTo("created")
lines.At(1).Node("event").IsString().EqualTo("updated")
})

// Файл
assertjson.FileLinesHas(t, "events.ndjson", func(lines *assertjson.AssertJSONLines) {
lines.At(0).Node("event").EqualToTheString("created")
lines.At(0).Node("event").IsString().EqualTo("created")
})
```

Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func TestYourAPI(t *testing.T) {

## `assertjson` package

The `assertjson` package provides fluent assertions for JSON values. Nodes are selected via [JSON Pointer](https://tools.ietf.org/html/rfc6901) or path elements. Supports strings, numbers, arrays, objects, UUID, email, URL, time, and JWT.
The `assertjson` package provides fluent assertions for JSON values. Nodes are selected by path elements passed to `Node` and `At`. Supports strings, numbers, arrays, objects, UUID, email, URL, time, and JWT.

### Example

Expand Down Expand Up @@ -105,9 +105,9 @@ func TestYourAPI(t *testing.T) {

```go
assertjson.LinesHas(t, body, func(lines *assertjson.AssertJSONLines) {
lines.At(0).Node("id").EqualToTheInteger(1)
lines.At(0).Node("name").EqualToTheString("Alice")
lines.At(1).Node("role").EqualToTheString("admin")
lines.At(0).Node("id").IsInteger().EqualTo(1)
lines.At(0).Node("name").IsString().EqualTo("Alice")
lines.At(1).Node("role").IsString().EqualTo("admin")
lines.WithLength(2)
})
```
Expand Down
8 changes: 0 additions & 8 deletions assertjson/array.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,6 @@ import (
"github.com/stretchr/testify/assert"
)

// IsArrayWithElementsCount asserts that the JSON node is an array with given elements count.
//
// Deprecated: use IsArray().WithLength() instead.
func (node *AssertNode) IsArrayWithElementsCount(count int, msgAndArgs ...interface{}) {
node.t.Helper()
node.IsArray().WithLength(count, msgAndArgs...)
}

// IsArray asserts that the JSON node is an array.
// It returns ArrayAssertion to execute a chain of assertions for the node value.
func (node *AssertNode) IsArray(msgAndArgs ...interface{}) *ArrayAssertion {
Expand Down
60 changes: 1 addition & 59 deletions assertjson/assertjson.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
// Package assertjson provides methods for testing JSON values.
// Selecting JSON values provided by JSON Pointer Syntax (https://tools.ietf.org/html/rfc6901).
// Nodes are selected by path elements passed to Node and At.
package assertjson

import (
"encoding/json"
"fmt"
"os"
"strconv"
"strings"

jsoniter "github.com/json-iterator/go"
"github.com/muonsoft/api-testing/internal/js"
Expand Down Expand Up @@ -78,15 +76,6 @@ func (j *AssertJSON) Node(path ...interface{}) *AssertNode {
return node
}

// Nodef searches for JSON node by JSON Path Syntax. Returns struct for asserting the node values.
// It calculates path by applying fmt.Sprintf function.
//
// Deprecated: use Node() with multiple arguments.
func (j *AssertJSON) Nodef(format string, a ...interface{}) *AssertNode {
j.t.Helper()
return j.Node(fmt.Sprintf(format, a...))
}

// At is used to test assertions on some node in a batch. It returns AssertJSON object on that node.
func (j *AssertJSON) At(path ...interface{}) *AssertJSON {
j.t.Helper()
Expand All @@ -107,15 +96,6 @@ func (j *AssertJSON) At(path ...interface{}) *AssertJSON {
return a
}

// Atf is used to test assertions on some node in a batch. It returns AssertJSON object on that node.
// It calculates path by applying fmt.Sprintf function.
//
// Deprecated: use At() with multiple arguments.
func (j *AssertJSON) Atf(format string, a ...interface{}) *AssertJSON {
j.t.Helper()
return j.At(fmt.Sprintf(format, a...))
}

func (j *AssertJSON) assert(data []byte, jsonAssert JSONAssertFunc) {
j.t.Helper()
err := json.Unmarshal(data, &j.data)
Expand All @@ -132,11 +112,6 @@ func (j *AssertJSON) fail(message string, msgAndArgs ...interface{}) {
}

func preprocessPath(path []interface{}) []interface{} {
// deprecated behaviour: should be removed
if jsonpath, ok := isJSONPointer(path); ok {
path = pathFromJSONPointer(jsonpath)
}

for i := range path {
if s, ok := path[i].(fmt.Stringer); ok {
path[i] = s.String()
Expand All @@ -146,33 +121,6 @@ func preprocessPath(path []interface{}) []interface{} {
return path
}

func isJSONPointer(path []interface{}) (string, bool) {
if len(path) != 1 {
return "", false
}
if jsonpath, ok := path[0].(string); ok && (strings.HasPrefix(jsonpath, "/") || jsonpath == "") {
return jsonpath, true
}

return "", false
}

// Deprecated: should be removed in future versions.
func pathFromJSONPointer(p string) []interface{} {
elements := strings.Split(p, "/")
path := make([]interface{}, 0, len(elements)-1)

for i := 1; i < len(elements); i++ {
if index, err := strconv.Atoi(elements[i]); err == nil {
path = append(path, index)
} else {
path = append(path, decodeReferenceToken(elements[i]))
}
}

return path
}

func getValueByPath(data interface{}, path ...interface{}) (interface{}, error) {
v := jsoniter.Wrap(data)
for _, e := range path {
Expand All @@ -190,9 +138,3 @@ func getValueByPath(data interface{}, path ...interface{}) (interface{}, error)

return v.GetInterface(), nil
}

func decodeReferenceToken(token string) string {
step1 := strings.ReplaceAll(token, `~1`, `/`)
step2 := strings.ReplaceAll(step1, `~0`, `~`)
return step2
}
Loading