slow_blink 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/ext/slow_blink/ext_schema_parser/extconf.rb +1 -0
  3. data/ext/slow_blink/ext_schema_parser/lexer.c +6 -8
  4. data/ext/slow_blink/ext_schema_parser/lexer.h +1 -1
  5. data/ext/slow_blink/ext_schema_parser/parser.c +3 -1
  6. data/ext/slow_blink/message/ext_compact_encoder/ext_compact_encoder.c +46 -24
  7. data/ext/slow_blink/message/ext_compact_encoder/extconf.rb +9 -2
  8. data/lib/slow_blink/enum.rb +4 -1
  9. data/lib/slow_blink/field.rb +1 -1
  10. data/lib/slow_blink/generate_c/model.rb +119 -12
  11. data/lib/slow_blink/message/binary.rb +9 -1
  12. data/lib/slow_blink/message/boolean.rb +12 -3
  13. data/lib/slow_blink/message/date.rb +9 -1
  14. data/lib/slow_blink/message/decimal.rb +9 -1
  15. data/lib/slow_blink/message/dynamic_group.rb +132 -0
  16. data/lib/slow_blink/message/enum.rb +6 -2
  17. data/lib/slow_blink/message/field.rb +67 -43
  18. data/lib/slow_blink/message/fixed.rb +5 -1
  19. data/lib/slow_blink/message/floating_point.rb +9 -1
  20. data/lib/slow_blink/message/group.rb +54 -197
  21. data/lib/slow_blink/message/integer.rb +16 -8
  22. data/lib/slow_blink/message/model.rb +20 -18
  23. data/lib/slow_blink/message/static_group.rb +63 -0
  24. data/lib/slow_blink/message/string.rb +9 -1
  25. data/lib/slow_blink/message/test_data.rb +126 -0
  26. data/lib/slow_blink/message/time.rb +10 -2
  27. data/lib/slow_blink/message/time_of_day.rb +18 -2
  28. data/lib/slow_blink/schema.rb +2 -2
  29. data/lib/slow_blink/type.rb +3 -3
  30. data/lib/slow_blink/version.rb +1 -1
  31. data/test/tc_inputs.rb +34 -25
  32. data/test/tc_model_enum.rb +47 -0
  33. data/test/tc_model_inputs.rb +47 -0
  34. metadata +9 -7
  35. data/ext/slow_blink/message/ext_compact_encoder/blink_compact.c +0 -642
  36. data/ext/slow_blink/message/ext_compact_encoder/blink_compact.h +0 -411
  37. data/ext/slow_blink/message/ext_compact_encoder/blink_debug.h +0 -46
  38. data/ext/slow_blink/message/ext_compact_encoder/blink_stream.c +0 -314
  39. data/ext/slow_blink/message/ext_compact_encoder/blink_stream.h +0 -185
@@ -24,6 +24,10 @@ module SlowBlink::Message
24
24
  # @abstract
25
25
  class INTEGER
26
26
 
27
+ def self.type
28
+ @type
29
+ end
30
+
27
31
  # @param value [Integer]
28
32
  # @return [true,false] integer value is within permitted range
29
33
  def self.in_range?(value)
@@ -56,13 +60,17 @@ module SlowBlink::Message
56
60
  set(value)
57
61
  end
58
62
 
63
+ def to_tag
64
+ @value.to_s
65
+ end
66
+
59
67
  end
60
68
 
61
69
  # @abstract
62
70
  class U8 < INTEGER
63
71
 
64
72
  # @private
65
- def self.from_compact(input, stack)
73
+ def self.from_compact(input, depth)
66
74
  if value = input.getU8
67
75
  self.new(value)
68
76
  else
@@ -81,7 +89,7 @@ module SlowBlink::Message
81
89
  class U16 < INTEGER
82
90
 
83
91
  # @private
84
- def self.from_compact(input, stack)
92
+ def self.from_compact(input, depth)
85
93
  if value = input.getU16
86
94
  self.new(value)
