paradocs 1.0.23 → 1.1.3

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