schemata-dea 0.0.1.beta18 → 0.0.1.beta20

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,18 +1,43 @@
1
1
  module Schemata
2
- class DecodeError < StandardError; end
3
- class EncodeError < StandardError; end
4
- class SchemaDefinitionError < StandardError; end
2
+ class Error < StandardError
5
3
 
6
- class UpdateAttributeError < StandardError
7
- def initialize(key, message)
8
- super("#{key}: #{message}")
4
+ attr_reader :source_exception, :source_backtrace
5
+
6
+ def initialize(source_exception = $!, message = nil)
7
+ message = source_exception.message if message.nil? && source_exception
8
+ super(message)
9
+ if source_exception
10
+ @source_exception = source_exception
11
+ @source_backtrace = source_exception.backtrace || []
12
+ end
13
+ end
14
+
15
+ def backtrace
16
+ self_backtrace = super
17
+ self_backtrace && source_backtrace ? self_backtrace + source_backtrace : self_backtrace
9
18
  end
10
19
  end
11
20
 
12
- class IncompatibleVersionError < DecodeError
21
+ class DecodeError < Error; end
22
+ class EncodeError < Error; end
23
+ class SchemaDefinitionError < Error; end
24
+
25
+ class UpdateAttributeError < Error
26
+ attr_reader :key
27
+
28
+ def initialize(key, exception = $!)
29
+ super(exception, "#{key}: #{exception.message}")
30
+ @key = key
31
+ end
32
+ end
33
+
34
+ class IncompatibleVersionError < Error
35
+ attr_reader :msg_version, :component_version
36
+
13
37
  def initialize(msg_version, component_version)
