paradocs 1.0.24 → 1.1.4

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.
@@ -1,7 +1,7 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Paradocs::Field do
4
- let(:context) { Paradocs::Context.new }
4
+ let(:context) { Paradocs::Context.new }
5
5
 
6
6
  subject { described_class.new(:a_key) }
7
7
 
@@ -16,7 +16,7 @@ describe Paradocs::Schema do
16
16
 
17
17
  subject do
18
18
  described_class.new do
19
- field(:title).policy(:string).present
19
+ field(:title).policy(:string).present.as(:article_title)
20
20
  field(:price).policy(:integer).meta(label: "A price")
21
21
  field(:status).policy(:string).options(['visible', 'hidden'])
22
22
  field(:tags).policy(:split).policy(:array)
@@ -32,9 +32,9 @@ 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
36
- expect(sc[:title][:present]).to be true
37
- expect(sc[:title][:type]).to eq :string
35
+ sc = subject.structure.nested
36
+ expect(sc[:article_title][:present]).to be true
37
+ expect(sc[:article_title][:type]).to eq :string
38
38
  expect(sc[:price][:type]).to eq :integer
39
39
  expect(sc[:price][:label]).to eq "A price"
40
40
  expect(sc[:variants][:type]).to eq :array
@@ -76,7 +76,7 @@ describe Paradocs::Schema do
76
76
 
77
77
  output = subject.resolve(payload).output
78
78
  expect(output).to eq({
79
- title: "title",
79
+ article_title: "title",
80
80
  price: 100,
81
81
  status: "visible",
82
82
  tags: ["tag"],
@@ -101,7 +101,7 @@ describe Paradocs::Schema do
101
101
  variants: [{name: 'v1', sku: 'ABC', stock: '10', available_if_no_stock: true}]
102
102
  },
103
103
  {
104
- title: 'iPhone 6 Plus',
104
+ article_title: 'iPhone 6 Plus',
105
105
  price: 100,
106
106
  status: 'visible',
107
107
  tags: ['tag1', 'tag2'],
@@ -114,7 +114,7 @@ describe Paradocs::Schema do
114
114
  variants: [{name: 'v1', available_if_no_stock: '1'}]
115
115
  },
116
116
  {
117
- title: 'iPhone 6 Plus',
117
+ article_title: 'iPhone 6 Plus',
118
118
  variants: [{name: 'v1', stock: 1, available_if_no_stock: true}]
119
119
  })
120
120
 
@@ -16,13 +16,13 @@ describe Paradocs::Struct do
16
16
  include Paradocs::Struct
17
17
 
18
18
  schema do
19
- field(:title).type(:string).present
19
+ field(:title).type(:string).present.as(:example_title)
20
20
  field(:friends).type(:array).default([]).schema friend_class
21
21
  end
22
22
  end
23
23
 
24
24
  new_instance = klass.new
25
- expect(new_instance.title).to eq ''
25
+ expect(new_instance.example_title).to eq ''
26
26
  expect(new_instance.friends).to eq []
27
27
  expect(new_instance.valid?).to be false
28
28
  expect(new_instance.errors['$.title']).not_to be_nil
@@ -35,7 +35,7 @@ describe Paradocs::Struct do
35
35
  ]
36
36
  })
37
37
 
38
- expect(instance.title).to eq 'foo'
38
+ expect(instance.example_title).to eq 'foo'
39
39
  expect(instance.friends.size).to eq 2
40
40
  expect(instance.friends.first.name).to eq 'Ismael'
41
41
  expect(instance.friends.first).to be_a friend_class
@@ -154,7 +154,7 @@ describe Paradocs::Struct do
154
154
  schema do
155
155
  field(:title).type(:string).present
156
156
  field(:friends).type(:array).schema do
157
- field(:name).type(:string)
157
+ field(:name).type(:string).as(:person_name)
158
158
  field(:age).type(:integer).default(20)
159
159
  end
160
160
  end
@@ -171,8 +171,8 @@ describe Paradocs::Struct do
171
171
  expect(instance.to_h).to eq({
172
172
  title: 'foo',
173
173
  friends: [
174
- {name: 'Jane', age: 20},
175
- {name: 'Joe', age: 39},
174
+ {person_name: 'Jane', age: 20},
175
+ {person_name: 'Joe', age: 39},
176
176
  ]
177
177
  })
178
178
 
@@ -190,7 +190,7 @@ describe Paradocs::Struct do
190
190
  include Paradocs::Struct
191
191
 
192
192
  schema do
193
- field(:title).type(:string).present
193
+ field(:title).type(:string).present.as(:example_title)
194
194
  field(:friends).type(:array).schema do
195
195
  field(:name).type(:string)
196
196
  field(:age).type(:integer).default(20)
@@ -213,7 +213,7 @@ describe Paradocs::Struct do
213
213
  ]
214
214
  )
215
215
 
216
- expect(instance.title).to eq 'foo'
216
+ expect(instance.example_title).to eq 'foo'
217
217
  expect(instance.email).to eq 'email@me.com'
