slow_blink 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/ext/slow_blink/ext_schema_parser/parser.c +245 -245
  3. data/lib/slow_blink/annotatable.rb +1 -2
  4. data/lib/slow_blink/annotation.rb +8 -1
  5. data/lib/slow_blink/compact_encoder.rb +1 -0
  6. data/lib/slow_blink/definition.rb +34 -10
  7. data/lib/slow_blink/enumeration.rb +15 -12
  8. data/lib/slow_blink/field.rb +9 -8
  9. data/lib/slow_blink/group.rb +61 -24
  10. data/lib/slow_blink/incremental_annotation.rb +7 -4
  11. data/lib/slow_blink/integer.rb +1 -1
  12. data/{test/tc_model.rb → lib/slow_blink/log.rb} +23 -40
  13. data/lib/slow_blink/message/binary.rb +39 -45
  14. data/lib/slow_blink/message/boolean.rb +25 -33
  15. data/lib/slow_blink/message/date.rb +2 -7
  16. data/lib/slow_blink/message/decimal.rb +1 -1
  17. data/lib/slow_blink/message/enumeration.rb +29 -33
  18. data/lib/slow_blink/message/field.rb +29 -37
  19. data/lib/slow_blink/message/fixed.rb +37 -45
  20. data/lib/slow_blink/message/floating_point.rb +24 -32
  21. data/lib/slow_blink/message/group.rb +172 -187
  22. data/lib/slow_blink/message/integer.rb +83 -132
  23. data/lib/slow_blink/message/model.rb +64 -63
  24. data/lib/slow_blink/message/sequence.rb +40 -48
  25. data/lib/slow_blink/message/string.rb +44 -51
  26. data/lib/slow_blink/message/time.rb +25 -40
  27. data/lib/slow_blink/message/time_of_day.rb +73 -86
  28. data/lib/slow_blink/name_with_id.rb +2 -6
  29. data/lib/slow_blink/namespace.rb +36 -36
  30. data/lib/slow_blink/ref.rb +29 -13
  31. data/lib/slow_blink/schema.rb +26 -10
  32. data/lib/slow_blink/schema_buffer.rb +14 -0
  33. data/lib/slow_blink/sequence.rb +16 -20
  34. data/lib/slow_blink/string.rb +0 -2
  35. data/lib/slow_blink/sym.rb +7 -5
  36. data/lib/slow_blink/type.rb +8 -5
  37. data/lib/slow_blink/version.rb +1 -1
  38. data/test/tc_field.rb +41 -0
  39. data/test/tc_group.rb +11 -0
  40. data/test/tc_model_static_group.rb +114 -0
  41. data/test/{tc_model_encode.rb → tc_model_think_blink.rb} +58 -13
  42. data/test/tc_types.rb +39 -0
  43. metadata +7 -6
@@ -17,13 +17,24 @@
17
17
  # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
18
  # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
19
 
20
+ require 'slow_blink/log'
21
+
20
22
  module SlowBlink
21
23
 
24
+ # @!macro location
25
+ # Location string formatted as:
26
+ # [ FILENAME, ':' ], LINE_NUMBER, ':', COLUMN_NUMBER
27
+ # @return [String]
28
+
22
29
  class Schema
23
30
 
24
- # Initialise a Schema from one or more Blink Schema files
31
+ # @api user
32
+ #
33
+ # Create a Schema from one or more Blink Schema files that are evaluated
34
+ # in the order they appear.
25
35
  #
26
36
  # @param filename [Array<String>]
37
+ # @return [Schema]
27
38
  def self.read(*filename)
28
39
  input = []
29
40
  if filename.size > 0
@@ -40,12 +51,17 @@ module SlowBlink
40
51
  #
41
52
  # - These groups are of interest to message code generators
42
53
  #
43
- # @return [Hash]
54
+ # @return [Hash<Group>]
44
55
  attr_reader :tagged
45
56
 
46
57
  # @return [Array<Namespace>]
47
58
  attr_reader :ns
48
59
 
60
+ # @api user
61
+ #
62
+ # Create a Schema from one or more SchemaBuffers that are evaluated
63
+ # in the order they appear.
64
+ #
49
65
  # @param buffer [Array<SchemaBuffer>]
50
66
  def initialize(*buffer)
51
67
 
@@ -61,7 +77,7 @@ module SlowBlink
61
77
  @ns = {}
62
78
  @tagged = {}
63
79
 
64
- errors = 0
80
+ error = false
65
81
 
66
82
  # gather and merge namespaces
67
83
  namespace.each do |ns|
@@ -69,7 +85,7 @@ module SlowBlink
69
85
  begin
