reqcord 0.1.1 → 0.1.3

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 (229) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/Gemfile +5 -0
  4. data/README.md +13 -0
  5. data/docs/configuration.md +14 -0
  6. data/examples/reqcord.yml +4 -2
  7. data/gemfiles/rails_7.1.gemfile +13 -0
  8. data/gemfiles/rails_7.2.gemfile +13 -0
  9. data/gemfiles/rails_8.0.gemfile +13 -0
  10. data/gemfiles/rails_8.1.gemfile +13 -0
  11. data/lib/reqcord/configuration.rb +7 -1
  12. data/lib/reqcord/generator.rb +1 -1
  13. data/lib/reqcord/route_collector.rb +4 -2
  14. data/lib/reqcord/version.rb +1 -1
  15. data/lib/tasks/reqcord.rake +29 -2
  16. data/reqcord.gemspec +18 -4
  17. metadata +65 -217
  18. data/.gitignore +0 -8
  19. data/Gemfile.lock +0 -171
  20. data/examples/complex-spec-app/.rspec +0 -1
  21. data/examples/complex-spec-app/README.md +0 -21
  22. data/examples/complex-spec-app/app.rb +0 -363
  23. data/examples/complex-spec-app/docs/api/README.md +0 -104
  24. data/examples/complex-spec-app/docs/api/api/v1/admin/products/create.md +0 -117
  25. data/examples/complex-spec-app/docs/api/api/v1/admin/products/destroy.md +0 -51
  26. data/examples/complex-spec-app/docs/api/api/v1/admin/products/index.md +0 -11
  27. data/examples/complex-spec-app/docs/api/api/v1/admin/products/list.md +0 -106
  28. data/examples/complex-spec-app/docs/api/api/v1/auth/index.md +0 -9
  29. data/examples/complex-spec-app/docs/api/api/v1/auth/login.md +0 -76
  30. data/examples/complex-spec-app/docs/api/api/v1/cart-items/create.md +0 -91
  31. data/examples/complex-spec-app/docs/api/api/v1/cart-items/destroy.md +0 -51
  32. data/examples/complex-spec-app/docs/api/api/v1/cart-items/index.md +0 -10
  33. data/examples/complex-spec-app/docs/api/api/v1/carts/checkout.md +0 -102
  34. data/examples/complex-spec-app/docs/api/api/v1/carts/index.md +0 -10
  35. data/examples/complex-spec-app/docs/api/api/v1/carts/show.md +0 -73
  36. data/examples/complex-spec-app/docs/api/api/v1/home/index.md +0 -9
  37. data/examples/complex-spec-app/docs/api/api/v1/home/list.md +0 -47
  38. data/examples/complex-spec-app/docs/api/api/v1/notes/create.md +0 -94
  39. data/examples/complex-spec-app/docs/api/api/v1/notes/index.md +0 -10
  40. data/examples/complex-spec-app/docs/api/api/v1/notes/list.md +0 -61
  41. data/examples/complex-spec-app/docs/api/api/v1/orders/cancel.md +0 -69
  42. data/examples/complex-spec-app/docs/api/api/v1/orders/create.md +0 -150
  43. data/examples/complex-spec-app/docs/api/api/v1/orders/destroy.md +0 -37
  44. data/examples/complex-spec-app/docs/api/api/v1/orders/index.md +0 -13
  45. data/examples/complex-spec-app/docs/api/api/v1/orders/list.md +0 -78
  46. data/examples/complex-spec-app/docs/api/api/v1/orders/show.md +0 -83
  47. data/examples/complex-spec-app/docs/api/api/v1/products/index.md +0 -11
  48. data/examples/complex-spec-app/docs/api/api/v1/products/list.md +0 -83
  49. data/examples/complex-spec-app/docs/api/api/v1/products/search.md +0 -88
  50. data/examples/complex-spec-app/docs/api/api/v1/products/show.md +0 -71
  51. data/examples/complex-spec-app/docs/api/api/v1/profiles/index.md +0 -10
  52. data/examples/complex-spec-app/docs/api/api/v1/profiles/show.md +0 -61
  53. data/examples/complex-spec-app/docs/api/api/v1/profiles/update.md +0 -91
  54. data/examples/complex-spec-app/docs/api/api/v2/products/index.md +0 -9
  55. data/examples/complex-spec-app/docs/api/api/v2/products/list.md +0 -77
  56. data/examples/complex-spec-app/docs/api/curl/api/v1/admin/products/create.sh +0 -18
  57. data/examples/complex-spec-app/docs/api/curl/api/v1/admin/products/destroy.sh +0 -9
  58. data/examples/complex-spec-app/docs/api/curl/api/v1/admin/products/list.sh +0 -9
  59. data/examples/complex-spec-app/docs/api/curl/api/v1/auth/login.sh +0 -9
  60. data/examples/complex-spec-app/docs/api/curl/api/v1/cart-items/create.sh +0 -16
  61. data/examples/complex-spec-app/docs/api/curl/api/v1/cart-items/destroy.sh +0 -9
  62. data/examples/complex-spec-app/docs/api/curl/api/v1/carts/checkout.sh +0 -13
  63. data/examples/complex-spec-app/docs/api/curl/api/v1/carts/show.sh +0 -9
  64. data/examples/complex-spec-app/docs/api/curl/api/v1/home/list.sh +0 -8
  65. data/examples/complex-spec-app/docs/api/curl/api/v1/notes/create.sh +0 -15
  66. data/examples/complex-spec-app/docs/api/curl/api/v1/notes/list.sh +0 -9
  67. data/examples/complex-spec-app/docs/api/curl/api/v1/orders/cancel.sh +0 -9
  68. data/examples/complex-spec-app/docs/api/curl/api/v1/orders/create.sh +0 -29
  69. data/examples/complex-spec-app/docs/api/curl/api/v1/orders/destroy.sh +0 -9
  70. data/examples/complex-spec-app/docs/api/curl/api/v1/orders/list.sh +0 -9
  71. data/examples/complex-spec-app/docs/api/curl/api/v1/orders/show.sh +0 -9
  72. data/examples/complex-spec-app/docs/api/curl/api/v1/products/list.sh +0 -8
  73. data/examples/complex-spec-app/docs/api/curl/api/v1/products/search.sh +0 -8
  74. data/examples/complex-spec-app/docs/api/curl/api/v1/products/show.sh +0 -8
  75. data/examples/complex-spec-app/docs/api/curl/api/v1/profiles/show.sh +0 -9
  76. data/examples/complex-spec-app/docs/api/curl/api/v1/profiles/update.sh +0 -16
  77. data/examples/complex-spec-app/docs/api/curl/api/v2/products/list.sh +0 -8
  78. data/examples/complex-spec-app/docs/api/dataset.json +0 -5116
  79. data/examples/complex-spec-app/docs/api/postman/collection.json +0 -2519
  80. data/examples/complex-spec-app/generate.rb +0 -14
  81. data/examples/complex-spec-app/reqcord.yml +0 -28
  82. data/examples/complex-spec-app/spec/requests/admin_spec.rb +0 -67
  83. data/examples/complex-spec-app/spec/requests/cart_spec.rb +0 -61
  84. data/examples/complex-spec-app/spec/requests/home_and_auth_spec.rb +0 -49
  85. data/examples/complex-spec-app/spec/requests/orders_spec.rb +0 -124
  86. data/examples/complex-spec-app/spec/requests/products_spec.rb +0 -65
  87. data/examples/complex-spec-app/spec/spec_helper.rb +0 -17
  88. data/examples/complex-test-app/README.md +0 -40
  89. data/examples/complex-test-app/app.rb +0 -384
  90. data/examples/complex-test-app/docs/api/README.md +0 -104
  91. data/examples/complex-test-app/docs/api/api/v1/admin/products/create.md +0 -117
  92. data/examples/complex-test-app/docs/api/api/v1/admin/products/destroy.md +0 -51
  93. data/examples/complex-test-app/docs/api/api/v1/admin/products/index.md +0 -11
  94. data/examples/complex-test-app/docs/api/api/v1/admin/products/list.md +0 -106
  95. data/examples/complex-test-app/docs/api/api/v1/auth/index.md +0 -9
  96. data/examples/complex-test-app/docs/api/api/v1/auth/login.md +0 -76
  97. data/examples/complex-test-app/docs/api/api/v1/cart-items/create.md +0 -91
  98. data/examples/complex-test-app/docs/api/api/v1/cart-items/destroy.md +0 -51
  99. data/examples/complex-test-app/docs/api/api/v1/cart-items/index.md +0 -10
  100. data/examples/complex-test-app/docs/api/api/v1/carts/checkout.md +0 -102
  101. data/examples/complex-test-app/docs/api/api/v1/carts/index.md +0 -10
  102. data/examples/complex-test-app/docs/api/api/v1/carts/show.md +0 -73
  103. data/examples/complex-test-app/docs/api/api/v1/home/index.md +0 -9
  104. data/examples/complex-test-app/docs/api/api/v1/home/list.md +0 -47
  105. data/examples/complex-test-app/docs/api/api/v1/notes/create.md +0 -94
  106. data/examples/complex-test-app/docs/api/api/v1/notes/index.md +0 -10
  107. data/examples/complex-test-app/docs/api/api/v1/notes/list.md +0 -61
  108. data/examples/complex-test-app/docs/api/api/v1/orders/cancel.md +0 -69
  109. data/examples/complex-test-app/docs/api/api/v1/orders/create.md +0 -150
  110. data/examples/complex-test-app/docs/api/api/v1/orders/destroy.md +0 -37
  111. data/examples/complex-test-app/docs/api/api/v1/orders/index.md +0 -13
  112. data/examples/complex-test-app/docs/api/api/v1/orders/list.md +0 -71
  113. data/examples/complex-test-app/docs/api/api/v1/orders/show.md +0 -83
  114. data/examples/complex-test-app/docs/api/api/v1/products/index.md +0 -11
  115. data/examples/complex-test-app/docs/api/api/v1/products/list.md +0 -83
  116. data/examples/complex-test-app/docs/api/api/v1/products/search.md +0 -88
  117. data/examples/complex-test-app/docs/api/api/v1/products/show.md +0 -71
  118. data/examples/complex-test-app/docs/api/api/v1/profiles/index.md +0 -10
  119. data/examples/complex-test-app/docs/api/api/v1/profiles/show.md +0 -61
  120. data/examples/complex-test-app/docs/api/api/v1/profiles/update.md +0 -91
  121. data/examples/complex-test-app/docs/api/api/v2/products/index.md +0 -9
  122. data/examples/complex-test-app/docs/api/api/v2/products/list.md +0 -77
  123. data/examples/complex-test-app/docs/api/curl/api/v1/admin/products/create.sh +0 -18
  124. data/examples/complex-test-app/docs/api/curl/api/v1/admin/products/destroy.sh +0 -9
  125. data/examples/complex-test-app/docs/api/curl/api/v1/admin/products/list.sh +0 -9
  126. data/examples/complex-test-app/docs/api/curl/api/v1/auth/login.sh +0 -9
  127. data/examples/complex-test-app/docs/api/curl/api/v1/cart-items/create.sh +0 -16
  128. data/examples/complex-test-app/docs/api/curl/api/v1/cart-items/destroy.sh +0 -9
  129. data/examples/complex-test-app/docs/api/curl/api/v1/carts/checkout.sh +0 -13
  130. data/examples/complex-test-app/docs/api/curl/api/v1/carts/show.sh +0 -9
  131. data/examples/complex-test-app/docs/api/curl/api/v1/home/list.sh +0 -8
  132. data/examples/complex-test-app/docs/api/curl/api/v1/notes/create.sh +0 -15
  133. data/examples/complex-test-app/docs/api/curl/api/v1/notes/list.sh +0 -9
  134. data/examples/complex-test-app/docs/api/curl/api/v1/orders/cancel.sh +0 -9
  135. data/examples/complex-test-app/docs/api/curl/api/v1/orders/create.sh +0 -29
  136. data/examples/complex-test-app/docs/api/curl/api/v1/orders/destroy.sh +0 -9
  137. data/examples/complex-test-app/docs/api/curl/api/v1/orders/list.sh +0 -9
  138. data/examples/complex-test-app/docs/api/curl/api/v1/orders/show.sh +0 -9
  139. data/examples/complex-test-app/docs/api/curl/api/v1/products/list.sh +0 -8
  140. data/examples/complex-test-app/docs/api/curl/api/v1/products/search.sh +0 -8
  141. data/examples/complex-test-app/docs/api/curl/api/v1/products/show.sh +0 -8
  142. data/examples/complex-test-app/docs/api/curl/api/v1/profiles/show.sh +0 -9
  143. data/examples/complex-test-app/docs/api/curl/api/v1/profiles/update.sh +0 -16
  144. data/examples/complex-test-app/docs/api/curl/api/v2/products/list.sh +0 -8
  145. data/examples/complex-test-app/docs/api/dataset.json +0 -5109
  146. data/examples/complex-test-app/docs/api/postman/collection.json +0 -2568
  147. data/examples/complex-test-app/generate.rb +0 -14
  148. data/examples/complex-test-app/reqcord.yml +0 -28
  149. data/examples/complex-test-app/test/integration/admin_test.rb +0 -70
  150. data/examples/complex-test-app/test/integration/cart_test.rb +0 -64
  151. data/examples/complex-test-app/test/integration/home_and_auth_test.rb +0 -53
  152. data/examples/complex-test-app/test/integration/orders_test.rb +0 -127
  153. data/examples/complex-test-app/test/integration/products_test.rb +0 -66
  154. data/examples/spec-app/.rspec +0 -1
  155. data/examples/spec-app/README.md +0 -36
  156. data/examples/spec-app/app.rb +0 -209
  157. data/examples/spec-app/docs/api/README.md +0 -45
  158. data/examples/spec-app/docs/api/api/v1/customers/create.md +0 -95
  159. data/examples/spec-app/docs/api/api/v1/customers/index.md +0 -11
  160. data/examples/spec-app/docs/api/api/v1/customers/list.md +0 -67
  161. data/examples/spec-app/docs/api/api/v1/customers/show.md +0 -65
  162. data/examples/spec-app/docs/api/api/v1/tasks/complete.md +0 -51
  163. data/examples/spec-app/docs/api/api/v1/tasks/create.md +0 -90
  164. data/examples/spec-app/docs/api/api/v1/tasks/destroy.md +0 -35
  165. data/examples/spec-app/docs/api/api/v1/tasks/index.md +0 -14
  166. data/examples/spec-app/docs/api/api/v1/tasks/list.md +0 -65
  167. data/examples/spec-app/docs/api/api/v1/tasks/show.md +0 -65
  168. data/examples/spec-app/docs/api/api/v1/tasks/update.md +0 -74
  169. data/examples/spec-app/docs/api/api/v1/users/create.md +0 -95
  170. data/examples/spec-app/docs/api/api/v1/users/index.md +0 -11
  171. data/examples/spec-app/docs/api/api/v1/users/list.md +0 -67
  172. data/examples/spec-app/docs/api/api/v1/users/show.md +0 -65
  173. data/examples/spec-app/docs/api/curl/api/v1/customers/create.sh +0 -17
  174. data/examples/spec-app/docs/api/curl/api/v1/customers/list.sh +0 -9
  175. data/examples/spec-app/docs/api/curl/api/v1/customers/show.sh +0 -9
  176. data/examples/spec-app/docs/api/curl/api/v1/tasks/complete.sh +0 -8
  177. data/examples/spec-app/docs/api/curl/api/v1/tasks/create.sh +0 -15
  178. data/examples/spec-app/docs/api/curl/api/v1/tasks/destroy.sh +0 -8
  179. data/examples/spec-app/docs/api/curl/api/v1/tasks/list.sh +0 -8
  180. data/examples/spec-app/docs/api/curl/api/v1/tasks/show.sh +0 -8
  181. data/examples/spec-app/docs/api/curl/api/v1/tasks/update.sh +0 -14
  182. data/examples/spec-app/docs/api/curl/api/v1/users/create.sh +0 -17
  183. data/examples/spec-app/docs/api/curl/api/v1/users/list.sh +0 -9
  184. data/examples/spec-app/docs/api/curl/api/v1/users/show.sh +0 -9
  185. data/examples/spec-app/docs/api/dataset.json +0 -2402
  186. data/examples/spec-app/docs/api/postman/collection.json +0 -1290
  187. data/examples/spec-app/generate.rb +0 -14
  188. data/examples/spec-app/reqcord.yml +0 -27
  189. data/examples/spec-app/spec/requests/customers_spec.rb +0 -71
  190. data/examples/spec-app/spec/requests/tasks_spec.rb +0 -78
  191. data/examples/spec-app/spec/requests/users_spec.rb +0 -68
  192. data/examples/spec-app/spec/spec_helper.rb +0 -17
  193. data/examples/test-app/README.md +0 -57
  194. data/examples/test-app/app.rb +0 -212
  195. data/examples/test-app/docs/api/README.md +0 -45
  196. data/examples/test-app/docs/api/api/v1/customers/create.md +0 -95
  197. data/examples/test-app/docs/api/api/v1/customers/index.md +0 -11
  198. data/examples/test-app/docs/api/api/v1/customers/list.md +0 -67
  199. data/examples/test-app/docs/api/api/v1/customers/show.md +0 -65
  200. data/examples/test-app/docs/api/api/v1/tasks/complete.md +0 -51
  201. data/examples/test-app/docs/api/api/v1/tasks/create.md +0 -90
  202. data/examples/test-app/docs/api/api/v1/tasks/destroy.md +0 -35
  203. data/examples/test-app/docs/api/api/v1/tasks/index.md +0 -14
  204. data/examples/test-app/docs/api/api/v1/tasks/list.md +0 -65
  205. data/examples/test-app/docs/api/api/v1/tasks/show.md +0 -65
  206. data/examples/test-app/docs/api/api/v1/tasks/update.md +0 -74
  207. data/examples/test-app/docs/api/api/v1/users/create.md +0 -95
  208. data/examples/test-app/docs/api/api/v1/users/index.md +0 -11
  209. data/examples/test-app/docs/api/api/v1/users/list.md +0 -67
  210. data/examples/test-app/docs/api/api/v1/users/show.md +0 -65
  211. data/examples/test-app/docs/api/curl/api/v1/customers/create.sh +0 -17
  212. data/examples/test-app/docs/api/curl/api/v1/customers/list.sh +0 -9
  213. data/examples/test-app/docs/api/curl/api/v1/customers/show.sh +0 -9
  214. data/examples/test-app/docs/api/curl/api/v1/tasks/complete.sh +0 -8
  215. data/examples/test-app/docs/api/curl/api/v1/tasks/create.sh +0 -15
  216. data/examples/test-app/docs/api/curl/api/v1/tasks/destroy.sh +0 -8
  217. data/examples/test-app/docs/api/curl/api/v1/tasks/list.sh +0 -8
  218. data/examples/test-app/docs/api/curl/api/v1/tasks/show.sh +0 -8
  219. data/examples/test-app/docs/api/curl/api/v1/tasks/update.sh +0 -14
  220. data/examples/test-app/docs/api/curl/api/v1/users/create.sh +0 -17
  221. data/examples/test-app/docs/api/curl/api/v1/users/list.sh +0 -9
  222. data/examples/test-app/docs/api/curl/api/v1/users/show.sh +0 -9
  223. data/examples/test-app/docs/api/dataset.json +0 -2402
  224. data/examples/test-app/docs/api/postman/collection.json +0 -1290
  225. data/examples/test-app/generate.rb +0 -14
  226. data/examples/test-app/reqcord.yml +0 -28
  227. data/examples/test-app/test/integration/customers_test.rb +0 -72
  228. data/examples/test-app/test/integration/tasks_test.rb +0 -80
  229. data/examples/test-app/test/integration/users_test.rb +0 -72
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2203f5a2f9ca4548874caf3a40a93c8fbe5a73e6f9d916f6162cbd843fec4341
4
- data.tar.gz: 05b67df4290c1e6aeba3e5a29416df3f5e779c2d5fcf3eef6cfd76e4a8fabdb8
3
+ metadata.gz: 5b5479eb9ebc313b6b16250eb40692a664c4d7f56eba83a5875a061153714941
4
+ data.tar.gz: 61a8fa46ddcef53e0e318589d94fd485e25f7666a3042d2050d05138350db83b
5
5
  SHA512:
