diff --git a/README.md b/README.md
index 2c02887..ed10699 100644
--- a/README.md
+++ b/README.md
@@ -474,6 +474,14 @@ See also template [`file_xml2json`](#file_xml2json-path).
On that json you can work as you are used to with the json syntax. For seeing how the converted json looks you can use the `--log-verbose` command line flag
+## HTML Data comparison
+
+If the response format is specified as `"type": "html"`, we internally marshal that HTML into json using [github.com/PuerkitoBio/goquery](https://github.com/PuerkitoBio/goquery).
+
+This marshalling is less strict than for [XHTML](#file_xhtml2json-path). For example it will not raise errors for unclosed tags like `
` or `
`, as well as Javascript code inside the HTML code. But it is possible that unclosed tags are missing in the resulting JSON if the tokenizer can not find a matching closing tag.
+
+See also template [`file_html2json`](#file_html2json-path).
+
## XHTML Data comparison
If the response format is specified as `"type": "xhtml"`, we internally marshal that XHTML into json using [github.com/clbanning/mxj](https://github.com/clbanning/mxj).
@@ -1855,6 +1863,102 @@ would result in
}
```
+## `file_html2json [path]`
+
+Helper function to parse an HTML file and convert it into json
+- `@path`: string; a path to the HTML file that should be loaded. The path is either relative to the manifest or a weburl
+
+This marshalling is less strict than for [XHTML](#file_xhtml2json-path). For example it will not raise errors for unclosed tags like `` or `
`, as well as Javascript code inside the HTML code. But it is possible that unclosed tags are missing in the resulting JSON if the [goquery](https://github.com/PuerkitoBio/goquery) tokenizer can not find a matching closing tag.
+
+### Example
+
+Content of HTML file `some/path/example.html`:
+
+```html
+
+
+
+
+
+ fylr
+
+
+
+
+
+
+
Register
+
+
* Mandatory fields
+
Form has errors
+
+
+
+
+
+
+```
+
+The call
+
+```django
+{{ file_html2json "some/path/example.html" }}
+```
+
+would result in
+
+```json
+{
+ "html": {
+ "-lang": "en",
+ "head": {
+ "meta": [
+ {
+ "-charset": "utf-8"
+ },
+ {
+ "-content": "fylr - manage your data",
+ "-name": "description"
+ }
+ ],
+ "title": {
+ "#text": "fylr"
+ },
+ "script": {
+ "#text": "function onInputHandler(event) {\n\t\t\t\tconst form = event.currentTarget;\n\t\t\t\tsubmitForm(form);\n\t\t\t}"
+ }
+ },
+ "body": {
+ "div": {
+ "-class": "container",
+ "h1": {
+ "#text": "Register"
+ },
+ "p": [
+ {
+ "-class": "required-information",
+ "sup": {
+ "#text": "*"
+ },
+ "br": {}
+ },
+ {
+ "#text": "Form has errors",
+ "-class": "error-summary"
+ }
+ ],
+ "hr": {}
+ }
+ }
+ }
+}
+```
+
## `file_xhtml2json [path]`
Helper function to parse an XHTML file and convert it into json
@@ -1865,6 +1969,7 @@ Helper function to parse an XHTML file and convert it into json
Content of XHTML file `some/path/example.xhtml`:
```html
+
diff --git a/api_testcase.go b/api_testcase.go
index af9814f..46dfbc0 100644
--- a/api_testcase.go
+++ b/api_testcase.go
@@ -23,20 +23,20 @@ import (
// Case defines the structure of our single testcase
// It gets read in by our config reader at the moment the mainfest.json gets parsed
type Case struct {
- Name string `json:"name"`
- Description string `json:"description"`
- RequestData *interface{} `json:"request"`
- ResponseData interface{} `json:"response"`
- ContinueOnFailure bool `json:"continue_on_failure"`
- Store map[string]interface{} `json:"store"` // init datastore before testrun
- StoreResponse map[string]string `json:"store_response_qjson"` // store qjson parsed response in datastore
-
- Timeout int `json:"timeout_ms"`
- WaitBefore *int `json:"wait_before_ms"`
- WaitAfter *int `json:"wait_after_ms"`
- Delay *int `json:"delay_ms"`
- BreakResponse []interface{} `json:"break_response"`
- CollectResponse interface{} `json:"collect_response"`
+ Name string `json:"name"`
+ Description string `json:"description"`
+ RequestData *any `json:"request"`
+ ResponseData any `json:"response"`
+ ContinueOnFailure bool `json:"continue_on_failure"`
+ Store map[string]any `json:"store"` // init datastore before testrun
+ StoreResponse map[string]string `json:"store_response_qjson"` // store qjson parsed response in datastore
+
+ Timeout int `json:"timeout_ms"`
+ WaitBefore *int `json:"wait_before_ms"`
+ WaitAfter *int `json:"wait_after_ms"`
+ Delay *int `json:"delay_ms"`
+ BreakResponse []any `json:"break_response"`
+ CollectResponse any `json:"collect_response"`
LogNetwork *bool `json:"log_network"`
LogVerbose *bool `json:"log_verbose"`
@@ -543,7 +543,7 @@ func (testCase Case) loadRequestSerialization() (api.Request, error) {
return spec, nil
}
-func (testCase Case) loadResponseSerialization(genJSON interface{}) (spec api.ResponseSerialization, err error) {
+func (testCase Case) loadResponseSerialization(genJSON any) (spec api.ResponseSerialization, err error) {
resLoader := testCase.loader
_, responseData, err := template.LoadManifestDataAsObject(genJSON, testCase.manifestDir, resLoader)
if err != nil {
diff --git a/api_testsuite.go b/api_testsuite.go
index 70095b0..4c52182 100644
--- a/api_testsuite.go
+++ b/api_testsuite.go
@@ -32,8 +32,8 @@ type Suite struct {
Testmode bool `json:"testmode"`
Proxy httpproxy.ProxyConfig `json:"proxy"`
} `json:"http_server,omitempty"`
- Tests []interface{} `json:"tests"`
- Store map[string]interface{} `json:"store"`
+ Tests []any `json:"tests"`
+ Store map[string]any `json:"store"`
StandardHeader map[string]*string `yaml:"header" json:"header"`
StandardHeaderFromStore map[string]string `yaml:"header_from_store" json:"header_from_store"`
@@ -213,7 +213,7 @@ type TestContainer struct {
Path string
}
-func (ats *Suite) parseAndRunTest(v interface{}, manifestDir, testFilePath string, k, repeatNTimes int, runParallel bool, r *report.ReportElement, rootLoader template.Loader) bool {
+func (ats *Suite) parseAndRunTest(v any, manifestDir, testFilePath string, k, repeatNTimes int, runParallel bool, r *report.ReportElement, rootLoader template.Loader) bool {
//Init variables
// logrus.Warnf("Test %s, Prev delimiters: %#v", testFilePath, rootLoader.Delimiters)
loader := template.NewLoader(ats.datastore)
diff --git a/config.go b/config.go
index 13a00a4..3687d63 100644
--- a/config.go
+++ b/config.go
@@ -17,8 +17,8 @@ import (
type ConfigStruct struct {
Apitest struct {
- Server string `mapstructure:"server"`
- StoreInit map[string]interface{} `mapstructure:"store"`
+ Server string `mapstructure:"server"`
+ StoreInit map[string]any `mapstructure:"store"`
Limit struct {
Request int `mapstructure:"request"`
Response int `mapstructure:"response"`
diff --git a/go.mod b/go.mod
index eff9000..722e347 100644
--- a/go.mod
+++ b/go.mod
@@ -1,72 +1,68 @@
module github.com/programmfabrik/apitest
-go 1.18
+go 1.20
require (
- github.com/Masterminds/sprig/v3 v3.2.2
+ github.com/Masterminds/sprig/v3 v3.2.3
+ github.com/PuerkitoBio/goquery v1.8.1
github.com/clbanning/mxj v1.8.4
- github.com/mattn/go-sqlite3 v1.14.12
+ github.com/mattn/go-sqlite3 v1.14.17
github.com/moul/http2curl v1.0.0
github.com/pkg/errors v0.9.1
github.com/programmfabrik/go-test-utils v0.0.0-20191114143449-b8e16b04adb1
- github.com/programmfabrik/golib v0.0.0-20220506120914-94c5900ef991
- github.com/sergi/go-diff v1.2.0
- github.com/sirupsen/logrus v1.8.1
- github.com/spf13/afero v1.8.2
- github.com/spf13/cobra v1.4.0
- github.com/spf13/viper v1.11.0
- github.com/stretchr/testify v1.7.1
- github.com/tidwall/gjson v1.14.1
+ github.com/programmfabrik/golib v0.0.0-20230614100546-9870ba66917d
+ github.com/sergi/go-diff v1.3.1
+ github.com/sirupsen/logrus v1.9.3
+ github.com/spf13/afero v1.9.5
+ github.com/spf13/cobra v1.7.0
+ github.com/spf13/viper v1.16.0
+ github.com/stretchr/testify v1.8.4
+ github.com/tidwall/gjson v1.14.4
github.com/tidwall/jsonc v0.3.2
- golang.org/x/mod v0.5.1
- golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5
+ golang.org/x/mod v0.12.0
+ golang.org/x/net v0.11.0
+ golang.org/x/oauth2 v0.9.0
)
require (
github.com/Masterminds/goutils v1.1.1 // indirect
- github.com/Masterminds/semver/v3 v3.1.1 // indirect
- github.com/antchfx/xmlquery v1.3.10 // indirect
- github.com/antchfx/xpath v1.2.0 // indirect
+ github.com/Masterminds/semver/v3 v3.2.1 // indirect
+ github.com/andybalholm/cascadia v1.3.2 // indirect
+ github.com/antchfx/xmlquery v1.3.17 // indirect
+ github.com/antchfx/xpath v1.2.4 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
- github.com/fsnotify/fsnotify v1.5.4 // indirect
- github.com/gabriel-vasile/mimetype v1.4.0 // indirect
- github.com/gofrs/uuid v4.2.0+incompatible // indirect
+ github.com/fsnotify/fsnotify v1.6.0 // indirect
+ github.com/gabriel-vasile/mimetype v1.4.2 // indirect
+ github.com/gofrs/uuid v4.4.0+incompatible // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
- github.com/golang/protobuf v1.5.2 // indirect
+ github.com/golang/protobuf v1.5.3 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
- github.com/huandu/xstrings v1.3.2 // indirect
- github.com/imdario/mergo v0.3.12 // indirect
- github.com/inconshreveable/mousetrap v1.0.0 // indirect
+ github.com/huandu/xstrings v1.4.0 // indirect
+ github.com/imdario/mergo v0.3.16 // indirect
+ github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/logrusorgru/aurora v2.0.3+incompatible // indirect
- github.com/magiconair/properties v1.8.6 // indirect
- github.com/mattn/go-colorable v0.1.12 // indirect
- github.com/mattn/go-isatty v0.0.14 // indirect
+ github.com/magiconair/properties v1.8.7 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
- github.com/pelletier/go-toml v1.9.5 // indirect
- github.com/pelletier/go-toml/v2 v2.0.0 // indirect
+ github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
- github.com/smartystreets/goconvey v1.7.2 // indirect
- github.com/spf13/cast v1.4.1 // indirect
+ github.com/smartystreets/goconvey v1.8.1 // indirect
+ github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
- github.com/subosito/gotenv v1.2.0 // indirect
+ github.com/subosito/gotenv v1.4.2 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
- github.com/yudai/pp v2.0.1+incompatible // indirect
- github.com/yuin/goldmark v1.4.12 // indirect
- golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122 // indirect
- golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 // indirect
- golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 // indirect
- golang.org/x/text v0.3.7 // indirect
+ github.com/yuin/goldmark v1.4.13 // indirect
+ golang.org/x/crypto v0.10.0 // indirect
+ golang.org/x/sys v0.9.0 // indirect
+ golang.org/x/text v0.10.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
- google.golang.org/protobuf v1.28.0 // indirect
- gopkg.in/ini.v1 v1.66.4 // indirect
- gopkg.in/yaml.v2 v2.4.0 // indirect
- gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
- moul.io/http2curl v1.0.0 // indirect
+ google.golang.org/protobuf v1.30.0 // indirect
+ gopkg.in/ini.v1 v1.67.0 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff --git a/go.sum b/go.sum
index fd6f5b7..7128482 100644
--- a/go.sum
+++ b/go.sum
@@ -40,14 +40,20 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
-github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
-github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
-github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8=
-github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
-github.com/antchfx/xmlquery v1.3.10 h1:U2yMwr8U0KmGM2iDG2Ky/3LfxNsiK4uw1bSBkeMO9+g=
-github.com/antchfx/xmlquery v1.3.10/go.mod h1:wojC/BxjEkjJt6dPiAqUzoXO5nIMWtxHS8PD8TmN4ks=
-github.com/antchfx/xpath v1.2.0 h1:mbwv7co+x0RwgeGAOHdrKy89GvHaGvxxBtPK0uF9Zr8=
-github.com/antchfx/xpath v1.2.0/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
+github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
+github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
+github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
+github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
+github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
+github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM=
+github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ=
+github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
+github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=
+github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
+github.com/antchfx/xmlquery v1.3.17 h1:d0qWjPp/D+vtRw7ivCwT5ApH/3CkQU8JOeo3245PpTk=
+github.com/antchfx/xmlquery v1.3.17/go.mod h1:Afkq4JIeXut75taLSuI31ISJ/zeq+3jG7TunF7noreA=
+github.com/antchfx/xpath v1.2.4 h1:dW1HB/JxKvGtJ9WyVGJ0sIoEcqftV3SqIstujI+B9XY=
+github.com/antchfx/xpath v1.2.4/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
@@ -58,7 +64,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
-github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
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=
@@ -68,15 +74,16 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
-github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
-github.com/gabriel-vasile/mimetype v1.4.0 h1:Cn9dkdYsMIu56tGho+fqzh7XmvY2YyGU0FnbhiOsEro=
-github.com/gabriel-vasile/mimetype v1.4.0/go.mod h1:fA8fi6KUiG7MgQQ+mEWotXoEOvmxRtOJlERCzSmRvr8=
+github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
+github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
+github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
+github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
+github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
-github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0=
-github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
+github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
+github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -105,8 +112,8 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
-github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
-github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
+github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@@ -119,7 +126,7 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
+github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
@@ -141,45 +148,39 @@ github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
-github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
-github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
-github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
-github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw=
-github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
+github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
+github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
+github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
-github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
-github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
-github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
-github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
+github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
+github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
+github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
-github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
-github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8=
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
-github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
-github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
-github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
-github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
-github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
-github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
-github.com/mattn/go-sqlite3 v1.14.12 h1:TJ1bhYJPV44phC+IMu1u2K/i5RriLTPe+yc68XDJ1Z0=
-github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
+github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
+github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
+github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
+github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
@@ -190,10 +191,8 @@ github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zx
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/moul/http2curl v1.0.0 h1:dRMWoAtb+ePxMlLkrCbAqh4TlPHXvoGUSQ323/9Zahs=
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
-github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
-github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
-github.com/pelletier/go-toml/v2 v2.0.0 h1:P7Bq0SaI8nsexyay5UAyDo+ICWy5MQPgEZ5+l8JQTKo=
-github.com/pelletier/go-toml/v2 v2.0.0/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
+github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
+github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
@@ -201,60 +200,63 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/programmfabrik/go-test-utils v0.0.0-20191114143449-b8e16b04adb1 h1:NbjvVAvjVfIse7/zgFpP0P93Hj3o4lRJCzGgkNQ87Gc=
github.com/programmfabrik/go-test-utils v0.0.0-20191114143449-b8e16b04adb1/go.mod h1:6Tg7G+t9KYiFa0sU8PpISt9RUgIpgrEI+tXvWz3tSIU=
-github.com/programmfabrik/golib v0.0.0-20220506120914-94c5900ef991 h1:eO4XFHHF7F2FXMI9Mu+TbiUXCbu05Jcm1InFxV+LJgE=
-github.com/programmfabrik/golib v0.0.0-20220506120914-94c5900ef991/go.mod h1:jIJCXINJJ5LJagQBGn393Mxh+A8sKEwqJ+UZm+MQJHA=
+github.com/programmfabrik/golib v0.0.0-20230614100546-9870ba66917d h1:4sunXbhS/Y9XdhmsPL20w9C5E1o7qxfRXvSvsW/SO8A=
+github.com/programmfabrik/golib v0.0.0-20230614100546-9870ba66917d/go.mod h1:jIJCXINJJ5LJagQBGn393Mxh+A8sKEwqJ+UZm+MQJHA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
-github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
+github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
+github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
-github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
-github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
-github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
-github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
-github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg=
-github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM=
-github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo=
-github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
+github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
+github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY=
+github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY=
+github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60=
+github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
+github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
-github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA=
-github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
-github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q=
-github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
+github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
+github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48=
+github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
+github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-github.com/spf13/viper v1.11.0 h1:7OX/1FS6n7jHD1zGrZTM7WtY13ZELRyosK4k93oPr44=
-github.com/spf13/viper v1.11.0/go.mod h1:djo0X/bA5+tYVoCn+C7cAYJGcVn/qYLFTG8gdUsX7Zk=
+github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc=
+github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
-github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
-github.com/tidwall/gjson v1.14.1 h1:iymTbGkQBhveq21bEvAQ81I0LEBork8BFe1CUZXdyuo=
-github.com/tidwall/gjson v1.14.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
+github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
+github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
+github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/jsonc v0.3.2 h1:ZTKrmejRlAJYdn0kcaFqRAKlxxFIC21pYq8vLa4p2Wc=
github.com/tidwall/jsonc v0.3.2/go.mod h1:dw+3CIxqHi+t8eFSpzzMlcVYxKp08UP5CD8/uSFCyJE=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
-github.com/yudai/pp v2.0.1+incompatible h1:Q4//iY4pNF6yPLZIigmvcl7k/bPgrcTPIFIcmawg5bI=
-github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.4.12 h1:6hffw6vALvEDqJ19dOJvJKOoAOKe4NDaTqvd2sktGN0=
-github.com/yuin/goldmark v1.4.12/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
@@ -265,12 +267,13 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
-golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122 h1:NvGWuYG8dkDHFSKksI1P9faiVJ9rayE6l0+ouWVIDs8=
-golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
+golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
+golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -304,8 +307,10 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
-golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
+golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -331,17 +336,21 @@ golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA=
-golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
+golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
+golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -351,8 +360,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE=
-golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
+golang.org/x/oauth2 v0.9.0 h1:BPpt2kU7oMRq3kCHAA1tbSEshXRw1LpG2ztgDwrzuAs=
+golang.org/x/oauth2 v0.9.0/go.mod h1:qYgFZaFiu6Wg24azG8bdV52QJXJGbZzIIsRCdVKzbLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -363,6 +372,8 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -373,7 +384,6 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -399,14 +409,20 @@ golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 h1:nonptSpoQ4vQjyraW20DXPAglgQfVnM9ZC6MmNLMR60=
-golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
+golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -414,8 +430,12 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
+golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -425,7 +445,6 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
@@ -467,11 +486,12 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
@@ -563,23 +583,21 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
-google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
+google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
-gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4=
-gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
+gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@@ -587,8 +605,6 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-moul.io/http2curl v1.0.0 h1:6XwpyZOYsgZJrU8exnG87ncVkU1FVCcTRpwzOkTDUi8=
-moul.io/http2curl v1.0.0/go.mod h1:f6cULg+e4Md/oW1cYmwW4IWQOVl2lGbmCNGOHvzX2kE=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
diff --git a/http_server.go b/http_server.go
index 5badfa9..e80d95f 100644
--- a/http_server.go
+++ b/http_server.go
@@ -12,6 +12,7 @@ import (
"unicode/utf8"
"github.com/programmfabrik/apitest/internal/httpproxy"
+ "github.com/programmfabrik/golib"
"github.com/sirupsen/logrus"
)
@@ -110,17 +111,17 @@ func (ats *Suite) StopHttpServer() {
}
type ErrorResponse struct {
- Error string `json:"error"`
- Body interface{} `json:"body,omitempty"`
+ Error string `json:"error"`
+ Body any `json:"body,omitempty"`
}
-func errorResponse(w http.ResponseWriter, statuscode int, err error, body interface{}) {
+func errorResponse(w http.ResponseWriter, statuscode int, err error, body any) {
resp := ErrorResponse{
Error: err.Error(),
Body: body,
}
- b, err2 := json.MarshalIndent(resp, "", " ")
+ b, err2 := golib.JsonBytesIndent(resp, "", " ")
if err2 != nil {
logrus.Debugf("Could not marshall error message %s: %s", err, err2)
http.Error(w, err2.Error(), 500)
@@ -132,17 +133,16 @@ func errorResponse(w http.ResponseWriter, statuscode int, err error, body interf
type BounceResponse struct {
Header http.Header `json:"header"`
QueryParams url.Values `json:"query_params"`
- Body interface{} `json:"body"`
+ Body any `json:"body"`
}
// bounceJSON builds a json response including the header, query params and body of the request
func bounceJSON(w http.ResponseWriter, r *http.Request) {
var (
- err error
- bodyBytes []byte
- bodyJSON interface{}
- errorBody interface{}
+ err error
+ bodyBytes []byte
+ bodyJSON, errorBody any
)
bodyBytes, err = ioutil.ReadAll(r.Body)
@@ -175,7 +175,7 @@ func bounceJSON(w http.ResponseWriter, r *http.Request) {
response.Body = bodyJSON
}
- responseData, err := json.MarshalIndent(response, "", " ")
+ responseData, err := golib.JsonBytesIndent(response, "", " ")
if err != nil {
errorResponse(w, 500, err, response)
return
diff --git a/pkg/lib/api/build_policies.go b/pkg/lib/api/build_policies.go
index 95bf378..d60d977 100644
--- a/pkg/lib/api/build_policies.go
+++ b/pkg/lib/api/build_policies.go
@@ -20,7 +20,7 @@ func buildMultipart(request Request) (additionalHeaders map[string]string, body
w := multipart.NewWriter(buf)
var replaceFilename *string
- val, ok := request.Body.(map[string]interface{})["file:filename"]
+ val, ok := request.Body.(map[string]any)["file:filename"]
if ok {
f, ok := val.(util.JsonString)
if !ok {
@@ -30,7 +30,7 @@ func buildMultipart(request Request) (additionalHeaders map[string]string, body
}
additionalHeaders["Content-Type"] = w.FormDataContentType()
- for key, val := range request.Body.(map[string]interface{}) {
+ for key, val := range request.Body.(map[string]any) {
if key == "file:filename" {
continue
@@ -75,7 +75,7 @@ func buildUrlencoded(request Request) (additionalHeaders map[string]string, body
additionalHeaders = make(map[string]string, 0)
additionalHeaders["Content-Type"] = "application/x-www-form-urlencoded"
formParams := url.Values{}
- for key, value := range request.Body.(map[string]interface{}) {
+ for key, value := range request.Body.(map[string]any) {
switch v := value.(type) {
case string:
formParams.Set(key, v)
diff --git a/pkg/lib/api/build_policies_test.go b/pkg/lib/api/build_policies_test.go
index d86ca5f..be94ef7 100644
--- a/pkg/lib/api/build_policies_test.go
+++ b/pkg/lib/api/build_policies_test.go
@@ -20,7 +20,7 @@ func TestBuildMultipart(t *testing.T) {
afero.WriteFile(filesystem.Fs, fmt.Sprintf("test/%s", assertFilename), []byte(assertContent), 0644)
testRequest := Request{
- Body: map[string]interface{}{
+ Body: map[string]any{
"somekey": fmt.Sprintf("@%s", assertFilename),
},
ManifestDir: "test/",
@@ -43,7 +43,7 @@ func TestBuildMultipart(t *testing.T) {
func TestBuildMultipart_ErrPathSpec(t *testing.T) {
testRequest := Request{
- Body: map[string]interface{}{
+ Body: map[string]any{
"somekey": fmt.Sprintf("noPathspec"),
},
ManifestDir: "test/path/",
@@ -60,7 +60,7 @@ func TestBuildMultipart_ErrPathSpec(t *testing.T) {
func TestBuildMultipart_ErrPathSpecNoString(t *testing.T) {
testRequest := Request{
- Body: map[string]interface{}{
+ Body: map[string]any{
"somekey": 1,
},
ManifestDir: "test/path/",
@@ -77,7 +77,7 @@ func TestBuildMultipart_ErrPathSpecNoString(t *testing.T) {
func TestBuildMultipart_FileDoesNotExist(t *testing.T) {
testRequest := Request{
- Body: map[string]interface{}{
+ Body: map[string]any{
"somekey": "@does_not_exist.json",
},
ManifestDir: "test/path/",
diff --git a/pkg/lib/api/pre_process.go b/pkg/lib/api/pre_process.go
index 5e76c56..c31bd1d 100644
--- a/pkg/lib/api/pre_process.go
+++ b/pkg/lib/api/pre_process.go
@@ -2,11 +2,12 @@ package api
import (
"bytes"
- "encoding/json"
"fmt"
"os/exec"
"strconv"
"strings"
+
+ "github.com/programmfabrik/golib"
)
type CmdOutputType string
@@ -79,7 +80,7 @@ func (proc *PreProcess) RunPreProcess(response Response) (Response, error) {
case CmdOutputStderr:
response.Body = stderrBytes
case CmdOutputStdout:
- response.Body, err2 = json.MarshalIndent(preProcessError{
+ response.Body, err2 = golib.JsonBytesIndent(preProcessError{
Command: strings.Join(cmd.Args, " "),
Error: err.Error(),
ExitCode: exitCode,
diff --git a/pkg/lib/api/request.go b/pkg/lib/api/request.go
index d0984d0..e3055f0 100755
--- a/pkg/lib/api/request.go
+++ b/pkg/lib/api/request.go
@@ -47,7 +47,7 @@ type Request struct {
ServerURL string `yaml:"server_url" json:"server_url"`
Method string `yaml:"method" json:"method"`
NoRedirect bool `yaml:"no_redirect" json:"no_redirect"`
- QueryParams map[string]interface{} `yaml:"query_params" json:"query_params"`
+ QueryParams map[string]any `yaml:"query_params" json:"query_params"`
QueryParamsFromStore map[string]string `yaml:"query_params_from_store" json:"query_params_from_store"`
Headers map[string]*string `yaml:"header" json:"header"`
HeaderFromStore map[string]string `yaml:"header_from_store" json:"header_from_store"`
@@ -55,7 +55,7 @@ type Request struct {
SetCookies []*Cookie `yaml:"header-x-test-set-cookie" json:"header-x-test-set-cookie"`
BodyType string `yaml:"body_type" json:"body_type"`
BodyFile string `yaml:"body_file" json:"body_file"`
- Body interface{} `yaml:"body" json:"body"`
+ Body any `yaml:"body" json:"body"`
buildPolicy func(Request) (additionalHeaders map[string]string, body io.Reader, err error)
ManifestDir string
@@ -175,7 +175,7 @@ func (request Request) buildHttpRequest() (req *http.Request, err error) {
return nil, fmt.Errorf("could not get '%s' from Datastore: %s", datastoreKey, err)
}
- ownHeaders, ok := headersInt.([]interface{})
+ ownHeaders, ok := headersInt.([]any)
if ok {
for _, val := range ownHeaders {
valString, ok := val.(string)
@@ -296,7 +296,7 @@ func (request Request) ToString(curl bool) (res string) {
cString := curl.String()
rep := ""
- for key, val := range request.Body.(map[string]interface{}) {
+ for key, val := range request.Body.(map[string]any) {
pathSpec, ok := val.(util.JsonString)
if !ok {
panic(fmt.Errorf("pathSpec should be a string"))
diff --git a/pkg/lib/api/request_test.go b/pkg/lib/api/request_test.go
index cd03af9..8381647 100755
--- a/pkg/lib/api/request_test.go
+++ b/pkg/lib/api/request_test.go
@@ -17,7 +17,7 @@ func TestRequestBuildHttp(t *testing.T) {
request := Request{
Endpoint: "endpoint",
Method: "DO!",
- QueryParams: map[string]interface{}{
+ QueryParams: map[string]any{
"query_param": "value",
},
ServerURL: "serverUrl",
@@ -45,7 +45,7 @@ func TestBuildCurl(t *testing.T) {
request := Request{
Endpoint: "endpoint",
Method: "GET",
- QueryParams: map[string]interface{}{
+ QueryParams: map[string]any{
"query_param": "value",
},
ServerURL: "https://serverUrl",
diff --git a/pkg/lib/api/response.go b/pkg/lib/api/response.go
index 0aa8306..43d8fea 100755
--- a/pkg/lib/api/response.go
+++ b/pkg/lib/api/response.go
@@ -17,6 +17,7 @@ import (
"github.com/programmfabrik/apitest/pkg/lib/csv"
"github.com/programmfabrik/apitest/pkg/lib/util"
+ "github.com/programmfabrik/golib"
)
type Response struct {
@@ -76,14 +77,14 @@ type ResponseSerialization struct {
Headers map[string]any `yaml:"header" json:"header,omitempty"`
HeaderControl util.JsonObject `yaml:"header:control" json:"header:control,omitempty"`
Cookies map[string]Cookie `yaml:"cookie" json:"cookie,omitempty"`
- Body interface{} `yaml:"body" json:"body,omitempty"`
+ Body any `yaml:"body" json:"body,omitempty"`
BodyControl util.JsonObject `yaml:"body:control" json:"body:control,omitempty"`
Format ResponseFormat `yaml:"format" json:"format,omitempty"`
}
type ResponseFormat struct {
IgnoreBody bool `json:"-"` // if true, do not try to parse the body (since it is not expected in the response)
- Type string `json:"type"` // default "json", allowed: "csv", "json", "xml", "xml2", "xhtml", "binary"
+ Type string `json:"type"` // default "json", allowed: "csv", "json", "xml", "xml2", "html", "xhtml", "binary"
CSV struct {
Comma string `json:"comma,omitempty"`
} `json:"csv,omitempty"`
@@ -147,9 +148,9 @@ func NewResponseFromSpec(spec ResponseSerialization) (res Response, err error) {
}
// ServerResponseToGenericJSON parse response from server. convert xml, csv, binary to json if necessary
-func (response Response) ServerResponseToGenericJSON(responseFormat ResponseFormat, bodyOnly bool) (interface{}, error) {
+func (response Response) ServerResponseToGenericJSON(responseFormat ResponseFormat, bodyOnly bool) (any, error) {
var (
- res, bodyJSON interface{}
+ res, bodyJSON any
bodyData []byte
err error
resp Response
@@ -170,6 +171,11 @@ func (response Response) ServerResponseToGenericJSON(responseFormat ResponseForm
if err != nil {
return res, errors.Wrap(err, "Could not marshal xml to json")
}
+ case "html":
+ bodyData, err = util.Html2Json(resp.Body)
+ if err != nil {
+ return res, errors.Wrap(err, "Could not marshal html to json")
+ }
case "xhtml":
bodyData, err = util.Xhtml2Json(resp.Body)
if err != nil {
@@ -263,9 +269,9 @@ func (response Response) ServerResponseToGenericJSON(responseFormat ResponseForm
}
// ToGenericJSON parse expected response
-func (response Response) ToGenericJSON() (interface{}, error) {
+func (response Response) ToGenericJSON() (any, error) {
var (
- bodyJSON, res interface{}
+ bodyJSON, res any
err error
)
@@ -328,14 +334,14 @@ func (response Response) ServerResponseToJsonString(bodyOnly bool) (string, erro
if err != nil {
return "", fmt.Errorf("error formatting response: %s", err)
}
- bytes, err := json.MarshalIndent(genericJSON, "", " ")
+ bytes, err := golib.JsonBytesIndent(genericJSON, "", " ")
if err != nil {
return "", fmt.Errorf("error formatting response: %s", err)
}
return string(bytes), nil
}
-func (response *Response) marshalBodyInto(target interface{}) (err error) {
+func (response *Response) marshalBodyInto(target any) (err error) {
bodyBytes := response.Body
if len(bodyBytes) > 0 {
if err = json.Unmarshal(bodyBytes, target); err != nil {
@@ -381,7 +387,7 @@ func (response Response) ToString() string {
body := resp.Body
switch resp.Format.Type {
- case "xml", "xml2", "csv", "xhtml":
+ case "xml", "xml2", "csv", "html", "xhtml":
if utf8.Valid(body) {
bodyString, err = resp.ServerResponseToJsonString(true)
if err != nil {
diff --git a/pkg/lib/api/response_test.go b/pkg/lib/api/response_test.go
index 7c78492..4c0fd07 100644
--- a/pkg/lib/api/response_test.go
+++ b/pkg/lib/api/response_test.go
@@ -22,7 +22,7 @@ func TestResponse_ToGenericJson(t *testing.T) {
genericJson, err := response.ToGenericJSON()
go_test_utils.ExpectNoError(t, err, "error calling response.ToGenericJson")
- jsonObjResp, ok := genericJson.(map[string]interface{})
+ jsonObjResp, ok := genericJson.(map[string]any)
if !ok {
t.Fatalf("responseJson should be object")
}
@@ -37,11 +37,11 @@ func TestResponse_ToGenericJson(t *testing.T) {
if !ok {
t.Fatalf("responseJsonObj should have headers")
}
- headersMap, ok := jsonHeaders.(map[string]interface{})
+ headersMap, ok := jsonHeaders.(map[string]any)
if !ok {
t.Fatalf("headers should be map")
}
- if headersMap["foo"].([]interface{})[0].(string) != "bar" {
+ if headersMap["foo"].([]any)[0].(string) != "bar" {
t.Errorf("expected foo header to be bar")
}
}
diff --git a/pkg/lib/compare/comparer.go b/pkg/lib/compare/comparer.go
index 1449166..1ee7fd8 100644
--- a/pkg/lib/compare/comparer.go
+++ b/pkg/lib/compare/comparer.go
@@ -24,7 +24,7 @@ func (f CompareFailure) Error() string {
return f.String()
}
-func JsonEqual(left, right interface{}, control ComparisonContext) (res CompareResult, err error) {
+func JsonEqual(left, right any, control ComparisonContext) (res CompareResult, err error) {
//left may be nil, because we dont specify the content of the field
if left == nil && right == nil {
diff --git a/pkg/lib/compare/comparer_test.go b/pkg/lib/compare/comparer_test.go
index 6d6244c..350054d 100644
--- a/pkg/lib/compare/comparer_test.go
+++ b/pkg/lib/compare/comparer_test.go
@@ -370,7 +370,7 @@ var trivialComparerTestData = []struct {
}
func TestTrivialJsonComparer(t *testing.T) {
- var json1, json2 interface{}
+ var json1, json2 any
for _, td := range trivialComparerTestData {
t.Run(td.name, func(t *testing.T) {
util.Unmarshal([]byte(td.want), &json1)
diff --git a/pkg/lib/compare/comparison_functions.go b/pkg/lib/compare/comparison_functions.go
index 678f0ee..40ef7bf 100755
--- a/pkg/lib/compare/comparison_functions.go
+++ b/pkg/lib/compare/comparison_functions.go
@@ -9,6 +9,7 @@ import (
"github.com/pkg/errors"
"github.com/programmfabrik/apitest/pkg/lib/util"
+ "github.com/programmfabrik/golib"
)
type ComparisonContext struct {
@@ -249,7 +250,7 @@ func objectComparison(left, right util.JsonObject, noExtra bool) (res CompareRes
if takenInLeft[ck] {
continue
}
- var rv, lv interface{}
+ var rv, lv any
var rOK, lOK bool
control := &ComparisonContext{}
var k string
@@ -368,11 +369,11 @@ func arrayComparison(left, right util.JsonArray, currControl ComparisonContext,
if len(left) > len(right) {
res.Equal = false
- leftJson, err := json.MarshalIndent(left, "", " ")
+ leftJson, err := golib.JsonBytesIndent(left, "", " ")
if err != nil {
return CompareResult{}, errors.Wrap(err, "Could not marshal expected array")
}
- rightJson, err := json.MarshalIndent(right, "", " ")
+ rightJson, err := golib.JsonBytesIndent(right, "", " ")
if err != nil {
return CompareResult{}, errors.Wrap(err, "Could not marshal actual array")
}
@@ -506,7 +507,7 @@ func ArrayEqualWithControl(left, right util.JsonArray, control ComparisonContext
return arrayComparison(left, right, control, nextControl)
}
-func keyChecks(lk string, right interface{}, rOK bool, control ComparisonContext) (err error) {
+func keyChecks(lk string, right any, rOK bool, control ComparisonContext) (err error) {
if control.isString {
if right == nil {
return fmt.Errorf("== nil but should exist")
@@ -683,7 +684,7 @@ func keyChecks(lk string, right interface{}, rOK bool, control ComparisonContext
return nil
}
-func getJsonType(value interface{}) string {
+func getJsonType(value any) string {
switch value.(type) {
case util.JsonObject:
return "Object"
@@ -700,7 +701,7 @@ func getJsonType(value interface{}) string {
}
}
-func getAsInt64(value interface{}) (int64, error) {
+func getAsInt64(value any) (int64, error) {
switch t := value.(type) {
case int64:
return t, nil
diff --git a/pkg/lib/csv/csv.go b/pkg/lib/csv/csv.go
index 22f1308..a3a723a 100644
--- a/pkg/lib/csv/csv.go
+++ b/pkg/lib/csv/csv.go
@@ -18,7 +18,7 @@ type info struct {
format string
}
-func CSVToMap(inputCSV []byte, comma rune) ([]map[string]interface{}, error) {
+func CSVToMap(inputCSV []byte, comma rune) ([]map[string]any, error) {
if len(inputCSV) == 0 {
return nil, fmt.Errorf("The given input csv was empty")
}
@@ -35,11 +35,11 @@ func CSVToMap(inputCSV []byte, comma rune) ([]map[string]interface{}, error) {
return nil, err
}
- output := []map[string]interface{}{}
+ output := []map[string]any{}
//Iterate over the records with skipping the first two lines (as they contain the infos)
for _, v := range records[2:] {
- tmpRow := make(map[string]interface{}, 0)
+ tmpRow := make(map[string]any, 0)
for ki, vi := range v {
if ki >= len(infos) || infos[ki].format == "SKIP_COLUMN" {
@@ -74,7 +74,7 @@ func CSVToMap(inputCSV []byte, comma rune) ([]map[string]interface{}, error) {
}
-func GenericCSVToMap(inputCSV []byte, comma rune) ([]map[string]interface{}, error) {
+func GenericCSVToMap(inputCSV []byte, comma rune) ([]map[string]any, error) {
if len(inputCSV) == 0 {
return nil, fmt.Errorf("The given input csv was empty")
}
@@ -89,11 +89,11 @@ func GenericCSVToMap(inputCSV []byte, comma rune) ([]map[string]interface{}, err
infos = append(infos, info{name: strings.TrimSpace(v)})
}
- output := []map[string]interface{}{}
+ output := []map[string]any{}
//Iterate over the records with skipping the first two lines (as they contain the infos)
for _, v := range records[1:] {
- tmpRow := make(map[string]interface{}, 0)
+ tmpRow := make(map[string]any, 0)
for ki, vi := range v {
if ki >= len(infos) {
@@ -189,7 +189,7 @@ func isValidFormat(format string) bool {
}
// getTyped
-func getTyped(value, format string) (interface{}, error) {
+func getTyped(value, format string) (any, error) {
switch format {
case "string":
@@ -318,7 +318,7 @@ func getTyped(value, format string) (interface{}, error) {
if value == "" {
return nil, nil
}
- var data interface{}
+ var data any
err := json.Unmarshal([]byte(value), &data)
if err != nil {
return nil, fmt.Errorf("file_csv: Error in JSON: \"%s\": %s", value, err)
diff --git a/pkg/lib/datastore/datastore.go b/pkg/lib/datastore/datastore.go
index dedd2de..f00b16c 100755
--- a/pkg/lib/datastore/datastore.go
+++ b/pkg/lib/datastore/datastore.go
@@ -13,15 +13,15 @@ import (
)
type Datastore struct {
- storage map[string]interface{} // custom storage
- responseJson []string // store the responses
+ storage map[string]any // custom storage
+ responseJson []string // store the responses
logDatastore bool
lock *sync.Mutex
}
func NewStore(logDatastore bool) *Datastore {
ds := Datastore{}
- ds.storage = make(map[string]interface{}, 0)
+ ds.storage = make(map[string]any, 0)
ds.responseJson = make([]string, 0)
ds.logDatastore = logDatastore
ds.lock = &sync.Mutex{}
@@ -92,7 +92,7 @@ func (ds *Datastore) AppendResponse(s string) {
ds.responseJson = append(ds.responseJson, s)
}
-func (ds *Datastore) SetMap(smap map[string]interface{}) error {
+func (ds *Datastore) SetMap(smap map[string]any) error {
for k, v := range smap {
err := ds.Set(k, v)
if err != nil {
@@ -102,7 +102,7 @@ func (ds *Datastore) SetMap(smap map[string]interface{}) error {
return nil
}
-func (ds *Datastore) Set(index string, value interface{}) error {
+func (ds *Datastore) Set(index string, value any) error {
var dsMapRegex = regexp.MustCompile(`^(.*?)\[(.+?)\]$`)
//typeswitch for checking if float is actually int
@@ -123,14 +123,14 @@ func (ds *Datastore) Set(index string, value interface{}) error {
use_index := index[:len(index)-2]
_, ok := ds.storage[use_index]
if !ok {
- ds.storage[use_index] = make([]interface{}, 0)
+ ds.storage[use_index] = make([]any, 0)
}
- s, ok := ds.storage[use_index].([]interface{})
+ s, ok := ds.storage[use_index].([]any)
if !ok {
tmp := ds.storage[use_index]
- ds.storage[use_index] = make([]interface{}, 0)
- s = ds.storage[use_index].([]interface{})
+ ds.storage[use_index] = make([]any, 0)
+ s = ds.storage[use_index].([]any)
if tmp != nil {
ds.storage[use_index] = append(s, tmp)
@@ -144,13 +144,13 @@ func (ds *Datastore) Set(index string, value interface{}) error {
use_index := rego[1]
_, ok := ds.storage[use_index]
if !ok {
- ds.storage[use_index] = make(map[string]interface{}, 0)
+ ds.storage[use_index] = make(map[string]any, 0)
}
- s, ok := ds.storage[use_index].(map[string]interface{})
+ s, ok := ds.storage[use_index].(map[string]any)
if !ok {
- ds.storage[use_index] = make(map[string]interface{}, 0)
- s = ds.storage[use_index].(map[string]interface{})
+ ds.storage[use_index] = make(map[string]any, 0)
+ s = ds.storage[use_index].(map[string]any)
}
s[rego[2]] = value
ds.storage[use_index] = s
@@ -166,7 +166,7 @@ func (ds *Datastore) Set(index string, value interface{}) error {
return nil
}
-func (ds Datastore) Get(index string) (res interface{}, err error) {
+func (ds Datastore) Get(index string) (res any, err error) {
// strings are evalulated as int, so
// that we can support "-" notations
@@ -188,7 +188,7 @@ func (ds Datastore) Get(index string) (res interface{}, err error) {
return "", DatastoreKeyNotFoundError{error: fmt.Sprintf("datastore: key: %s not found.", useIndex)}
}
- tmpResMap, ok := tmpRes.(map[string]interface{})
+ tmpResMap, ok := tmpRes.(map[string]any)
if ok {
//We have a map
mapVal, ok := tmpResMap[mapIndex]
@@ -200,7 +200,7 @@ func (ds Datastore) Get(index string) (res interface{}, err error) {
}
}
- tmpResSlice, ok := tmpRes.([]interface{})
+ tmpResSlice, ok := tmpRes.([]any)
if ok {
//We have a slice
sliceIdx, err := strconv.Atoi(mapIndex)
diff --git a/pkg/lib/datastore/datastore_test.go b/pkg/lib/datastore/datastore_test.go
index 2bb0ec2..272984f 100644
--- a/pkg/lib/datastore/datastore_test.go
+++ b/pkg/lib/datastore/datastore_test.go
@@ -3,7 +3,7 @@ package datastore
import (
"testing"
- "github.com/programmfabrik/go-test-utils"
+ go_test_utils "github.com/programmfabrik/go-test-utils"
)
func TestDataStore_Get(t *testing.T) {
@@ -101,12 +101,12 @@ func TestDataStore_MAP(t *testing.T) {
t.Fatal(err)
}
- if tA.(map[string]interface{})["head1"] != 1 {
- t.Errorf("Have '%v' != '%d' Want", tA.(map[string]interface{})["head1"], 1)
+ if tA.(map[string]any)["head1"] != 1 {
+ t.Errorf("Have '%v' != '%d' Want", tA.(map[string]any)["head1"], 1)
}
- if tA.(map[string]interface{})["head3"] != 3 {
- t.Errorf("Have '%v' != '%d' Want", tA.(map[string]interface{})["head1"], 3)
+ if tA.(map[string]any)["head3"] != 3 {
+ t.Errorf("Have '%v' != '%d' Want", tA.(map[string]any)["head1"], 3)
}
}
diff --git a/pkg/lib/report/parsing_functions.go b/pkg/lib/report/parsing_functions.go
index b91d4e5..2cd885d 100755
--- a/pkg/lib/report/parsing_functions.go
+++ b/pkg/lib/report/parsing_functions.go
@@ -1,7 +1,6 @@
package report
import (
- "encoding/json"
"encoding/xml"
"fmt"
"os"
@@ -10,6 +9,8 @@ import (
"strconv"
"strings"
"time"
+
+ "github.com/programmfabrik/golib"
)
type XMLRoot struct {
@@ -89,7 +90,7 @@ func (groups statsGroups) getLowestRuntimeGroup() (group int) {
// ParseJSONResult Print the result to the console
func ParseJSONResult(baseResult *ReportElement) []byte {
- jsonResult, _ := json.MarshalIndent(baseResult, "", " ")
+ jsonResult, _ := golib.JsonBytesIndent(baseResult, "", " ")
return jsonResult
}
@@ -144,7 +145,7 @@ func ParseJSONStatsResult(baseResult *ReportElement) []byte {
stats.Groups[i].RuntimeStr = g.Runtime.String()
}
- jsonResult, _ := json.MarshalIndent(stats, "", " ")
+ jsonResult, _ := golib.JsonBytesIndent(stats, "", " ")
return jsonResult
}
diff --git a/pkg/lib/report/report.go b/pkg/lib/report/report.go
index 692e5f2..a8f072a 100755
--- a/pkg/lib/report/report.go
+++ b/pkg/lib/report/report.go
@@ -170,7 +170,7 @@ func (r *ReportElement) SaveToReportLog(v string) {
}
}
-func (r *ReportElement) SaveToReportLogF(v string, args ...interface{}) {
+func (r *ReportElement) SaveToReportLogF(v string, args ...any) {
r.m.Lock()
defer r.m.Unlock()
diff --git a/pkg/lib/report/report_test.go b/pkg/lib/report/report_test.go
index 8da692d..33cfd35 100644
--- a/pkg/lib/report/report_test.go
+++ b/pkg/lib/report/report_test.go
@@ -80,7 +80,7 @@ func TestReportGetJSONResult(t *testing.T) {
]
}`)
- var expJ, realJ interface{}
+ var expJ, realJ any
util.Unmarshal(jsonResult, &realJ)
util.Unmarshal(expResult, &expJ)
@@ -136,7 +136,7 @@ func TestReportGetJUnitResult(t *testing.T) {
expJBytes, _ := json.Marshal(expX)
realJBytes, _ := json.Marshal(realX)
- var expJ, realJ interface{}
+ var expJ, realJ any
util.Unmarshal(expJBytes, &expJ)
util.Unmarshal(realJBytes, &realJ)
diff --git a/pkg/lib/template/template_funcs.go b/pkg/lib/template/template_funcs.go
index e0426f0..1eb046c 100644
--- a/pkg/lib/template/template_funcs.go
+++ b/pkg/lib/template/template_funcs.go
@@ -20,7 +20,7 @@ func qjson(path string, json string) string {
}
// N returns a slice of n 0-sized elements, suitable for ranging over. (github.com/bradfitz)
-func N(n interface{}) ([]struct{}, error) {
+func N(n any) ([]struct{}, error) {
switch v := n.(type) {
case float64:
return make([]struct{}, int(v)), nil
@@ -34,8 +34,8 @@ func N(n interface{}) ([]struct{}, error) {
// rowsToMap creates a new map, maps "key" column of each to the "value" column of that row. #51482
// if "value" is empty "", the whole row is mapped
-func rowsToMap(keyCol, valCol string, rows []map[string]interface{}) (retMap map[string]interface{}, err error) {
- retMap = make(map[string]interface{})
+func rowsToMap(keyCol, valCol string, rows []map[string]any) (retMap map[string]any, err error) {
+ retMap = make(map[string]any)
//If there is no keyCol, return empty map
if keyCol == "" {
@@ -109,7 +109,7 @@ func pivotRows(key, typ string, rows []map[string]any) (sheet []map[string]any,
case "string":
sheetRow[sheetKey] = v
case "json":
- var i interface{}
+ var i any
err = json.Unmarshal([]byte(v), &i)
if err == nil {
sheetRow[sheetKey] = i
@@ -135,7 +135,7 @@ func pivotRows(key, typ string, rows []map[string]any) (sheet []map[string]any,
// functions copied from: https://github.com/hashicorp/consul-template/blob/de2ebf4/template_functions.go#L727-L901
// add returns the sum of a and b.
-func add(b, a interface{}) (interface{}, error) {
+func add(b, a any) (any, error) {
av := reflect.ValueOf(a)
bv := reflect.ValueOf(b)
@@ -189,7 +189,7 @@ func add(b, a interface{}) (interface{}, error) {
}
// subtract returns the difference of b from a.
-func subtract(b, a interface{}) (interface{}, error) {
+func subtract(b, a any) (any, error) {
av := reflect.ValueOf(a)
bv := reflect.ValueOf(b)
@@ -233,7 +233,7 @@ func subtract(b, a interface{}) (interface{}, error) {
}
// multiply returns the product of a and b.
-func multiply(b, a interface{}) (interface{}, error) {
+func multiply(b, a any) (any, error) {
av := reflect.ValueOf(a)
bv := reflect.ValueOf(b)
@@ -279,7 +279,7 @@ func multiply(b, a interface{}) (interface{}, error) {
// FROM https://github.com/hashicorp/consul-template/blob/de2ebf4/template_functions.go#L727-L901
// divide returns the division of b from a.
-func divide(b, a interface{}) (interface{}, error) {
+func divide(b, a any) (any, error) {
av := reflect.ValueOf(a)
bv := reflect.ValueOf(b)
@@ -337,13 +337,13 @@ func fileReadInternal(pathOrURL, rootDir string) ([]byte, error) {
// fileRender loads file from path and renders is as Go template passing
// the arguments as ".Param1", ".Param2" into the template.
-func loadFileAndRender(rootDir string, loader *Loader) interface{} {
- return func(path string, params ...interface{}) (st string, err error) {
+func loadFileAndRender(rootDir string, loader *Loader) any {
+ return func(path string, params ...any) (st string, err error) {
data, err := fileReadInternal(path, rootDir)
if err != nil {
return "", err
}
- tmplParams := map[string]interface{}{}
+ tmplParams := map[string]any{}
for idx, param := range params {
tmplParams["Param"+strconv.Itoa(idx+1)] = param
}
@@ -357,8 +357,8 @@ func loadFileAndRender(rootDir string, loader *Loader) interface{} {
// fileRender loads file from path and renders is as Go template passing
// the arguments as ".Param1", ".Param2" into the template.
-func loadFile(rootDir string, loader *Loader) interface{} {
- return func(path string, params ...interface{}) (st string, err error) {
+func loadFile(rootDir string, loader *Loader) any {
+ return func(path string, params ...any) (st string, err error) {
data, err := fileReadInternal(path, rootDir)
if err != nil {
return "", err
@@ -369,8 +369,8 @@ func loadFile(rootDir string, loader *Loader) interface{} {
// loadFileCSV reads file and parses it in the CSV map. A delimiter can
// be specified. Defaults to ','
-func loadFileCSV(rootDir string, loader *Loader) interface{} {
- return func(path string, delimiters ...rune) (m []map[string]interface{}, err error) {
+func loadFileCSV(rootDir string, loader *Loader) any {
+ return func(path string, delimiters ...rune) (m []map[string]any, err error) {
var delimiter rune
switch len(delimiters) {
case 0:
diff --git a/pkg/lib/template/template_funcs_test.go b/pkg/lib/template/template_funcs_test.go
index e95b786..21f45e2 100644
--- a/pkg/lib/template/template_funcs_test.go
+++ b/pkg/lib/template/template_funcs_test.go
@@ -43,14 +43,14 @@ func Test_QJson_Object(t *testing.T) {
func TestRowsToMap(t *testing.T) {
tests := []struct {
- In []map[string]interface{}
+ In []map[string]any
Key string
Value string
- Out map[string]interface{}
+ Out map[string]any
ExpErr error
}{
{
- In: []map[string]interface{}{
+ In: []map[string]any{
{
"column_a": "row1a",
"column_b": "row1b",
@@ -64,14 +64,14 @@ func TestRowsToMap(t *testing.T) {
},
Key: "column_a",
Value: "column_b",
- Out: map[string]interface{}{
+ Out: map[string]any{
"row1a": "row1b",
"row2a": "row2b",
},
ExpErr: nil,
},
{
- In: []map[string]interface{}{
+ In: []map[string]any{
{
"column_a": "row1a",
"column_b": "row1b",
@@ -85,14 +85,14 @@ func TestRowsToMap(t *testing.T) {
},
Key: "column_a",
Value: "column_c",
- Out: map[string]interface{}{
+ Out: map[string]any{
"row1a": "row1c",
"row2a": "row2c",
},
ExpErr: nil,
},
{
- In: []map[string]interface{}{
+ In: []map[string]any{
{
"column_a": "row1a",
"column_b": "row1b",
@@ -106,13 +106,13 @@ func TestRowsToMap(t *testing.T) {
},
Key: "column_a",
Value: "",
- Out: map[string]interface{}{
- "row1a": map[string]interface{}{
+ Out: map[string]any{
+ "row1a": map[string]any{
"column_a": "row1a",
"column_b": "row1b",
"column_c": "row1c",
},
- "row2a": map[string]interface{}{
+ "row2a": map[string]any{
"column_a": "row2a",
"column_b": "row2b",
"column_c": "row2c",
@@ -121,7 +121,7 @@ func TestRowsToMap(t *testing.T) {
ExpErr: nil,
},
{
- In: []map[string]interface{}{
+ In: []map[string]any{
{
"column_a": "row1a",
"column_b": "row1b",
@@ -137,7 +137,7 @@ func TestRowsToMap(t *testing.T) {
},
Key: "column_a",
Value: "column_b",
- Out: map[string]interface{}{
+ Out: map[string]any{
"row1a": "row1b",
"row2a": "row2b",
"row3a": "row3b",
@@ -145,7 +145,7 @@ func TestRowsToMap(t *testing.T) {
ExpErr: nil,
},
{
- In: []map[string]interface{}{
+ In: []map[string]any{
{
"column_a": "row1a",
"column_b": "row1b",
@@ -160,7 +160,7 @@ func TestRowsToMap(t *testing.T) {
},
Key: "column_a",
Value: "column_b",
- Out: map[string]interface{}{
+ Out: map[string]any{
"row1a": "row1b",
"row2a": "",
"row3a": "row3b",
@@ -168,7 +168,7 @@ func TestRowsToMap(t *testing.T) {
ExpErr: nil,
},
{
- In: []map[string]interface{}{
+ In: []map[string]any{
{
"column_a": "row1a",
"column_b": "row1b",
@@ -184,14 +184,14 @@ func TestRowsToMap(t *testing.T) {
},
Key: "column_a",
Value: "column_b",
- Out: map[string]interface{}{
+ Out: map[string]any{
"row1a": "row1b",
"row3a": "row3b",
},
ExpErr: nil,
},
{
- In: []map[string]interface{}{
+ In: []map[string]any{
{
"column_a": "row1a",
"column_b": "row1b",
@@ -207,11 +207,11 @@ func TestRowsToMap(t *testing.T) {
},
Key: "column_ZZ",
Value: "column_b",
- Out: map[string]interface{}{},
+ Out: map[string]any{},
ExpErr: nil,
},
{
- In: []map[string]interface{}{
+ In: []map[string]any{
{
"column_a": "row1a",
"column_b": "row1b",
@@ -227,7 +227,7 @@ func TestRowsToMap(t *testing.T) {
},
Key: "column_a",
Value: "column_ZZ",
- Out: map[string]interface{}{
+ Out: map[string]any{
"row1a": "",
"row2a": "",
"row3a": "",
@@ -235,7 +235,7 @@ func TestRowsToMap(t *testing.T) {
ExpErr: nil,
},
{
- In: []map[string]interface{}{
+ In: []map[string]any{
{
"column_a": "row1a",
"column_b": "row1b",
@@ -251,7 +251,7 @@ func TestRowsToMap(t *testing.T) {
},
Key: "column_a",
Value: "column_ZZ",
- Out: map[string]interface{}{
+ Out: map[string]any{
"row1a": "",
"row2a": "",
"row3a": "",
@@ -272,7 +272,7 @@ func TestRowsToMap(t *testing.T) {
}
} else {
for k, v := range v.Out {
- mapV, ok := v.(map[string]interface{})
+ mapV, ok := v.(map[string]any)
if !ok {
@@ -280,7 +280,7 @@ func TestRowsToMap(t *testing.T) {
t.Errorf("Value: Want '%s' != '%s' Got", v, aOut[k])
}
} else {
- go_test_utils.AssertMapsEqual(t, aOut[k].(map[string]interface{}), mapV)
+ go_test_utils.AssertMapsEqual(t, aOut[k].(map[string]any), mapV)
}
}
}
diff --git a/pkg/lib/template/template_loader.go b/pkg/lib/template/template_loader.go
index 315a72c..a73c6b1 100644
--- a/pkg/lib/template/template_loader.go
+++ b/pkg/lib/template/template_loader.go
@@ -53,7 +53,7 @@ func NewLoader(datastore *datastore.Datastore) Loader {
func (loader *Loader) Render(
tmplBytes []byte,
rootDir string,
- ctx interface{}) (res []byte, err error) {
+ ctx any) (res []byte, err error) {
// First check for custom delimiters
matches := delimsRE.FindStringSubmatch(string(tmplBytes))
@@ -112,7 +112,7 @@ func (loader *Loader) Render(
hasher.Write([]byte(fileBytes))
return hex.EncodeToString(hasher.Sum(nil)), nil
},
- // "parse_csv": func(path string, delimiter rune) ([]map[string]interface{}, error) {
+ // "parse_csv": func(path string, delimiter rune) ([]map[string]any, error) {
// _, file, err := util.OpenFileOrUrl(path, rootDir)
// if err != nil {
// return nil, err
@@ -130,7 +130,7 @@ func (loader *Loader) Render(
"file": loadFile(rootDir, loader),
"file_render": loadFileAndRender(rootDir, loader),
"file_csv": loadFileCSV(rootDir, loader),
- "file_sqlite": func(path, statement string) ([]map[string]interface{}, error) {
+ "file_sqlite": func(path, statement string) ([]map[string]any, error) {
sqliteFile := filepath.Join(rootDir, path)
database, err := sql.Open("sqlite3", sqliteFile)
if err != nil {
@@ -148,14 +148,14 @@ func (loader *Loader) Render(
if err != nil {
return nil, err
}
- row := make([]interface{}, len(columns))
+ row := make([]any, len(columns))
- data := []map[string]interface{}{}
+ data := []map[string]any{}
for rows.Next() {
- dataEntry := map[string]interface{}{}
+ dataEntry := map[string]any{}
for idx, col := range columns {
- dataEntry[col.Name()] = new(interface{})
+ dataEntry[col.Name()] = new(any)
row[idx] = dataEntry[col.Name()]
}
@@ -199,10 +199,23 @@ func (loader *Loader) Render(
return string(bytes), nil
},
+ "file_html2json": func(path string) (string, error) {
+ fileBytes, err := fileReadInternal(path, rootDir)
+ if err != nil {
+ return "", err
+ }
+
+ bytes, err := util.Html2Json(fileBytes)
+ if err != nil {
+ return "", errors.Wrap(err, "Could not marshal html to json")
+ }
+
+ return string(bytes), nil
+ },
"file_path": func(path string) string {
return util.LocalPath(path, rootDir)
},
- "datastore": func(index interface{}) (interface{}, error) {
+ "datastore": func(index any) (any, error) {
var key string
switch idxType := index.(type) {
@@ -219,8 +232,8 @@ func (loader *Loader) Render(
return loader.datastore.Get(key)
},
- "unmarshal": func(s string) (interface{}, error) {
- var gj interface{}
+ "unmarshal": func(s string) (any, error) {
+ var gj any
err := util.Unmarshal([]byte(s), &gj)
if err != nil {
return nil, err
@@ -228,7 +241,7 @@ func (loader *Loader) Render(
return gj, nil
},
"N": N,
- "marshal": func(data interface{}) (string, error) {
+ "marshal": func(data any) (string, error) {
bytes, err := json.Marshal(data)
if err != nil {
return "", err
@@ -253,15 +266,15 @@ func (loader *Loader) Render(
// divide a / b
"divide": divide,
// create a slice
- "slice": func(args ...interface{}) []interface{} {
+ "slice": func(args ...any) []any {
return args
},
- "rows_to_map": func(keyColumn, valueColumn string, rowsInput interface{}) (map[string]interface{}, error) {
+ "rows_to_map": func(keyColumn, valueColumn string, rowsInput any) (map[string]any, error) {
return rowsToMap(keyColumn, valueColumn, getRowsFromInput(rowsInput))
},
"pivot_rows": pivotRows,
- "group_map_rows": func(groupColumn string, rowsInput interface{}) (map[string][]map[string]interface{}, error) {
- grouped_rows := make(map[string][]map[string]interface{}, 1000)
+ "group_map_rows": func(groupColumn string, rowsInput any) (map[string][]map[string]any, error) {
+ grouped_rows := make(map[string][]map[string]any, 1000)
rows := getRowsFromInput(rowsInput)
for _, row := range rows {
group_key, ok := row[groupColumn]
@@ -272,7 +285,7 @@ func (loader *Loader) Render(
case string:
_, ok := grouped_rows[idx]
if !ok {
- grouped_rows[idx] = make([]map[string]interface{}, 0)
+ grouped_rows[idx] = make([]map[string]any, 0)
}
grouped_rows[idx] = append(grouped_rows[idx], row)
default:
@@ -281,8 +294,8 @@ func (loader *Loader) Render(
}
return grouped_rows, nil
},
- "group_rows": func(groupColumn string, rowsInput interface{}) ([][]map[string]interface{}, error) {
- grouped_rows := make([][]map[string]interface{}, 1000)
+ "group_rows": func(groupColumn string, rowsInput any) ([][]map[string]any, error) {
+ grouped_rows := make([][]map[string]any, 1000)
rows := getRowsFromInput(rowsInput)
for _, row := range rows {
@@ -297,7 +310,7 @@ func (loader *Loader) Render(
}
rows2 := grouped_rows[idx]
if rows2 == nil {
- grouped_rows[idx] = make([]map[string]interface{}, 0)
+ grouped_rows[idx] = make([]map[string]any, 0)
}
grouped_rows[idx] = append(grouped_rows[idx], row)
default:
@@ -305,7 +318,7 @@ func (loader *Loader) Render(
}
}
// remove empty rows
- g_rows := make([][]map[string]interface{}, 0)
+ g_rows := make([][]map[string]any, 0)
for _, row := range grouped_rows {
if row == nil {
continue
@@ -345,7 +358,7 @@ func (loader *Loader) Render(
u.User = nil
return u
},
- "is_zero": func(v interface{}) bool {
+ "is_zero": func(v any) bool {
if v == nil {
return true
}
@@ -461,14 +474,14 @@ func (loader *Loader) Render(
return buf.Bytes(), nil
}
-func getRowsFromInput(rowsInput interface{}) []map[string]interface{} {
- rows := make([]map[string]interface{}, 0)
+func getRowsFromInput(rowsInput any) []map[string]any {
+ rows := make([]map[string]any, 0)
switch t := rowsInput.(type) {
- case []map[string]interface{}:
+ case []map[string]any:
rows = t
- case []interface{}:
+ case []any:
for _, v := range t {
- rows = append(rows, v.(map[string]interface{}))
+ rows = append(rows, v.(map[string]any))
}
}
return rows
diff --git a/pkg/lib/template/util.go b/pkg/lib/template/util.go
index 5458481..9b914da 100644
--- a/pkg/lib/template/util.go
+++ b/pkg/lib/template/util.go
@@ -28,7 +28,7 @@ func loadFileFromPathSpec(pathSpec, manifestDir string) (string, []byte, error)
return filepath, requestTmpl, nil
}
-func LoadManifestDataAsObject(data interface{}, manifestDir string, loader Loader) (filepath string, res interface{}, err error) {
+func LoadManifestDataAsObject(data any, manifestDir string, loader Loader) (filepath string, res any, err error) {
switch typedData := data.(type) {
case string:
filepath, requestTmpl, err := loadFileFromPathSpec(typedData, manifestDir)
@@ -62,7 +62,7 @@ func LoadManifestDataAsObject(data interface{}, manifestDir string, loader Loade
}
}
-func LoadManifestDataAsRawJson(data interface{}, manifestDir string) (filepath string, res json.RawMessage, err error) {
+func LoadManifestDataAsRawJson(data any, manifestDir string) (filepath string, res json.RawMessage, err error) {
switch typedData := data.(type) {
case []byte:
err = res.UnmarshalJSON(typedData)
diff --git a/pkg/lib/test_utils/test_utils.go b/pkg/lib/test_utils/test_utils.go
index 8a881d8..50b2391 100644
--- a/pkg/lib/test_utils/test_utils.go
+++ b/pkg/lib/test_utils/test_utils.go
@@ -11,6 +11,7 @@ import (
"testing"
go_test_utils "github.com/programmfabrik/go-test-utils"
+ "github.com/programmfabrik/golib"
"github.com/sergi/go-diff/diffmatchpatch"
)
@@ -108,7 +109,7 @@ func AssertLoggingEqualsRegex(log bytes.Buffer, want []LoggingRegexAssertion) (b
func AssertJsonStringEquals(t testing.TB, expected, got string) {
var (
- expectedJson, gotJson interface{}
+ expectedJson, gotJson any
expectedMinified, gotMinifed []byte
)
@@ -116,7 +117,7 @@ func AssertJsonStringEquals(t testing.TB, expected, got string) {
if err != nil {
t.Error(err)
}
- expectedMinified, err = json.MarshalIndent(expectedJson, "", "")
+ expectedMinified, err = golib.JsonBytesIndent(expectedJson, "", "")
if err != nil {
log.Fatal(err)
}
@@ -125,7 +126,7 @@ func AssertJsonStringEquals(t testing.TB, expected, got string) {
if err != nil {
t.Error(err)
}
- gotMinifed, err = json.MarshalIndent(gotJson, "", "")
+ gotMinifed, err = golib.JsonBytesIndent(gotJson, "", "")
if err != nil {
log.Fatal(err)
}
diff --git a/pkg/lib/util/json.go b/pkg/lib/util/json.go
index 8149ee4..c00720e 100644
--- a/pkg/lib/util/json.go
+++ b/pkg/lib/util/json.go
@@ -12,8 +12,8 @@ import (
"github.com/tidwall/jsonc"
)
-type JsonObject = map[string]interface{}
-type JsonArray = []interface{}
+type JsonObject = map[string]any
+type JsonArray = []any
type JsonString = string
type JsonNumber = float64
type JsonBool = bool
@@ -24,7 +24,7 @@ func init() {
coloredError = true
}
-func Unmarshal(input []byte, output interface{}) error {
+func Unmarshal(input []byte, output any) error {
// Remove # comments from template
var commentRegex = regexp.MustCompile(`(?m)^[\t ]*#.*$`)
diff --git a/pkg/lib/util/oauth.go b/pkg/lib/util/oauth.go
index 2f5d7ec..b38896d 100644
--- a/pkg/lib/util/oauth.go
+++ b/pkg/lib/util/oauth.go
@@ -6,6 +6,8 @@ import (
"net/url"
"time"
+ "log"
+
"github.com/pkg/errors"
"golang.org/x/oauth2"
"golang.org/x/oauth2/clientcredentials"
@@ -52,8 +54,13 @@ func getOAuthClientCredentialsConfig(c OAuthClientConfig) clientcredentials.Conf
// GetPasswordCredentialsAuthToken sends request to oAuth token endpoint
// to get a token on behalf of a user
-func (c OAuthClientConfig) GetPasswordCredentialsAuthToken(username string, password string) (*oauth2.Token, error) {
+func (c OAuthClientConfig) GetPasswordCredentialsAuthToken(username string, password string) (tok *oauth2.Token, err error) {
cfg := getOAuthClientConfig(c)
+ defer func() {
+ if err != nil {
+ log.Printf("oauth2 password error: %s client: %s secret: %s", err.Error(), cfg.ClientID, cfg.ClientSecret)
+ }
+ }()
httpClient := &http.Client{Timeout: 60 * time.Second}
ctx := context.WithValue(context.Background(), oauth2.HTTPClient, httpClient)
return cfg.PasswordCredentialsToken(ctx, username, password)
diff --git a/pkg/lib/util/util.go b/pkg/lib/util/util.go
index fed9916..df0fc4f 100644
--- a/pkg/lib/util/util.go
+++ b/pkg/lib/util/util.go
@@ -1,13 +1,18 @@
package util
import (
+ "bytes"
"encoding/json"
"fmt"
"regexp"
"strconv"
+ "strings"
+ "github.com/PuerkitoBio/goquery"
"github.com/clbanning/mxj"
"github.com/pkg/errors"
+ "github.com/programmfabrik/golib"
+ "golang.org/x/net/html"
)
func Max(x, y int) int {
@@ -17,8 +22,8 @@ func Max(x, y int) int {
return y
}
-func RemoveFromJsonArray(input []interface{}, removeIndex int) (output []interface{}) {
- output = make([]interface{}, len(input))
+func RemoveFromJsonArray(input []any, removeIndex int) (output []any) {
+ output = make([]any, len(input))
copy(output, input)
// Remove the element at index i from a.
@@ -29,7 +34,7 @@ func RemoveFromJsonArray(input []interface{}, removeIndex int) (output []interfa
return output
}
-func GetStringFromInterface(queryParam interface{}) (string, error) {
+func GetStringFromInterface(queryParam any) (string, error) {
switch t := queryParam.(type) {
case string:
return t, nil
@@ -69,11 +74,11 @@ func Xml2Json(rawXml []byte, format string) ([]byte, error) {
return []byte{}, errors.Wrap(err, "Could not parse xml")
}
- json, err := mv.JsonIndent("", " ")
+ jsonStr, err := mv.JsonIndent("", " ")
if err != nil {
return []byte{}, errors.Wrap(err, "Could not convert to json")
}
- return json, nil
+ return jsonStr, nil
}
// Xhtml2Json parses the raw xhtml data and converts it into a json string
@@ -88,9 +93,99 @@ func Xhtml2Json(rawXhtml []byte) ([]byte, error) {
return []byte{}, errors.Wrap(err, "Could not parse xhtml")
}
- json, err := mv.JsonIndent("", " ")
+ jsonStr, err := mv.JsonIndent("", " ")
if err != nil {
return []byte{}, errors.Wrap(err, "Could not convert to json")
}
- return json, nil
+ return jsonStr, nil
+}
+
+// Html2Json parses the raw html data and converts it into a json string
+func Html2Json(rawHtml []byte) ([]byte, error) {
+ var (
+ htmlDoc *goquery.Document
+ err error
+ )
+
+ htmlDoc, err = goquery.NewDocumentFromReader(bytes.NewReader(rawHtml))
+ if err != nil {
+ return []byte{}, errors.Wrap(err, "Could not parse html")
+ }
+
+ htmlData := map[string]any{}
+ htmlDoc.Selection.Contents().Each(func(_ int, node *goquery.Selection) {
+ switch node.Get(0).Type {
+ case html.ElementNode:
+ htmlData = parseHtmlNode(node)
+ return
+ default:
+ return
+ }
+ })
+
+ jsonStr, err := golib.JsonBytesIndent(htmlData, "", " ")
+ if err != nil {
+ return []byte{}, errors.Wrap(err, "Could not convert html to json")
+ }
+
+ return jsonStr, nil
+}
+
+// parseHtmlNode recursivly parses the html node and adds it to a map
+// the resulting structure is the same as the result of format "xml2" (using mxj.NewMapXmlSeq)
+func parseHtmlNode(node *goquery.Selection) map[string]any {
+ tagData := map[string]any{}
+
+ childrenByName := map[string][]any{}
+ comments := []string{}
+
+ node.Contents().Each(func(i int, content *goquery.Selection) {
+ switch content.Get(0).Type {
+ case html.ElementNode:
+ // recursively parse child nodes
+ for childName, childContent := range parseHtmlNode(content) {
+ childrenByName[childName] = append(childrenByName[childName], childContent)
+ }
+ case html.CommentNode:
+ comments = append(comments, strings.Trim(content.Get(0).Data, " \n\t"))
+ default:
+ return
+ }
+ })
+
+ // include attributes
+ for _, attr := range node.Get(0).Attr {
+ tagData["-"+attr.Key] = attr.Val
+ }
+
+ // include comments
+ if len(comments) == 1 {
+ tagData["#comment"] = comments[0]
+ } else if len(comments) > 1 {
+ tagData["#comment"] = comments
+ }
+
+ // include children
+ for childName, children := range childrenByName {
+ if len(children) == 0 {
+ continue
+ }
+ if len(children) == 1 {
+ tagData[childName] = children[0]
+ continue
+ }
+ tagData[childName] = children
+ }
+
+ // include tag text only if there are no children, since goquery would render all children into a single string
+ if len(childrenByName) == 0 {
+ text := strings.Trim(node.Text(), " \n\t")
+ if len(text) > 0 {
+ tagData["#text"] = text
+ }
+ }
+
+ return map[string]any{
+ node.Get(0).Data: tagData,
+ }
}
diff --git a/pkg/lib/util/util_test.go b/pkg/lib/util/util_test.go
index aaf753d..6a7e382 100644
--- a/pkg/lib/util/util_test.go
+++ b/pkg/lib/util/util_test.go
@@ -3,7 +3,7 @@ package util
import "testing"
func TestRemoveFromJsonArray(t *testing.T) {
- input := []interface{}{JsonString("0"), JsonString("1"), JsonString("2"), JsonString("3"), JsonString("4"), JsonString("5")}
+ input := []any{JsonString("0"), JsonString("1"), JsonString("2"), JsonString("3"), JsonString("4"), JsonString("5")}
output := RemoveFromJsonArray(input, 2)
if len(output) != 5 || output[2] != JsonString("3") {
diff --git a/test/csv/check_store_values.json b/test/response/format/csv/check_store_values.json
similarity index 100%
rename from test/csv/check_store_values.json
rename to test/response/format/csv/check_store_values.json
diff --git a/test/csv/csv_requests.json b/test/response/format/csv/csv_requests.json
similarity index 100%
rename from test/csv/csv_requests.json
rename to test/response/format/csv/csv_requests.json
diff --git a/test/csv/manifest.json b/test/response/format/csv/manifest.json
similarity index 90%
rename from test/csv/manifest.json
rename to test/response/format/csv/manifest.json
index c0795f6..dcb4cee 100644
--- a/test/csv/manifest.json
+++ b/test/response/format/csv/manifest.json
@@ -2,7 +2,7 @@
{
"http_server": {
"addr": "{{ $local_port }}",
- "dir": "../_res/assets",
+ "dir": "../../../_res/assets",
"testmode": false
},
"store": {
diff --git a/test/csv/preserve_trailing_spaces.json b/test/response/format/csv/preserve_trailing_spaces.json
similarity index 100%
rename from test/csv/preserve_trailing_spaces.json
rename to test/response/format/csv/preserve_trailing_spaces.json
diff --git a/test/csv/trailing_spaces.csv b/test/response/format/csv/trailing_spaces.csv
similarity index 100%
rename from test/csv/trailing_spaces.csv
rename to test/response/format/csv/trailing_spaces.csv
diff --git a/test/response/format/html/check_local_file_against_response.json b/test/response/format/html/check_local_file_against_response.json
new file mode 100644
index 0000000..144ec2f
--- /dev/null
+++ b/test/response/format/html/check_local_file_against_response.json
@@ -0,0 +1,18 @@
+[
+ {
+ "name": "Get existing HTML file",
+ "request": {
+ "server_url": "{{ datastore "req_base_url" }}",
+ "endpoint": "bounce-json",
+ "method": "POST",
+ "body": {{ file_html2json "sample.html" }}
+ },
+ "response": {
+ "statuscode": 200,
+ "body": {
+ "header": {},
+ "body": {{ file "result_html.json" }}
+ }
+ }
+ }
+]
\ No newline at end of file
diff --git a/test/response/format/html/check_response_format_html.json b/test/response/format/html/check_response_format_html.json
new file mode 100644
index 0000000..84f4fa8
--- /dev/null
+++ b/test/response/format/html/check_response_format_html.json
@@ -0,0 +1,14 @@
+{
+ "name": "get sample.html from test server, use response format \"html\"",
+ "request": {
+ "server_url": "{{ datastore "req_base_url" }}",
+ "endpoint": "sample.html",
+ "method": "GET"
+ },
+ "response": {
+ "format": {
+ "type": "html"
+ },
+ "body": {{ file "result_html.json" }}
+ }
+}
\ No newline at end of file
diff --git a/test/response/format/html/manifest.json b/test/response/format/html/manifest.json
new file mode 100644
index 0000000..d6a84fd
--- /dev/null
+++ b/test/response/format/html/manifest.json
@@ -0,0 +1,16 @@
+{{ $local_port:=":9999"}}
+{
+ "http_server": {
+ "addr": "{{ $local_port }}",
+ "dir": ".",
+ "testmode": false
+ },
+ "store": {
+ "req_base_url": "http://localhost{{ $local_port }}"
+ },
+ "name": "HTML tests",
+ "tests": [
+ "@check_response_format_html.json",
+ "@check_local_file_against_response.json"
+ ]
+}
\ No newline at end of file
diff --git a/test/response/format/html/result_html.json b/test/response/format/html/result_html.json
new file mode 100644
index 0000000..1d8423c
--- /dev/null
+++ b/test/response/format/html/result_html.json
@@ -0,0 +1,224 @@
+{
+ "html": {
+ "-lang": "de",
+ "#text:control": {
+ "must_not_exist": true
+ },
+ "body": {
+ "#comment": "comment body",
+ "#text:control": {
+ "must_not_exist": true
+ },
+ "main": {
+ "-class": "page-register",
+ "#text:control": {
+ "must_not_exist": true
+ },
+ "article": {
+ "-class": "access-container access-container--wide",
+ "#text:control": {
+ "must_not_exist": true
+ },
+ "div": {
+ "-class": "container",
+ "#text:control": {
+ "must_not_exist": true
+ },
+ "footer": {
+ "#comment": [
+ "1. comment in footer",
+ "2. comment in footer"
+ ],
+ "#text:control": {
+ "must_not_exist": true
+ },
+ "nav": {
+ "div": {
+ "-class": "language-switcher",
+ "#text:control": {
+ "must_not_exist": true
+ },
+ "select": {
+ "-onchange": "onLanguageChange(event)",
+ "#text:control": {
+ "must_not_exist": true
+ },
+ "option": [
+ {
+ "-value": "en-US",
+ "#text": "American English (Amerikanisches Englisch)"
+ },
+ {
+ "-selected": "selected",
+ "-value": "de-DE",
+ "#text": "Deutsch"
+ }
+ ]
+ }
+ },
+ "script": {
+ "#text:control": {
+ "starts_with": "function onLanguageChange(evt) {"
+ }
+ }
+ }
+ },
+ "h1": {
+ "#text": "Registrieren"
+ },
+ "section": {
+ "#text:control": {
+ "must_not_exist": true
+ },
+ "form": {
+ "-action": "",
+ "-class": "form-grid",
+ "-id": "registerForm",
+ "-method": "POST",
+ "#text:control": {
+ "must_not_exist": true
+ },
+ "fieldset": [
+ {
+ "-data-field-name": "email",
+ "-data-width": "1",
+ "#text:control": {
+ "must_not_exist": true
+ },
+ "label": {
+ "-for": "email",
+ "#text:control": {
+ "must_not_exist": true
+ },
+ "input": {
+ "-autocomplete": "email",
+ "-class": "has-error",
+ "-id": "email",
+ "-name": "email",
+ "-placeholder": " ",
+ "-required": "",
+ "-type": "email",
+ "#text:control": {
+ "must_not_exist": true
+ }
+ },
+ "span": [
+ {
+ "-class": "field-label",
+ "#text:control": {
+ "must_not_exist": true
+ },
+ "sup": {
+ "-class": "required",
+ "#text": "*"
+ }
+ },
+ {
+ "-class": "field-hint",
+ "-title": "Nutzer exisitert bereits",
+ "#text:control": {
+ "starts_with": "Nutzer exisitert"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "-class": "actions",
+ "-data-pre": "1",
+ "-data-width": "1",
+ "#text:control": {
+ "must_not_exist": true
+ },
+ "button": {
+ "-type": "submit",
+ "#text": "Jetzt registrieren"
+ }
+ },
+ {
+ "-class": "secondary-actions",
+ "#text:control": {
+ "must_not_exist": true
+ },
+ "a": {
+ "-href": "http://localhost:8085/",
+ "#text": "Zur Startseite"
+ }
+ }
+ ],
+ "p": [
+ {
+ "-class": "required-information",
+ "#text:control": {
+ "must_not_exist": true
+ },
+ "sup": {
+ "#text": "*"
+ }
+ },
+ {
+ "-class": "error-summary",
+ "#comment:control": {
+ "match": "comment form\\n\\s*multiline"
+ },
+ "#text": "Das Formular enthält Fehler"
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "head": {
+ "#comment": "comment head",
+ "#text:control": {
+ "must_not_exist": true
+ },
+ "link": [
+ {
+ "-href": "/api/page/static/images/favicon.png",
+ "-rel": "icon",
+ "#text:control": {
+ "must_not_exist": true
+ }
+ },
+ {
+ "-href": "/api/page/static/css/main.css",
+ "-rel": "stylesheet",
+ "#text:control": {
+ "must_not_exist": true
+ }
+ }
+ ],
+ "meta": [
+ {
+ "-charset": "utf-8",
+ "#text:control": {
+ "must_not_exist": true
+ }
+ },
+ {
+ "-content": "fylr - manage your data",
+ "-name": "description",
+ "#text:control": {
+ "must_not_exist": true
+ }
+ }
+ ],
+ "script": {
+ "#text:control": {
+ "starts_with": "async function submitForm(form) {"
+ }
+ },
+ "style": {
+ "#text:control": {
+ "starts_with": ":root {}"
+ }
+ },
+ "title": {
+ "#text": "fylr"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/response/format/html/sample.html b/test/response/format/html/sample.html
new file mode 100644
index 0000000..671d5eb
--- /dev/null
+++ b/test/response/format/html/sample.html
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+ fylr
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/xhtml/check_local_file_against_response.json b/test/response/format/xhtml/check_local_file_against_response.json
similarity index 100%
rename from test/xhtml/check_local_file_against_response.json
rename to test/response/format/xhtml/check_local_file_against_response.json
diff --git a/test/xhtml/check_response_format_xhtml.json b/test/response/format/xhtml/check_response_format_xhtml.json
similarity index 100%
rename from test/xhtml/check_response_format_xhtml.json
rename to test/response/format/xhtml/check_response_format_xhtml.json
diff --git a/test/xhtml/manifest.json b/test/response/format/xhtml/manifest.json
similarity index 89%
rename from test/xhtml/manifest.json
rename to test/response/format/xhtml/manifest.json
index f3d66bc..4aa6861 100644
--- a/test/xhtml/manifest.json
+++ b/test/response/format/xhtml/manifest.json
@@ -2,7 +2,7 @@
{
"http_server": {
"addr": "{{ $local_port }}",
- "dir": "../_res/assets",
+ "dir": "../../../_res/assets",
"testmode": false
},
"store": {
diff --git a/test/xhtml/result_xhtml.json b/test/response/format/xhtml/result_xhtml.json
similarity index 100%
rename from test/xhtml/result_xhtml.json
rename to test/response/format/xhtml/result_xhtml.json
diff --git a/test/xhtml/sample.xhtml b/test/response/format/xhtml/sample.xhtml
similarity index 85%
rename from test/xhtml/sample.xhtml
rename to test/response/format/xhtml/sample.xhtml
index 908b5cb..e917c0d 100644
--- a/test/xhtml/sample.xhtml
+++ b/test/response/format/xhtml/sample.xhtml
@@ -1,5 +1,6 @@
+
-
+
diff --git a/test/xml/check_local_file_against_response.json b/test/response/format/xml/check_local_file_against_response.json
similarity index 100%
rename from test/xml/check_local_file_against_response.json
rename to test/response/format/xml/check_local_file_against_response.json
diff --git a/test/xml/check_response_against_local_file.json b/test/response/format/xml/check_response_against_local_file.json
similarity index 100%
rename from test/xml/check_response_against_local_file.json
rename to test/response/format/xml/check_response_against_local_file.json
diff --git a/test/xml/check_response_format_xml.json b/test/response/format/xml/check_response_format_xml.json
similarity index 100%
rename from test/xml/check_response_format_xml.json
rename to test/response/format/xml/check_response_format_xml.json
diff --git a/test/xml/check_response_format_xml2.json b/test/response/format/xml/check_response_format_xml2.json
similarity index 100%
rename from test/xml/check_response_format_xml2.json
rename to test/response/format/xml/check_response_format_xml2.json
diff --git a/test/xml/compare_exiftool_with_xml.json b/test/response/format/xml/compare_exiftool_with_xml.json
similarity index 100%
rename from test/xml/compare_exiftool_with_xml.json
rename to test/response/format/xml/compare_exiftool_with_xml.json
diff --git a/test/xml/exiftool_result.xml b/test/response/format/xml/exiftool_result.xml
similarity index 100%
rename from test/xml/exiftool_result.xml
rename to test/response/format/xml/exiftool_result.xml
diff --git a/test/xml/manifest.json b/test/response/format/xml/manifest.json
similarity index 92%
rename from test/xml/manifest.json
rename to test/response/format/xml/manifest.json
index 8862382..a752e3b 100644
--- a/test/xml/manifest.json
+++ b/test/response/format/xml/manifest.json
@@ -2,7 +2,7 @@
{
"http_server": {
"addr": "{{ $local_port }}",
- "dir": "../_res/assets",
+ "dir": "../../../_res/assets",
"testmode": false
},
"store": {
diff --git a/test/xml/result_xml.json b/test/response/format/xml/result_xml.json
similarity index 100%
rename from test/xml/result_xml.json
rename to test/response/format/xml/result_xml.json
diff --git a/test/xml/result_xml2.json b/test/response/format/xml/result_xml2.json
similarity index 100%
rename from test/xml/result_xml2.json
rename to test/response/format/xml/result_xml2.json
diff --git a/test/xml/sample.xml b/test/response/format/xml/sample.xml
similarity index 100%
rename from test/xml/sample.xml
rename to test/response/format/xml/sample.xml
diff --git a/test/preprocess/bounce_json.json b/test/response/preprocess/bounce_json.json
similarity index 100%
rename from test/preprocess/bounce_json.json
rename to test/response/preprocess/bounce_json.json
diff --git a/test/preprocess/load_static_files.json b/test/response/preprocess/load_static_files.json
similarity index 100%
rename from test/preprocess/load_static_files.json
rename to test/response/preprocess/load_static_files.json
diff --git a/test/preprocess/manifest.json b/test/response/preprocess/manifest.json
similarity index 95%
rename from test/preprocess/manifest.json
rename to test/response/preprocess/manifest.json
index 407db89..2e27629 100644
--- a/test/preprocess/manifest.json
+++ b/test/response/preprocess/manifest.json
@@ -2,7 +2,7 @@
{
"http_server": {
"addr": "{{ $local_port }}",
- "dir": "../_res/assets/",
+ "dir": "../../_res/assets",
"testmode": false
},
"name": "new feature pre_process",
diff --git a/test/preprocess/preprocess_bounce_exiftool_json.json b/test/response/preprocess/preprocess_bounce_exiftool_json.json
similarity index 97%
rename from test/preprocess/preprocess_bounce_exiftool_json.json
rename to test/response/preprocess/preprocess_bounce_exiftool_json.json
index e6dc4c8..3beaf79 100644
--- a/test/preprocess/preprocess_bounce_exiftool_json.json
+++ b/test/response/preprocess/preprocess_bounce_exiftool_json.json
@@ -16,7 +16,7 @@
"header2": "XYZ"
},
"body": {
- "file": "@../_res/assets/camera.jpg"
+ "file": "@../../_res/assets/camera.jpg"
},
"body_type": "multipart"
},
diff --git a/test/preprocess/preprocess_file_exiftool_json.json b/test/response/preprocess/preprocess_file_exiftool_json.json
similarity index 100%
rename from test/preprocess/preprocess_file_exiftool_json.json
rename to test/response/preprocess/preprocess_file_exiftool_json.json
diff --git a/test/preprocess/preprocess_file_exiftool_xml.json b/test/response/preprocess/preprocess_file_exiftool_xml.json
similarity index 100%
rename from test/preprocess/preprocess_file_exiftool_xml.json
rename to test/response/preprocess/preprocess_file_exiftool_xml.json
diff --git a/test/preprocess/preprocess_file_exiftool_xml_collect.json b/test/response/preprocess/preprocess_file_exiftool_xml_collect.json
similarity index 100%
rename from test/preprocess/preprocess_file_exiftool_xml_collect.json
rename to test/response/preprocess/preprocess_file_exiftool_xml_collect.json
diff --git a/test/preprocess/preprocess_file_imagemagick_compare.json b/test/response/preprocess/preprocess_file_imagemagick_compare.json
similarity index 89%
rename from test/preprocess/preprocess_file_imagemagick_compare.json
rename to test/response/preprocess/preprocess_file_imagemagick_compare.json
index b03a6ed..85f724e 100644
--- a/test/preprocess/preprocess_file_imagemagick_compare.json
+++ b/test/response/preprocess/preprocess_file_imagemagick_compare.json
@@ -1,6 +1,6 @@
[
{
- "name": "preprocess asset camera.jpg with imagemagick compare against itsefl (should pass)",
+ "name": "preprocess asset camera.jpg with imagemagick compare against itself (should pass)",
"request": {
// load static file
"server_url": "{{ datastore "local_url" }}",
@@ -21,7 +21,7 @@
"-fuzz",
"2%",
"-",
- {{ file_path "../_res/assets/camera.jpg" | marshal }},
+ {{ file_path "../../_res/assets/camera.jpg" | marshal }},
"/dev/null"
],
"output": "stderr"
@@ -50,7 +50,7 @@
"-fuzz",
"2%",
"-",
- {{ file_path "../_res/assets/berlin.jpg" | marshal }},
+ {{ file_path "../../_res/assets/berlin.jpg" | marshal }},
"/dev/null"
],
"output": "stderr"
diff --git a/test/preprocess/preprocess_file_imagemagick_compare_collect.json b/test/response/preprocess/preprocess_file_imagemagick_compare_collect.json
similarity index 82%
rename from test/preprocess/preprocess_file_imagemagick_compare_collect.json
rename to test/response/preprocess/preprocess_file_imagemagick_compare_collect.json
index 7f1a737..5bf5485 100644
--- a/test/preprocess/preprocess_file_imagemagick_compare_collect.json
+++ b/test/response/preprocess/preprocess_file_imagemagick_compare_collect.json
@@ -1,6 +1,6 @@
[
{
- "name": " (collect) preprocess asset camera.jpg with imagemagick compare against itself (should pass)",
+ "name": "(collect) preprocess asset camera.jpg with imagemagick compare against itself (should pass)",
"request": {
// load static file
"server_url": "{{ datastore "local_url" }}",
@@ -22,7 +22,7 @@
"-fuzz",
"2%",
"-",
- {{ file_path "../_res/assets/camera.jpg" | marshal }},
+ {{ file_path "../../_res/assets/camera.jpg" | marshal }},
"/dev/null"
],
"output": "stderr"
@@ -36,7 +36,7 @@
"timeout_ms": 5000
},
{
- "name": " (collect) preprocess asset camera.jpg with imagemagick compare against a different one (should fail)",
+ "name": "(collect) preprocess asset camera.jpg with imagemagick compare against a different one (should fail)",
"request": {
// load static file
"server_url": "{{ datastore "local_url" }}",
@@ -55,7 +55,7 @@
"-fuzz",
"2%",
"-",
- {{ file_path "../_res/assets/berlin.jpg" | marshal }},
+ {{ file_path "../../_res/assets/berlin.jpg" | marshal }},
"/dev/null"
],
"output": "stderr"