87
95
  else
@@ -100,7 +108,7 @@ module SlowBlink::Message
100
108
  class U32 < INTEGER
101
109
 
102
110
  # @private
103
- def self.from_compact(input, stack)
111
+ def self.from_compact(input, depth)
104
112
  if value = input.getU32
105
113
  self.new(value)
106
114
  else
@@ -119,7 +127,7 @@ module SlowBlink::Message
119
127
  class U64 < INTEGER
120
128
 
121
129
  # @private
122
- def self.from_compact(input, stack)
130
+ def self.from_compact(input, depth)
123
131
  if value = input.getU64
124
132
  self.new(value)
125
133
  else
@@ -138,7 +146,7 @@ module SlowBlink::Message
138
146
  class I8 < INTEGER
139
147
 
140
148
  # @private
141
- def self.from_compact(input, stack)
149
+ def self.from_compact(input, depth)
142
150
  if value = input.getI8
143
151
  self.new(value)
144
152
  else
@@ -157,7 +165,7 @@ module SlowBlink::Message
157
165
  class I16 < INTEGER
158
166
 
159
167
  # @private
160
- def self.from_compact(input, stack)
168
+ def self.from_compact(input, depth)
161
169
  if value = input.getI16
162
170
  self.new(value)
163
171
  else
@@ -176,7 +184,7 @@ module SlowBlink::Message
176
184
  class I32 < INTEGER
177
185
 
178
186
  # @private
179
- def self.from_compact(input, stack)
187
+ def self.from_compact(input, depth)
180
188
  if value = input.getI32
181
189
  self.new(value)
182
190
  else
@@ -195,7 +203,7 @@ module SlowBlink::Message
195
203
  class I64 < INTEGER
196
204
 
197
205
  # @private
198
- def self.from_compact(input, stack)
206
+ def self.from_compact(input, depth)
199
207
  if value = input.getI64
200
208
  self.new(value)
201
209
  else
@@ -96,6 +96,9 @@ module SlowBlink
96
96
  # @return [Integer]
97
97
  attr_reader :maxRecursion
98
98
 
99
+ # @return [SlowBlink::Schema]
100
+ attr_reader :schema
101
+
99
102
  # @api user
100
103
  #
101
104
  # Generate a Model from a {Schema}
@@ -111,27 +114,21 @@ module SlowBlink
111
114
  @taggedGroups = {}
112
115
  @groups = {}
113
116
  @maxRecursion = opts[:maxRecursion]||DEFAULT_MAX_RECURSION
114
- maxRecursion = @maxRecursion
115
117
 
116
118
  # any of the groups
117
119
 
118
120
  taggedGroups = @taggedGroups
119
121
 
120
122
  @anyTaggedGroup = Class.new(DynamicGroup) do
121
- @maxRecursion = maxRecursion
122
123
  @anyTaggedGroup = self
123
124
  @taggedGroups = taggedGroups
124
125
  @permittedID = schema.groups.map{|g|g.id}.select{|g|g}
125
126
  end
126
-
127
- anyTaggedGroup = @anyTaggedGroup
128
127
 
129
128
  # create an anon class for each group defined in schema
130
129
  schema.groups.each do |g|
131
130
  fields = g.fields.map{|f| _model_field(f)}
132
- @groups[g.name] = Class.new(Group) do
133
- @maxRecursion = maxRecursion
134
- @anyTaggedGroup = anyTaggedGroup
131
+ @groups[g.name] = Class.new(Group) do
135
132
  @name = g.name
136
133
  @id = g.id
137
134
  @fields = fields
@@ -151,7 +148,13 @@ module SlowBlink
151
148
  # @raise [WeakError,StrongError]
152
149
  # @raise [RecursionLimit]
153
150
  def decode_compact(input)
154
- @anyTaggedGroup.from_compact(input, []).get
151
+ depth = @maxRecursion
152
+ group = @anyTaggedGroup.from_compact(input, depth)
153
+ if group.nil?
154
+ raise "top level group cannot be null"
155
+ else
156
+ group.get
157
+ end
155
158
  end