14
- super("min message version #{msg_version} too high for component ver\
15
- sion #{component_version}")
38
+ super(self, "min message version #{msg_version} too high for component version #{component_version}")
39
+ @msg_version = msg_version
40
+ @component_version = component_version
16
41
  end
17
42
  end
18
43
  end
@@ -10,31 +10,18 @@ module Schemata
10
10
  class ValidatingContainer
11
11
  def initialize(data = {})
12
12
  data ||= {}
13
- @schema = self.class.const_get(:SCHEMA)
14
13
  @contents = {}
15
14
 
16
15
  data.each do |key, field_value|
17
- key = Schemata::Helpers.stringify(key)
18
- field_schema = @schema.schemas[key]
16
+ key = Schemata::Helpers.stringify_symbols(key) # TODO see test
17
+ field_schema = schema.schemas[key]
19
18
  next unless field_schema
20
19
 
21
- # TODO This call to stringify should be removed when cc/dea stop using
22
- # Symbols.
23
- #
24
- # Currently, some fields (for example, 'states' in requests sent
25
- # on dea.find.droplet), are are symbols, During Yajl decoding, however,
26
- # they become strings. Thus, on the encoding side, Schemata should expect
27
- # symbols, but on the decoding side, it should expect strings. To allow
28
- # for this in the schema definition, Schemata stringifies all symbols during
29
- # construction of Schemata objects.
30
- field_value = Schemata::Helpers.stringify(field_value)
31
-
32
20
  begin
33
- field_schema.validate(field_value)
21
+ field_value = validate_field(field_schema, key, field_value)
34
22
  rescue Membrane::SchemaValidationError => e
35
- raise Schemata::UpdateAttributeError.new(key, e.message)
23
+ raise Schemata::UpdateAttributeError.new(key, e)
36
24
  end
37
-
38
25
  @contents[key] = Schemata::Helpers.deep_copy(field_value)
39
26
  end
40
27
  end
@@ -50,17 +37,9 @@ module Schemata
50
37
  nil
51
38
  end
52
39
 
53
- # TODO This call to stringify should be removed when cc/dea stops using
54
- # symbols. See comment above for a better description.
40
+
55
41
  vc_klass.send(:define_method, "#{key}=") do |field_value|
56
- field_value = Schemata::Helpers.stringify(field_value)
57
- unless schema.optional_keys.include?(key) && field_value == nil
58
- begin
59
- field_schema.validate(field_value)
60
- rescue Membrane::SchemaValidationError => e
61
- raise Schemata::UpdateAttributeError.new(key, e.message)
62
- end
63
- end
42
+ field_value = validate_field(field_schema, key, field_value)
64
43
  @contents[key] = Schemata::Helpers.deep_copy(field_value)
65
44
  field_value
66
45
  end
@@ -77,7 +56,23 @@ module Schemata
77
56
  end
78
57
 
79
58
  def validate
80
- @schema.validate(@contents)
59
+ schema.schemas.each do |key, field_schema|
60
+ validate_field(field_schema, key, @contents[key])
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ def validate_field(field_schema, key, field_value)
67
+ field_value = Schemata::Helpers.stringify_symbols(field_value) # TODO see test
68
+ unless schema.optional_keys.include?(key) && field_value == nil
69
+ field_schema.validate(field_value)
70
+ end
71
+ field_value
72
+ end
73
+
74
+ def schema
75
+ self.class.const_get(:SCHEMA)
81
76
  end
82
77
  end
83
78
 
@@ -86,7 +81,7 @@ module Schemata
86
81
  end
87
82
 
88
83
  def aux_vc_klass
89
- return self.class.const_get(:AUX_VC_KLASS) if self.class.aux_schema
84
+ self.class.const_get(:AUX_VC_KLASS) if self.class.aux_schema
90
85
  end
91
86
 
92
87
  def initialize(msg_data_hash = nil, aux_data_hash = nil)
@@ -101,10 +96,10 @@ module Schemata
101
96
  validate_contents
102
97
  validate_aux_data
103
98
  rescue Membrane::SchemaValidationError => e
104
- raise Schemata::EncodeError.new(e.message)
99
+ raise Schemata::EncodeError.new(e)
105
100
  end
106
101
 
107
- msg_type = message_type
102
+ message_type
108
103
  curr_version = self.class.version
109
104
  min_version = self.class::MIN_VERSION_ALLOWED
110
105
 
@@ -146,140 +141,138 @@ module Schemata
146
141
  end
147
142
 
148
143
  def message_type
149
- _, component, msg_type, version = self.class.name.split("::")
144
+ _, component, msg_type, _ = self.class.name.split("::")
150
145
  Schemata::const_get(component)::const_get(msg_type)
151
146
  end
152
147
 
153
148
  def component
154
- _, component, msg_type, version = self.class.name.split("::")
149
+ component = self.class.name.split("::")[1]
155
150
  Schemata::const_get(component)
156
151
  end
157
152
 
158
153
  def self.included(klass)
159
- klass.extend(Schemata::ClassMethods)
160
- klass.extend(Dsl)
154
+ klass.extend(Schemata::MessageBase::ClassMethods)
155
+ klass.extend(Schemata::MessageBase::Dsl)
161
156
  end
162
- end
163
157
 
164
- module ClassMethods
165
- def mock
166
- mock = {}
167
- mock_values.keys.each do |k|
168
- value = mock_values[k]
169
- mock[k] = value.respond_to?("call") ? value.call : value
158
+ module ClassMethods
159
+ def mock
160
+ mock = {}
161
+ mock_values.keys.each do |k|
162
+ value = mock_values[k]
163
+ mock[k] = value.respond_to?("call") ? value.call : value
164
+ end
165
+ self.new(mock)
170
166
  end
171
- self.new(mock)
172
- end
173
-
174
- def schema
175
- self::SCHEMA
176
- end
177
-
178
- def aux_schema
179
- return self::AUX_SCHEMA if defined?(self::AUX_SCHEMA)
180
- end
181
-
182
- def mock_values
183
- self::MOCK_VALUES
184
- end
185
167
 
186
- def version
187
- _, component, msg_type, version = self.name.split("::")
188
- version[1..-1].to_i
189
- end
168
+ def schema
169
+ self::SCHEMA
170
+ end
190
171
 
191
- def previous_version
192
- _, component, msg_type, version = self.name.split("::")
193
- version = version[1..-1].to_i - 1
194
- Schemata::const_get(component)::const_get(msg_type)::
195
- const_get("V#{version}")
196
- end
197
- end
172
+ def aux_schema
173
+ return self::AUX_SCHEMA if defined?(self::AUX_SCHEMA)
174
+ end
198
175
 
199
- module Dsl
200
- def define_schema(&blk)
201
- schema = Membrane::SchemaParser.parse(&blk)
202
- unless schema.kind_of? Membrane::Schema::Record
203
- Schemata::SchemaDefinitionError.new("Schema must be a hash")
176
+ def mock_values
177
+ self::MOCK_VALUES
204
178
  end
205
- self::const_set(:SCHEMA, schema)
206
- end
207
179
 
208
- def define_aux_schema(&blk)
209
- aux_schema = Membrane::SchemaParser.parse(&blk)
210
- unless aux_schema.kind_of? Membrane::Schema::Record
211
- Schemata::SchemaDefinitionError.new("Schema must be a hash")
180
+ def version
181
+ self.name.split("::")[-1][1..-1].to_i
212
182
  end
213
183
 
214
- self::const_set(:AUX_SCHEMA, aux_schema)
184
+ def previous_version
185
+ _, component, msg_type, version = self.name.split("::")
186
+ version = version[1..-1].to_i - 1
187
+ Schemata::const_get(component)::const_get(msg_type)::const_get("V#{version}")
188
+ end
215
189
  end
216
190
 
217
- def define_min_version(min_version)
218
- unless min_version.is_a? Integer
219
- raise SchemaDefinitionError.new("Min version must be an integer")
191
+ module Dsl
192
+ def define_schema(&blk)
193
+ schema = Membrane::SchemaParser.parse(&blk)
194
+ unless schema.kind_of? Membrane::Schema::Record
195
+ raise Schemata::SchemaDefinitionError.new(nil, "Schema must be a hash")
196
+ end
197
+ self::const_set(:SCHEMA, schema)
220
198
  end
221
- const_set(:MIN_VERSION_ALLOWED, min_version)
222
- end
223
199
 
224
- def define_upvert(&blk)
225
- eigenclass.send(:define_method, :upvert) do |old_data|
226
- # No need to validate aux_data because upvert is only called during
227
- # decode, when aux_data is irrelevant
228
- begin
229
- previous_version::SCHEMA.validate(old_data)
230
- rescue Membrane::SchemaValidationError => e
231
- raise Schemata::DecodeError.new(e.message)
200
+ def define_aux_schema(&blk)
201
+ aux_schema = Membrane::SchemaParser.parse(&blk)
202
+ unless aux_schema.kind_of? Membrane::Schema::Record
203
+ raise Schemata::SchemaDefinitionError.new(nil, "Schema must be a hash")
232
204
  end
233
205
 
234
- blk.call(old_data)
206
+ self::const_set(:AUX_SCHEMA, aux_schema)
235
207
  end
236
- end
237
208
 
238
- def define_generate_old_fields(&blk)
239
- self.send(:define_method, :generate_old_fields) do
240
- if self.class.aux_schema && aux_data.empty?
241
- raise Schemata::DecodeError.new("Necessary aux_data missing")
209
+ def define_min_version(min_version)
210
+ unless min_version.is_a? Integer
211
+ raise SchemaDefinitionError.new(nil, "Min version must be an integer")
242
212
  end
243
- old_fields = blk.call(self)
213
+ const_set(:MIN_VERSION_ALLOWED, min_version)
214
+ end
244
215
 
245
- msg_contents = contents
246
- msg_contents.update(old_fields)
247
- msg_obj = self.class.previous_version.new(msg_contents)
216
+ def define_upvert(&blk)
217
+ eigenclass.send(:define_method, :upvert) do |old_data|
218
+ # No need to validate aux_data because upvert is only called during
219
+ # decode, when aux_data is irrelevant
220
+ begin
221
+ previous_version::SCHEMA.validate(old_data)
222
+ rescue Membrane::SchemaValidationError => e
223
+ raise Schemata::DecodeError.new(e)
224
+ end
248
225
 
249
- msg_obj.validate_contents
250
- return msg_obj, old_fields
226
+ blk.call(old_data)
227
+ end
251
228
  end
252
- end
253
229
 
254
- def define_mock_values(hash=nil, &blk)
255
- if (hash && blk) || (!hash && !blk)
256
- # value defined twice or not at all
257
- raise SchemaDefinitionError.new("Mock values incorrectly defined")
230
+ def define_generate_old_fields(&blk)
231
+ self.send(:define_method, :generate_old_fields) do
232
+ if self.class.aux_schema && aux_data.empty?
233
+ raise Schemata::DecodeError.new(nil, "Necessary aux_data missing")
234
+ end
235
+ old_fields = blk.call(self)
236
+
237
+ msg_contents = contents
238
+ msg_contents.update(old_fields)
239
+ msg_obj = self.class.previous_version.new(msg_contents)
240
+
241
+ msg_obj.validate_contents
242
+ return msg_obj, old_fields
243
+ end
258
244
  end
259
245
 
260
- hash = blk.call if blk
246
+ def define_mock_values(hash=nil, &blk)
247
+ if (hash && blk) || (!hash && !blk)
248
+ # value defined twice or not at all
249
+ raise SchemaDefinitionError.new(nil, "Mock values incorrectly defined")
250
+ end
251
+
252
+ hash = blk.call if blk
261
253
 
262
- # Validate a sample of the mock values.
263
- mock = {}
264
- hash.each do |key, value|
265
- mock[key] = value.respond_to?("call") ? value.call : value
254
+ # Validate a sample of the mock values.
255
+ mock = {}
256
+ hash.each do |key, value|
257
+ mock[key] = value.respond_to?("call") ? value.call : value
258
+ end
259
+
260
+ begin
261
+ self.schema.validate(mock)
262
+ define_constant(:MOCK_VALUES, hash)
263
+ rescue Membrane::SchemaValidationError => e
264
+ raise SchemaDefinitionError.new(nil, "Sample mock values do not match schema: #{e}")
265
+ end
266
266
  end
267
267
 
268
- begin
269
- self.schema.validate(mock)
270
- define_constant(:MOCK_VALUES, hash)
271
- rescue Membrane::SchemaValidationError => e
272
- raise SchemaDefinitionError.new("Sample mock values do not match schema: #{e}")
268
+ def define_constant(constant_name, constant_value)
269
+ self.const_set(constant_name, constant_value)
273
270
  end
274
- end
275
271
 
276
- def define_constant(constant_name, constant_value)
277
- self.const_set(constant_name, constant_value)
278
- end
272
+ def include_preschemata
273
+ define_constant(:INCLUDE_PRESCHEMATA, true)
274
+ end
279
275
 
280
- def include_preschemata
281
- define_constant(:INCLUDE_PRESCHEMATA, true)
282
276
  end
283
-
284
277
  end
285
278
  end
@@ -60,9 +60,9 @@ module Schemata
60
60
  # We don't validate aux data in decode.
61
61
  return msg_obj
62
62
  rescue Schemata::UpdateAttributeError => e
63
- raise Schemata::DecodeError.new(e.message)
63
+ raise Schemata::DecodeError.new(e)
64
64
  rescue Membrane::SchemaValidationError => e
65
- raise Schemata::DecodeError.new(e.message)
65
+ raise Schemata::DecodeError.new(e)
66
66
  end
67
67
  end
68
68
 
@@ -124,12 +124,14 @@ module Schemata
124
124
  end
125
125
 
126
126
  # Define attribute accessors for the message class
127
- klass.schema.schemas.each do |key, field_schema|
128
- klass.send(:define_method, key) do
129
- @contents.send(key)
130
- end
127
+ klass.schema.schemas.each do |key, _|
128
+ klass.send(:define_method, key) { @contents.send(key) }
131
129
  klass.send(:define_method, "#{key}=") do |field_value|
132
- @contents.send("#{key}=", field_value)
130
+ begin
131
+ @contents.send("#{key}=", field_value)
132
+ rescue Membrane::SchemaValidationError => e
133
+ raise Schemata::UpdateAttributeError.new(key, e)
134
+ end
133
135
  end
134
136
  end
135
137
  self::const_set("V#{v}", klass)
@@ -144,9 +146,8 @@ module Schemata
144
146
  msg_obj = current_class.new(msg_contents)
145
147
  msg_obj.validate_contents
146
148
  return msg_obj
147
- rescue Schemata::UpdateAttributeError,
148
- Membrane::SchemaValidationError => e
149
- raise Schemata::DecodeError.new(e.message)
149
+ rescue Schemata::UpdateAttributeError, Membrane::SchemaValidationError => e
150
+ raise Schemata::DecodeError.new(e)
150
151
  end
151
152
  end
152
153
 
@@ -12,24 +12,24 @@ module Schemata
12
12
 
13
13
  @min_version = @contents['min_version']
14
14
  if !@min_version
15
- raise DecodeError.new("Field 'min_version' abset from message")
15
+ raise DecodeError.new(nil, "Field 'min_version' abset from message")
16
16
  end
17
17
 
18
18
  versions = []
19
19
  @contents.keys.each do |k|
20
20
  next if k == 'min_version'
21
21
  unless k =~ /^V[0-9]+$/
22
- raise DecodeError.new("Invalid key: #{k}")
22
+ raise DecodeError.new(nil, "Invalid key: #{k}")
23
23
  end
24
24
  versions << k[1..-1].to_i
25
25
  end
26
26
 
27
27
  if versions.empty?
28
- raise DecodeError.new("Message contains no versioned hashes")
28
+ raise DecodeError.new(nil, "Message contains no versioned hashes")
29
29
  end
30
30
 
31
31
  if Set.new(versions.min..versions.max) != Set.new(versions)
32
- raise DecodeError.new("There are versions missing between\
32
+ raise DecodeError.new(nil, "There are versions missing between\
33
33
  #{versions.min} and #{versions.max}")
34
34
  end
35
35
 
@@ -1,5 +1,5 @@
1
1
  module Schemata
2
2
  module Dea
3
- VERSION = "0.0.1.beta18"
3
+ VERSION = "0.0.1.beta20"
4
4
  end
5
5
  end
@@ -0,0 +1 @@
1
+ Dir[File.expand_path("../helpers/*.rb", __FILE__)].each { |file| require file }
@@ -1,24 +1,21 @@
1
1
  module Schemata
2
2
  module Helpers
3
+ class StringifyError < StandardError; end
3
4
 
4
- def self.stringify(node)
5
+ def self.stringify_symbols(node)
5
6
  case node
6
- when String
7
- return node
8
- when Numeric, TrueClass, FalseClass
9
- return node
10
7
  when Hash
11
8
  copy = {}
12
- node.each { |k, v| copy[k.to_s] = stringify(v) }
9
+ node.each { |k, v| copy[k.to_s] = stringify_symbols(v) }
13
10
  return copy
14
11
  when Array
15
- return node.map { |v| stringify(v) }
16
- when NilClass
17
- return nil
12
+ return node.map { |v| stringify_symbols(v) }
18
13
  when Symbol
19
14
  return node.to_s
15
+ when String, Numeric, TrueClass, FalseClass, NilClass
16
+ return node
20
17
  else
21
- raise CopyError.new("Unexpected class: #{node.class}")
18
+ raise StringifyError.new("Unexpected class: #{node.class}")
22
19
  end
23
20
  end
24
21
 
@@ -0,0 +1,90 @@
1
+ require 'spec_helper'
2
+ require 'schemata/common/error'
3
+
4
+ describe Schemata do
5
+ let(:backtrace) { %w(foo bar) }
6
+ let(:message) { "message" }
7
+ let(:exception) do
8
+ error = StandardError.new(message)
9
+ error.set_backtrace backtrace
10
+ error
11
+ end
12
+
13
+ describe Schemata::Error do
14
+ context 'when an exception is explicitly passed in' do
15
+ context 'and a message is not passed in' do
16
+ subject { Schemata::Error.new(exception) }
17
+
18
+ its(:message) { should eq message }
19
+ its(:backtrace) { should be_nil }
20
+ end
21
+
22
+ context 'and a message is passed in' do
23
+ subject { Schemata::Error.new(exception, "other message") }
24
+
25
+ its(:message) { should eq "other message" }
26
+ its(:backtrace) { should be_nil }
27
+ end
28
+ end
29
+
30
+ context 'when no exception is passed in' do
31
+ context 'and it is a reraise' do
32
+ subject do
33
+ error = nil
34
+ begin
35
+ begin
36
+ raise exception
37
+ rescue
38
+ raise Schemata::Error.new
39
+ end
40
+ rescue => e
41
+ error = e
42
+ end
43
+ error
44
+ end
45
+
46
+ its(:message) { should eq message }
47
+ its(:source_backtrace) { should eq backtrace }
48
+
49
+ it 'includes the re raised exception' do
50
+ expect(subject.backtrace.first).to match /error_spec\.rb/
51
+ end
52
+
53
+ it 'includes the chained exception' do
54
+ expect(subject.backtrace.last).to eq "bar"
55
+ end
56
+ end
57
+
58
+ context 'and it is a standlone exception' do
59
+ subject { Schemata::Error.new(nil, message) }
60
+
61
+ its(:message) { should eq message }
62
+ its(:backtrace) { should be_nil }
63
+ end
64
+ end
65
+ end
66
+
67
+ describe Schemata::UpdateAttributeError do
68
+ let(:key) { "key" }
69
+ subject { Schemata::UpdateAttributeError.new(key, exception) }
70
+
71
+ its(:message) { should eq "#{key}: #{message}" }
72
+ its(:to_s) { should eq "#{key}: #{message}" }
73
+ its(:key) { should eq key }
74
+ its(:backtrace) { should be_nil }
75
+ end
76
+
77
+ describe Schemata::IncompatibleVersionError do
78
+ let(:msg_version) { 1 }
79
+ let(:component_version) { 2 }
80
+
81
+ subject { Schemata::IncompatibleVersionError.new(msg_version, component_version) }
82
+
83
+ its(:message) { should eq "min message version #{msg_version} too high for component version #{component_version}" }
84
+ its(:to_s) { should eq "min message version #{msg_version} too high for component version #{component_version}" }
85
+ its(:msg_version) { should eq msg_version }
86
+ its(:component_version) { should eq component_version }
87
+ its(:backtrace) { should be_nil }
88
+ end
89
+ end
90
+
@@ -87,29 +87,4 @@ describe Schemata::Helpers do
87
87
  end.to raise_error(described_class::CopyError, /Unexpected class: /)
88
88
  end
89
89
  end
90
-
91
- describe "#stringify" do
92
- it "should stringify nil" do
93
- str = Schemata::Helpers.stringify(nil)
94
- str.should == nil
95
- end
96
-
97
- it "should stringify a string" do
98
- original = "foo"
99
- str = Schemata::Helpers.stringify(original)
100
- str.should == "foo"
101
- end
102
-
103
- it "should stringify a symbol" do
104
- original = :foo
105
- str = Schemata::Helpers.stringify(original)
106
- str.should == "foo"
107
- end
108
-
109
- it "should stringify a hash" do
110
- original = { "foo" => :foo }
111
- str = Schemata::Helpers.stringify(original)
112
- str.should == { "foo" => "foo" }
113
- end
114
- end
115
90
  end
@@ -0,0 +1,162 @@
1
+ require 'spec_helper'
2
+ require 'membrane'
3
+ require 'schemata/helpers'
4
+ require 'schemata/common/msgbase'
5
+
6
+ describe Schemata::MessageBase do
7
+ describe Schemata::MessageBase::ValidatingContainer do
8
+ let(:data) { {"required" => "value"} }
9
+ let(:validating_container) { Schemata::MessageBase::ValidatingContainer.define(schema) }
10
+ let(:instance_validating_container) { validating_container.new(data) }
11
+ let(:schema) do
12
+ Membrane::SchemaParser.parse do
13
+ {
14
+ "required" => String,
15
+ optional("optional") => String
16
+ }
17
+ end
18
+ end
19
+
20
+ describe ".new" do
21
+ context 'when the field is an optional attribute' do
22
+ let(:data) { {:optional => nil} }
23
+ it 'allows it to be set to nil' do
24
+ expect(instance_validating_container.optional).to be_nil
25
+ end
26
+ end
27
+
28
+ context "when the keys are string in the data" do
29
+ it { expect(instance_validating_container.required).to eq "value" }
30
+ end
31
+
32
+ context "when keys are symbols in the data due to DEA inconsistencies" do
33
+ let(:data) { {:required => "value"} }
34
+
35
+ it 'stringifies them temporarily' do
36
+ # TODO Yajl decodes keys become strings. Thus, on the encoding side, Schemata should allow symbols,
37
+ # but on the decoding side, it should expect strings. E.g. states in dea.find.droplet
38
+ expect(instance_validating_container.required).to eq "value"
39
+ end
40
+ end
41
+ end
42
+
43
+ describe ".define" do
44
+ context 'when the field is required' do
45
+ it "doesn't it to be set to nil" do
46
+ expect { instance_validating_container.required = nil }.to raise_error Membrane::SchemaValidationError
47
+ end
48
+ end
49
+
50
+ context 'when the field is an optional attribute' do
51
+ it 'allows it to be set to nil' do
52
+ expect { instance_validating_container.optional = nil }.not_to raise_error
53
+ end
54
+ end
55
+ end
56
+
57
+ describe '#validate' do
58
+ let(:required) { "foo" }
59
+ let(:optional) { "bar" }
60
+
61
+ subject do
62
+ instance_validating_container.required = required
63
+ instance_validating_container.optional = optional
64
+ instance_validating_container.validate
65
+ end
66
+
67
+ it { expect { subject }.not_to raise_error }
68
+
69
+ context 'when the schema an optional nil value' do
70
+ let(:optional) { nil }
71
+ it { expect { subject }.not_to raise_error }
72
+ end
73
+
74
+ context 'when the schema an optional wrong type value' do
75
+ let(:optional) { 123 }
76
+ it { expect { subject }.to raise_error Membrane::SchemaValidationError }
77
+ end
78
+
79
+ context 'when the schema a required nil value' do
80
+ let(:required) { nil }
81
+ it { expect { subject }.to raise_error Membrane::SchemaValidationError }
82
+ end
83
+
84
+ context 'when the schema a required wrong type value' do
85
+ let(:required) { 123 }
86
+ it { expect { subject }.to raise_error Membrane::SchemaValidationError }
87
+ end
88
+ end
89
+ end
90
+
91
+ describe Schemata::MessageBase::Dsl do
92
+ describe '#define_aux_schema' do
93
+ let(:dsl) do
94
+ class TestDsl
95
+ extend Schemata::MessageBase::Dsl
96
+ end
97
+ end
98
+
99
+ after do
100
+ dsl::AUX_SCHEMA
101
+ end
102
+
103
+ subject do
104
+ dsl.define_aux_schema &schema
105
+ end
106
+
107
+ context 'when the aux schema is a Record' do
108
+ let(:schema) { ->(_) { {"key" => String} } }
109
+
110
+ it 'sets the AUX_SCHEMA constant to the parse schema' do
111
+ subject
112
+ expect(dsl::AUX_SCHEMA).to be_a Membrane::Schema::Record
113
+ end
114
+
115
+ it "correctly parses the schema" do
116
+ subject
117
+ expect(dsl::AUX_SCHEMA.schemas["key"].klass).to eq String
118
+ end
119
+ end
120
+
121
+ context 'when the aux schema is not a Record' do
122
+ let(:schema) { ->(_) { [String] } }
123
+ it { expect { subject }.to raise_error Schemata::SchemaDefinitionError, "Schema must be a hash" }
124
+ end
125
+ end
126
+
127
+ describe '#define_schema' do
128
+ let(:dsl) do
129
+ class TestDsl
130
+ extend Schemata::MessageBase::Dsl
131
+ end
132
+ end
133
+
134
+ after do
135
+ dsl::SCHEMA
136
+ end
137
+
138
+ subject do
139
+ dsl.define_schema &schema
140
+ end
141
+
142
+ context 'when the aux schema is a Record' do
143
+ let(:schema) { ->(_) { {"key" => String} } }
144
+
145
+ it 'sets the SCHEMA constant to the parse schema' do
146
+ subject
147
+ expect(dsl::SCHEMA).to be_a Membrane::Schema::Record
148
+ end
149
+
150
+ it "correctly parses the schema" do
151
+ subject
152
+ expect(dsl::SCHEMA.schemas["key"].klass).to eq String
153
+ end
154
+ end
155
+
156
+ context 'when the aux schema is not a Record' do
157
+ let(:schema) { ->(_) { [String] } }
158
+ it { expect { subject }.to raise_error Schemata::SchemaDefinitionError, "Schema must be a hash" }
159
+ end
160
+ end
161
+ end
162
+ end
@@ -7,7 +7,7 @@ describe Schemata::ParsedMessage do
7
7
  "V10" : { "foo" : "bar" }
8
8
  }'
9
9
  expect {
10
- msg = Schemata::ParsedMessage.new(json)
10
+ Schemata::ParsedMessage.new(json)
11
11
  }.to raise_error(Schemata::DecodeError)
12
12
  end
13
13
 
@@ -17,7 +17,7 @@ describe Schemata::ParsedMessage do
17
17
  "foo" : "bar"
18
18
  }'
19
19
  expect {
20
- msg = Schemata::ParsedMessage.new(json)
20
+ Schemata::ParsedMessage.new(json)
21
21
  }.to raise_error(Schemata::DecodeError)
22
22
  end
23
23
 
@@ -26,7 +26,7 @@ describe Schemata::ParsedMessage do
26
26
  "min_version" : 10
27
27
  }'
