paradocs 1.0.24 → 1.1.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.
@@ -0,0 +1,70 @@
1
+ require "spec_helper"
2
+
3
+ describe Paradocs::Extensions::PayloadBuilder do
4
+ let(:schema) do
5
+ Paradocs::Schema.new do
6
+ field(:test).present.type(:string).mutates_schema! { :subschema1 }
7
+ subschema(:subschema1) do
8
+ field(:subtest1).declared.type(:number)
9
+ end
10
+ subschema(:subschema2) do
11
+ field(:subtest2).required.type(:array).schema do
12
+ field(:hello).type(:string).mutates_schema! { |*| :deep_schema }
13
+ subschema(:deep_schema) { field(:deep_field).type(:boolean) }
14
+ subschema(:empty) { }
15
+ end
16
+ end
17
+ # 2 mutation fields and more than 1 subschema pack work good in validation but docs
18
+ # will contain only 1 subschema at once: foo subschemes will never be mixed with test subschemes
19
+ field(:foo).required.type(:object).schema do
20
+ field(:bar).present.type(:string).options(["foo", "bar"]).mutates_schema! do |value, *|
21
+ value == "foo" ? :fooschema : :barschema
22
+ end
23
+ subschema(:fooschema) { }
24
+ subschema(:barschema) do
25
+ field(:barfield).present.type(:boolean)
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ it "gives an example payload and takes into account the subschemes" do
32
+ allow_any_instance_of(Array).to receive(:sample) { "bar" }
33
+ payloads = described_class.new(schema).build!
34
+ expect(payloads.keys.sort).to eq([:barschema, :fooschema, :subschema1, :subschema2_deep_schema, :subschema2_empty])
35
+ expect(payloads[:barschema]).to eq({"test" => nil, "foo" => {"bar" => "bar", "barfield" => nil}})
36
+ expect(payloads[:fooschema]).to eq({"test" => nil, "foo" => {"bar" => "bar"}})
37
+ expect(payloads[:subschema1]).to eq({"test" => nil, "foo" => {"bar" => "bar"}, "subtest1" => nil})
38
+ expect(payloads[:subschema2_deep_schema]).to eq({
39
+ "subtest2" => [{"deep_field" => nil, "hello" => nil}], "test" => nil, "foo" => {"bar" => "bar"}
40
+ })
41
+ expect(payloads[:subschema2_empty]).to eq({
42
+ "test" => nil, "foo" => {"bar" => "bar"}, "subtest2" => [{"hello" => nil}]
43
+ })
44
+ end
45
+
46
+ it "yields a usefull block that changes the result" do
47
+ payloads = described_class.new(schema).build! do |key, meta, example, skip_word|
48
+ if key == "bar"
49
+ nil
50
+ elsif meta[:type] == :boolean
51
+ true
52
+ elsif key == "subtest1"
53
+ skip_word # this key value pair will be ommited
54
+ else
55
+ example # return suggested value
56
+ end
57
+ end
58
+
59
+ expect(payloads.keys.sort).to eq([:barschema, :fooschema, :subschema1, :subschema2_deep_schema, :subschema2_empty])
60
+ expect(payloads[:barschema]).to eq({"test" => nil, "foo" => {"bar" => nil, "barfield" => true}}) # barfield is change to true and bar is nil
61
+ expect(payloads[:fooschema]).to eq({"test" => nil, "foo" => {"bar" => nil}}) # bar is nil
62
+ expect(payloads[:subschema1]).to eq({"test" => nil, "foo" => {"bar" => nil}}) # subtest is missing, bar is nil
63
+ expect(payloads[:subschema2_deep_schema]).to eq({
64
+ "subtest2" => [{"deep_field" => true, "hello" => nil}], "test" => nil, "foo" => {"bar" => nil}
65
+ })
66
+ expect(payloads[:subschema2_empty]).to eq({
67
+ "test" => nil, "foo" => {"bar" => nil}, "subtest2" => [{"hello" => nil}]
68
+ })
69
+ end
70
+ end
@@ -0,0 +1,237 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paradocs::Extensions::Structure do
4
+ Paradocs.policy :policy_with_error do
5
+ register_error ArgumentError
6
+
7
+ validate do |*|
8
+ raise ArgumentError
9
+ end
10
+ end
11
+
12
+ Paradocs.policy :policy_with_silent_error do
13
+ register_silent_error RuntimeError
14
+ end
15
+
16
+ let(:schema) do
17
+ Paradocs::Schema.new do
18
+ subschema(:highest_level) { field(:test).present } # no mutations on this level -> subschema ignored
19
+
20
+ field(:data).type(:object).present.schema do
21
+ field(:id).type(:integer).present.policy(:policy_with_error)
22
+ field(:name).type(:string).meta(label: "very important staff")
23
+ field(:role).type(:string).declared.options(["admin", "user"]).default("user").mutates_schema! do |*|
24
+ :test_subschema
25
+ end
26
+ field(:extra).type(:array).required.schema do
27
+ field(:extra).declared.default(false).policy(:policy_with_silent_error)
28
+ end
29
+
30
+ mutation_by!(:name) { :subschema }
31
+
32
+ subschema(:subschema) do
33
+ field(:test_field).present
34
+ end
35
+ subschema(:test_subschema) do
36
+ field(:test1).present
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ describe "#nested" do
43
+ it "generates nested data for documentation generation" do
44
+ result = schema.structure.nested { |k, meta| meta[:block_works] = true unless meta[:present] }
45
+ expect(result[:_subschemes]).to eq({})
46
+ expect(result[:_errors]).to eq([ArgumentError])
47
+ data_structure = result[:data].delete(:structure)
48
+ expect(result[:data]).to eq({
49
+ type: :object,
50
+ required: true,
51
+ present: true,
52
+ json_path: "$.data",
53
+ nested_name: "data",
54
+ })
55
+ expect(data_structure[:_subschemes]).to eq({
56
+ test_subschema: {
57
+ _errors: [],
58
+ _subschemes: {},
59
+ test1: {required: true, present: true, json_path: "$.data.test1", nested_name: "data.test1"}
60
+ },
61
+ subschema: {
62
+ _errors: [],
63
+ _subschemes: {},
64
+ test_field: {required: true, present: true, json_path: "$.data.test_field", nested_name: "data.test_field"}
65
+ }
66
+ })
67
+ expect(data_structure[:id]).to eq({
68
+ type: :integer,
69
+ required: true,
70
+ present: true,
71
+ policy_with_error: {errors: [ArgumentError]},
72
+ json_path: "$.data.id",
73
+ nested_name: "data.id"
74
+ })
75
+ expect(data_structure[:name]).to eq({
76
+ type: :string,
77
+ label: "very important staff",
78
+ mutates_schema: true,
79
+ block_works: true,
80
+ json_path: "$.data.name",
81
+ nested_name: "data.name"
82
+ })
83
+ expect(data_structure[:role]).to eq({
84
+ type: :string,
85
+ options: ["admin", "user"],
86
+ default: "user",
87
+ mutates_schema: true,
88
+ block_works: true,
89
+ json_path: "$.data.role",
90
+ nested_name: "data.role"
91
+ })
92
+ expect(data_structure[:extra]).to eq({
93
+ type: :array,
94
+ required: true,
95
+ block_works: true,
96
+ json_path: "$.data.extra[]",
97
+ nested_name: "data.extra",
98
+ structure: {
99
+ extra: {
100
+ default: false,
101
+ block_works: true,
102
+ json_path: "$.data.extra[].extra",
103
+ nested_name: "data.extra.extra",
104
+ policy_with_silent_error: {errors: []}
105
+ },
106
+ _subschemes: {}
107
+ }
108
+ })
109
+ end
110
+ end
111
+
112
+ describe "#flatten" do
113
+ it "generates flatten data for documentation generation" do
114
+ expect(schema.structure.flatten { |key, meta| meta[:block_works] = true if key.split(".").size == 1 }).to eq({
115
+ "data" => {
116
+ type: :object,
117
+ required: true,
118
+ present: true,
119
+ block_works: true,
120
+ json_path: "$.data"
121
+ },
122
+ "data.extra" => {
123
+ type: :array,
124
+ required: true,
125
+ json_path: "$.data.extra[]"
126
+ },
127
+ "data.extra.extra" => {
128
+ default: false,
129
+ json_path: "$.data.extra[].extra",
130
+ policy_with_silent_error: {errors: []}
131
+ },
132
+ "data.id" => {
133
+ type: :integer,
134
+ required: true,
135
+ present: true,
136
+ json_path: "$.data.id",
137
+ policy_with_error: {errors: [ArgumentError]}
138
+ },
139
+ "data.name" => {
140
+ type: :string,
141
+ json_path: "$.data.name",
142
+ label: "very important staff",
143
+ mutates_schema: true
144
+ },
145
+ "data.role" => {
146
+ type: :string,
147
+ options: ["admin", "user"],
148
+ default: "user",
149
+ json_path: "$.data.role",
150
+ mutates_schema: true
151
+ },
152
+ _errors: [ArgumentError],
153
+ _subschemes: {
154
+ test_subschema: {
155
+ _errors: [],
156
+ _subschemes: {},
157
+ "data.test1"=>{
158
+ required: true,
159
+ present: true,
160
+ json_path: "$.data.test1"
161
+ }
162
+ },
163
+ subschema: {
164
+ _errors: [],
165
+ _subschemes: {},
166
+ "data.test_field" => {required: true, present: true, json_path: "$.data.test_field"}
167
+ }
168
+ }
169
+ })
170
+ end
171
+ end
172
+
173
+ describe "#all_flatten" do
174
+ it "generates N structures, where N = number of unique combinations of applied subschemas" do
175
+ expect(schema.structure.all_flatten).to eq({
176
+ subschema: {
177
+ _errors: [],
178
+ "data" => {type: :object, required: true, present: true, json_path: "$.data"},
179
+ "data.id" => {type: :integer, required: true, present: true, policy_with_error: {errors: [ArgumentError]}, json_path: "$.data.id"},
180
+ "data.name" => {type: :string, label: "very important staff", json_path: "$.data.name", mutates_schema: true},
181
+ "data.role" => {type: :string, options: ["admin", "user"], default: "user", json_path: "$.data.role", mutates_schema: true},
182
+ "data.extra" => {type: :array, required: true, json_path: "$.data.extra[]"},
183
+ "data.extra.extra" => {default: false, policy_with_silent_error: {errors: []}, json_path: "$.data.extra[].extra"},
184
+ "data.test_field" => {required: true, present: true, json_path: "$.data.test_field"}
185
+ },
186
+ test_subschema: {
187
+ _errors: [],
188
+ "data" => {type: :object, required: true, present: true, json_path: "$.data"},
189
+ "data.id" => {type: :integer, required: true, present: true, policy_with_error: {errors: [ArgumentError]}, json_path: "$.data.id"},
190
+ "data.name" => {type: :string, label: "very important staff", json_path: "$.data.name", mutates_schema: true},
191
+ "data.role" => {type: :string, options: ["admin", "user"], default: "user", json_path: "$.data.role", mutates_schema: true},
192
+ "data.extra" => {type: :array, required: true, json_path: "$.data.extra[]"},
193
+ "data.extra.extra" => {default: false, policy_with_silent_error: {errors: []}, json_path: "$.data.extra[].extra"},
194
+ "data.test1" => {required: true, present: true, json_path: "$.data.test1"}
195
+ }
196
+ })
197
+ end
198
+ end
199
+
200
+ describe "#all_nested" do
201
+ it "generates N structures, where N = number of unique combinations of applied subschemas" do
202
+ result = schema.structure.all_nested
203
+ expect(result[:subschema]).to eq({
204
+ _errors: [],
205
+ "data" => {
206
+ type: :object,
207
+ required: true,
208
+ present: true,
209
+ json_path: "$.data",
210
+ structure: {
211
+ "role" => {type: :string, options: ["admin", "user"], default: "user", json_path: "$.data.role", mutates_schema: true},
212
+ "extra" => {type: :array, required: true, json_path: "$.data.extra[]", structure: {"extra" => {default: false, policy_with_silent_error: {errors: []}, json_path: "$.data.extra[].extra"}}},
213
+ "test_field" => {required: true, present: true, json_path: "$.data.test_field"},
214
+ "id" => {type: :integer, required: true, present: true, policy_with_error: {errors: [ArgumentError]}, json_path: "$.data.id"},
215
+ "name" => {type: :string, label: "very important staff", json_path: "$.data.name", mutates_schema: true}
216
+ }
217
+ }
218
+ })
219
+ expect(result[:test_subschema]).to eq({
220
+ _errors: [],
221
+ "data" => {
222
+ type: :object,
223
+ required: true,
224
+ present: true,
225
+ json_path: "$.data",
226
+ structure: {
227
+ "role" => {type: :string, options: ["admin", "user"], default: "user", json_path: "$.data.role", mutates_schema: true},
228
+ "extra" => {type: :array, required: true, json_path: "$.data.extra[]", structure: {"extra" => {default: false, policy_with_silent_error: {errors: []}, json_path: "$.data.extra[].extra"}}},
229
+ "test1" => {required: true, present: true, json_path: "$.data.test1"},
230
+ "id" => {type: :integer, required: true, present: true, policy_with_error: {errors: [ArgumentError]}, json_path: "$.data.id"},
231
+ "name" => {type: :string, label: "very important staff", json_path: "$.data.name", mutates_schema: true}
232
+ }
233
+ }
234
+ })
235
+ end
236
+ end
237
+ end
@@ -32,7 +32,7 @@ describe Paradocs::Schema do
32
32
 
