swaggest / rest

Web services with OpenAPI and JSON Schema done quick in Go
https://pkg.go.dev/github.com/swaggest/rest
MIT License
362 stars 17 forks source link

Add request loader interface for manual decoding, update CI and deps #65

Closed vearutop closed 2 years ago

github-actions[bot] commented 2 years ago

Lines Of Code

Language Files Lines Code Comments Blanks Complexity Bytes
Go 96 6332 (+11) 4582 (+6) 438 (+3) 1312 (+2) 712 (+1) 154.8K (+290B)
Go (test) 43 4352 (+37) 3336 (+27) 132 884 (+10) 118 121.2K (+1K)
Markdown 3 400 (+3) 309 (+3) 0 91 0 13.5K (+299B)
YAML 10 673 (+3) 590 (+3) 46 37 0 20.9K (+77B)
github-actions[bot] commented 2 years ago

Unit Test Coverage

total: (statements) 82.8%

Coverage diff with base branch ```diff 161c161 < total: (statements) 82.7% --- > total: (statements) 82.8% ```
github-actions[bot] commented 2 years ago

Go API Changes

# github.com/swaggest/rest/request
## compatible changes
Loader: added

# summary
Inferred base version: v0.2.23
Suggested version: v0.3.0
github-actions[bot] commented 2 years ago

Benchmark Result

