schemata-dea 0.0.1.beta18 → 0.0.1.beta20

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