156
159
 
157
160
  # @api user
@@ -192,27 +195,24 @@ module SlowBlink
192
195
  # @param type [SlowBlink::Type] type definition
193
196
  # @param opt [true,false] parent definition may allow this type to be optional
194
197
  def _model_type(type)
195
- anyTaggedGroup = @anyTaggedGroup
196
- maxRecursion = @maxRecursion
197
-
198
+
198
199
  case type.class
199
200
  when SlowBlink::OBJECT
200
201
  @anyTaggedGroup
201
202
  when SlowBlink::DynamicGroup
203
+ anyTaggedGroup = @anyTaggedGroup
202
204
  taggedGroups = @taggedGroups
203
205
  Class.new(DynamicGroup) do
204
206
  @anyTaggedGroup = anyTaggedGroup
205
- @maxRecursion = maxRecursion
206
207
  @taggedGroups = taggedGroups
207
208
  @permittedID = type.groups.map{|g|g.id}
209
+ @type = type
208
210
  end
209
211
  when SlowBlink::StaticGroup
210
- fields = type.fields.map{|f| _model_field(f)}
212
+ groups = @groups
211
213
  Class.new(StaticGroup) do
212
- @maxRecursion = maxRecursion
213
- @name = type.name
214
- @id = type.id
215
- @fields = fields
214
+ @groups = groups
215
+ @type = type
216
216
  end
217
217
  else
218
218
  Class.new(SlowBlink::Message.const_get(type.class.name.split('::').last)) do
@@ -238,8 +238,10 @@ require "slow_blink/message/boolean"
238
238
  require "slow_blink/message/enum"
239
239
  require "slow_blink/message/floating_point"
240
240
  require "slow_blink/message/group"
241
+ require "slow_blink/message/static_group"
242
+ require "slow_blink/message/dynamic_group"
241
243
  require "slow_blink/message/time"
242
244
  require "slow_blink/message/time_of_day"
243
245
  require "slow_blink/message/date"
244
246
  require "slow_blink/message/decimal"
245
-
247
+ require "slow_blink/message/test_data"
@@ -0,0 +1,63 @@
1
+ # @license
2
+ #
3
+ # Copyright (c) 2016 Cameron Harper
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ # this software and associated documentation files (the "Software"), to deal in
7
+ # the Software without restriction, including without limitation the rights to
8
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ # the Software, and to permit persons to whom the Software is furnished to do so,
10
+ # subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ module SlowBlink::Message
23
+
24
+ class StaticGroup
25
+
26
+ def self.group
27
+ @groups[@type.name]
28
+ end
29
+
30
+ def self.from_compact(input, depth)
31
+ self.new(group.from_compact(input, depth))
32
+ end
33
+
34
+ def initialize(value)
35
+ set(value)
36
+ end
37
+
38
+ def set(value)
39
+ if value.is_a? self.class.group
40
+ @value = value
41
+ elsif value.is_a? Hash
42
+ @value = self.class.group.new(value)
43
+ else
44
+ raise
45
+ end
46
+ end
47
+
48
+ def get
49
+ @value
50
+ end
51
+
52
+ # @private
53
+ def to_compact(out)
54
+ @value.to_compact(out)
55
+ end
56
+
57
+ def to_tag
58
+ "{#{@value.to_tag_value.sub("|","")}}"
59
+ end
60
+
61
+ end
62
+
63
+ end
@@ -24,8 +24,12 @@ module SlowBlink::Message
24
24
  # @abstract
25
25
  class STRING
26
26
 
27
+ def self.type
28
+ @type
29
+ end
30
+
27
31
  # @private
28
- def self.from_compact(input, stack)
32
+ def self.from_compact(input, depth)
29
33
  if value = input.getString
30
34
  if !@type.size or value.size <= @type.size
31
35
  self.new(value)
@@ -73,6 +77,10 @@ module SlowBlink::Message
73
77
  out.putString(@value)