33
33
  describe "#structure" do
34
34
  it "represents data structure and meta data" do
35
- sc = subject.structure
35
+ sc = subject.structure.nested
36
36
  expect(sc[:title][:present]).to be true
37
37
  expect(sc[:title][:type]).to eq :string
38
38
  expect(sc[:price][:type]).to eq :integer
@@ -71,16 +71,19 @@ describe "schemes with subschemes" do
71
71
  result = schema.resolve({error: :here})
72
72
  expect(result.errors).to eq({"$.fail_field"=>["is required"]})
73
73
  expect(result.output).to eq({error: :here, fail_field: nil})
74
- expect(schema.structure).to eq(structure)
75
- expect(schema.structure(ignore_transparent: false)).to eq(structure.merge(
74
+ expect(schema.structure.nested).to eq(structure)
75
+ schema.structure.flush!
76
+ expect(schema.structure(ignore_transparent: false).nested).to eq(structure.merge(
76
77
  error: {transparent: true, mutates_schema: true, json_path: "$.error", nested_name: "error"}
77
78
  ))
78
79
 
79
80
  result = schema.resolve({})
80
81
  expect(result.errors).to eq({"$.success_field"=>["is required"]})
81
82
  expect(result.output).to eq({success_field: nil})
82
- expect(schema.structure).to eq(structure)
83
- expect(schema.structure(ignore_transparent: false)).to eq(structure.merge(
83
+ schema.structure.flush!
84
+ expect(schema.structure.nested).to eq(structure)
85
+ schema.structure.flush!
86
+ expect(schema.structure(ignore_transparent: false).nested).to eq(structure.merge(
84
87
  error: {transparent: true, mutates_schema: true, json_path: "$.error", nested_name: "error"}
85
88
  ))
86
89
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paradocs
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.24
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maxim Tkachenko
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-09-07 00:00:00.000000000 Z
12
+ date: 2020-09-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -29,16 +29,16 @@ dependencies:
29
29
  name: rake
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - ">="
32
+ - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: 12.3.3
34
+ version: '12.3'
35
35
  type: :development
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - ">="
39
+ - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: 12.3.3
41
+ version: '12.3'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: rspec
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +80,7 @@ files:
80
80
  - ".github/workflows/spec.yml"
81
81
  - ".gitignore"
82
82
  - ".gitlab-ci.yml"
83
+ - ".readthedocs.yml"
83
84
  - ".rspec"
84
85
  - ".travis.yml"
85
86
  - Gemfile
@@ -87,12 +88,23 @@ files:
87
88
  - README.md
88
89
  - Rakefile
89
90
  - bin/console
91
+ - docs/custom_configuration.md
92
+ - docs/documentation_generation.md
93
+ - docs/faq.md
94
+ - docs/form_objects_dsl.md
95
+ - docs/index.md
96
+ - docs/payload_builder.md
97
+ - docs/policies.md
98
+ - docs/schema.md
99
+ - docs/struct.md
100
+ - docs/subschema.md
90
101
  - lib/paradocs.rb
91
102
  - lib/paradocs/base_policy.rb
92
103
  - lib/paradocs/context.rb
93
104
  - lib/paradocs/default_types.rb
94
105
  - lib/paradocs/dsl.rb
95
- - lib/paradocs/extensions/insides.rb
106
+ - lib/paradocs/extensions/payload_builder.rb
107
+ - lib/paradocs/extensions/structure.rb
96
108
  - lib/paradocs/field.rb
97
109
  - lib/paradocs/field_dsl.rb
98
110
  - lib/paradocs/policies.rb
@@ -103,23 +115,26 @@ files:
103
115
  - lib/paradocs/support.rb
104
116
  - lib/paradocs/version.rb
105
117
  - lib/paradocs/whitelist.rb
118
+ - mkdocs.yml
106
119
  - paradocs.gemspec
120
+ - requirements.txt
107
121
  - spec/custom_block_validator_spec.rb
108
122
  - spec/custom_validator.rb
109
123
  - spec/dsl_spec.rb
110
124
  - spec/expand_spec.rb
125
+ - spec/extensions/payload_builder_spec.rb
126
+ - spec/extensions/structures_spec.rb
111
127
  - spec/field_spec.rb
112
128
  - spec/helpers.rb
113
129
  - spec/policies_spec.rb
114
130
  - spec/schema_spec.rb
115
- - spec/schema_structures_spec.rb
116
131
  - spec/schema_walk_spec.rb
117
132
  - spec/spec_helper.rb
118
133
  - spec/struct_spec.rb
119
134
  - spec/subschema_spec.rb
120
135
  - spec/validators_spec.rb
121
136
  - spec/whitelist_spec.rb
122
- homepage: https://github.com/mtkachenk0/paradocs
137
+ homepage: https://paradocs.readthedocs.io/en/latest
123
138
  licenses:
124
139
  - MIT
125
140
  metadata: {}
@@ -149,11 +164,12 @@ test_files:
149
164
  - spec/custom_validator.rb
150
165
  - spec/dsl_spec.rb
151
166
  - spec/expand_spec.rb
167
+ - spec/extensions/payload_builder_spec.rb
168
+ - spec/extensions/structures_spec.rb
152
169
  - spec/field_spec.rb
153
170
  - spec/helpers.rb
154
171
  - spec/policies_spec.rb
155
172
  - spec/schema_spec.rb
156
- - spec/schema_structures_spec.rb
157
173
  - spec/schema_walk_spec.rb
158
174
  - spec/spec_helper.rb
159
175
  - spec/struct_spec.rb