218
218
  expect(instance.friends.size).to eq 2
219
219
  end
@@ -71,16 +71,16 @@ 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
+ expect(schema.structure(ignore_transparent: false).nested).to eq(structure.merge(
76
76
  error: {transparent: true, mutates_schema: true, json_path: "$.error", nested_name: "error"}
77
77
  ))
78
78
 
79
79
  result = schema.resolve({})
80
80
  expect(result.errors).to eq({"$.success_field"=>["is required"]})
81
81
  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(
82
+ expect(schema.structure.nested).to eq(structure)
83
+ expect(schema.structure(ignore_transparent: false).nested).to eq(structure.merge(
84
84
  error: {transparent: true, mutates_schema: true, json_path: "$.error", nested_name: "error"}
85
85
  ))
86
86
  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.4
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-11-05 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
@@ -67,8 +67,8 @@ dependencies:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
69
  version: '0'
70
- description: Flexible DSL for declaring allowed parameters focused on DRY validation
71
- that gives you opportunity to generate API documentation on-the-fly.
70
+ description: Flexible DRY validations with API docs generation done right TLDR; parametrics
71
+ on steroids.
72
72
  email:
73
73
  - tkachenko.maxim.w@gmail.com
74
74
  - ismaelct@gmail.com
@@ -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,24 @@ files:
87
88
  - README.md
88
89
  - Rakefile
89
90
  - bin/console
91
+ - docs/changelog.md
92
+ - docs/custom_configuration.md
93
+ - docs/documentation_generation.md
94
+ - docs/faq.md
95
+ - docs/form_objects_dsl.md
96
+ - docs/index.md
97
+ - docs/payload_builder.md
98
+ - docs/policies.md
99
+ - docs/schema.md
100
+ - docs/struct.md
101
+ - docs/subschema.md
90
102
  - lib/paradocs.rb
91
103
  - lib/paradocs/base_policy.rb
92
104
  - lib/paradocs/context.rb
93
105
  - lib/paradocs/default_types.rb
94
106
  - lib/paradocs/dsl.rb
95
- - lib/paradocs/extensions/insides.rb
107
+ - lib/paradocs/extensions/payload_builder.rb
108
+ - lib/paradocs/extensions/structure.rb
96
109
  - lib/paradocs/field.rb
97
110
  - lib/paradocs/field_dsl.rb
98
111
  - lib/paradocs/policies.rb
@@ -103,23 +116,26 @@ files:
103
116
  - lib/paradocs/support.rb
104
117
  - lib/paradocs/version.rb
105
118
  - lib/paradocs/whitelist.rb
119
+ - mkdocs.yml
106
120
  - paradocs.gemspec
121
+ - requirements.txt
107
122
  - spec/custom_block_validator_spec.rb
108
123
  - spec/custom_validator.rb
109
124
  - spec/dsl_spec.rb
110
125
  - spec/expand_spec.rb
126
+ - spec/extensions/payload_builder_spec.rb
127
+ - spec/extensions/structures_spec.rb
111
128
  - spec/field_spec.rb
112
129
  - spec/helpers.rb
113
130
  - spec/policies_spec.rb
114
131
  - spec/schema_spec.rb
115
- - spec/schema_structures_spec.rb
116
132
  - spec/schema_walk_spec.rb
117
133
  - spec/spec_helper.rb
118
134
  - spec/struct_spec.rb
119
135
  - spec/subschema_spec.rb
120
136
  - spec/validators_spec.rb
121
137
  - spec/whitelist_spec.rb
122
- homepage: https://github.com/mtkachenk0/paradocs
138
+ homepage: https://paradocs.readthedocs.io/en/latest
123
139
  licenses:
124
140
  - MIT
125
141
  metadata: {}
@@ -149,11 +165,12 @@ test_files:
149
165
  - spec/custom_validator.rb
150
166
  - spec/dsl_spec.rb
151
167
  - spec/expand_spec.rb
168
+ - spec/extensions/payload_builder_spec.rb
169
+ - spec/extensions/structures_spec.rb
152
170
  - spec/field_spec.rb
153
171
  - spec/helpers.rb
154
172
  - spec/policies_spec.rb
155
173
  - spec/schema_spec.rb
156
- - spec/schema_structures_spec.rb
157
174
  - spec/schema_walk_spec.rb
158
175
  - spec/spec_helper.rb
159
176
  - spec/struct_spec.rb
@@ -1,77 +0,0 @@
1
- module Paradocs
2
- module Extensions
3
- module Insides
4
- def structure(ignore_transparent: true, root: "", &block)
5
- flush!
6
- fields.each_with_object({meta_keys[:errors] => [], meta_keys[:subschemes] => {}}) do |(_, field), obj|
7
- meta, sc = collect_meta(field, root)
8
- if sc
9
- meta[:structure] = sc.structure(ignore_transparent: ignore_transparent, root: meta[:json_path], &block)
10
- obj[meta_keys[:errors]] += meta[:structure].delete(meta_keys[:errors])
11
- else
12
- obj[meta_keys[:errors]] += field.possible_errors
13
- end
14
- obj[field.key] = meta unless ignore_transparent && field.transparent?
15
- yield(field.key, meta) if block_given?
16
-
17
- next unless field.mutates_schema?
18
- subschemes.each do |name, subschema|
19
- obj[meta_keys[:subschemes]][name] = subschema.structure(ignore_transparent: ignore_transparent, root: root, &block)
20
- obj[meta_keys[:errors]] += obj[meta_keys[:subschemes]][name][meta_keys[:errors]]
21
- end
22
- end
23
- end
24
-
25
- def flatten_structure(ignore_transparent: true, root: "", &block)
26
- flush!
27
- fields.each_with_object({meta_keys[:errors] => [], meta_keys[:subschemes] => {}}) do |(_, field), obj|
28
- meta, sc = collect_meta(field, root)
29
- humanized_name = meta.delete(:nested_name)
30
- obj[humanized_name] = meta unless ignore_transparent && field.transparent?
31
-
32
- if sc
33
- deep_result = sc.flatten_structure(ignore_transparent: ignore_transparent, root: meta[:json_path], &block)
34
- obj[meta_keys[:errors]] += deep_result.delete(meta_keys[:errors])
35
- obj[meta_keys[:subschemes]].merge!(deep_result.delete(meta_keys[:subschemes]))
36
- obj.merge!(deep_result)
37
- else
38
- obj[meta_keys[:errors]] += field.possible_errors
39
- end
40
- yield(humanized_name, meta) if block_given?
41
- next unless field.mutates_schema?
42
- subschemes.each do |name, subschema|
43
- obj[meta_keys[:subschemes]][name] ||= subschema.flatten_structure(ignore_transparent: ignore_transparent, root: root, &block)
44
- obj[meta_keys[:errors]] += obj[meta_keys[:subschemes]][name][meta_keys[:errors]]
45
- end
46
- end
47
- end
48
-
49
- def walk(meta_key = nil, &visitor)
50
- r = visit(meta_key, &visitor)
51
- Results.new(r, {}, {})
52
- end
53
-
54
- def visit(meta_key = nil, &visitor)
55
- fields.each_with_object({}) do |(_, field), m|
56
- m[field.key] = field.visit(meta_key, &visitor)
57
- end
58
- end
59
-
60
- private
61
-
62
- def collect_meta(field, root)
63
- json_path = root.empty? ? "$.#{field.key}" : "#{root}.#{field.key}"
64
- meta = field.meta_data.merge(json_path: json_path)
65
- sc = meta.delete(:schema)
66
- meta[:mutates_schema] = true if meta.delete(:mutates_schema)
67
- json_path << "[]" if meta[:type] == :array
68
- meta[:nested_name] = json_path.gsub("[]", "")[2..-1]
69
- [meta, sc]
70
- end
71
-
72
- def meta_keys
73
- %i(errors subschemes).map! { |key| [key, "#{Paradocs.config.meta_prefix}#{key}".to_sym] }.to_h
74
- end
75
- end
76
- end
77
- end
@@ -1,169 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "Schema structures generation" 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
-
43
- it "generates nested data for documentation generation" do
44
- result = schema.structure { |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
-
111
- it "generates flatten data for documentation generation" do
112
- expect(schema.flatten_structure { |key, meta| meta[:block_works] = true if key.split(".").size == 1 }).to eq({
113
- "data" => {
114
- type: :object,
115
- required: true,
116
- present: true,
117
- block_works: true,
118
- json_path: "$.data"
119
- },
120
- "data.extra" => {
121
- type: :array,
122
- required: true,
123
- json_path: "$.data.extra[]"
124
- },
125
- "data.extra.extra" => {
126
- default: false,
127
- json_path: "$.data.extra[].extra",
128
- policy_with_silent_error: {errors: []}
129
- },
130
- "data.id" => {
131
- type: :integer,
132
- required: true,
133
- present: true,
134
- json_path: "$.data.id",
135
- policy_with_error: {errors: [ArgumentError]}
136
- },
137
- "data.name" => {
138
- type: :string,
139
- json_path: "$.data.name",
140
- label: "very important staff",
141
- mutates_schema: true
142
- },
143
- "data.role" => {
144
- type: :string,
145
- options: ["admin", "user"],
146
- default: "user",
147
- json_path: "$.data.role",
148
- mutates_schema: true
149
- },
150
- _errors: [ArgumentError],
151
- _subschemes: {
152
- test_subschema: {
153
- _errors: [],
154
- _subschemes: {},
155
- "data.test1"=>{
156
- required: true,
157
- present: true,
158
- json_path: "$.data.test1"
159
- }
160
- },
161
- subschema: {
162
- _errors: [],
163
- _subschemes: {},
164
- "data.test_field" => {required: true, present: true, json_path: "$.data.test_field"}
165
- }
166
- }
167
- })
168
- end
169
- end