paradocs 1.0.22 → 1.1.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.
@@ -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
@@ -93,5 +93,38 @@ describe "classes including Whitelist module" do
93
93
  }
94
94
  )
95
95
  end
96
+
97
+ context "when Paradocs.config.whitelist_coercion block is set" do
98
+ before { Paradocs.config.whitelist_coercion = Proc.new { |value, meta| meta[:type] != :string ? "FILTER" : value.to_s }}
99
+
100
+ it "executes block for each value" do
101
+ whitelisted = TestWhitelist.new.filter!(input, schema)
102
+ expect(whitelisted).to eq(
103
+ {
104
+ unexpected: "[FILTERED]",
105
+ from_config: "FILTER",
106
+ data: [
107
+ {
108
+ id: "5",
109
+ name: "[EMPTY]",
110
+ unexpected: "[EMPTY]",
111
+ empty_array: [],
112
+ subschema_1: "FILTER",
113
+ subfield_1: "FILTER",
114
+ subschema_2: "[FILTERED]",
115
+ subfield_2: "FILTER",
116
+ empty_hash: {},
117
+ extra: {
118
+ id: "6",
119
+ name: "[FILTERED]",
120
+ unexpected: "[FILTERED]",
121
+ empty_string: "[EMPTY]"
122
+ }
123
+ }
124
+ ]
125
+ }
126
+ )
127
+ end
128
+ end
96
129
  end
97
130
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paradocs
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.22
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
- - Ismael Celis
8
7
  - Maxim Tkachenko
8
+ - Ismael Celis
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-08-26 00:00:00.000000000 Z
12
+ date: 2020-09-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -31,14 +31,14 @@ dependencies:
31
31
  requirements:
32
32
  - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: '0'
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: '0'
41
+ version: '12.3'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: rspec
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -70,8 +70,8 @@ dependencies:
70
70
  description: Flexible DSL for declaring allowed parameters focused on DRY validation
71
71
  that gives you opportunity to generate API documentation on-the-fly.
72
72
  email:
73
- - ismaelct@gmail.com
74
73
  - tkachenko.maxim.w@gmail.com
74
+ - ismaelct@gmail.com
75
75
  executables:
76
76
  - console
77
77
  extensions: []
@@ -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