json-spec 0.1.0

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.
Files changed (114) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/.gitmodules +3 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +960 -0
  7. data/Rakefile +10 -0
  8. data/api_documentation.md +611 -0
  9. data/cachivache/.gitignore +1 -0
  10. data/cachivache/Gemfile +4 -0
  11. data/cachivache/README.md +247 -0
  12. data/cachivache/Rakefile +19 -0
  13. data/cachivache/Vagrantfile +70 -0
  14. data/cachivache/cachivache.rb +59 -0
  15. data/cachivache/lib/let-behaviour.rb +27 -0
  16. data/cachivache/lib/rake-helper.rb +131 -0
  17. data/cachivache/lib/sh-file-context.rb +39 -0
  18. data/cachivache/lib/sh-if-context.rb +31 -0
  19. data/cachivache/stuff/.gitkeep +0 -0
  20. data/cachivache/stuff/ruby-json-spec.rb +22 -0
  21. data/examples/example-1-simple.rb +66 -0
  22. data/examples/example-2-default-expectations.rb +63 -0
  23. data/examples/example-3-each-field.rb +104 -0
  24. data/examples/example-4-to-be-as-defined-in.rb +117 -0
  25. data/examples/example-5-custom-expectations.rb +153 -0
  26. data/examples/example-6-custom-messages.rb +36 -0
  27. data/examples/example-7-full-example.rb +231 -0
  28. data/examples/fixtures.rb +77 -0
  29. data/examples/validation-printer.rb +47 -0
  30. data/json-spec.gemspec +29 -0
  31. data/lib/cabeza-de-termo/json-spec/errors/error.rb +6 -0
  32. data/lib/cabeza-de-termo/json-spec/errors/expectation-not-found-error.rb +8 -0
  33. data/lib/cabeza-de-termo/json-spec/errors/modifier-not-found-error.rb +8 -0
  34. data/lib/cabeza-de-termo/json-spec/errors/unkown-json-type-error.rb +8 -0
  35. data/lib/cabeza-de-termo/json-spec/errors/validation-error.rb +8 -0
  36. data/lib/cabeza-de-termo/json-spec/expectations-library/default-expectations/default-expectation-builder.rb +29 -0
  37. data/lib/cabeza-de-termo/json-spec/expectations-library/default-expectations/default-expectations-mapping.rb +54 -0
  38. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-builders/block-expectation-definition.rb +16 -0
  39. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-builders/class-expectation-definition.rb +15 -0
  40. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-builders/expectation-definition.rb +19 -0
  41. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-builders/expectations-definition-builder.rb +136 -0
  42. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-builders/expecting-all-of-expectation-definition.rb +23 -0
  43. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-builders/expecting-any-of-expectation-definition.rb +23 -0
  44. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-builders/expecting-expectation-definition.rb +17 -0
  45. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-builders/negating-expectation-definition.rb +16 -0
  46. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-library-definition-builder.rb +35 -0
  47. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/modifier-builders/class-modifier-definition.rb +15 -0
  48. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/modifier-builders/composing-modifiers-definition.rb +28 -0
  49. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/modifier-builders/modifier-definition.rb +13 -0
  50. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/modifier-builders/modifiers-definition-builder.rb +73 -0
  51. data/lib/cabeza-de-termo/json-spec/expectations-library/expectations-library.rb +150 -0
  52. data/lib/cabeza-de-termo/json-spec/expectations-library/initializers/default-library-initializer.rb +265 -0
  53. data/lib/cabeza-de-termo/json-spec/expectations-library/initializers/library-initializer.rb +9 -0
  54. data/lib/cabeza-de-termo/json-spec/expectations-library/messages/expectation-messages-mapping.rb +27 -0
  55. data/lib/cabeza-de-termo/json-spec/expectations/abstract-expectation.rb +39 -0
  56. data/lib/cabeza-de-termo/json-spec/expectations/all-expectations-composite.rb +33 -0
  57. data/lib/cabeza-de-termo/json-spec/expectations/any-expectation-composite.rb +33 -0
  58. data/lib/cabeza-de-termo/json-spec/expectations/block-expectation.rb +28 -0
  59. data/lib/cabeza-de-termo/json-spec/expectations/expectation.rb +51 -0
  60. data/lib/cabeza-de-termo/json-spec/expectations/is-email-expectation.rb +16 -0
  61. data/lib/cabeza-de-termo/json-spec/expectations/is-scalar-expectation.rb +17 -0
  62. data/lib/cabeza-de-termo/json-spec/expectations/is-url-expectation.rb +21 -0
  63. data/lib/cabeza-de-termo/json-spec/expectations/negated-expectation.rb +31 -0
  64. data/lib/cabeza-de-termo/json-spec/expectations/runner/abstract-expectations-runner.rb +27 -0
  65. data/lib/cabeza-de-termo/json-spec/expectations/runner/can-be-absent-expectations-runner.rb +50 -0
  66. data/lib/cabeza-de-termo/json-spec/expectations/runner/can-be-null-expectations-runner.rb +48 -0
  67. data/lib/cabeza-de-termo/json-spec/expectations/runner/expectations-runner.rb +43 -0
  68. data/lib/cabeza-de-termo/json-spec/expressions/json-any-of.rb +62 -0
  69. data/lib/cabeza-de-termo/json-spec/expressions/json-anything.rb +16 -0
  70. data/lib/cabeza-de-termo/json-spec/expressions/json-each-field.rb +58 -0
  71. data/lib/cabeza-de-termo/json-spec/expressions/json-each.rb +58 -0
  72. data/lib/cabeza-de-termo/json-spec/expressions/json-expression.rb +314 -0
  73. data/lib/cabeza-de-termo/json-spec/expressions/json-field-name.rb +16 -0
  74. data/lib/cabeza-de-termo/json-spec/expressions/json-field.rb +76 -0
  75. data/lib/cabeza-de-termo/json-spec/expressions/json-list.rb +40 -0
  76. data/lib/cabeza-de-termo/json-spec/expressions/json-object.rb +82 -0
  77. data/lib/cabeza-de-termo/json-spec/expressions/json-scalar.rb +20 -0
  78. data/lib/cabeza-de-termo/json-spec/expressions/json-spec.rb +174 -0
  79. data/lib/cabeza-de-termo/json-spec/instantiators/abstract-instantiator.rb +9 -0
  80. data/lib/cabeza-de-termo/json-spec/instantiators/all-expectations-composite-instantiator.rb +12 -0
  81. data/lib/cabeza-de-termo/json-spec/instantiators/any-expectation-composite-instantiator.rb +12 -0
  82. data/lib/cabeza-de-termo/json-spec/instantiators/block-expectation-instantiator.rb +16 -0
  83. data/lib/cabeza-de-termo/json-spec/instantiators/composite-instantiator.rb +45 -0
  84. data/lib/cabeza-de-termo/json-spec/instantiators/modifier-composite-instantiator.rb +12 -0
  85. data/lib/cabeza-de-termo/json-spec/instantiators/negated-expectation-instantiator.rb +20 -0
  86. data/lib/cabeza-de-termo/json-spec/instantiators/patial-application-instantiator.rb +26 -0
  87. data/lib/cabeza-de-termo/json-spec/json-spec.rb +2 -0
  88. data/lib/cabeza-de-termo/json-spec/message-formatters/block-message-formatter.rb +15 -0
  89. data/lib/cabeza-de-termo/json-spec/message-formatters/erb-message-formatter.rb +60 -0
  90. data/lib/cabeza-de-termo/json-spec/message-formatters/message-formatter.rb +9 -0
  91. data/lib/cabeza-de-termo/json-spec/metaprogramming/message-send.rb +37 -0
  92. data/lib/cabeza-de-termo/json-spec/metaprogramming/message.rb +37 -0
  93. data/lib/cabeza-de-termo/json-spec/metaprogramming/object-method.rb +14 -0
  94. data/lib/cabeza-de-termo/json-spec/modifiers/can-be-absent-modifier.rb +13 -0
  95. data/lib/cabeza-de-termo/json-spec/modifiers/can-be-null-modifier.rb +13 -0
  96. data/lib/cabeza-de-termo/json-spec/modifiers/expression-modifier.rb +9 -0
  97. data/lib/cabeza-de-termo/json-spec/modifiers/modifier-composite.rb +27 -0
  98. data/lib/cabeza-de-termo/json-spec/signals/signal.rb +6 -0
  99. data/lib/cabeza-de-termo/json-spec/signals/skip-branch-signal.rb +8 -0
  100. data/lib/cabeza-de-termo/json-spec/utilities/bind.rb +20 -0
  101. data/lib/cabeza-de-termo/json-spec/utilities/range.rb +70 -0
  102. data/lib/cabeza-de-termo/json-spec/value-holders/accessors-chain.rb +27 -0
  103. data/lib/cabeza-de-termo/json-spec/value-holders/missing-value.rb +21 -0
  104. data/lib/cabeza-de-termo/json-spec/value-holders/value-holder.rb +135 -0
  105. data/lib/cabeza-de-termo/json-spec/version.rb +5 -0
  106. data/lib/cabeza-de-termo/json-spec/walkers/expression-walker.rb +66 -0
  107. data/lib/cabeza-de-termo/json-spec/walkers/json-expectations-runner.rb +214 -0
  108. data/lib/cabeza-de-termo/json-spec/walkers/json-expression-explainer.rb +183 -0
  109. data/lib/cabeza-de-termo/json-spec/walkers/reporter/expectation-report.rb +63 -0
  110. data/lib/cabeza-de-termo/json-spec/walkers/reporter/json-expectations-reporter.rb +111 -0
  111. data/lib/cabeza-de-termo/json-spec/walkers/validator/json-validator-error.rb +29 -0
  112. data/lib/cabeza-de-termo/json-spec/walkers/validator/json-validator.rb +133 -0
  113. data/lib/cabeza-de-termo/json-spec/walkers/value-holders-stack-behaviour.rb +57 -0
  114. metadata +242 -0
