paradocs 1.0.24 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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