70
86
  @ns[ns.name].merge!(ns)
71
87
  rescue
72
- errors += 1
88
+ raise
73
89
  end
74
90
  else
75
91
  @ns[ns.name] = ns
@@ -88,8 +104,8 @@ module SlowBlink
88
104
  ns.groups.each do |g|
89
105
  if g.nameWithID.id
90
106
  if @tagged[g.nameWithID.id]
91
- puts "error: duplicate group id"
92
- errors += 1
107
+ Log.error "error: groups that have identifiers must have unique identifiers ('#{@g.nameWithID.id}' was first assigned to '#{@tagged[g.nameWithID.id].nameWithID.name}' at #{@tagged[g.nameWithID.id].location}"
108
+ error = true
93
109
  else
94
110
  @tagged[g.nameWithID.id] = g
95
111
  end
@@ -100,17 +116,17 @@ module SlowBlink
100
116
  # resolve all references
101
117
  @ns.each do |name, ns|
102
118
  if !ns.link(self)
103
- errors += 1
119
+ error = true
104
120
  end
105
121
  end
106
122
 
107
- if errors > 0
108
- raise Error.new "#{errors} errors"
123
+ if error
124
+ raise
109
125
  end
110
126
 
111
127
  end
112
128
 
113
- # resolve a name to a definition in any namespace
129
+ # Resolve a name to a definition in any namespace
114
130
  #
115
131
  # @param namespace [String,nil]
116
132
  # @param name [String]
@@ -19,6 +19,16 @@
19
19
 
20
20
  module SlowBlink
21
21
 
22
+ # Use schema buffer when you want to deal with schemas in-memory
23
+ # rather than loading from files.
24
+ #
25
+ # It combines the schema string with an optional filename string.
26
+ #
27
+ # e.g:
28
+ #
29
+ # anonBuffer = SchemaBuffer.new("Hello/0 -> string greeting")
30
+ # namedBuffer = SchemaBuffer.new("Hello/0 -> string greeting", "nameThatWillAppearInErrorMessage.txt")
31
+ #
22
32
  class SchemaBuffer
23
33
 
24
34
  # @return [String]
@@ -27,6 +37,10 @@ module SlowBlink
27
37
  # @return [String]
28
38
  attr_reader :filename
29
39
 
40
+ # @api user
41
+ #
42
+ # Create a SchemaBuffer
43
+ #
30
44
  # @param buffer [String] the contents of the file
31
45
  # @param filename [String] name of the file (for error reporting)
32
46
  def initialize(buffer, filename=nil)
@@ -25,34 +25,30 @@ module SlowBlink
25
25
  # @return [Type]
26
26
  attr_reader :type
27
27
 
28
- # @private
29
- #
30
28
  # @param type [Type] repeating type
31
29
  # @param location [String]
32
30
  def initialize(type, location)
33
- @type = nil
34
- @rawType = type
31
+ @type = type
35
32
  super(location)
36
33
  end
37
34
 
38
- # @private
35
+ # @api private
36
+ #
37
+ # Resolve references, enforce constraints, and detect cycles
39
38
  #
40
- # @macro common_link
41
- def link(schema, stack=[])
42
- if @schema.nil?
43
- case @rawType.class
44
- when REF
45
- schema.definition(@rawType)
46
- when SEQUENCE
47
- puts "error: sequence of sequence is not permitted"
48
- else
49
- @type = @rawType
50
- @schema = schema
51
- end
52
- end
53
- @schema
39
+ # @param schema [Schema] schema this definition belongs to
40
+ # @param ns [Namespace] namespace this definition belongs to
41
+ # @param stack [nil, Array] objects that depend on this object
42
+ # @return [true,false] linked?
43
+ def link(schema, ns, stack=[])
44
+ if stack.detect{|sf| sf.is_a? SEQUENCE}
45
+ Log.error "#{@location}: error: a sequence type specifier must not specify a sequence as the item type"
46
+ false
47
+ else
48
+ @type.link(schema, ns, stack << self)
49
+ end
54
50
  end
55
-
51
+
56
52
  end
57
53
 
58
54
  end
@@ -26,8 +26,6 @@ module SlowBlink
26
26
  # @return [nil] no maximum size
27
27
  attr_reader :size
28
28
 
29
- # @private
30
- #
31
29
  # @param size [Integer] maximum size
32
30
  # @param location [String]
33
31
  def initialize(size, location)
@@ -22,7 +22,7 @@ module SlowBlink
22
22
 
23
23
  include Annotatable
24
24
 
25
- # @return [String]
25
+ # @macro location
26
26
  attr_reader :location
