Skip to content

Commit

Permalink
Add support for Nullable (#9)
Browse files Browse the repository at this point in the history
* Add support for nullable

* Add release binstub

* rubocop
  • Loading branch information
mkon authored Jun 2, 2022
1 parent 7128602 commit 97130d6
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 6 deletions.
4 changes: 2 additions & 2 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2022-05-04 19:32:20 UTC using RuboCop version 1.28.2.
# on 2022-06-02 11:51:09 UTC using RuboCop version 1.29.1.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
Expand All @@ -11,7 +11,7 @@
Metrics/AbcSize:
Max: 27

# Offense count: 2
# Offense count: 3
# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
Metrics/MethodLength:
Max: 15
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ First parse your api documentation:

```ruby
# This must point to the folder where the "openapi.yaml" file is
$doc = OpenapiContracts::Doc.parse(Rails.root.join('spec', 'fixtures', 'openapi', 'api-docs', 'openapi'))
$doc = OpenapiContracts::Doc.parse(Rails.root.join('spec/fixtures/openapi/api-docs/openapi'))
```

Ideally you do this once in a RSpec `before(:suite)` hook.
Expand Down
32 changes: 32 additions & 0 deletions bin/release
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/bash -le

name="openapi_contracts"

git fetch origin
current=`bin/version`
sha=`git rev-parse HEAD`

read -p "Which version? (${current}) " version
version=${version:=$current}

VERSION=$version gem build ${name}.gemspec

echo "Creating GitHub release"
link=`gh release create v${version} --target $sha --generate-notes`
echo $link
git fetch --tags origin

file="${name}-${version}.gem"
read -p "Push to rubygems? (y/n) " yn
case $yn in
y ) echo Pushing to rubygems ...;;
n ) echo Aborting.;
exit;;
* ) echo invalid response;
exit 1;;
esac

gem push $file
rm $file

open $link
18 changes: 16 additions & 2 deletions lib/openapi_contracts/doc/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ def parse(path = 'openapi.yaml')
abs_path = @dir.join(path)
data = parse_file(abs_path, translate: false)
data.deep_merge! merge_components
join_partials(abs_path.dirname, data)
data = join_partials(abs_path.dirname, data)
nullable_to_type!(data)
end

private
Expand All @@ -34,10 +35,23 @@ def join_partials(cwd, data)
end
end

def nullable_to_type!(object)
case object
when Hash
if object['type'] && object['nullable']
object['type'] = [object['type'], 'null']
object.delete 'nullable'
else
object.each_value { |o| nullable_to_type! o }
end
when Array
object.each { |o| nullable_to_type! o }
end
end

def merge_components
data = {}
Dir[File.expand_path('components/**/*.yaml', @dir)].each do |file|
# pn = Pathname(file).relative_path_from(@dir)
pointer = json_pointer(Pathname(file)).split('/')
i = 0
pointer.reduce(data) do |h, p|
Expand Down
4 changes: 4 additions & 0 deletions spec/fixtures/openapi/components/schemas/User.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@ properties:
attributes:
type: object
properties:
name:
type: string
nullable: true
email:
$ref: './Email.yaml'
additionalProperties: false
required:
- name
- email
additionalProperties: false
required:
Expand Down
1 change: 1 addition & 0 deletions spec/integration/rspec_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
id: 'some-id',
type: 'user',
attributes: {
name: nil,
email: 'name@me.example'
}
}
Expand Down
2 changes: 1 addition & 1 deletion spec/openapi_contracts/doc_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
hash = subject.to_h
expect(hash).to be_a(Hash)
expect(hash['type']).to eq 'object'
expect(hash.dig('properties', 'attributes', 'required')).to eq %w(email)
expect(hash.dig('properties', 'attributes', 'required')).to eq %w(name email)
end
end

Expand Down
9 changes: 9 additions & 0 deletions spec/openapi_contracts/matchers/match_openapi_doc_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
id: 'some-id',
type: 'user',
attributes: {
name: 'Hugo',
email: 'name@me.example'
}
}
Expand Down Expand Up @@ -86,6 +87,14 @@
end
end

context 'when a nullable attribute is null' do
before { response_body[:data][:attributes][:name] = nil }

it 'behaves correctly' do
expect(matcher.matches?(response)).to be true
end
end

context 'when path is not documented' do
before { request_env['PATH_INFO'] = '/unknown' }

Expand Down

0 comments on commit 97130d6

Please sign in to comment.