paradocs 1.0.24 → 1.1.4

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