27
27
 
28
28
  # @return [String]
@@ -31,12 +31,11 @@ module SlowBlink
31
31
  # @return [Integer]
32
32
  attr_reader :val
33
33
 
34
+ # @api private
34
35
  def val=(value)
35
36
  @val = value.to_i
36
37
  end
37
38
 
38
- # @private
39
- #
40
39
  # @param name [String]
41
40
  # @param val [nil,Integer] explicit value
42
41
  # @param location [String]
@@ -47,9 +46,12 @@ module SlowBlink
47
46
  @location = location
48
47
  end
49
48
 
50
- # @private
49
+ # @api private
50
+ # Resolve references, enforce constraints, and detect cycles
51
51
  #
52
- # @macro common_link
52
+ # @param schema [Schema] schema this definition belongs to
53
+ # @param stack [nil, Array] objects that depend on this object
54
+ # @return [true,false] linked?
53
55
  def link(schema, stack=[])
54
56
  @schema = schema
55
57
  end
@@ -23,15 +23,13 @@ module SlowBlink
23
23
 
24
24
  include Annotatable
25
25
 
26
- # @param [String]
26
+ # @macro location
27
27
  attr_reader :location
28
28
 
29
29
  def self.===(other)
30
30
  self == other
31
31
  end
32
32
 
33
- # @private
34
- #
35
33
  # @param location [String]
36
34
  def initialize(location)
37
35
  @schema = nil
@@ -39,9 +37,14 @@ module SlowBlink
39
37
  @location = location
40
38
  end
41
39
 
42
- # @private
40
+ # @api private
41
+ #
42
+ # Resolve references, enforce constraints, and detect cycles
43
43
  #
44
- # @macro common_link
44
+ # @param schema [Schema] schema this definition belongs to
45
+ # @param ns [Namespace] namespace this definition belongs to
46
+ # @param stack [nil, Array] objects that depend on this object
47
+ # @return [true,false] linked?
45
48
  def link(schema, ns, stack=[])
46
49
  @schema = schema
47
50
  end
@@ -18,5 +18,5 @@
18
18
  # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
19
 
20
20
  module SlowBlink
21
- VERSION = '0.0.3'.freeze
21
+ VERSION = '0.0.4'.freeze
22
22
  end
data/test/tc_field.rb CHANGED
@@ -50,4 +50,45 @@ class TestField < Test::Unit::TestCase
50
50
  end
51
51
  end
52
52
 
53
+ def test_field_direct_cycle
54
+ input = <<-eos
55
+ test ->
56
+ test field
57
+ eos
58
+ assert_raise do
59
+ Schema.new(SchemaBuffer.new(input))
60
+ end
61
+ end
62
+
63
+ def test_field_direct_dynamic_cycle
64
+ input = <<-eos
65
+ test ->
66
+ test * field
67
+ eos
68
+
69
+ Schema.new(SchemaBuffer.new(input))
70
+
71
+ end
72
+
73
+ def test_field_indirect_cycle
74
+ input = <<-eos
75
+ intermediate = test
76
+ test ->
77
+ intermediate field
78
+ eos
79
+ assert_raise do
80
+ Schema.new(SchemaBuffer.new(input))
81
+ end
82
+ end
83
+
84
+ def test_field_indirect_dynamic_cycle
85
+ input = <<-eos
86
+ intermediate = test *
87
+ test ->
88
+ intermediate field
89
+ eos
90
+
91
+ Schema.new(SchemaBuffer.new(input))
92
+ end
93
+
53
94
  end
data/test/tc_group.rb CHANGED
@@ -119,4 +119,15 @@ class TestGroup < Test::Unit::TestCase
119
119
  end
120
120
  end
121
121
 
122
+ def test_supergroup_dynamic_reference
123
+ input = <<-eos
124
+ Super
125
+ Intermediate = Super *
126
+ Test : Intermediate
127
+ eos
128
+ assert_raise do
129
+ Schema.new(SchemaBuffer.new(input))
130
+ end
131
+ end
132
+
122
133
  end
