json.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. package httpexpect
  2. import (
  3. "errors"
  4. "fmt"
  5. "reflect"
  6. "regexp"
  7. "github.com/xeipuuv/gojsonschema"
  8. "github.com/yalp/jsonpath"
  9. )
  10. func jsonPath(opChain *chain, value interface{}, path string) *Value {
  11. if opChain.failed() {
  12. return newValue(opChain, nil)
  13. }
  14. filterFn, err := jsonpath.Prepare(path)
  15. if err != nil {
  16. opChain.fail(AssertionFailure{
  17. Type: AssertValid,
  18. Actual: &AssertionValue{path},
  19. Errors: []error{
  20. errors.New("expected: valid json path"),
  21. err,
  22. },
  23. })
  24. return newValue(opChain, nil)
  25. }
  26. result, err := filterFn(value)
  27. if err != nil {
  28. opChain.fail(AssertionFailure{
  29. Type: AssertMatchPath,
  30. Actual: &AssertionValue{value},
  31. Expected: &AssertionValue{path},
  32. Errors: []error{
  33. errors.New("expected: value matches given json path"),
  34. err,
  35. },
  36. })
  37. return newValue(opChain, nil)
  38. }
  39. return newValue(opChain, result)
  40. }
  41. func jsonSchema(opChain *chain, value, schema interface{}) {
  42. if opChain.failed() {
  43. return
  44. }
  45. getString := func(in interface{}) (out string, ok bool) {
  46. ok = true
  47. defer func() {
  48. if err := recover(); err != nil {
  49. ok = false
  50. }
  51. }()
  52. out = reflect.ValueOf(in).Convert(reflect.TypeOf("")).String()
  53. return
  54. }
  55. var schemaLoader gojsonschema.JSONLoader
  56. var schemaData interface{}
  57. if str, ok := getString(schema); ok {
  58. if ok, _ := regexp.MatchString(`^\w+://`, str); ok {
  59. schemaLoader = gojsonschema.NewReferenceLoader(str)
  60. schemaData = str
  61. } else {
  62. schemaLoader = gojsonschema.NewStringLoader(str)
  63. schemaData, _ = schemaLoader.LoadJSON()
  64. }
  65. } else {
  66. schemaLoader = gojsonschema.NewGoLoader(schema)
  67. schemaData = schema
  68. }
  69. valueLoader := gojsonschema.NewGoLoader(value)
  70. result, err := gojsonschema.Validate(schemaLoader, valueLoader)
  71. if err != nil {
  72. opChain.fail(AssertionFailure{
  73. Type: AssertValid,
  74. Actual: &AssertionValue{schema},
  75. Errors: []error{
  76. errors.New("expected: valid json schema"),
  77. err,
  78. },
  79. })
  80. return
  81. }
  82. if !result.Valid() {
  83. errors := []error{
  84. errors.New("expected: value matches given json schema"),
  85. }
  86. for _, err := range result.Errors() {
  87. errors = append(errors, fmt.Errorf("%s", err))
  88. }
  89. opChain.fail(AssertionFailure{
  90. Type: AssertMatchSchema,
  91. Actual: &AssertionValue{value},
  92. Expected: &AssertionValue{schemaData},
  93. Errors: errors,
  94. })
  95. }
  96. }