74
78
  end
75
79
 
80
+ def to_tag
81
+ @value
82
+ end
83
+
76
84
  end
77
85
 
78
86
  end
@@ -0,0 +1,126 @@
1
+ # @license
2
+ #
3
+ # Copyright (c) 2016 Cameron Harper
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ # this software and associated documentation files (the "Software"), to deal in
7
+ # the Software without restriction, including without limitation the rights to
8
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ # the Software, and to permit persons to whom the Software is furnished to do so,
10
+ # subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ module SlowBlink::Message
23
+
24
+ class TestData
25
+
26
+ # generate test data for a particular model
27
+ def initialize(model)
28
+ @model = model
29
+ end
30
+
31
+ # create an instance of group (name) and initialise
32
+ # the fields
33
+ def set(name)
34
+ group = @model.group(name).new
35
+ @model.schema.groups.detect{|g|g.name == name}.fields.each do |f|
36
+
37
+ data = fieldData(f)
38
+
39
+ if !f.optional? and data.nil?
40
+ raise "what the its #{f.type}"
41
+ end
42
+
43
+ if f.type.sequence? and data
44
+ group[f.name] = [data]
45
+ else
46
+ group[f.name] = data
47
+ end
48
+ end
49
+ group
50
+ end
51
+
52
+ # return a random valid test value for a given field type
53
+ #
54
+ #
55
+ def fieldData(field, **opts)
56
+
57
+
58
+ if !field.is_a? SlowBlink::Field
59
+ ArgumentError.new "field argument must be an instance of SlowBlink::Field"
60
+ end
61
+
62
+ case field.type.class
63
+ when SlowBlink::FIXED
64
+ s = (0...field.type.size).map { (65 + rand(26)).chr }.join
65
+
66
+ s
67
+
68
+ when SlowBlink::BINARY, SlowBlink::STRING
69
+ if field.type.size
70
+ s = (0...rand(field.type.size)).map { (65 + rand(26)).chr }.join
71
+ else
72
+ s = (0...rand(50)).map { (65 + rand(26)).chr }.join
73
+ end
74
+
75
+ s
76
+
77
+ when SlowBlink::BOOLEAN
78
+
79
+ [true, false].sample
80
+
81
+ when SlowBlink::U8, SlowBlink::U16, SlowBlink::U32, SlowBlink::U64, SlowBlink::I8, SlowBlink::I16, SlowBlink::I32, SlowBlink::I64
82
+
83
+ rand(field.type.class::RANGE)
84
+
85
+ when SlowBlink::FLOATING_POINT, SlowBlink::DECIMAL
86
+
87
+ rand(Float::MIN, Float::MAX)
88
+
89
+ when SlowBlink::ENUM
90
+
91
+ field.type.symbols.sample.name
92
+
93
+ when SlowBlink::MILLI_TIME, SlowBlink::NANO_TIME, SlowBlink::DATE
94
+
95
+ 0
96
+
97
+ when SlowBlink::TIME_OF_DAY_MILLI, SlowBlink::TIME_OF_DAY_NANO
98
+
99
+ 0
100
+
101
+ when SlowBlink::StaticGroup
102
+
103
+
104
+ set(field.type.name)
105
+
106
+
107
+ when SlowBlink::DynamicGroup
108
+
109
+ set(field.type.groups.select{|g|g.id}.sample.name)
110
+
111
+ else
112
+ raise "no support for #{field.type}"
113
+ end
114
+
115
+ end
116
+
117
+ private
118
+
119
+ def time_rand(from=0.0, to=Time.now)
120
+ Time.at(from + rand * (to.to_f - from.to_f))
121
+ end
122
+
123
+ end
124
+
125
+
126
+ end
@@ -26,8 +26,12 @@ module SlowBlink::Message
26
26
  # @abstract
27
27
  class MILLI_TIME
28
28
 
29
+ def self.type
30
+ @type
31
+ end
32
+
29
33
  # @private