28
28
  expect {
29
- msg = Schemata::ParsedMessage.new(json)
29
+ Schemata::ParsedMessage.new(json)
30
30
  }.to raise_error(Schemata::DecodeError)
31
31
  end
32
32
 
@@ -94,7 +94,7 @@ describe Schemata::Component do
94
94
  }
95
95
  json_msg = Yajl::Encoder.encode msg_hash
96
96
  expect {
97
- foo_obj = Schemata::Component::Foo.decode(json_msg)
97
+ Schemata::Component::Foo.decode(json_msg)
98
98
  }.to raise_error(Schemata::DecodeError)
99
99
  end
100
100
 
@@ -104,7 +104,7 @@ describe Schemata::Component do
104
104
  }
105
105
  json_msg = Yajl::Encoder.encode msg_hash
106
106
  expect {
107
- foo_obj = Schemata::Component::Foo.decode(json_msg)
107
+ Schemata::Component::Foo.decode(json_msg)
108
108
  }.to raise_error(Schemata::DecodeError)
109
109
  end
110
110
 
@@ -147,7 +147,7 @@ describe Schemata::Component do
147
147
  }
148
148
  json_msg = Yajl::Encoder.encode(msg_hash)
149
149
  expect {
150
- foo_obj = Schemata::Component::Foo.decode(json_msg)
150
+ Schemata::Component::Foo.decode(json_msg)
151
151
  }.to raise_error(Schemata::DecodeError)