Benchmark diff with base branch ``` name old time/op new time/op delta pkg:github.com/swaggest/rest/jsonschema goos:linux goarch:amd64 RequestValidator_ValidateRequestData-2 1.31µs ± 5% 1.28µs ± 0% -2.52% (p=0.016 n=5+4) pkg:github.com/swaggest/rest/request goos:linux goarch:amd64 Decoder_Decode-2 682ns ± 1% 692ns ± 6% ~ (p=0.651 n=5+5) DecoderFunc_Decode-2 2.01µs ± 7% 2.00µs ± 1% ~ (p=0.690 n=5+5) Decoder_Decode_json-2 21.9µs ± 1% 22.1µs ± 2% ~ (p=0.151 n=5+5) Decoder_Decode_queryObject-2 4.73µs ± 1% 4.76µs ± 0% +0.70% (p=0.032 n=5+5) Decoder_Decode_jsonParam-2 1.77µs ± 0% 1.77µs ± 0% ~ (p=0.325 n=5+5) DecoderFactory_SetDecoderFunc-2 1.62µs ± 0% 1.63µs ± 0% ~ (p=0.214 n=5+5) pkg:github.com/swaggest/rest/response/gzip goos:linux goarch:amd64 Middleware-2 11.1µs ± 1% 11.1µs ± 1% ~ (p=0.690 n=5+5) Middleware_control-2 3.14µs ± 0% 3.16µs ± 2% ~ (p=0.730 n=4+5) name old alloc/op new alloc/op delta pkg:github.com/swaggest/rest/jsonschema goos:linux goarch:amd64 RequestValidator_ValidateRequestData-2 2.46kB ± 0% 2.46kB ± 0% ~ (all equal) pkg:github.com/swaggest/rest/request goos:linux goarch:amd64 Decoder_Decode-2 440B ± 0% 440B ± 0% ~ (all equal) DecoderFunc_Decode-2 1.51kB ± 0% 1.51kB ± 0% ~ (all equal) Decoder_Decode_json-2 12.2kB ± 0% 12.2kB ± 0% ~ (all equal) Decoder_Decode_queryObject-2 2.00kB ± 0% 2.00kB ± 0% ~ (all equal) Decoder_Decode_jsonParam-2 736B ± 0% 736B ± 0% ~ (all equal) DecoderFactory_SetDecoderFunc-2 1.02kB ± 0% 1.02kB ± 0% ~ (all equal) pkg:github.com/swaggest/rest/response/gzip goos:linux goarch:amd64 Middleware-2 1.18kB ± 6% 1.15kB ± 2% ~ (p=0.421 n=5+5) Middleware_control-2 11.2kB ± 0% 11.2kB ± 0% ~ (all equal) name old allocs/op new allocs/op delta pkg:github.com/swaggest/rest/jsonschema goos:linux goarch:amd64 RequestValidator_ValidateRequestData-2 8.00 ± 0% 8.00 ± 0% ~ (all equal) pkg:github.com/swaggest/rest/request goos:linux goarch:amd64 Decoder_Decode-2 4.00 ± 0% 4.00 ± 0% ~ (all equal) DecoderFunc_Decode-2 12.0 ± 0% 12.0 ± 0% ~ (all equal) Decoder_Decode_json-2 177 ± 0% 177 ± 0% ~ (all equal) Decoder_Decode_queryObject-2 36.0 ± 0% 36.0 ± 0% ~ (all equal) Decoder_Decode_jsonParam-2 13.0 ± 0% 13.0 ± 0% ~ (all equal) DecoderFactory_SetDecoderFunc-2 16.0 ± 0% 16.0 ± 0% ~ (all equal) pkg:github.com/swaggest/rest/response/gzip goos:linux goarch:amd64 Middleware-2 11.0 ± 0% 11.0 ± 0% ~ (all equal) Middleware_control-2 9.00 ± 0% 9.00 ± 0% ~ (all equal) ```
Benchmark result ``` name time/op pkg:github.com/swaggest/rest/jsonschema goos:linux goarch:amd64 RequestValidator_ValidateRequestData-2 1.28µs ± 0% pkg:github.com/swaggest/rest/request goos:linux goarch:amd64 Decoder_Decode-2 692ns ± 6% DecoderFunc_Decode-2 2.00µs ± 1% Decoder_Decode_json-2 22.1µs ± 2% Decoder_Decode_queryObject-2 4.76µs ± 0% Decoder_Decode_jsonParam-2 1.77µs ± 0% DecoderFactory_SetDecoderFunc-2 1.63µs ± 0% pkg:github.com/swaggest/rest/response/gzip goos:linux goarch:amd64 Middleware-2 11.1µs ± 1% Middleware_control-2 3.16µs ± 2% name alloc/op pkg:github.com/swaggest/rest/jsonschema goos:linux goarch:amd64 RequestValidator_ValidateRequestData-2 2.46kB ± 0% pkg:github.com/swaggest/rest/request goos:linux goarch:amd64 Decoder_Decode-2 440B ± 0% DecoderFunc_Decode-2 1.51kB ± 0% Decoder_Decode_json-2 12.2kB ± 0% Decoder_Decode_queryObject-2 2.00kB ± 0% Decoder_Decode_jsonParam-2 736B ± 0% DecoderFactory_SetDecoderFunc-2 1.02kB ± 0% pkg:github.com/swaggest/rest/response/gzip goos:linux goarch:amd64 Middleware-2 1.15kB ± 2% Middleware_control-2 11.2kB ± 0% name allocs/op pkg:github.com/swaggest/rest/jsonschema goos:linux goarch:amd64 RequestValidator_ValidateRequestData-2 8.00 ± 0% pkg:github.com/swaggest/rest/request goos:linux goarch:amd64 Decoder_Decode-2 4.00 ± 0% DecoderFunc_Decode-2 12.0 ± 0% Decoder_Decode_json-2 177 ± 0% Decoder_Decode_queryObject-2 36.0 ± 0% Decoder_Decode_jsonParam-2 13.0 ± 0% DecoderFactory_SetDecoderFunc-2 16.0 ± 0% pkg:github.com/swaggest/rest/response/gzip goos:linux goarch:amd64 Middleware-2 11.0 ± 0% Middleware_control-2 9.00 ± 0% ```
codecov[bot] commented 2 years ago

Codecov Report

Merging #65 (65279d9) into master (a0cbf55) will increase coverage by 0.03%. The diff coverage is 100.00%.

:exclamation: Current head 65279d9 differs from pull request most recent head 80bdfd3. Consider uploading reports for the commit 80bdfd3 to get more accurate results

@@            Coverage Diff             @@
##           master      #65      +/-   ##
==========================================
+ Coverage   76.72%   76.76%   +0.03%     
==========================================
  Files          27       27              
  Lines        1319     1321       +2     
==========================================
+ Hits         1012     1014       +2     
  Misses        194      194              
  Partials      113      113              
