api_matchers 0.6.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ci.yml +30 -0
  3. data/.gitignore +1 -1
  4. data/Gemfile +1 -1
  5. data/History.markdown +62 -46
  6. data/README.markdown +1070 -114
  7. data/TODO.markdown +39 -3
  8. data/api_matchers.gemspec +13 -6
  9. data/lib/api_matchers/collection/base.rb +65 -0
  10. data/lib/api_matchers/collection/be_sorted_by.rb +97 -0
  11. data/lib/api_matchers/collection/have_json_size.rb +54 -0
  12. data/lib/api_matchers/core/exceptions.rb +5 -0
  13. data/lib/api_matchers/core/find_in_json.rb +57 -28
  14. data/lib/api_matchers/core/http_status_codes.rb +118 -0
  15. data/lib/api_matchers/core/json_path_finder.rb +87 -0
  16. data/lib/api_matchers/core/parser.rb +4 -2
  17. data/lib/api_matchers/core/rspec_matchers.rb +130 -37
  18. data/lib/api_matchers/core/setup.rb +49 -23
  19. data/lib/api_matchers/core/value_normalizer.rb +26 -0
  20. data/lib/api_matchers/error_response/base.rb +77 -0
  21. data/lib/api_matchers/error_response/have_error.rb +69 -0
  22. data/lib/api_matchers/error_response/have_error_on.rb +173 -0
  23. data/lib/api_matchers/hateoas/base.rb +77 -0
  24. data/lib/api_matchers/hateoas/have_link.rb +102 -0
  25. data/lib/api_matchers/headers/base.rb +7 -7
  26. data/lib/api_matchers/headers/be_json.rb +2 -4
  27. data/lib/api_matchers/headers/be_xml.rb +2 -4
  28. data/lib/api_matchers/headers/have_cache_control.rb +90 -0
  29. data/lib/api_matchers/headers/have_cors_headers.rb +102 -0
  30. data/lib/api_matchers/headers/have_header.rb +102 -0
  31. data/lib/api_matchers/http_status/base.rb +48 -0
  32. data/lib/api_matchers/http_status/be_client_error.rb +17 -0
  33. data/lib/api_matchers/http_status/be_forbidden.rb +17 -0
  34. data/lib/api_matchers/http_status/be_no_content.rb +17 -0
  35. data/lib/api_matchers/http_status/be_not_found.rb +17 -0
  36. data/lib/api_matchers/http_status/be_redirect.rb +17 -0
  37. data/lib/api_matchers/http_status/be_server_error.rb +17 -0
  38. data/lib/api_matchers/http_status/be_successful.rb +17 -0
  39. data/lib/api_matchers/http_status/be_unauthorized.rb +17 -0
  40. data/lib/api_matchers/http_status/be_unprocessable.rb +17 -0
  41. data/lib/api_matchers/http_status/have_http_status.rb +39 -0
  42. data/lib/api_matchers/json_api/base.rb +83 -0
  43. data/lib/api_matchers/json_api/be_json_api_compliant.rb +158 -0
  44. data/lib/api_matchers/json_api/have_json_api_attributes.rb +62 -0
  45. data/lib/api_matchers/json_api/have_json_api_data.rb +110 -0
  46. data/lib/api_matchers/json_api/have_json_api_relationships.rb +62 -0
  47. data/lib/api_matchers/json_structure/base.rb +65 -0
  48. data/lib/api_matchers/json_structure/have_json_keys.rb +55 -0
  49. data/lib/api_matchers/json_structure/have_json_type.rb +72 -0
  50. data/lib/api_matchers/pagination/base.rb +73 -0
  51. data/lib/api_matchers/pagination/be_paginated.rb +73 -0
  52. data/lib/api_matchers/pagination/have_pagination_links.rb +74 -0
  53. data/lib/api_matchers/pagination/have_total_count.rb +77 -0
  54. data/lib/api_matchers/response_body/base.rb +10 -9
  55. data/lib/api_matchers/response_body/have_json.rb +2 -4
  56. data/lib/api_matchers/response_body/have_json_node.rb +45 -1
  57. data/lib/api_matchers/response_body/have_node.rb +2 -0
  58. data/lib/api_matchers/response_body/have_xml_node.rb +13 -14
  59. data/lib/api_matchers/response_body/match_json_schema.rb +89 -0
  60. data/lib/api_matchers/version.rb +3 -1
  61. data/lib/api_matchers.rb +75 -14
  62. data/spec/api_matchers/collection/be_sorted_by_spec.rb +110 -0
  63. data/spec/api_matchers/collection/have_json_size_spec.rb +101 -0
  64. data/spec/api_matchers/error_response/have_error_on_spec.rb +123 -0
  65. data/spec/api_matchers/error_response/have_error_spec.rb +108 -0
  66. data/spec/api_matchers/hateoas/have_link_spec.rb +105 -0
  67. data/spec/api_matchers/headers/base_spec.rb +8 -3
  68. data/spec/api_matchers/headers/be_json_spec.rb +1 -1
  69. data/spec/api_matchers/headers/be_xml_spec.rb +1 -1
  70. data/spec/api_matchers/headers/have_cache_control_spec.rb +102 -0
  71. data/spec/api_matchers/headers/have_cors_headers_spec.rb +74 -0
  72. data/spec/api_matchers/headers/have_header_spec.rb +88 -0
  73. data/spec/api_matchers/http_status/be_client_error_spec.rb +53 -0
  74. data/spec/api_matchers/http_status/be_forbidden_spec.rb +33 -0
  75. data/spec/api_matchers/http_status/be_no_content_spec.rb +33 -0
  76. data/spec/api_matchers/http_status/be_not_found_spec.rb +39 -0
  77. data/spec/api_matchers/http_status/be_redirect_spec.rb +55 -0
  78. data/spec/api_matchers/http_status/be_server_error_spec.rb +49 -0
  79. data/spec/api_matchers/http_status/be_successful_spec.rb +78 -0
  80. data/spec/api_matchers/http_status/be_unauthorized_spec.rb +33 -0
  81. data/spec/api_matchers/http_status/be_unprocessable_spec.rb +39 -0
  82. data/spec/api_matchers/http_status/have_http_status_spec.rb +81 -0
  83. data/spec/api_matchers/json_api/be_json_api_compliant_spec.rb +109 -0
  84. data/spec/api_matchers/json_api/have_json_api_attributes_spec.rb +61 -0
  85. data/spec/api_matchers/json_api/have_json_api_data_spec.rb +95 -0
  86. data/spec/api_matchers/json_api/have_json_api_relationships_spec.rb +61 -0
  87. data/spec/api_matchers/json_structure/have_json_keys_spec.rb +81 -0
  88. data/spec/api_matchers/json_structure/have_json_type_spec.rb +134 -0
  89. data/spec/api_matchers/pagination/be_paginated_spec.rb +95 -0
  90. data/spec/api_matchers/pagination/have_pagination_links_spec.rb +80 -0
  91. data/spec/api_matchers/pagination/have_total_count_spec.rb +85 -0
  92. data/spec/api_matchers/response_body/base_spec.rb +15 -7
  93. data/spec/api_matchers/response_body/have_json_node_spec.rb +57 -0
  94. data/spec/api_matchers/response_body/match_json_schema_spec.rb +86 -0
  95. metadata +154 -48
  96. data/.rvmrc.example +0 -1
  97. data/.travis.yml +0 -12
  98. data/lib/api_matchers/http_status_code/base.rb +0 -32
  99. data/lib/api_matchers/http_status_code/be_bad_request.rb +0 -25
  100. data/lib/api_matchers/http_status_code/be_forbidden.rb +0 -21
  101. data/lib/api_matchers/http_status_code/be_internal_server_error.rb +0 -25
  102. data/lib/api_matchers/http_status_code/be_not_found.rb +0 -25
  103. data/lib/api_matchers/http_status_code/be_ok.rb +0 -25
  104. data/lib/api_matchers/http_status_code/be_unauthorized.rb +0 -25
  105. data/lib/api_matchers/http_status_code/be_unprocessable_entity.rb +0 -25
  106. data/lib/api_matchers/http_status_code/create_resource.rb +0 -25
  107. data/spec/api_matchers/http_status_code/base_spec.rb +0 -12
  108. data/spec/api_matchers/http_status_code/be_bad_request_spec.rb +0 -49
  109. data/spec/api_matchers/http_status_code/be_forbidden_spec.rb +0 -49
  110. data/spec/api_matchers/http_status_code/be_internal_server_error_spec.rb +0 -49
  111. data/spec/api_matchers/http_status_code/be_not_found_spec.rb +0 -49
  112. data/spec/api_matchers/http_status_code/be_ok_spec.rb +0 -49
  113. data/spec/api_matchers/http_status_code/be_unauthorized_spec.rb +0 -49
  114. data/spec/api_matchers/http_status_code/be_unprocessable_entity_spec.rb +0 -27
  115. data/spec/api_matchers/http_status_code/create_resource_spec.rb +0 -49
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 5898931ec179ab8dd81ed8552603cb2b8af12579
4
- data.tar.gz: bf28c99233720e3051d57ddf4b877720439214a4
2
+ SHA256:
3
+ metadata.gz: e95d5e4168a2bd1c785f8b34e09bfe20bd4dcec0cc3ee0abe9a9b8aaf8ed7e3f
4
+ data.tar.gz: a0a040ed88113347d1ef6cb0d106fb22f1a7d8fad9cb06efcc0e8f5d1fe74972
5
5
  SHA512:
6
- metadata.gz: 51c74fc5d3cd98e4d9b94a72c5c2301f1abed5bab16173eb20332b31f723ad206a4e95eb28931fcf6e260fa9b6d91d8d2cc09dbab35774363af8f958fc64ca48
7
- data.tar.gz: 6c13e7610d754784d6e5d7ea21223cf52c54103d5e09fad374779a3366d2a5e3cb1d0d2a3a902fcfcd3aac086ec1c581d90a0f6ad6de56060774d6f49faaaad6
6
+ metadata.gz: 1c4256cd5c98b95ef782c915a39b06adad236ae0fe6a4d2b0622151556594bc6a34644d444c0a21f25f79bf43347e34b9c5c454bd046c7aa60174da24ac60ec4
7
+ data.tar.gz: 76bb73874d08e845c587dd880418080c03eb9ae834389f3e5ec3534da4b19cdc26c8a800698d78fd239cd07965402a9e71d6ff9967fd8638adaa492e4ee3e98b
@@ -0,0 +1,30 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ ruby-version: ['3.1', '3.2', '3.3', '3.4']
16
+
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+
20
+ - name: Set up Ruby ${{ matrix.ruby-version }}
21
+ uses: ruby/setup-ruby@v1
22
+ with:
23
+ ruby-version: ${{ matrix.ruby-version }}
24
+ bundler-cache: false
25
+
26
+ - name: Install dependencies
27
+ run: bundle install
28
+
29
+ - name: Run tests
30
+ run: bundle exec rspec
data/.gitignore CHANGED
@@ -3,7 +3,6 @@
3
3
  .bundle