30
- def self.from_compact(input, stack)
34
+ def self.from_compact(input, depth)
31
35
  if value = input.getI64
32
36
  self.new(value)
33
37
  else
@@ -70,6 +74,10 @@ module SlowBlink::Message
70
74
  def to_compact(out)
71
75
  out.putI64(@value.strftime('%Q').to_i)
72
76
  end
77
+
78
+ def to_tag
79
+ @value.to_s
80
+ end
73
81
 
74
82
  end
75
83
 
@@ -100,7 +108,7 @@ module SlowBlink::Message
100
108
  # @private
101
109
  def to_compact(out)
102
110
  out.putI64(@value.strftime('%N').to_i)
103
- end
111
+ end
104
112
 
105
113
  end
106
114
 
@@ -24,8 +24,12 @@ module SlowBlink::Message
24
24
  # @abstract
25
25
  class TIME_OF_DAY_MILLI
26
26
 
27
+ def self.type
28
+ @type
29
+ end
30
+
27
31
  # @private
28
- def self.from_compact(input, stack)
32
+ def self.from_compact(input, depth)
29
33
  if value = input.getU32
30
34
  self.new(value)
31
35
  else
@@ -60,14 +64,22 @@ module SlowBlink::Message
60
64
  def to_compact(out)
61
65
  out.putU32(@value)
62
66
  end
67
+
68
+ def to_tag
69
+ @value.to_s
70
+ end
63
71
 
64
72
  end
65
73
 
66
74
  # @abstract
67
75
  class TIME_OF_DAY_NANO
68
76
 
77
+ def self.type
78
+ @type
79
+ end
80
+
69
81
  # @private
70
- def self.from_compact(input, stack)
82
+ def self.from_compact(input, depth)
71
83
  if value = input.getU64
72
84
  self.new(value)
73
85
  else
@@ -102,6 +114,10 @@ module SlowBlink::Message
102
114
  def to_compact(out)
103
115
  out.putU64(@value)
104
116
  end
117
+
118
+ def to_tag
119
+ @value.to_s
120
+ end
105
121
 
106
122
  end
107
123
 
@@ -74,8 +74,8 @@ module SlowBlink
74
74
 
75
75
  if buffer.size > 0
76
76
  buffer.each do |b|
77
- if buffer.kind_of? String
78
- namespace << SlowBlink.parse_file_buffer(buffer)
77
+ if b.kind_of? String
78
+ namespace << SlowBlink.parse_file_buffer(b)
79
79
  else
80
80
  namespace << SlowBlink.parse_file_buffer(b.buffer, filename: b.filename)
81
81
  end
@@ -25,7 +25,7 @@ module SlowBlink
25
25
  class Type
26
26
 
27
27
  # @macro location
28
- attr_reader :location
28
+ attr_reader :location
29
29
 
30
30
  # @return [true] this type is sequence (repeating) type
31
31
  def sequence?
@@ -38,8 +38,8 @@ module SlowBlink
38
38
 
39
39
  # @private
40
40
  def initialize(attr)
41
- @location = attr[:loc].freeze
42
- @sequence = attr[:sequence]
41
+ @sequence = (attr[:sequence] ? true : false )
42
+ @location = attr[:loc].freeze
43
43
  @ns = attr[:ns].freeze
44
44
  end
45
45
 
@@ -21,5 +21,5 @@
21
21
 
22
22
 
23
23
  module SlowBlink
24
- VERSION = '0.0.7'.freeze
24
+ VERSION = '0.0.8'.freeze
25
25
  end
data/test/tc_inputs.rb CHANGED
@@ -2,50 +2,59 @@ require_relative "capture_stderr"
2
2
  require "test/unit"
3
3
  require "slow_blink"
4
4
 
5
- inputs = {}
6
- root = "test/input"
5
+ #inputs = {}
6
+ #root = File.expand_path(__FILE__) "test/input"
7
7
 
8
- testClass = Class.new(Test::Unit::TestCase) do
8
+ root = File.expand_path(File.join(File.dirname(__FILE__), "input"))
9
9
 