6
- metadata.gz: 11602f1a318f214c92cec4f68723d47ba8b237fa8fb4d7a46e2fe2628168441e9ab3ec8f1f8cf73922f2b3bc5ac0954876e2904e03f9454fd8c99faa7648141f
7
- data.tar.gz: a273eb86d0b0939215a3375054239c2361d1520c0bf2c8faa8429ae15a9db8c1d923cf005731bd8690da67529496217c807d75abb760f2d963588109273f9e9e
6
+ metadata.gz: 3794123441aba25e1aa5a0fd5560ef280cda236ce4eee98b939f684d2cb40a6833b82358331cdf5a609b18076112901b7b9cefa623bea10145350a5d6f729205
7
+ data.tar.gz: 5b416b598625d8f76df50cdce032eafddd6102f0a00f364231f334c7d3939041b2e5d622adb801ee3e04ef00d61936ab0c75b1850c3018445954e78ea8236869
data/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.3] - Unreleased
4
+
5
+ ### Added
6
+
7
+ * `routes.prefix` accepts a list (`[/v1, /v2, /partner]`) for APIs whose
8
+ versions or audiences do not share a root.
9
+
10
+ ### Changed
11
+
12
+ * The `reqcord:init` template now names test directories (`test.paths`)
13
+ instead of running the whole suite, and documents every key inline.
14
+
15
+ ## [0.1.2] - 2026-09-16
16
+
17
+ ### Added
18
+
19
+ * Rails 7.1 and 7.2 are supported alongside 8.x (Ruby 3.2+); CI runs every
20
+ supported Ruby × Rails pair through `gemfiles/`.
21
+
22
+ ### Fixed
23
+
24
+ * CI resolves the bundle per Ruby (no committed `Gemfile.lock`) and pins
25
+ `json < 3` for development: activesupport 8.1 calls `JSON.parse(json,
26
+ options)`, a signature json 3.0 dropped.
27
+
3
28
  ## [0.1.1] - 2026-09-15