4
4
  .config
5
5
  .yardoc
6
- Gemfile.lock
7
6
  InstalledFiles
8
7
  _yardoc
9
8
  coverage
@@ -17,3 +16,4 @@ test/version_tmp
17
16
  tmp
18
17
  *.DS_Store
19
18
  .rvmrc
19
+ Gemfile.lock
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source 'http://rubygems.org'
1
+ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in api_matchers.gemspec
4
4
  gemspec
data/History.markdown CHANGED
@@ -1,67 +1,83 @@
1
- ## 0.6.1
1
+ # History
2
2
 
3
- * Add description to matchers. This makes RSpec not complain about missing
4
- description.
3
+ ## 1.0.0 (2026-02-04)
5
4
 
6
- ## 0.6.0
7
-
8
- * Add be_forbidden matcher:
9
-
10
- ```ruby
11
- expect(response.status).to be_forbidden
12
- ```
13
-
14
- * Add RSpec 3 and RSpec 2 compatibility.
15
-
16
- ## 0.5.1
5
+ ### Major Release - Comprehensive API Testing Suite
17
6
 
18
- * Fix #have_json matcher fail message. Fix issue #20
7
+ This release transforms API Matchers into a complete API testing toolkit with 30+ new matchers.
19
8
 
20
- ## 0.5.0
21
-
22
- * Internals - Migrate to the RSpec expect syntax.
23
-
24
- ## v0.4.0
9
+ #### New Features
25
10
 
