dry-types-json-schema 0.0.1 → 0.0.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 33b4fa74b0afcb773080ea49a615812cb32e2d23fc0a498a5f5f8e3a5d729532
4
- data.tar.gz: d3cddcc29c63e0cdbef859ce7259155cc038e40374690b58c9e5eafaa103dd08
3
+ metadata.gz: d53a441b9ed9f57e185e971538b1a3b3f81038527e9f071c7af8fbfb8cd10a3c
4
+ data.tar.gz: d6693481b3aaa1d6b5b81b34ae91c90eea58758f094681b68ea11f9fca5ea34c
5
5
  SHA512:
6
- metadata.gz: 8b10cc09ab9ff064cf2d1fabaa859e1ca4442e247b368f3aa2c73c8f54f46e2b958898549d91c5bdf0884b97914249646a76280deddec3e0a1d7aa9243961bed
7
- data.tar.gz: 380965c43395d6742b673f9926d092fe746a593277b027edf4c90ee3f3995893ce94c838d1257d8e9eaa573dfc26ae78f304075e93d4ad4375c753c1a9397668
6
+ metadata.gz: 939497ac477bdc404b3ab166f3af9d2f42260617f96f145e73921d0dc721a57cea618d48b4738958b322be5c549268829fda68bd7309487db1e1695f47da3b16
7
+ data.tar.gz: 4e86da1db6970398e73fb22ee6d7dd3e1505198705bdcc0cddf28d7df849afcd521703043e6a550e42ee75bd526d30ecf5077d81b048498f914251554095ff26
data/.gitignore CHANGED
@@ -1 +1,2 @@
1
1
  coverage
2
+ *.gem
data/Gemfile.lock CHANGED
@@ -1,17 +1,19 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dry-types-json-schema (0.0.1)
4
+ dry-types-json-schema (0.0.2)
5
5
  dry-types (~> 1.7.2)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
10
  ast (2.4.2)
11
+ attr_extras (7.1.0)
11
12
  base64 (0.2.0)
12
13
  bigdecimal (3.1.7)
13
14
  coderay (1.1.3)
14
15
  concurrent-ruby (1.2.3)
16
+ diff-lcs (1.5.1)
15
17
  docile (1.4.0)
16
18
  dry-core (1.0.1)
17
19
  concurrent-ruby (~> 1.0)
@@ -45,10 +47,13 @@ GEM
45
47
  language_server-protocol (3.17.0.3)
46
48
  method_source (1.0.0)
47
49
  minitest (5.22.3)
50
+ optimist (3.1.0)
48
51
  parallel (1.24.0)
49
52
  parser (3.3.0.5)
50
53
  ast (~> 2.4.1)
51
54
  racc
55
+ patience_diff (1.2.0)
56
+ optimist (~> 3.0)
52
57
  pry (0.14.2)
53
58
  coderay (~> 1.1)
54
59
  method_source (~> 1.0)
@@ -81,6 +86,10 @@ GEM
81
86
  simplecov_json_formatter (0.1.4)
82
87
  simpleidn (0.2.1)
83
88
  unf (~> 0.1.4)
89
+ super_diff (0.11.0)
90
+ attr_extras (>= 6.2.4)
91
+ diff-lcs
92
+ patience_diff
84
93
  unf (0.1.4)
85
94
  unf_ext
86
95
  unf_ext (0.0.9.1)
@@ -100,6 +109,7 @@ DEPENDENCIES
100
109
  rubocop (~> 1.62.1)
101
110
  rubocop-minitest (~> 0.35.0)
102
111
  simplecov (~> 0.22.0)
112
+ super_diff (~> 0.11.0)
103
113
 
104
114
  BUNDLED WITH
105
115
  2.5.3
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "dry-types-json-schema"
5
- s.version = "0.0.1"
5
+ s.version = "0.0.2"
6
6
  s.summary = "Generate JSON Schema from dry-types"
7
7
  s.authors = ["elcuervo"]
8
8
  s.licenses = %w[MIT]