@@ -0,0 +1,183 @@
1
+ require_relative "expression-walker"
2
+
3
+ module CabezaDeTermo
4
+ module JsonSpec
5
+ class JsonExpressionExplainer < ExpressionWalker
6
+ def initialize()
7
+ reset
8
+ end
9
+
10
+ def reset
11
+ @text = ''
12
+ @tabs = 0
13
+ end
14
+
15
+ def text
16
+ @text
17
+ end
18
+
19
+ def explain(json_walkable)
20
+ reset
21
+ walk_on(json_walkable)
22
+ text
23
+ end
24
+
25
+ def walk_on(json_walkable)
26
+ json_walkable.accept_walker(self)
27
+ end
28
+
29
+ def walk_json_spec(json_spec)
30
+ walk_on(json_spec.root_expression)
31
+ end
32
+
33
+ def walk_json_object(json_object)
34
+ append_with_tabs('{')
35
+
36
+ during_tab do
37
+ walk_each_defined_field_of(json_object)
38
+ end
39
+
40
+ if json_object.has_each_field?
41
+ during_tab do
42
+ cr
43
+ walk_on(json_object.each_field_expression)
44
+ end
45
+ end
46
+
47
+ append_in_new_line('}')
48
+
49
+ walk_on_expectations_of(json_object)
50
+ end
51
+
52
+ def walk_each_defined_field_of(json_object)
53
+ json_object.fields.each do |field|
54
+ cr
55
+ walk_on(field)
56
+ end
57
+ end
58
+
59
+ def walk_json_each_field(json_each_field)
60
+ append_with_tabs('each field')
61
+
62
+ during_tab do
63
+ append_in_new_line('name')
64
+ walk_on( json_each_field.name_expression )
65
+ end
66
+
67
+ during_tab do
68
+ append_in_new_line('value')
69
+ cr
70
+
71
+ during_tab do
72
+ walk_on(json_each_field.value_expression)
73
+ end
74
+ end
75
+ end
76
+
77
+ def walk_json_field_name(json_field_name)
78
+ walk_on_expectations_of(json_field_name)
79
+ end
80
+
81
+ def walk_json_list(json_list_expression)
82
+ append_with_tabs('[')
83
+
84
+ walk_on(json_list_expression.each_expression)
85
+
86
+ append_in_new_line(']')
87
+
88
+ walk_on_expectations_of(json_list_expression)
89
+ end
90
+
91
+ def walk_json_each(json_each_expression)
92
+ return unless json_each_expression.has_each_item_expression?
93
+
94
+ cr
95
+ during_tab do
96
+ walk_on(json_each_expression.each_item_expression)
97
+ end
98
+ end
99
+
100
+ def walk_json_field(json_field_expression)
101
+ append_with_tabs('"' + json_field_expression.name + '":')
102
+
103
+ during_tab do
104
+ cr
105
+ walk_on(json_field_expression.value_expression)
106
+ end
107
+ end
108
+
109
+ def walk_json_anything(json_anything)
110
+ append_with_tabs('anything')
111
+ walk_on_expectations_of(json_anything)
112
+ end
113
+
114
+ def walk_json_scalar(json_scalar)
115
+ append_with_tabs('scalar')
116
+ walk_on_expectations_of(json_scalar)
117
+ end
118
+
119
+ def walk_json_any_of(any_of)
120
+ append_with_tabs('any of')
121
+
122
+ isFirst = true
123
+
124
+ any_of.possible_expressions.each do |expression|
125
+ append_in_new_line('or') unless isFirst
126
+
127
+ during_tab do
128
+ cr
129
+ walk_on(expression)
130
+ end
131
+
132
+ isFirst = false
133
+ end
134
+ end
135
+
136
+ def walk_on_expectations_of(expression)
137
+ walk_on(expression.expectations_runner)
138
+ end
139
+
140
+ def walk_expectation_runner(expectation_runner)
141
+ expectation_runner.explain_with(self)
142
+ end
143
+
144
+ def walk_expectation(expectation)
145
+ append(' .' + expectation.explain)
146
+ end
147
+
148
+ # Text
149
+
150
+ def append_with_tabs(text)
151
+ append_tabs
152
+ append(text)
153
+ end
154
+
155
+ def append_in_new_line(text)
156
+ cr
157
+ append_with_tabs(text)
158
+ end
159
+
160
+ def append_tabs()
161
+ @tabs.times { |i| tab }
162
+ end
163
+
164
+ def append(text)
165
+ @text += text
166
+ end
167
+
168
+ def cr()
169
+ append("\n")
170
+ end
171
+
172
+ def tab()
173
+ append("\t")
174
+ end
175
+
176
+ def during_tab(&block)
177
+ @tabs += 1
178
+ block.call
179
+ @tabs -= 1
180
+ end
181
+ end
182
+ end
183
+ end
@@ -0,0 +1,63 @@
1
+ module CabezaDeTermo
2
+ module JsonSpec
3
+ class ExpectationReport
4
+ def initialize()
5
+ super()
6
+
7
+ @expectation_method = nil
8
+ @failed_message = nil
9
+ @status = nil
10
+ end
11
+
12
+ def set_expectation_method(expectation_method)
13
+ @expectation_method = expectation_method
14
+
15
+ self
16
+ end
17
+
18
+ def expectation_method()
19
+ @expectation_method
20
+ end
21
+
22
+ def set_failed_message(failed_message)
23
+ @failed_message = failed_message
24
+
25
+ self
26
+ end
27
+
28
+ def failed_message()
29
+ @failed_message
30
+ end
31
+
32
+ def set_status(status)
33
+ @status = status
34
+
35
+ self
36
+ end
37
+
38
+ def status()
39
+ @status
40
+ end
41
+
42
+ def set_was_satisfied(was_satisfied)
43
+ set_status(was_satisfied ? :was_satisfied : :failed)
44
+ end
45
+
46
+ def failed?()
47
+ status == :failed
48
+ end
49
+
50
+ def was_satisfied?()
51
+ status == :was_satisfied
52
+ end
53
+
54
+ def to_array()
55
+ [
56
+ expectation_method,
57
+ status,
58
+ failed_message
59
+ ]
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,111 @@
1
+ require_relative "../json-expectations-runner"
2
+ require_relative "expectation-report"
3
+ require 'json'
4
+
5
+ module CabezaDeTermo
6
+ module JsonSpec
7
+ class JsonExpectationsReporter < JsonExpectationsRunner
8
+ def initialize()
9
+ super()
10
+
11
+ @expectation_reports = []
12
+ end
13
+
14
+ def run_on_json_string(json_expression, json_string)
15
+ run_on(json_expression, JSON.parse(json_string))
16
+ end
17
+
18
+ def run_on(json_expression, json)
19
+ walk_with_json(json_expression, json)
20
+ end
21
+
22
+ # Accessing
23
+
24
+ def expectation_reports()
25
+ @expectation_reports
26
+ end
27
+
28
+ def expectation_reports_as_array()
29
+ arrays = []
30
+ expectation_reports.each do |expectation_report|
31
+ arrays << expectation_report.to_array
32
+ end
33
+
34
+ arrays
35
+ end
36
+
37
+ # Asking
38
+
39
+ #
40
+ # Answer true if all the walked Expectations were satisfied.
41
+ #
42
+ def no_errors?()
43
+ expectation_reports.all? { |expectation_report| expectation_report.was_satisfied? }
44
+ end
45
+
46
+ # Instance creation
47
+
48
+ def new_expectation_report()
49
+ ExpectationReport.new
50
+ end
51
+
52
+ # Logging Expectations reports
53
+
54
+ def log_expectation(expectation, value_holder, was_satisfied)
55
+ expectation_report = new_expectation_report
56
+ .set_expectation_method(expectation.expectation_method)
57
+ .set_was_satisfied(was_satisfied)
58
+ .set_failed_message( expectation.failed_message_on(value_holder) )
59
+
60
+ add_expectation_report(expectation_report)
61
+ end
62
+
63
+ def log_unwalked_field(field)
64
+ access_chain = @value_holder.accessors_chain.append_accessor(field).to_s
65
+
66
+ expectation_report = new_expectation_report
67
+ .set_expectation_method(:unexpected_field)
68
+ .set_status(:unexpected_field)
69
+ .set_failed_message("Unexpected field '#{access_chain}'.")
70
+
71
+ add_expectation_report(expectation_report)
72
+ end
73
+
74
+ def add_expectation_report(expectation_report)
75
+ @expectation_reports << expectation_report
76
+ end
77
+
78
+ def add_all_expectation_reports(expectation_reports)
79
+ expectation_reports.each do |report|
80
+ add_expectation_report(report)
81
+ end
82
+ end
83
+
84
+ # Hooks
85
+
86
+ def on_unwalked_field(field_name, value_holder)
87
+ log_unwalked_field(field_name)
88
+ end
89
+
90
+ def on_json_any_of_was_satisfied_with_runner(expectations_runner)
91
+ add_all_expectation_reports(expectations_runner.expectation_reports)
92
+ end
93
+
94
+ def on_json_any_of_failed_with_all_runners(expectations_runners)
95
+ expectations_runners.each do |each_runner|
96
+ add_all_expectation_reports(each_runner.expectation_reports)
97
+ end
98
+ end
99
+
100
+ def on_walked_expectation(expectation, value_holder, was_satisfied)
101
+ log_expectation(expectation, value_holder, was_satisfied)
102
+ end
103
+
104
+ # Instance creation
105
+
106
+ def new_json_expectations_runner()
107
+ self.class.new
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,29 @@
1
+ module CabezaDeTermo
2
+ module JsonSpec
3
+ class JsonValidatorError
4
+ def initialize(accessors_chain, message)
5
+ @accessors_chain = accessors_chain
6
+ @message = message
7
+ end
8
+
9
+ # Accessing
10
+
11
+ def message()
12
+ @message
13
+ end
14
+
15
+ def accessors_chain()
16
+ @accessors_chain
17
+ end
18
+
19
+ # Converting
20
+
21
+ def to_hash()
22
+ {
23
+ access_chain: accessors_chain().to_s,
24
+ message: message
25
+ }
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,133 @@
1
+ require_relative "json-validator-error"
2
+ require_relative "../json-expectations-runner"
3
+
4
+ module CabezaDeTermo
5
+ module JsonSpec
6
+ class JsonValidator < JsonExpectationsRunner
7
+ def initialize()
8
+ super()
9
+
10
+ @errors = []
11
+ @unexpected_field_errors = []
12
+ @treat_unexpected_fields_as_errors = false
13
+ end
14
+
15
+ def validate(json_expression, json)
16
+ walk_with_json(json_expression, json)
17
+
18
+ self
19
+ end
20
+
21
+ # Configuring
22
+
23
+ def treat_unexpected_fields_as_errors(boolean = true)
24
+ @treat_unexpected_fields_as_errors = boolean
25
+
26
+ self
27
+ end
28
+
29
+ # Asking
30
+
31
+ def no_errors?()
32
+ errors.empty?
33
+ end
34
+
35
+ def no_unexpected_fields?()
36
+ unexpected_fields.empty?
37
+ end
38
+
39
+ def has_unexpected_fields?()
40
+ !no_unexpected_fields?
41
+ end
42
+
43
+ def treat_unexpected_fields_as_errors?()
44
+ @treat_unexpected_fields_as_errors
45
+ end
46
+
47
+ # Counting
48
+
49
+ def errors_count()
50
+ errors.size
51
+ end
52
+
53
+ def unexpected_fields_count()
54
+ unexpected_fields.size
55
+ end
56
+
57
+ # Accessing
58
+
59
+ def errors()
60
+ @errors
61
+ end
62
+
63
+ def unexpected_fields()
64
+ @unexpected_field_errors
65
+ end
66
+
67
+ # Hooks
68
+
69
+ def on_unwalked_field(field_name, value_holder)
70
+ error = new_validation_error(
71
+ value_holder,
72
+ "An unexpected '#{field_name}' field was found."
73
+ )
74
+
75
+ add_unexpected_field(error)
76
+
77
+ add_error(error) if treat_unexpected_fields_as_errors?
78
+ end
79
+
80
+ def on_json_any_of_was_satisfied_with_runner(expectations_runner)
81
+ add_all_unexpected_fields(expectations_runner.unexpected_fields)
82
+ end
83
+
84
+ def on_json_any_of_failed_with_all_runners(expectations_runners)
85
+ expectations_runners.each do |each_expectations_runner|
86
+ add_all_errors(each_expectations_runner.errors)
87
+ end
88
+
89
+ expectations_runners.each do |each_expectations_runner|
90
+ add_all_unexpected_fields(each_expectations_runner.unexpected_fields)
91
+ end
92
+ end
93
+
94
+ def on_walked_expectation(expectation, value_holder, was_satisfied)
95
+ return if was_satisfied
96
+
97
+ add_error( new_validation_error(value_holder, expectation.failed_message_on(value_holder)) )
98
+ end
99
+
100
+ # Instance creation
101
+
102
+ def new_json_expectations_runner()
103
+ self.class.new
104
+ end
105
+
106
+ def new_validation_error(value_holder, message)
107
+ JsonValidatorError.new(value_holder.accessors_chain, message)
108
+ end
109
+
110
+ # Logging
111
+
112
+ def add_error(error)
113
+ @errors << error
114
+ end
115
+
116
+ def add_all_errors(errors)
117
+ errors.each do |error|
118
+ add_error(error)
119
+ end
120
+ end
121
+
122
+ def add_unexpected_field(error)
123
+ @unexpected_field_errors << error
124
+ end
125
+
126
+ def add_all_unexpected_fields(errors)
127
+ errors.each do |error|
128
+ add_unexpected_field(error)
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end