26
- * jRuby support;
27
- * have_json matcher;
11
+ **HTTP Status Matchers**
12
+ - `have_http_status(status)` - Match by code or symbol
13
+ - `be_successful` - Match 2xx responses
14
+ - `be_redirect` - Match 3xx responses
15
+ - `be_client_error` - Match 4xx responses
16
+ - `be_server_error` - Match 5xx responses
17
+ - `be_not_found` - Match 404
18
+ - `be_unauthorized` - Match 401
19
+ - `be_forbidden` - Match 403
20
+ - `be_unprocessable` - Match 422
21
+ - `be_no_content` - Match 204
28
22
 
29
- ## v0.1.1
23
+ **JSON Structure Matchers**
24
+ - `have_json_keys(*keys)` - Verify key presence
25
+ - `have_json_type(type)` - Check value types
30
26
 
31
- 1) Support Datetime, Date and Time comparison (Thanks to Stephen Orens).
32
- 2) The have_node should accept boolean values (Thanks to Stephen Orens).
27
+ **Collection Matchers**
28
+ - `have_json_size(size)` - Verify collection sizes
29
+ - `be_sorted_by(field)` - Check sorting with `.ascending`/`.descending`
33
30
 
34
- ## v0.1.0
31
+ **Header Matchers**
32
+ - `have_header(name)` - Check headers with `.with_value`
33
+ - `have_cors_headers` - Verify CORS compliance
34
+ - `have_cache_control(*directives)` - Check cache directives
35
35
 
36
- 1) Add the #including_text for have_json_node and have_xml_node matcher:
36
+ **Pagination Matchers**
37
+ - `be_paginated` - Check pagination metadata
38
+ - `have_pagination_links(*types)` - Verify link types
39
+ - `have_total_count(count)` - Match total counts
37
40
 
38
- { :error => "Transaction error: Name can't be blank" }.to_json.should have_json_node(:error).including_text("Transaction error")
41
+ **Error Response Matchers**
42
+ - `have_error` / `have_errors` - Check error presence
43
+ - `have_error_on(field)` - Field-specific errors with `.with_message`
39
44
 
40
- "<error>Transaction error: Name can't be blank</error>".should have_xml_node(:error).including_text("Transaction error")
45
+ **JSON:API Matchers**
46
+ - `be_json_api_compliant` - Validate spec compliance
47
+ - `have_json_api_data` - Check data with `.of_type`/`.with_id`
48
+ - `have_json_api_attributes(*attrs)` - Verify attributes
49
+ - `have_json_api_relationships(*rels)` - Check relationships
41
50
 
42
- ## v0.0.2
51
+ **HATEOAS Matchers**
52
+ - `have_link(rel)` - Match HAL-style links with `.with_href`
43
53
 
44
- 1) Put the headers method and the content type key in the setup class and that will be used by the headers matchers(be_json and be_xml).
54
+ #### Improvements
55
+ - Added Ruby 3.4 support
56
+ - Modernized codebase with `frozen_string_literal` pragmas
57
+ - Simplified internal setup pattern
58
+ - Enhanced error messages across all matchers
59
+ - Comprehensive README documentation with examples
45
60
 
46
- This:
61
+ #### Breaking Changes
62
+ - Minimum Ruby version is now 3.1
63
+ - Removed deprecated configuration options
47
64
 
48
- response.headers['Content-Type'].should be_in_json
49
- response.headers['Content-Type'].should be_in_xml
65
+ ---
50
66
 
51
- With:
67
+ ## 0.6.0
52
68
 
53
- APIMatchers.setup do |config|
54
- config.header_method = :headers
55
- config.header_content_type_key = 'Content-Type'
56
- end
69
+ - Added `have_json` matcher for exact JSON matching
70
+ - Added `match_json_schema` matcher for JSON Schema validation
71
+ - Improved `have_json_node` with better nested path support
57
72
 
58
- Becomes:
73
+ ## 0.5.0
59
74
 
60
- response.should be_in_json
61
- response.should be_in_xml
75
+ - Added support for RSpec 3
76
+ - Added `have_xml_node` matcher
77
+ - Improved error messages
62
78
 
63
- ## v0.0.1
79
+ ## 0.4.0
64
80
 
65
- 1) Headers Matchers: be_xml, be_json (**OBS:** Need to think about the setup!)
66
- 2) HTTP Status Matchers: be_a_bad_request, be_internal_server_error, be_unauthorized, create_resource
67
- 3) Response body Matchers: have_node, have_json_node, have_xml_node
81
+ - Initial configurable setup
82
+ - Added `be_json` and `be_xml` content type matchers
83
+ - Added `have_node` matcher with format detection