@@ -20,4 +20,5 @@ Gem::Specification.new do |s|
20
20
  s.add_development_dependency("simplecov", "~> 0.22.0")
21
21
  s.add_development_dependency("rubocop", "~> 1.62.1")
22
22
  s.add_development_dependency("rubocop-minitest", "~> 0.35.0")
23
+ s.add_development_dependency("super_diff", "~> 0.11.0")
23
24
  end
@@ -71,14 +71,13 @@ module Dry
71
71
  lt?: { exclusiveMaximum: IDENTITY },
72
72
  lteq?: { maximum: IDENTITY },
73
73
  format?: { format: INSPECT },
74
- included_in?: { enum: TO_ARRAY },
74
+ included_in?: { enum: TO_ARRAY }
75
75
  }.freeze
76
76
 
77
77
  # @return [Set] the set of required keys for the JSON Schema.
78
78
  #
79
79
  attr_reader :required
80
80
 
81
-
82
81
  # Initializes a new instance of the JSONSchema class.
83
82
  # @param root [Boolean] whether this schema is the root schema.
84
83
  # @param loose [Boolean] whether to ignore unknown predicates.
@@ -141,10 +140,7 @@ module Dry
141
140
  type, meta = node
142
141
 
143
142
  if opts.fetch(:key, false)
144
- if meta.any?
145
- @keys[opts[:key]] ||= {}
146
- @keys[opts[:key]].merge!(meta.slice(*ALLOWED_TYPES_META_OVERRIDES))
147
- end
143
+ visit_nominal_with_key(node, opts)
148
144
  else
149
145
  @keys.merge!(type: CLASS_TO_TYPE[type.to_s.to_sym])
150
146
  @keys.merge!(meta.slice(*ALLOWED_TYPES_META_OVERRIDES)) if meta.any?
@@ -178,17 +174,9 @@ module Dry
178
174
  def visit_sum(node, opts = EMPTY_HASH)
179
175
  *types, _ = node
180
176
 
181
- # FIXME: cleaner way to generate individual types
182
- #
183
- process = -> (type) do
184
- self.class.new
185
- .tap { |target| target.visit(type, opts) }
186
- .to_hash
187
- .values
188
- .first
189
- end
190
-
191
- result = types.map(&process).uniq
177
+ result = types
178
+ .map { |type| single_type(type, opts.merge(sum: true)) }
179
+ .uniq
192
180
 
193
181
  return @keys[opts[:key]] = result.first if result.count == 1
194
182
 
@@ -216,7 +204,15 @@ module Dry
216
204
 
217
205
  def visit_struct(node, opts = EMPTY_HASH)
218
206
  _, schema = node
219
- visit(schema, opts)
207
+
208
+ if opts[:key]
209
+ target = self.class.new
210
+ target.visit(schema)
211
+
212
+ @keys[opts[:key]] = target.to_hash
213
+ else
214
+ visit(schema, opts)
215
+ end
220
216
  end
221
217
 
222
218
  def visit_array(node, opts = EMPTY_HASH)
@@ -254,6 +250,32 @@ module Dry
254
250
 
255
251
  visit(rest, opts.merge(key: name))
256
252
  end
253
+
254
+ private
255
+
256
+ # FIXME: cleaner way to generate individual types
257
+ #
258
+ def single_type(type, opts)
259
+ self.class.new
260
+ .tap { |target| target.visit(type, opts) }
261
+ .to_hash
262
+ .values
263
+ .first
264
+ end
265
+
266
+ def visit_nominal_with_key(node, opts = EMPTY_HASH)
267
+ type, meta = node
268
+
269
+ if opts[:array] && !opts[:sum]
270
+ @keys[opts[:key]] ||= {}
271
+ @keys[opts[:key]].merge!(items: { type: CLASS_TO_TYPE[type.to_s.to_sym] })
272
+ end
273
+
274
+ if meta.any?
275
+ @keys[opts[:key]] ||= {}
276
+ @keys[opts[:key]].merge!(meta.slice(*ALLOWED_TYPES_META_OVERRIDES))
277
+ end
278
+ end
257
279
  end