@@ -0,0 +1,114 @@
1
+ # Copyright (c) 2016 Cameron Harper
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ # this software and associated documentation files (the "Software"), to deal in
5
+ # the Software without restriction, including without limitation the rights to
6
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ # the Software, and to permit persons to whom the Software is furnished to do so,
8
+ # subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
+
20
+ require "test/unit"
21
+ require 'slow_blink'
22
+
23
+ class TestModelStaticGroup < Test::Unit::TestCase
24
+
25
+ include SlowBlink
26
+
27
+ def setup
28
+
29
+ rawSchema = <<-eos
30
+ StaticGroup ->
31
+ string one,
32
+ u8 two,
33
+ u8 three
34
+
35
+ Test/0x00 ->
36
+ string one,
37
+ u8 two,
38
+ u8 three,
39
+ StaticGroup four
40
+ eos
41
+
42
+ schema = Schema.new(SchemaBuffer.new(rawSchema))
43
+ @model = Message::Model.new(schema)
44
+
45
+ end
46
+
47
+ def test_init_individual
48
+
49
+ message = @model.group "Test" do |g|
50
+ g["one"] = "hello"
51
+ g["two"] = 42
52
+ g["three"] = 42
53
+ g["four"]["one"] = "world"
54
+ g["four"]["two"] = 42
55
+ g["four"]["three"] = 42
56
+ end
57
+
58
+ assert_equal("hello", message["one"])
59
+ assert_equal(42, message["two"])
60
+ assert_equal(42, message["three"])
61
+ assert_equal("world", message["four"]["one"])
62
+ assert_equal(42, message["four"]["two"])
63
+ assert_equal(42, message["four"]["three"])
64
+
65
+ end
66
+
67
+ def test_init_part_bulk
68
+
69
+ message = @model.group "Test" do |g|
70
+ g["one"] = "hello"
71
+ g["two"] = 42
72
+ g["three"] = 42
73
+ g["four"] = {
74
+ "one" => "world",
75
+ "two" => 42,
76
+ "three" => 42
77
+ }
78
+ end
79
+
80
+ assert_equal("hello", message["one"])
81
+ assert_equal(42, message["two"])
82
+ assert_equal(42, message["three"])
83
+ assert_equal("world", message["four"]["one"])
84
+ assert_equal(42, message["four"]["two"])
85
+ assert_equal(42, message["four"]["three"])
86
+
87
+ end
88
+
89
+ def test_init_bulk
90
+
91
+ message = @model.group "Test", {
92
+ "one" => "hello",
93
+ "two" => 42,
94
+ "three" => 42,
95
+ "four" => {
96
+ "one" => "world",
97
+ "two" => 42,
98
+ "three" => 42
99
+ }
100
+ }
101
+
102
+ assert_equal("hello", message["one"])
103
+ assert_equal(42, message["two"])
104
+ assert_equal(42, message["three"])
105
+ assert_equal("world", message["four"]["one"])
106
+ assert_equal(42, message["four"]["two"])
107
+ assert_equal(42, message["four"]["three"])
108
+
109
+ end
110
+
111
+
112
+
113
+
114
+ end
@@ -20,11 +20,11 @@
20
20
  require "test/unit"
21
21
  require 'slow_blink'
22
22
 
23
- class TestModelEncode < Test::Unit::TestCase
23
+ class TestModelThinkBlink < Test::Unit::TestCase
24
24
 
25
25
  include SlowBlink
26
26
 
27
- def test_think_blink
27
+ def setup
28
28
  rawSchema = <<-eos
29
29
  OrderExecuted/0x4c ->
30
30
  string Symbol,
@@ -34,23 +34,55 @@ class TestModelEncode < Test::Unit::TestCase
34
34
  u8 MatchId
35
35
  eos
36
36
  schema = Schema.new(SchemaBuffer.new(rawSchema))
37
+ @model = Message::Model.new(schema)
38
+ end
39
+
40
+ def test_set_individual
41
+
42
+ message = @model.group "OrderExecuted" do |g|
43
+ g["Symbol"] = "hey"
44
+ g["OrderId"] = 42
45
+ g["Price"] = 42
46
+ g["Qty"] = 42
47
+ g["MatchId"] = 42
48
+ end
49
+
50
+ assert_equal("hey", message["Symbol"])
51
+ assert_equal(42, message["OrderId"])
52
+ assert_equal(42, message["Price"])
53
+ assert_equal(42, message["Qty"])
54
+ assert_equal(42, message["MatchId"])
37
55
 
38
- model = Message::Model.new(schema)
39
- message = model.new do
40
- group "OrderExecuted" do |g|
41
- g["Symbol"] = "hey"
42
- g["OrderId"] = 42
43
- g["Price"] = 42
44
- g["Qty"] = 42
45
- g["MatchId"] = 42
46
- end
47
- end
56
+ end
57
+
58
+ def test_set_bulk
59
+
60
+ message = @model.group "OrderExecuted", {
61
+ "Symbol" => "hey",
62
+ "OrderId" => 42,
63
+ "Price" => 42,
64
+ "Qty" => 42,
65
+ "MatchId" => 42
66
+ }
67
+
48
68
 