152
152
  end
153
153
 
@@ -164,7 +164,7 @@ of V11 and V10 hashes" do
164
164
  }
165
165
  json_msg = Yajl::Encoder.encode(msg_hash)
166
166
  expect {
167
- foo_obj = Schemata::Component::Foo.decode(
167
+ Schemata::Component::Foo.decode(
168
168
  json_msg)
169
169
  }.to raise_error(Schemata::DecodeError)
170
170
  end
@@ -183,20 +183,20 @@ of V10, V11, and V12 hashes" do
183
183
  }
184
184
  json_msg = Yajl::Encoder.encode msg_hash
185
185
  expect {
186
- foo_obj = Schemata::Component::Foo.decode(json_msg)
186
+ Schemata::Component::Foo.decode(json_msg)
187
187
  }.to raise_error(Schemata::DecodeError)
188
188
 
189
189
  msg_hash["V11"]["foo2"] = "bar"
190
190
  msg_hash["V12"]["foo2"] = 1
191
191
  json_msg = Yajl::Encoder.encode msg_hash
192
192
  expect {
193
- foo_obj = Schemata::Component::Foo.decode(json_msg)
193
+ Schemata::Component::Foo.decode(json_msg)
194
194
  }.to raise_error(Schemata::DecodeError)
195
195
  end