258
280
 
259
281
  # The `Builder` module provides a method to generate a JSON Schema hash from dry-types definitions.
@@ -263,8 +285,8 @@ module Dry
263
285
  # @param options [Hash] Initialization options passed to `JSONSchema.new`
264
286
  # @return [Hash] The generated JSON Schema as a hash.
265
287
  #
266
- def json_schema(**)
267
- compiler = JSONSchema.new(**)
288
+ def json_schema(root: false, loose: false)
289
+ compiler = JSONSchema.new(root: root, loose: loose)
268
290
  compiler.call(to_ast)
269
291
  compiler.to_hash
270
292
  end
@@ -66,6 +66,10 @@ describe Dry::Types::JSONSchema do
66
66
  .constrained(format: /\A[\w+\-.]+@[a-z\d-]+(\.[a-z]+)*\.[a-z]+\z/i)
67
67
  .meta(description: "The internally used pattern")
68
68
 
69
+ ArrayOfStrings = Types::Array
70
+ .of(Types::String)
71
+ .constrained(min_size: 1)
72
+
69
73
  attribute :data, Types::String | Types::Hash
70
74
  attribute :string, Types::String.constrained(min_size: 1, max_size: 255)
71
75
  attribute :list, VariableList
@@ -76,6 +80,10 @@ describe Dry::Types::JSONSchema do
76
80
  attribute? :epoch, Types::Time
77
81
  attribute? :meta, Types::String.meta(format: :email)
78
82
  attribute? :enum, Types::String.enum(*%w[draft published archived])
83
+ attribute? :array, ArrayOfStrings
84
+ attribute? :nested do
85
+ attribute :deep, Types::Integer
86
+ end
79
87
  end
80
88
 
81
89
  let(:type) { StructTest }
@@ -146,6 +154,22 @@ describe Dry::Types::JSONSchema do
146
154
  enum: {
147
155
  type: :string,
148
156
  enum: %w[draft published archived]
157
+ },
158
+
159
+ array: {
160
+ type: :array,
161
+ minItems: 1,
162
+ items: { type: :string }
163
+ },
164
+
165
+ nested: {
166
+ type: :object,
167
+ properties: {
168
+ deep: { type: :integer }
169
+ },
170
+ required: [:deep],
171
+ title: "Title",
172
+ description: "description"
149
173
  }
150
174
  },
151
175
 
data/spec/spec_helper.rb CHANGED
@@ -6,6 +6,7 @@ SimpleCov.start
6
6
 
7
7
  require "minitest/autorun"
8
8
  require "json_schemer"
9
+ require "super_diff"
9
10
 
10
11
  require "dry/struct"
11
12
  require "dry/types"
@@ -13,13 +14,22 @@ require "dry/types/extensions"
13
14
 
14
15
  Dry::Types.load_extensions(:json_schema)
15
16
 
17
+ module Minitest::Assertions
18
+ def assert_equal_diff(expected, actual, msg = nil)
19
+ assert_equal(expected, actual, msg)
20
+ rescue Minitest::Assertion => e
21
+ puts SuperDiff::Differs::Main.call(expected, actual)
22
+ raise e
23
+ end
24
+ end
25
+
16
26
  class Minitest::Spec
17
27
  class << self
18
28
  def it_conforms_definition(&block)
19
29
  instance_exec(&block) if block
20
30
 
21
31
  describe "conforms the schema definition" do
22
- it { assert_equal type.json_schema, definition }
32
+ it { assert_equal_diff type.json_schema, definition }
23
33
  it { assert JSONSchemer.schema(type.json_schema.to_json).valid_schema? }
24
34
  end
25
35
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-types-json-schema
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - elcuervo
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: 0.35.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: super_diff
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 0.11.0
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 0.11.0
125
139
  description:
126
140
  email:
127
141
  - elcuervo@elcuervo.net