skooma 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +22 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.md +125 -0
  5. data/data/oas-3.1/dialect/base.json +25 -0
  6. data/data/oas-3.1/meta/base.json +96 -0
  7. data/data/oas-3.1/schema/2022-10-07.json +1441 -0
  8. data/data/oas-3.1/schema-base/2022-10-07.json +23 -0
  9. data/lib/skooma/body_parsers.rb +31 -0
  10. data/lib/skooma/dialects/oas_3_1.rb +41 -0
  11. data/lib/skooma/inflector.rb +19 -0
  12. data/lib/skooma/instance.rb +112 -0
  13. data/lib/skooma/keywords/oas_3_1/dialect/discriminator.rb +13 -0
  14. data/lib/skooma/keywords/oas_3_1/dialect/example.rb +13 -0
  15. data/lib/skooma/keywords/oas_3_1/dialect/external_docs.rb +13 -0
  16. data/lib/skooma/keywords/oas_3_1/dialect/xml.rb +13 -0
  17. data/lib/skooma/keywords/oas_3_1/schema.rb +32 -0
  18. data/lib/skooma/keywords/oas_3_1.rb +22 -0
  19. data/lib/skooma/objects/base/keywords/deprecated.rb +13 -0
  20. data/lib/skooma/objects/base/keywords/description.rb +13 -0
  21. data/lib/skooma/objects/base/keywords/security.rb +13 -0
  22. data/lib/skooma/objects/base/keywords/servers.rb +13 -0
  23. data/lib/skooma/objects/base/keywords/summary.rb +13 -0
  24. data/lib/skooma/objects/base/keywords/tags.rb +13 -0
  25. data/lib/skooma/objects/base.rb +33 -0
  26. data/lib/skooma/objects/callback.rb +12 -0
  27. data/lib/skooma/objects/components.rb +30 -0
  28. data/lib/skooma/objects/header/keywords/content.rb +50 -0
  29. data/lib/skooma/objects/header/keywords/example.rb +13 -0
  30. data/lib/skooma/objects/header/keywords/examples.rb +13 -0
  31. data/lib/skooma/objects/header/keywords/explode.rb +13 -0
  32. data/lib/skooma/objects/header/keywords/required.rb +19 -0
  33. data/lib/skooma/objects/header/keywords/schema.rb +19 -0
  34. data/lib/skooma/objects/header/keywords/style.rb +13 -0
  35. data/lib/skooma/objects/header.rb +23 -0
  36. data/lib/skooma/objects/media_type.rb +14 -0
  37. data/lib/skooma/objects/openapi/keywords/components.rb +23 -0
  38. data/lib/skooma/objects/openapi/keywords/info.rb +13 -0
  39. data/lib/skooma/objects/openapi/keywords/json_schema_dialect.rb +21 -0
  40. data/lib/skooma/objects/openapi/keywords/openapi.rb +24 -0
  41. data/lib/skooma/objects/openapi/keywords/paths.rb +62 -0
  42. data/lib/skooma/objects/openapi/keywords/security.rb +13 -0
  43. data/lib/skooma/objects/openapi/keywords/webhooks.rb +15 -0
  44. data/lib/skooma/objects/openapi.rb +39 -0
  45. data/lib/skooma/objects/operation/keywords/callbacks.rb +13 -0
  46. data/lib/skooma/objects/operation/keywords/operation_id.rb +13 -0
  47. data/lib/skooma/objects/operation/keywords/parameters.rb +53 -0
  48. data/lib/skooma/objects/operation/keywords/request_body.rb +21 -0
  49. data/lib/skooma/objects/operation/keywords/responses.rb +48 -0
  50. data/lib/skooma/objects/operation.rb +31 -0
  51. data/lib/skooma/objects/parameter/keywords/allow_empty_value.rb +13 -0
  52. data/lib/skooma/objects/parameter/keywords/allow_reserved.rb +13 -0
  53. data/lib/skooma/objects/parameter/keywords/content.rb +21 -0
  54. data/lib/skooma/objects/parameter/keywords/in.rb +13 -0
  55. data/lib/skooma/objects/parameter/keywords/name.rb +13 -0
  56. data/lib/skooma/objects/parameter/keywords/required.rb +19 -0
  57. data/lib/skooma/objects/parameter/keywords/schema.rb +21 -0
  58. data/lib/skooma/objects/parameter/keywords/value_parser.rb +80 -0
  59. data/lib/skooma/objects/parameter.rb +27 -0
  60. data/lib/skooma/objects/path_item/keywords/base_operation.rb +25 -0
  61. data/lib/skooma/objects/path_item/keywords/delete.rb +16 -0
  62. data/lib/skooma/objects/path_item/keywords/get.rb +16 -0
  63. data/lib/skooma/objects/path_item/keywords/head.rb +16 -0
  64. data/lib/skooma/objects/path_item/keywords/options.rb +16 -0
  65. data/lib/skooma/objects/path_item/keywords/parameters.rb +19 -0
  66. data/lib/skooma/objects/path_item/keywords/patch.rb +16 -0
  67. data/lib/skooma/objects/path_item/keywords/post.rb +16 -0
  68. data/lib/skooma/objects/path_item/keywords/put.rb +16 -0
  69. data/lib/skooma/objects/path_item/keywords/trace.rb +16 -0
  70. data/lib/skooma/objects/path_item.rb +28 -0
  71. data/lib/skooma/objects/ref_base.rb +33 -0
  72. data/lib/skooma/objects/request_body/keywords/required.rb +19 -0
  73. data/lib/skooma/objects/request_body.rb +17 -0
  74. data/lib/skooma/objects/response/keywords/content.rb +51 -0
  75. data/lib/skooma/objects/response/keywords/headers.rb +37 -0
  76. data/lib/skooma/objects/response/keywords/links.rb +13 -0
  77. data/lib/skooma/objects/response.rb +18 -0
  78. data/lib/skooma/output_format.rb +35 -0
  79. data/lib/skooma/rspec.rb +166 -0
  80. data/lib/skooma/validators/double.rb +13 -0
  81. data/lib/skooma/validators/float.rb +13 -0
  82. data/lib/skooma/validators/int_32.rb +15 -0
  83. data/lib/skooma/validators/int_64.rb +15 -0
  84. data/lib/skooma/version.rb +5 -0
  85. data/lib/skooma.rb +26 -0
  86. metadata +161 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 966ef8f92df0a6f38895c4aca4185b297256042173a3b42d32da01d5b826c24e