196
196
 
197
197
  it "should raise an IncompatibleVersionError when it gets a v13 msg" do
198
198
  expect {
199
- foo_obj = Schemata::Component::Foo.decode(@v13_msg)
199
+ Schemata::Component::Foo.decode(@v13_msg)
200
200
  }.to raise_error(Schemata::IncompatibleVersionError)
201
201
  end
202
202
  end
@@ -465,7 +465,7 @@ of V10, V11, and V12 hashes" do
465
465
  it "should raise an error if the msg_obj is incomplete" do
466
466
  msg_obj = Schemata::Component::Foo::V10.new({"foo1" => "foo"})
467
467
  expect {
468
- json = msg_obj.encode
468
+ msg_obj.encode
469
469
  }.to raise_error(Schemata::EncodeError)
470
470
  end
471
471
  end
@@ -475,7 +475,7 @@ of V10, V11, and V12 hashes" do
475
475
  set_current_version(Schemata::Component::Foo, 11)
476
476
  end
477
477
 
478
- after:each do
478
+ after :each do
479
479
  reset_version(Schemata::Component::Foo)
480
480
  end
481
481
 
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+ require 'schemata/helpers'
3
+
4
+ describe Schemata::Helpers do
5
+ describe ".stringify" do
6
+ subject { Schemata::Helpers.stringify_symbols(obj) }
7
+
8
+ context 'when the object is a String' do
9
+ let(:obj) { "foo" }
10
+ it { should eq obj }
11
+ end
12
+
13
+ context 'when the object is a symbol' do
14
+ let(:obj) { :foo }
15
+ it { should eq "foo" }
16
+ end
17
+
18
+ context 'when the object is a numeric' do
19
+ let(:obj) { 123.03 }
20
+ it { should eq obj }
21
+ end
22
+
23
+ context 'when the object is a nil' do
24
+ let(:obj) { nil }
25
+ it { should be_nil }
26
+ end
27
+
28
+ context 'when the object is a nil' do
29
+ let(:obj) { true }
30
+ it { should be_true }
31
+ end
32
+
33
+ context 'when the object is a nil' do
34
+ let(:obj) { false }
35
+ it { should be_false }
36
+ end
37
+
38
+ context 'when the object is an array' do
39
+ context 'and one of the values is a symobl' do
40
+ let(:obj) { [:foo, "bar", :baz] }
41
+ it { should eq %w(foo bar baz) }
42
+ end
43
+
44
+ context 'and their is a nested array' do
45
+ let(:obj) { [:foo, ["bar", :bar], :baz] }
46
+ it { should eq ["foo", ["bar", "bar"], "baz"] }
47
+ end
48
+ end
49
+
50
+ context "when the object is a hash" do
51
+ context 'and the value is a symbol' do
52
+ let(:obj) { { "foo" => :foo } }
53
+ it { should eq("foo" => "foo") }
54
+ end
55
+
56
+ context 'and the key is a symbol' do
57
+ let(:obj) { { :foo => 'foo'} }
58
+ it { should eq("foo" => "foo") }
59
+ end
60
+
61
+ context 'and their is a nested hash' do
62
+ let(:obj) { { :foo => {:foo => 'bar'}} }
63
+ it { should eq("foo" => {"foo" => "bar"}) }
64
+ end
65
+ end
66
+
67
+ context 'when the object is a nil' do
68
+ let(:obj) { Object.new }
69
+ it { expect { subject }.to raise_error Schemata::Helpers::StringifyError }
70
+ end
71
+ end
72
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: schemata-dea
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.beta18
4
+ version: 0.0.1.beta20
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -149,9 +149,12 @@ files:
149
149
  - lib/schemata/helpers/decamelize.rb
