slow_blink 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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