Flag Coverage Δ
unittests 76.76% <100.00%> (+0.03%) :arrow_up:

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
request/decoder.go 72.97% <100.00%> (+1.54%) :arrow_up:

:mega: Codecov can now indicate which changes are the most critical in Pull Requests. Learn more

github-actions[bot] commented 2 years ago

Examples Benchmark Result

Benchmark diff with base branch ``` name old time/op new time/op delta pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64 _directGzip-2 22.3µs ± 1% 23.4µs ±16% ~ (p=0.548 n=5+5) _directGzipHead-2 23.7µs ±14% 22.2µs ± 2% -6.08% (p=0.032 n=5+5) _noDirectGzip-2 137µs ± 2% 136µs ± 1% ~ (p=1.000 n=5+5) _directGzip_decode-2 457µs ± 6% 463µs ±10% ~ (p=0.841 n=5+5) _noDirectGzip_decode-2 137µs ± 3% 138µs ± 2% ~ (p=0.421 n=5+5) _jsonBody-2 40.3µs ± 2% 39.9µs ± 3% ~ (p=0.548 n=5+5) _jsonBodyValidation-2 45.3µs ± 2% 45.8µs ± 2% ~ (p=0.222 n=5+5) _outputHeaders-2 22.1µs ± 4% 22.2µs ± 6% ~ (p=1.000 n=5+5) _requestResponseMapping-2 38.8µs ± 2% 39.6µs ± 3% ~ (p=0.310 n=5+5) _validation-2 41.9µs ± 4% 42.6µs ± 3% ~ (p=0.421 n=5+5) _noValidation-2 28.3µs ± 1% 28.7µs ± 2% ~ (p=0.151 n=5+5) pkg:github.com/swaggest/rest/_examples/advanced-generic goos:linux goarch:amd64 _directGzip-2 22.5µs ± 2% 22.7µs ± 1% ~ (p=0.730 n=5+4) _directGzipHead-2 23.5µs ±13% 22.8µs ± 0% ~ (p=1.000 n=5+5) _noDirectGzip-2 138µs ± 2% 137µs ± 1% ~ (p=0.310 n=5+5) _directGzip_decode-2 441µs ± 2% 442µs ± 2% ~ (p=0.690 n=5+5) _noDirectGzip_decode-2 137µs ± 1% 138µs ± 3% ~ (p=0.421 n=5+5) _jsonBody-2 40.2µs ± 3% 40.4µs ± 1% ~ (p=0.690 n=5+5) _jsonBodyValidation-2 45.0µs ± 3% 45.3µs ± 3% ~ (p=0.690 n=5+5) _outputHeaders-2 22.1µs ± 2% 21.9µs ± 3% ~ (p=0.421 n=5+5) _requestResponseMapping-2 38.9µs ± 3% 39.3µs ± 2% ~ (p=0.310 n=5+5) _validation-2 41.5µs ± 3% 42.8µs ± 3% ~ (p=0.056 n=5+5) _noValidation-2 41.4µs ± 2% 42.3µs ± 1% +2.17% (p=0.008 n=5+5) pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64 _notFoundSrv-2 26.4µs ± 1% 26.2µs ± 2% ~ (p=0.421 n=5+5) _ok-2 26.4µs ± 2% 26.8µs ± 1% ~ (p=0.095 n=5+5) _invalidBody-2 36.8µs ± 3% 36.8µs ± 2% ~ (p=0.841 n=5+5) name old B:rcvd/op new B:rcvd/op delta pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64 _directGzip-2 639 ± 0% 639 ± 0% ~ (all equal) _directGzipHead-2 183 ± 0% 183 ± 0% ~ (all equal) _noDirectGzip-2 1.04k ± 0% 1.04k ± 0% ~ (all equal) _directGzip_decode-2 639 ± 0% 639 ± 0% ~ (all equal) _noDirectGzip_decode-2 1.04k ± 0% 1.04k ± 0% ~ (all equal) _jsonBody-2 208 ± 0% 208 ± 0% ~ (all equal) _jsonBodyValidation-2 194 ± 0% 194 ± 0% ~ (all equal) _outputHeaders-2 155 ± 0% 155 ± 0% ~ (all equal) _requestResponseMapping-2 94.0 ± 0% 94.0 ± 0% ~ (all equal) _validation-2 177 ± 0% 177 ± 0% ~ (all equal) _noValidation-2 177 ± 0% 177 ± 0% ~ (all equal) pkg:github.com/swaggest/rest/_examples/advanced-generic goos:linux goarch:amd64 _directGzip-2 639 ± 0% 639 ± 0% ~ (all equal) _directGzipHead-2 183 ± 0% 183 ± 0% ~ (all equal) _noDirectGzip-2 1.04k ± 0% 1.04k ± 0% ~ (all equal) _directGzip_decode-2 639 ± 0% 639 ± 0% ~ (all equal) _noDirectGzip_decode-2 1.04k ± 0% 1.04k ± 0% ~ (all equal) _jsonBody-2 208 ± 0% 208 ± 0% ~ (all equal) _jsonBodyValidation-2 194 ± 0% 194 ± 0% ~ (all equal) _outputHeaders-2 155 ± 0% 155 ± 0% ~ (all equal) _requestResponseMapping-2 94.0 ± 0% 94.0 ± 0% ~ (all equal) _validation-2 177 ± 0% 177 ± 0% ~ (all equal) _noValidation-2 177 ± 0% 177 ± 0% ~ (all equal) pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64 _notFoundSrv-2 337 ± 0% 337 ± 0% ~ (all equal) _ok-2 359 ± 0% 359 ± 0% ~ (all equal) _invalidBody-2 435 ± 0% 435 ± 0% ~ (all equal) name old B:sent/op new B:sent/op delta pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64 _directGzip-2 103 ± 0% 103 ± 0% ~ (all equal) _directGzipHead-2 104 ± 0% 104 ± 0% ~ (all equal) _noDirectGzip-2 117 ± 0% 117 ± 0% ~ (all equal) _directGzip_decode-2 116 ± 0% 116 ± 0% ~ (all equal) _noDirectGzip_decode-2 130 ± 0% 130 ± 0% ~ (all equal) _jsonBody-2 188 ± 0% 188 ± 0% ~ (all equal) _jsonBodyValidation-2 192 ± 0% 192 ± 0% ~ (all equal) _outputHeaders-2 77.0 ± 0% 77.0 ± 0% ~ (all equal) _requestResponseMapping-2 169 ± 0% 169 ± 0% ~ (all equal) _validation-2 170 ± 0% 170 ± 0% ~ (all equal) _noValidation-2 173 ± 0% 173 ± 0% ~ (all equal) pkg:github.com/swaggest/rest/_examples/advanced-generic goos:linux goarch:amd64 _directGzip-2 103 ± 0% 103 ± 0% ~ (all equal) _directGzipHead-2 104 ± 0% 104 ± 0% ~ (all equal) _noDirectGzip-2 117 ± 0% 117 ± 0% ~ (all equal) _directGzip_decode-2 116 ± 0% 116 ± 0% ~ (all equal) _noDirectGzip_decode-2 130 ± 0% 130 ± 0% ~ (all equal) _jsonBody-2 188 ± 0% 188 ± 0% ~ (all equal) _jsonBodyValidation-2 192 ± 0% 192 ± 0% ~ (all equal) _outputHeaders-2 77.0 ± 0% 77.0 ± 0% ~ (all equal) _requestResponseMapping-2 169 ± 0% 169 ± 0% ~ (all equal) _validation-2 170 ± 0% 170 ± 0% ~ (all equal) _noValidation-2 173 ± 0% 173 ± 0% ~ (all equal) pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64 _notFoundSrv-2 74.0 ± 0% 74.0 ± 0% ~ (all equal) _ok-2 74.0 ± 0% 74.0 ± 0% ~ (all equal) _invalidBody-2 137 ± 0% 137 ± 0% ~ (all equal) name old rps new rps delta pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64 _directGzip-2 44.7k ± 1% 42.9k ±14% ~ (p=0.548 n=5+5) _directGzipHead-2 42.4k ±13% 45.0k ± 2% +6.05% (p=0.032 n=5+5) _noDirectGzip-2 7.32k ± 2% 7.33k ± 1% ~ (p=1.000 n=5+5) _directGzip_decode-2 2.19k ± 6% 2.17k ± 9% ~ (p=0.841 n=5+5) _noDirectGzip_decode-2 7.32k ± 3% 7.23k ± 2% ~ (p=0.421 n=5+5) _jsonBody-2 24.8k ± 2% 25.0k ± 3% ~ (p=0.595 n=5+5) _jsonBodyValidation-2 22.1k ± 2% 21.9k ± 2% ~ (p=0.222 n=5+5) _outputHeaders-2 45.2k ± 3% 45.1k ± 6% ~ (p=1.000 n=5+5) _requestResponseMapping-2 25.8k ± 2% 25.2k ± 3% ~ (p=0.310 n=5+5) _validation-2 23.9k ± 4% 23.5k ± 3% ~ (p=0.421 n=5+5) _noValidation-2 35.3k ± 1% 34.9k ± 2% ~ (p=0.151 n=5+5) pkg:github.com/swaggest/rest/_examples/advanced-generic goos:linux goarch:amd64 _directGzip-2 44.3k ± 2% 44.1k ± 1% ~ (p=0.730 n=5+4) _directGzipHead-2 42.8k ±12% 43.9k ± 0% ~ (p=1.000 n=5+5) _noDirectGzip-2 7.25k ± 2% 7.32k ± 1% ~ (p=0.310 n=5+5) _directGzip_decode-2 2.27k ± 2% 2.26k ± 2% ~ (p=0.690 n=5+5) _noDirectGzip_decode-2 7.31k ± 1% 7.25k ± 3% ~ (p=0.421 n=5+5) _jsonBody-2 24.9k ± 3% 24.7k ± 1% ~ (p=0.690 n=5+5) _jsonBodyValidation-2 22.2k ± 3% 22.1k ± 3% ~ (p=0.690 n=5+5) _outputHeaders-2 45.3k ± 2% 45.6k ± 3% ~ (p=0.421 n=5+5) _requestResponseMapping-2 25.7k ± 3% 25.4k ± 2% ~ (p=0.310 n=5+5) _validation-2 24.1k ± 3% 23.4k ± 3% ~ (p=0.056 n=5+5) _noValidation-2 24.1k ± 2% 23.6k ± 1% -2.13% (p=0.008 n=5+5) pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64 _notFoundSrv-2 37.9k ± 1% 38.2k ± 2% ~ (p=0.421 n=5+5) _ok-2 37.9k ± 2% 37.3k ± 1% ~ (p=0.095 n=5+5) _invalidBody-2 27.2k ± 3% 27.2k ± 2% ~ (p=0.841 n=5+5) name old alloc/op new alloc/op delta pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64 _directGzip-2 3.92kB ± 0% 3.92kB ± 0% ~ (p=1.000 n=5+5) _directGzipHead-2 3.92kB ± 0% 3.92kB ± 0% ~ (p=1.000 n=5+5) _noDirectGzip-2 6.04kB ±20% 6.57kB ±19% ~ (p=0.421 n=5+5) _directGzip_decode-2 402kB ± 0% 402kB ± 0% ~ (p=0.310 n=5+5) _noDirectGzip_decode-2 5.33kB ± 8% 5.53kB ± 7% ~ (p=0.310 n=5+5) _jsonBody-2 13.2kB ± 0% 13.2kB ± 0% ~ (p=0.984 n=5+5) _jsonBodyValidation-2 19.0kB ± 0% 19.0kB ± 0% ~ (p=0.071 n=5+5) _outputHeaders-2 3.70kB ± 0% 3.71kB ± 0% ~ (p=1.000 n=5+5) _requestResponseMapping-2 16.6kB ± 0% 16.6kB ± 0% ~ (p=0.286 n=5+5) _validation-2 16.5kB ± 0% 16.5kB ± 0% ~ (p=0.198 n=5+5) _noValidation-2 6.13kB ± 0% 6.13kB ± 0% ~ (p=0.651 n=5+5) pkg:github.com/swaggest/rest/_examples/advanced-generic goos:linux goarch:amd64 _directGzip-2 3.94kB ± 0% 3.93kB ± 0% -0.03% (p=0.048 n=5+5) _directGzipHead-2 3.93kB ± 0% 3.93kB ± 0% ~ (p=0.103 n=5+5) _noDirectGzip-2 6.17kB ±17% 6.23kB ±17% ~ (p=1.000 n=5+5) _directGzip_decode-2 402kB ± 0% 402kB ± 0% ~ (p=0.548 n=5+5) _noDirectGzip_decode-2 5.43kB ±15% 5.05kB ± 6% ~ (p=0.151 n=5+5) _jsonBody-2 13.3kB ± 0% 13.3kB ± 0% ~ (p=0.643 n=5+5) _jsonBodyValidation-2 19.0kB ± 0% 19.0kB ± 0% ~ (p=0.746 n=5+5) _outputHeaders-2 3.71kB ± 0% 3.71kB ± 0% ~ (p=0.143 n=4+4) _requestResponseMapping-2 16.7kB ± 0% 16.7kB ± 0% ~ (p=0.175 n=5+5) _validation-2 16.6kB ± 0% 16.6kB ± 0% ~ (p=0.865 n=5+5) _noValidation-2 16.6kB ± 0% 16.6kB ± 0% ~ (p=0.683 n=5+5) pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64 _notFoundSrv-2 4.88kB ± 0% 4.88kB ± 0% ~ (p=1.000 n=5+5) _ok-2 4.78kB ± 0% 4.78kB ± 0% ~ (p=0.413 n=5+4) _invalidBody-2 8.67kB ± 0% 8.67kB ± 0% ~ (p=0.543 n=4+4) name old allocs/op new allocs/op delta pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64 _directGzip-2 42.0 ± 0% 42.0 ± 0% ~ (all equal) _directGzipHead-2 42.0 ± 0% 42.0 ± 0% ~ (all equal) _noDirectGzip-2 49.6 ± 3% 49.6 ± 3% ~ (p=1.000 n=5+5) _directGzip_decode-2 500 ± 0% 500 ± 0% ~ (all equal) _noDirectGzip_decode-2 50.0 ± 0% 50.0 ± 0% ~ (all equal) _jsonBody-2 127 ± 0% 127 ± 0% ~ (all equal) _jsonBodyValidation-2 183 ± 0% 183 ± 0% ~ (all equal) _outputHeaders-2 37.0 ± 0% 37.0 ± 0% ~ (all equal) _requestResponseMapping-2 123 ± 0% 123 ± 0% ~ (all equal) _validation-2 152 ± 0% 152 ± 0% ~ (all equal) _noValidation-2 72.0 ± 0% 72.0 ± 0% ~ (all equal) pkg:github.com/swaggest/rest/_examples/advanced-generic goos:linux goarch:amd64 _directGzip-2 43.0 ± 0% 43.0 ± 0% ~ (all equal) _directGzipHead-2 43.0 ± 0% 43.0 ± 0% ~ (all equal) _noDirectGzip-2 50.6 ± 3% 50.4 ± 3% ~ (p=1.000 n=5+5) _directGzip_decode-2 501 ± 0% 501 ± 0% ~ (p=0.444 n=5+5) _noDirectGzip_decode-2 51.0 ± 0% 51.0 ± 0% ~ (all equal) _jsonBody-2 128 ± 0% 128 ± 0% ~ (all equal) _jsonBodyValidation-2 184 ± 0% 184 ± 0% ~ (all equal) _outputHeaders-2 37.0 ± 0% 37.0 ± 0% ~ (all equal) _requestResponseMapping-2 124 ± 0% 124 ± 0% ~ (all equal) _validation-2 153 ± 0% 153 ± 0% ~ (all equal) _noValidation-2 153 ± 0% 153 ± 0% ~ (all equal) pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64 _notFoundSrv-2 54.0 ± 0% 54.0 ± 0% ~ (all equal) _ok-2 50.0 ± 0% 50.0 ± 0% ~ (all equal) _invalidBody-2 100 ± 0% 100 ± 0% ~ (all equal) ```