4
29
 
5
30
  ### Added
data/Gemfile CHANGED
@@ -3,3 +3,8 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gemspec
6
+
7
+ # activesupport 8.1.3.1 calls JSON.parse(json, options), a signature json 3.0
8
+ # dropped, so every JSON request body fails to parse with a 400. Development
9
+ # only: the gemspec leaves json to the host application and to Rails.
10
+ gem "json", "< 3"
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Reqcord
2
2
 
3
+ [![CI](https://github.com/ahmetsaridogan/reqcord/actions/workflows/ci.yml/badge.svg)](https://github.com/ahmetsaridogan/reqcord/actions/workflows/ci.yml)
4
+
3
5
  **Turn your Rails integration tests into living API documentation.**
4
6
 
5
7
  Reqcord observes real HTTP requests and responses executed by your Rails test suite and converts them into static, readable API documentation.
@@ -212,6 +214,17 @@ The internal dataset is framework-independent and output-independent.
212
214
 
213
215
  This allows Reqcord to support additional test frameworks and documentation formats without coupling them together.
214
216
 
217
+ ## Supported versions
218
+
219
+ | | |
220
+ | --- | --- |
221
+ | Ruby | 3.2, 3.3, 3.4 |
222
+ | Rails | 7.1, 7.2, 8.0, 8.1 |
223
+ | Test frameworks | Minitest integration tests, RSpec request specs |
224
+
225
+ Every Ruby × Rails pair that Rails itself supports runs in CI
226
+ (`gemfiles/rails_*.gemfile`).
227
+
215
228
  ## Installation
216
229
 
217
230
  Add Reqcord to the development and test groups:
@@ -146,6 +146,20 @@ routes:
146
146
  prefix: /api/v2
147
147
  ```
148
148
 
149
+ A list documents routes under any of the prefixes — for APIs whose versions
150
+ or audiences do not share a root:
151
+
152
+ ```yaml
153
+ routes:
154
+ prefix:
155
+ - /v1
156
+ - /v2
157
+ - /partner
158
+ ```
159
+
160
+ One prefix already covers every version beneath it (`/api` includes `/api/v1`
161
+ and `/api/v2`); use `VERSION=v2` to generate for one of them.
162
+
149
163
  Rails' own routes (`rails/…`, Active Storage, Action Mailbox, Turbo) are always
150
164
  left out. `redirect(...)` routes and plain Rack mounts cannot be documented from
151
165
  a test; they are counted as *skipped* in the report rather than dropped.
data/examples/reqcord.yml CHANGED
@@ -20,8 +20,10 @@ test:
20
20
  # command: bin/rails test test/integration test/api
21
21
 
22
22
  routes:
23
- # Only routes under this prefix are documented. Filter a single run with
24
- # RESOURCE=customers,cart or VERSION=v2 instead of editing this file.
23
+ # Only routes under this prefix are documented; a list works too:
24
+ # prefix: [/api, /partner]
25
+ # Filter a single run with RESOURCE=customers,cart or VERSION=v2 instead of
26
+ # editing this file.
25
27
  prefix: /api
26
28
 
27
29
  output:
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # CI: BUNDLE_GEMFILE=gemfiles/rails_7.1.gemfile bundle exec rake test
4
+
5
+ source "https://rubygems.org"
6
+
7
+ gemspec path: ".."
8
+
9
+ gem "railties", "~> 7.1.0"
10
+ gem "actionpack", "~> 7.1.0"
11
+
12
+ # activesupport calls JSON.parse(json, options); json 3.0 dropped that signature.
13
+ gem "json", "< 3"
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # CI: BUNDLE_GEMFILE=gemfiles/rails_7.2.gemfile bundle exec rake test
4
+
5
+ source "https://rubygems.org"
6
+
7
+ gemspec path: ".."
8
+
9
+ gem "railties", "~> 7.2.0"
10
+ gem "actionpack", "~> 7.2.0"
11
+
12
+ # activesupport calls JSON.parse(json, options); json 3.0 dropped that signature.
13
+ gem "json", "< 3"
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # CI: BUNDLE_GEMFILE=gemfiles/rails_8.0.gemfile bundle exec rake test
4
+
5
+ source "https://rubygems.org"
6
+
7
+ gemspec path: ".."
8
+
9
+ gem "railties", "~> 8.0.0"
10
+ gem "actionpack", "~> 8.0.0"
11
+
12
+ # activesupport calls JSON.parse(json, options); json 3.0 dropped that signature.
13
+ gem "json", "< 3"
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # CI: BUNDLE_GEMFILE=gemfiles/rails_8.1.gemfile bundle exec rake test
4
+
5
+ source "https://rubygems.org"
6
+
7
+ gemspec path: ".."
8
+
9
+ gem "railties", "~> 8.1.0"
10
+ gem "actionpack", "~> 8.1.0"
11
+
12
+ # activesupport calls JSON.parse(json, options); json 3.0 dropped that signature.
13
+ gem "json", "< 3"
@@ -123,8 +123,14 @@ module Reqcord
123
123
  Array(data.dig("test", "paths")).map(&:to_s)
124
124
  end
125
125
 
126
+ # `prefix: /api` or `prefix: [/v1, /v2]`; a route under any of them is
127
+ # documented. Empty means every route.
128
+ def route_prefixes
129
+ Array(data.dig("routes", "prefix")).map(&:to_s).reject(&:empty?)
130
+ end
131
+
126
132
  def route_prefix
127
- data.dig("routes", "prefix")
133
+ route_prefixes.first
128
134
  end
129
135
 
130
136
  def output_directory
@@ -187,7 +187,7 @@ module Reqcord
187
187
  collector = RouteCollector.new(
188
188
  resources: resources,
189
189
  version: version,
190
- prefix: configuration.route_prefix
190
+ prefix: configuration.route_prefixes
191
191
  )
192
192
 
193
193
  routes = collector.call
@@ -211,10 +211,12 @@ module Reqcord
211
211
  )
212
212
  end
213
213
 
214
+ # `prefix` is one string or a list; nothing configured means every route.
214
215
  def matches_prefix?(path)
215
- return true if prefix.nil? || prefix.empty?
216
+ prefixes = Array(prefix).map(&:to_s).reject(&:empty?)
217
+ return true if prefixes.empty?
216
218
 
217
- path.start_with?(prefix)
219
+ prefixes.any? { |candidate| path.start_with?(candidate) }
218
220
  end
219
221
 
220
222
  # `RESOURCE=customers`, `RESOURCE=cart` (a singular resource is served by
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Reqcord
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.3"
5
5
  end
@@ -11,31 +11,58 @@ namespace :reqcord do
11
11
  end
12
12
 
13
13
  content = <<~YAML
14
+ # Reqcord configuration. Every key is documented in the gem's
15
+ # docs/configuration.md. Precedence: environment > this file > defaults.
14
16
  version: 1
15
17
 
16
18
  test:
19
+ # minitest or rspec
17
20
  framework: minitest
18
- command: bin/rails test
21
+
22
+ # The tests that exercise your API. Reqcord runs `bin/rails test <paths>`
23
+ # (or `rspec <paths>`) with capture enabled; a directory is enough.
24
+ paths:
25
+ - test/integration
26
+
27
+ # Or spell the command out yourself; it wins over `paths`.
28
+ # command: bin/rails test test/integration test/api
19
29
 
20
30
  routes:
31
+ # Only routes under this prefix are documented; a list works too
32
+ # (`prefix: [/v1, /v2]`). Filter a single run with
33
+ # RESOURCE=customers,cart or VERSION=v2.
21
34
  prefix: /api
22
35
 
23
36
  output:
24
37
  directory: docs/api
38
+
39
+ # Routes no test reached with a 2xx are listed in the index either
40
+ # way; `true` also writes a page for each of them.
25
41
  include_uncovered: false
26
42
 
43
+ # markdown: pages under docs/api, curl: one runnable .sh per endpoint,
44
+ # postman: postman/collection.json (import into Postman or Hoppscotch).
27
45
  exporters:
28
46
  - curl
29
47
  - markdown
30
48
  - postman
31
49
 
32
50
  variables:
51
+ # Host of every generated cURL and the Postman `base_url` variable.
33
52
  base_url: http://localhost:3000
34
53
 
35
54
  sanitize:
55
+ # Header values are replaced verbatim. Authorization, Cookie and
56
+ # X-Api-Key are always redacted, configured here or not.
36
57
  headers:
37
58
  Authorization: "Bearer {{token}}"
38
59
  X-Api-Key: "{{api_key}}"
60
+
61
+ # Body keys, matched at any depth in requests and responses. password,
62
+ # token, access_token, api_key, secret are always redacted; add the
63
+ # fields your API exposes (a signed payment link, for example).
64
+ body:
65
+ password: "{{password}}"
39
66
  YAML
40
67
 
41
68
  File.write(path, content)
@@ -82,7 +109,7 @@ namespace :reqcord do
82
109
  Reqcord::RouteCollector.call(
83
110
  resources: ENV.fetch("RESOURCE", "").split(",").map(&:strip).reject(&:empty?),
84
111
  version: ENV["VERSION"],
85
- prefix: Reqcord.configuration.route_prefix
112
+ prefix: Reqcord.configuration.route_prefixes
86
113
  )
87
114
 
88
115
  if routes.empty?
data/reqcord.gemspec CHANGED
@@ -24,23 +24,37 @@ Gem::Specification.new do |spec|
24
24
  spec.metadata["source_code_uri"] = spec.homepage
25
25
  spec.metadata["rubygems_mfa_required"] = "true"
26
26
 
27
+ # What ships: lib/, the rake task, the docs and the annotated config. Tests,
28
+ # CI files and the example apps (with their generated output) stay on
29
+ # GitHub — `git ls-files` runs against the checkout, so `gem build` must be
30
+ # run from the repository root.
27
31
  spec.files = Dir.chdir(__dir__) do
28
32
  `git ls-files -z`.split("\x0").reject do |file|
29
33
  file.start_with?(
30
34
  "test/",
31
35
  "spec/",
32
36
  "features/",
33
- ".git/",
37
+ "examples/",
38
+ ".git",
34
39
  ".github/"
35
40
  ) || file.end_with?(".gem")
36
- end
41
+ end + ["examples/reqcord.yml"]
37
42
  end
38
43
 
39
44
  spec.require_paths = ["lib"]
40
45
 
41
- spec.add_dependency "railties", ">= 8.0", "< 9.0"
42
- spec.add_dependency "actionpack", ">= 8.0", "< 9.0"
46
+ # Rails 7.1 through 8.x; every version is exercised in CI (see gemfiles/).
47
+ spec.add_dependency "railties", ">= 7.1", "< 9.0"
48
+ spec.add_dependency "actionpack", ">= 7.1", "< 9.0"
43
49
 
44
50
  spec.add_development_dependency "minitest"
45
51
  spec.add_development_dependency "rake"
52
+
53
+ # The test suite serves the dummy app over HTTP to replay the generated
54
+ # cURL and Postman collection, validates the collection against the
55
+ # Postman schema, and runs the RSpec example apps.
56
+ spec.add_development_dependency "puma"
57
+ spec.add_development_dependency "json-schema"
58
+ spec.add_development_dependency "rspec-core"
59
+ spec.add_development_dependency "rspec-expectations"
46
60
  end