4
+ data.tar.gz: c1a4661e7228815c3d1a031ffb646cefd067031e1b1138346f845af469a89135
5
+ SHA512:
6
+ metadata.gz: 047e598c99b797d98b7758a015ced5323c0dfe2889f64cca8e33b7a139713fa7515683da2e054c1597a1a1b79e62b9f77ab10e72d0b7276908e15b862cb54367
7
+ data.tar.gz: 1b0dbfa91b60430bd1397d4145cc4d339c2144bfdda88d9c9085800a51a9fa0077087e09c3eb998136cf35c95b49d9449153113976fe6c72fbf6fa5258334841
data/CHANGELOG.md ADDED
@@ -0,0 +1,22 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog],
6
+ and this project adheres to [Semantic Versioning].
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2023-09-27
11
+
12
+ ### Added
13
+
14
+ - Initial implementation. ([@skryukov])
15
+
16
+ [@skryukov]: https://github.com/skryukov
17
+
18
+ [Unreleased]: https://github.com/skryukov/skooma/compare/v0.1.0...HEAD
19
+ [0.1.0]: https://github.com/skryukov/skooma/commits/v0.1.0
20
+
21
+ [Keep a Changelog]: https://keepachangelog.com/en/1.0.0/
22
+ [Semantic Versioning]: https://semver.org/spec/v2.0.0.html
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023 Svyatoslav Kryukov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,125 @@
1
+ # Skooma – Sugar for your APIs
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/skooma.svg)](https://rubygems.org/gems/skooma)
4
+ [![Ruby](https://github.com/skryukov/skooma/actions/workflows/main.yml/badge.svg)](https://github.com/skryukov/skooma/actions/workflows/main.yml)
5
+
6
+ Skooma is a Ruby library for validating API implementations against OpenAPI documents.
7
+
8
+ Features:
9
+ - Supports OpenAPI 3.1.0
10
+ - Supports OpenAPI document validation
11
+ - Supports request/response validations against OpenAPI document
12
+
13
+ <a href="https://evilmartians.com/?utm_source=skooma&utm_campaign=project_page">
14
+ <img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54">
15
+ </a>
16
+
17
+ ## Installation
18
+
19
+ Install the gem and add to the application's Gemfile by executing:
20
+
21
+ $ bundle add skooma
22
+
23
+ If bundler is not being used to manage dependencies, install the gem by executing:
24
+
25
+ $ gem install skooma
26
+
27
+ ## Usage
28
+
29
+ ### Configuration
30
+
31
+ ```ruby
32
+ # spec/rails_helper.rb
33
+
34
+ RSpec.configure do |config|
35
+ # ...
36
+ Skooma.create_registry
37
+ path_to_openapi = Rails.root.join("docs", "openapi.yml")
38
+ config.include Skooma::RSpec[path_to_openapi], type: :request
39
+ end
40
+ ```
41
+
42
+ ### Validate OpenAPI document
43
+
44
+ ```ruby
45
+ # spec/openapi_spec.rb
46
+
47
+ require "rails_helper"
48
+
49
+ describe "OpenAPI document", type: :request do
50
+ subject(:schema) { skooma_openapi_schema }
51
+
52
+ it { is_expected.to be_valid_document }
53
+ end
54
+ ```
55
+
56
+ ### Validate request
57
+
58
+ ```ruby
59
+ # spec/requests/feed_spec.rb
60
+
61
+ require "rails_helper"
62
+
63
+ describe "/animals/:animal_id/feed" do
64
+ let(:animal) { create(:animal, :unicorn) }
65
+
66
+ describe "POST" do
67
+ subject { post "/animals/#{animal.id}/feed", body:, as: :json }
68
+
69
+ let(:body) { {food: "apple", quantity: 3} }
70
+
71
+ it { is_expected.to conform_schema(200) }
72
+
73
+ context "with wrong food type" do
74
+ let(:body) { {food: "wood", quantity: 1} }
75
+
76
+ it { is_expected.to conform_schema(422) }
77
+ end
78
+ end
79
+ end
80
+
81
+ # Validation Result:
82
+ #
83
+ # {"valid"=>false,
84
+ # "instanceLocation"=>"",
85
+ # "keywordLocation"=>"",
86
+ # "absoluteKeywordLocation"=>"urn:uuid:1b4b39eb-9b93-4cc1-b6ac-32a25d9bff50#",
87
+ # "errors"=>
88
+ # [{"instanceLocation"=>"",
89
+ # "keywordLocation"=>
90
+ # "/paths/~1animals~1{animalId}~1feed/post/responses/200"/
91
+ # "/content/application~1json/schema/required",
92
+ # "error"=>
93
+ # "The object is missing required properties"/
94
+ # " [\"animalId\", \"food\", \"amount\"]"}]}
95
+ ```
96
+
97
+ ## Alternatives
98
+
99
+ - [openapi_first](https://github.com/ahx/openapi_first)
100
+ - [committee](https://github.com/interagent/committee)
101
+
102
+ ## Feature plans
103
+
104
+ - Full support for external `$ref`s
105
+ - Full OpenAPI 3.1.0 support:
106
+ - `discriminator` keyword
107
+ - respect `style` and `explode` keywords
108
+ - xml
109
+ - Callbacks and webhooks validations
110
+ - Example validations
111
+ - Ability to plug in custom X-*** keyword classes
112
+
113
+ ## Development
114
+
115
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
116
+
117
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
118
+
119
+ ## Contributing
120
+
121
+ Bug reports and pull requests are welcome on GitHub at https://github.com/skryukov/skooma.
122
+
123
+ ## License
124
+
125
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,25 @@
1
+ {
2
+ "$id": "https://spec.openapis.org/oas/3.1/dialect/base",
3
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
4
+
5
+ "title": "OpenAPI 3.1 Schema Object Dialect",
6
+ "description": "A JSON Schema dialect describing schemas found in OpenAPI documents",
7
+
8
+ "$vocabulary": {
9
+ "https://json-schema.org/draft/2020-12/vocab/core": true,
10
+ "https://json-schema.org/draft/2020-12/vocab/applicator": true,
11
+ "https://json-schema.org/draft/2020-12/vocab/unevaluated": true,
12
+ "https://json-schema.org/draft/2020-12/vocab/validation": true,
13
+ "https://json-schema.org/draft/2020-12/vocab/meta-data": true,
14
+ "https://json-schema.org/draft/2020-12/vocab/format-annotation": true,
15
+ "https://json-schema.org/draft/2020-12/vocab/content": true,
16
+ "https://spec.openapis.org/oas/3.1/vocab/base": false
17
+ },
18
+
19
+ "$dynamicAnchor": "meta",
20
+
21
+ "allOf": [
22
+ { "$ref": "https://json-schema.org/draft/2020-12/schema" },
23
+ { "$ref": "https://spec.openapis.org/oas/3.1/meta/base" }
24
+ ]
25
+ }
@@ -0,0 +1,96 @@
1
+ {
2
+ "$id": "https://spec.openapis.org/oas/3.1/meta/base",
3
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
4
+
5
+ "title": "OAS Base vocabulary",
6
+ "description": "A JSON Schema Vocabulary used in the OpenAPI Schema Dialect",
7
+
8
+ "$vocabulary": {
9
+ "https://spec.openapis.org/oas/3.1/vocab/base": true
10
+ },
11
+
12
+ "$dynamicAnchor": "meta",
13
+
14
+ "type": ["object", "boolean"],
15
+ "properties": {
16
+ "example": true,
17
+ "discriminator": { "$ref": "#/$defs/discriminator" },
18
+ "externalDocs": { "$ref": "#/$defs/external-docs" },
19
+ "xml": { "$ref": "#/$defs/xml" }
20
+ },
21
+ "dependentSchemas": {
22
+ "discriminator": {
23
+ "anyOf": [
24
+ { "required": [ "oneOf" ] },
25
+ { "required": [ "anyOf" ] },
26
+ { "required": [ "allOf" ] }
27
+ ]
28
+ }
29
+ },
30
+
31
+ "$defs": {
32
+ "extensible": {
33
+ "patternProperties": {
34
+ "^x-": true
35
+ }
36
+ },
37
+
38
+ "discriminator": {
39
+ "$ref": "#/$defs/extensible",
40
+ "type": "object",
41
+ "properties": {
42
+ "propertyName": {
43
+ "type": "string"
44
+ },
45
+ "mapping": {
46
+ "type": "object",
47
+ "additionalProperties": {
48
+ "type": "string"
49
+ }
50
+ }
51
+ },
52
+ "required": ["propertyName"],
53
+ "unevaluatedProperties": false
54
+ },
55
+
56
+ "external-docs": {
57
+ "$ref": "#/$defs/extensible",
58
+ "type": "object",
59
+ "properties": {
60
+ "url": {
61
+ "type": "string",
62
+ "format": "uri-reference"
63
+ },
64
+ "description": {
65
+ "type": "string"
66
+ }
67
+ },
68
+ "required": ["url"],
69
+ "unevaluatedProperties": false
70
+ },
71
+
72
+ "xml": {
73
+ "$ref": "#/$defs/extensible",
74
+ "type": "object",
75
+ "properties": {
76
+ "name": {
77
+ "type": "string"
78
+ },
79
+ "namespace": {
80
+ "type": "string",
81
+ "format": "uri"
82
+ },
83
+ "prefix": {
84
+ "type": "string"
85
+ },
86
+ "attribute": {
87
+ "type": "boolean"
88
+ },
89
+ "wrapped": {
90
+ "type": "boolean"
91
+ }
92
+ },
93
+ "unevaluatedProperties": false
94
+ }
95
+ }
96
+ }