49
69
  assert_equal("hey", message["Symbol"])
50
70
  assert_equal(42, message["OrderId"])
51
71
  assert_equal(42, message["Price"])
52
72
  assert_equal(42, message["Qty"])
53
- assert_equal(42, message["MatchId"])
73
+ assert_equal(42, message["MatchId"])
74
+
75
+ end
76
+
77
+ def test_encode_compact
78
+
79
+ message = @model.group "OrderExecuted" do |g|
80
+ g["Symbol"] = "hey"
81
+ g["OrderId"] = 42
82
+ g["Price"] = 42
83
+ g["Qty"] = 42
84
+ g["MatchId"] = 42
85
+ end
54
86
 
55
87
  output = message.to_compact
56
88
 
@@ -60,4 +92,17 @@ class TestModelEncode < Test::Unit::TestCase
60
92
 
61
93
  end
62
94
 
95
+ def test_decode_compact
96
+
97
+ input = "\x0b\x4c\x05hello\x00\x01\x02\x03"
98
+
99
+ message = @model.decode_compact(input)
100
+
101
+ assert_equal("hello", message["Symbol"])
102
+ assert_equal(0, message["OrderId"])
103
+ assert_equal(1, message["Price"])
104
+ assert_equal(2, message["Qty"])
105
+ assert_equal(3, message["MatchId"])
106
+ end
107
+
63
108
  end
data/test/tc_types.rb CHANGED
@@ -195,4 +195,43 @@ class TestTypes < Test::Unit::TestCase
195
195
  assert_equal(OBJECT, schema.ns[nil].group("test").field("one").type.class)
196
196
  end
197
197
 
198
+ def test_type_direct_reference_cycle
199
+ input = <<-eos
200
+ thing = thingref
201
+ thingref = thing
202
+ eos
203
+ assert_raise do
204
+ Schema.new(SchemaBuffer.new(input))
205
+ end
206
+ end
207
+
208
+ def test_type_inderect_reference_cycle
209
+ input = <<-eos
210
+ thing = intermediate
211
+ intermediate = thingref
212
+ thingref = thing
213
+ eos
214
+ assert_raise do
215
+ Schema.new(SchemaBuffer.new(input))
216
+ end
217
+ end
218
+
219
+ def test_sequence_sequence
220
+ input = "test -> i32 [] test"
221
+ Schema.new(SchemaBuffer.new(input))
222
+ end
223
+
224
+ def test_sequence_sequence_direct
225
+ input = <<-eos
226
+ intermediate = u32 []
227
+ test ->
228
+ intermediate [] test
229
+ eos
230
+
231
+ assert_raise do
232
+ Schema.new(SchemaBuffer.new(input))
233
+ end
234
+
235
+ end
236
+
198
237
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slow_blink
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cameron Harper
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-05 00:00:00.000000000 Z
11
+ date: 2016-09-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler
@@ -87,6 +87,7 @@ files:
87
87
  - lib/slow_blink/group.rb
88
88
  - lib/slow_blink/incremental_annotation.rb
89
89
  - lib/slow_blink/integer.rb
90
+ - lib/slow_blink/log.rb
90
91
  - lib/slow_blink/message/binary.rb
91
92
  - lib/slow_blink/message/boolean.rb
92
93
  - lib/slow_blink/message/date.rb
@@ -122,8 +123,8 @@ files:
122
123
  - test/tc_group.rb
123
124
  - test/tc_incr_annote.rb
124
125
  - test/tc_inputs.rb
125
- - test/tc_model.rb
126
- - test/tc_model_encode.rb
126
+ - test/tc_model_static_group.rb
127
+ - test/tc_model_think_blink.rb
127
128
  - test/tc_namespace.rb
128
129
  - test/tc_types.rb
129
130
  homepage: https://github.com/cjhdev/slow_blink
@@ -151,14 +152,14 @@ signing_key:
151
152
  specification_version: 4
152
153
  summary: Blink Protocol in Ruby
153
154
  test_files:
155
+ - test/tc_model_static_group.rb
154
156
  - test/tc_compact_encoder.rb
155
157
  - test/tc_group.rb
156
158
  - test/tc_inputs.rb
157
- - test/tc_model_encode.rb
158
159
  - test/tc_namespace.rb
159
160
  - test/tc_types.rb
160
161
  - test/capture_stderr.rb
161
- - test/tc_model.rb
162
+ - test/tc_model_think_blink.rb
162
163
  - test/tc_field.rb
163
164
  - test/tc_incr_annote.rb
164
165
  has_rdoc: yard