10
- class << self
11
- attr_accessor :inputs
12
- end
10
+ Dir.foreach(root) do |filename|
13
11
 
14
- Dir.foreach(root) do |filename|
12
+ next if filename == ".." or filename == "."
15
13
 
16
- next if filename == ".." or filename == "."
14
+ testClass = Class.new(Test::Unit::TestCase) do
17
15
 
18
- test_name = "test_#{filename.sub(".blink", "")}"
19
- inputs[test_name.to_sym] = "#{root}/#{filename}"
16
+ class << self
17
+ attr_accessor :inputs
18
+ end
20
19
 
21
- define_method( test_name ) do
20
+ test_name = "test_parse"
22
21
 
23
- # run and intercept stderr output
24
- err = capture_stderr do
22
+ test_name = "test_#{filename.sub(".blink", "")}"
23
+
24
+ define_method( "test_parse" ) do
25
+ SlowBlink::Schema.read(File.join(root, filename))
26
+ end
25
27
 
26
- SlowBlink::Schema.read(inputs[__method__])
28
+ define_method( "test_model" ) do
27
29
 
28
- end
30
+ #puts "parsing #{filename}"
31
+ schema = SlowBlink::Schema.read(File.join(root, filename))
32
+ #puts "modeling #{filename}"
33
+ model = SlowBlink::Message::Model.new(schema)
34
+ #puts "gen test data"
35
+ testData = SlowBlink::Message::TestData.new(model)
29
36
 
30
- # there should have been no messages to stderr
31
- assert_equal("", err.string, "unexpected error messages")
37
+ # self test all serialisable groups
38
+ schema.groups.select{|g|g.id}.each do |g|
32
39
 
33
- # if there were messages, forward them to stderr
34
- if err.string != ""
40
+ # initialise a group with valid test data
41
+ message = testData.set(g.name)
35
42
 
36
- STDERR.puts err.string
43
+ # serialise
44
+ msg = message.encode_compact
37
45
 
38
- end
46
+ # decode
47
+ model.decode_compact(msg)
39
48
 
49
+ end
50
+
40
51
  end
41
52
 
42
53
  end
43
54
 
55
+ Object.const_set("TestInputs_#{File.basename(filename, ".blink").gsub("-", "_")}", testClass)
56
+
44
57
  end
45
58
 
46
- # set inputs as a class variable
47
- testClass.inputs = inputs
48
59
 
49
- # name the dynamic test class
50
- Object.const_set("TestInputs", testClass)
51
60
 
@@ -0,0 +1,47 @@
1
+ require "test/unit"
2
+ require 'slow_blink'
3
+
4
+ class TestModelEnum < Test::Unit::TestCase
5
+
6
+ include SlowBlink
7
+
8
+ def setup
9
+
10
+ syntax = <<-eos
11
+ Singleton = | Lonely
12
+
13
+ Size = Small | Medium | Large
14
+
15
+ ExplicitSize = Small/38 | Medium/40 | Large/42
16
+
17
+ Colour = Red/0xff0000 | Green/0x00ff00 | Blue/0x0000ff
18
+
19
+ Message/0 ->
20
+ Singleton One,
21
+ Size Two,
22
+ ExplicitSize Three,
23
+ Colour Four
24
+ eos
25
+
26
+ schema = Schema.new(syntax)
27
+ @model = Message::Model.new(schema)
28
+ end
29
+
30
+ def test_init
31
+
32
+ message = @model.group("Message").new(
33
+ "One" => "Lonely",
34
+ "Two" => "Small",
35
+ "Three" => "Medium",
36
+ "Four" => "Blue"
37
+ )
38
+
39
+ assert_equal("Lonely", message["One"])
40
+ assert_equal("Small", message["Two"])
41
+ assert_equal("Medium", message["Three"])
42
+ assert_equal("Blue", message["Four"])
43
+
44
+ end
45
+
46
+ end
47
+