150
150
  - lib/schemata/helpers/hash_copy.rb
151
151
  - lib/schemata/helpers/stringify.rb
152
+ - lib/schemata/helpers.rb
152
153
  - spec/cloud_controller_spec.rb
153
154
  - spec/common/componentbase_spec.rb
155
+ - spec/common/error_spec.rb
154
156
  - spec/common/helpers_spec.rb
157
+ - spec/common/msgbase_spec.rb
155
158
  - spec/common/msgtypebase_spec.rb
156
159
  - spec/common/parsed_msg_spec.rb
157
160
  - spec/component/aux_data_spec.rb
@@ -161,6 +164,7 @@ files:
161
164
  - spec/component2/component2_bar_spec.rb
162
165
  - spec/dea_spec.rb
163
166
  - spec/health_manager_spec.rb
167
+ - spec/helpers/stringify_spec.rb
164
168
  - spec/router_spec.rb
165
169
  - spec/spec_helper.rb
166
170
  - spec/staging_spec.rb
@@ -195,7 +199,9 @@ summary: validation for cloundfoundry DEA messages
195
199
  test_files:
196
200
  - spec/cloud_controller_spec.rb
197
201
  - spec/common/componentbase_spec.rb
202
+ - spec/common/error_spec.rb
198
203
  - spec/common/helpers_spec.rb
204
+ - spec/common/msgbase_spec.rb
199
205
  - spec/common/msgtypebase_spec.rb
200
206
  - spec/common/parsed_msg_spec.rb
201
207
  - spec/component/aux_data_spec.rb
@@ -205,6 +211,7 @@ test_files:
205
211
  - spec/component2/component2_bar_spec.rb
206
212
  - spec/dea_spec.rb
207
213
  - spec/health_manager_spec.rb
214
+ - spec/helpers/stringify_spec.rb
208
215
  - spec/router_spec.rb
209
216
  - spec/spec_helper.rb
210
217
  - spec/staging_spec.rb