bindata 2.4.10 → 2.5.0

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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.rdoc +39 -0
  3. data/LICENSE +25 -0
  4. data/NEWS.rdoc +5 -0
  5. data/README.md +6 -9
  6. data/bindata.gemspec +9 -4
  7. data/examples/NBT.txt +1 -1
  8. data/examples/list.rb +1 -1
  9. data/lib/bindata/alignment.rb +15 -7
  10. data/lib/bindata/array.rb +54 -54
  11. data/lib/bindata/base.rb +14 -25
  12. data/lib/bindata/base_primitive.rb +24 -20
  13. data/lib/bindata/bits.rb +15 -15
  14. data/lib/bindata/buffer.rb +89 -11
  15. data/lib/bindata/choice.rb +9 -6
  16. data/lib/bindata/count_bytes_remaining.rb +1 -1
  17. data/lib/bindata/delayed_io.rb +18 -10
  18. data/lib/bindata/dsl.rb +37 -35
  19. data/lib/bindata/float.rb +3 -3
  20. data/lib/bindata/framework.rb +8 -10
  21. data/lib/bindata/int.rb +14 -16
  22. data/lib/bindata/io.rb +276 -253
  23. data/lib/bindata/name.rb +1 -1
  24. data/lib/bindata/params.rb +9 -7
  25. data/lib/bindata/primitive.rb +3 -3
  26. data/lib/bindata/registry.rb +18 -18
  27. data/lib/bindata/rest.rb +1 -1
  28. data/lib/bindata/sanitize.rb +9 -16
  29. data/lib/bindata/section.rb +97 -0
  30. data/lib/bindata/skip.rb +140 -51
  31. data/lib/bindata/string.rb +9 -9
  32. data/lib/bindata/stringz.rb +12 -10
  33. data/lib/bindata/struct.rb +92 -68
  34. data/lib/bindata/trace.rb +35 -42
  35. data/lib/bindata/transform/brotli.rb +35 -0
  36. data/lib/bindata/transform/lz4.rb +35 -0
  37. data/lib/bindata/transform/lzma.rb +35 -0
  38. data/lib/bindata/transform/xor.rb +19 -0
  39. data/lib/bindata/transform/xz.rb +35 -0
  40. data/lib/bindata/transform/zlib.rb +33 -0
  41. data/lib/bindata/transform/zstd.rb +35 -0
  42. data/lib/bindata/uint8_array.rb +2 -2
  43. data/lib/bindata/version.rb +1 -1
  44. data/lib/bindata/virtual.rb +4 -7
  45. data/lib/bindata/warnings.rb +1 -1
  46. data/lib/bindata.rb +1 -0
  47. data/test/alignment_test.rb +8 -8
  48. data/test/array_test.rb +98 -96
  49. data/test/base_primitive_test.rb +47 -47
  50. data/test/base_test.rb +24 -24
  51. data/test/bits_test.rb +15 -15
  52. data/test/buffer_test.rb +31 -22
  53. data/test/choice_test.rb +32 -32
  54. data/test/count_bytes_remaining_test.rb +8 -8
  55. data/test/delayed_io_test.rb +91 -30
  56. data/test/float_test.rb +8 -8
  57. data/test/int_test.rb +14 -14
  58. data/test/io_test.rb +110 -302
  59. data/test/lazy_test.rb +38 -38
  60. data/test/params_test.rb +19 -19
  61. data/test/primitive_test.rb +26 -26
  62. data/test/record_test.rb +99 -99
  63. data/test/registry_test.rb +43 -43
  64. data/test/rest_test.rb +5 -5
  65. data/test/section_test.rb +111 -0
  66. data/test/skip_test.rb +71 -26
  67. data/test/string_test.rb +60 -60
  68. data/test/stringz_test.rb +34 -26
  69. data/test/struct_test.rb +167 -92
  70. data/test/system_test.rb +159 -41
  71. data/test/test_helper.rb +24 -13
  72. data/test/uint8_array_test.rb +6 -6
  73. data/test/virtual_test.rb +7 -7
  74. data/test/warnings_test.rb +14 -2
  75. metadata +19 -22
  76. data/.gitignore +0 -2
  77. data/.travis.yml +0 -15
  78. data/BSDL +0 -22
  79. data/COPYING +0 -52
  80. data/INSTALL +0 -12
  81. data/lib/bindata/offset.rb +0 -94
  82. data/test/offset_test.rb +0 -100
@@ -14,14 +14,14 @@ describe BinData::Registry do
14
14
  r.register('ASubClass', A)
15
15
  r.register('AnotherSubClass', B)
16
16
 
17
- r.lookup('ASubClass').must_equal A
18
- r.lookup('a_sub_class').must_equal A
19
- r.lookup('AnotherSubClass').must_equal B
20
- r.lookup('another_sub_class').must_equal B
17
+ _(r.lookup('ASubClass')).must_equal A
18
+ _(r.lookup('a_sub_class')).must_equal A
19
+ _(r.lookup('AnotherSubClass')).must_equal B
20
+ _(r.lookup('another_sub_class')).must_equal B
21
21
  end
22
22
 
23
23
  it "does not lookup unregistered names" do
24
- lambda {
24
+ _ {
25
25
  r.lookup('a_non_existent_sub_class')
26
26
  }.must_raise BinData::UnRegisteredTypeError
27
27
  end
@@ -30,34 +30,34 @@ describe BinData::Registry do
30
30
  r.register('ASubClass', A)
31
31
  r.unregister('ASubClass')
32
32
 
33
- lambda {
33
+ _ {
34
34
  r.lookup('ASubClass')
35
35
  }.must_raise BinData::UnRegisteredTypeError
36
36
  end
37
37
 
38
38
  it "allows overriding of registered classes" do
39
- w, $-w = $-w, false
39
+ w, $-w = $-w, nil # disable warning
40
40
 
41
41
  begin
42
42
  r.register('A', A)
43
43
  r.register('A', B)
44
44
 
45
- r.lookup('a').must_equal B
45
+ _(r.lookup('a')).must_equal B
46
46
  ensure
47
47
  $-w = w
48
48
  end
49
49
  end
50
50
 
51
51
  it "converts CamelCase to underscores" do
52
- r.underscore_name('CamelCase').must_equal 'camel_case'
52
+ _(r.underscore_name('CamelCase')).must_equal 'camel_case'
53
53
  end
54
54
 
55
55
  it "converts adjacent caps camelCase to underscores" do
56
- r.underscore_name('XYZCamelCase').must_equal 'xyz_camel_case'
56
+ _(r.underscore_name('XYZCamelCase')).must_equal 'xyz_camel_case'
57
57
  end
58
58
 
59
59
  it "ignores the outer nestings of classes" do
60
- r.underscore_name('A::B::C').must_equal 'c'
60
+ _(r.underscore_name('A::B::C')).must_equal 'c'
61
61
  end
62
62
  end
63
63
 
@@ -65,14 +65,14 @@ describe BinData::Registry, "with numerics" do
65
65
  let(:r) { BinData::RegisteredClasses }
66
66
 
67
67
  it "lookup integers with endian" do
68
- r.lookup("int24", {endian: :big}).to_s.must_equal "BinData::Int24be"
69
- r.lookup("int24", {endian: :little}).to_s.must_equal "BinData::Int24le"
70
- r.lookup("uint24", {endian: :big}).to_s.must_equal "BinData::Uint24be"
71
- r.lookup("uint24", {endian: :little}).to_s.must_equal "BinData::Uint24le"
68
+ _(r.lookup("int24", {endian: :big}).to_s).must_equal "BinData::Int24be"
69
+ _(r.lookup("int24", {endian: :little}).to_s).must_equal "BinData::Int24le"
70
+ _(r.lookup("uint24", {endian: :big}).to_s).must_equal "BinData::Uint24be"
71
+ _(r.lookup("uint24", {endian: :little}).to_s).must_equal "BinData::Uint24le"
72
72
  end
73
73
 
74
74
  it "does not lookup integers without endian" do
75
- lambda {
75
+ _ {
76
76
  r.lookup("int24")
77
77
  }.must_raise BinData::UnRegisteredTypeError
78
78
  end
@@ -81,47 +81,47 @@ describe BinData::Registry, "with numerics" do
81
81
  begin
82
82
  r.lookup("int24")
83
83
  rescue BinData::UnRegisteredTypeError => e
84
- e.message.must_equal "int24, do you need to specify endian?"
84
+ _(e.message).must_equal "int24, do you need to specify endian?"
85
85
  end
86
86
  end
87
87
 
88
88
  it "does not lookup non byte based integers" do
89
- lambda {
89
+ _ {
90
90
  r.lookup("int3")
91
91
  }.must_raise BinData::UnRegisteredTypeError
92
- lambda {
92
+ _ {
93
93
  r.lookup("int3", {endian: :big})
94
94
  }.must_raise BinData::UnRegisteredTypeError
95
- lambda {
95
+ _ {
96
96
  r.lookup("int3", {endian: :little})
97
97
  }.must_raise BinData::UnRegisteredTypeError
98
98
  end
99
99
 
100
100
  it "lookup floats with endian" do
101
- r.lookup("float", {endian: :big}).to_s.must_equal "BinData::FloatBe"
102
- r.lookup("float", {endian: :little}).to_s.must_equal "BinData::FloatLe"
103
- r.lookup("double", {endian: :big}).to_s.must_equal "BinData::DoubleBe"
104
- r.lookup("double", {endian: :little}).to_s.must_equal "BinData::DoubleLe"
101
+ _(r.lookup("float", {endian: :big}).to_s).must_equal "BinData::FloatBe"
102
+ _(r.lookup("float", {endian: :little}).to_s).must_equal "BinData::FloatLe"
103
+ _(r.lookup("double", {endian: :big}).to_s).must_equal "BinData::DoubleBe"
104
+ _(r.lookup("double", {endian: :little}).to_s).must_equal "BinData::DoubleLe"
105
105
  end
106
106
 
107
107
  it "lookup bits" do
108
- r.lookup("bit5").to_s.must_equal "BinData::Bit5"
109
- r.lookup("sbit5").to_s.must_equal "BinData::Sbit5"
110
- r.lookup("bit6le").to_s.must_equal "BinData::Bit6le"
108
+ _(r.lookup("bit5").to_s).must_equal "BinData::Bit5"
109
+ _(r.lookup("sbit5").to_s).must_equal "BinData::Sbit5"
110
+ _(r.lookup("bit6le").to_s).must_equal "BinData::Bit6le"
111
111
  end
112
112
 
113
113
  it "lookup bits by ignoring endian" do
114
- r.lookup("bit2", {endian: :big}).to_s.must_equal "BinData::Bit2"
115
- r.lookup("bit3le", {endian: :big}).to_s.must_equal "BinData::Bit3le"
116
- r.lookup("bit2", {endian: :little}).to_s.must_equal "BinData::Bit2"
117
- r.lookup("bit3le", {endian: :little}).to_s.must_equal "BinData::Bit3le"
114
+ _(r.lookup("bit2", {endian: :big}).to_s).must_equal "BinData::Bit2"
115
+ _(r.lookup("bit3le", {endian: :big}).to_s).must_equal "BinData::Bit3le"
116
+ _(r.lookup("bit2", {endian: :little}).to_s).must_equal "BinData::Bit2"
117
+ _(r.lookup("bit3le", {endian: :little}).to_s).must_equal "BinData::Bit3le"
118
118
  end
119
119
 
120
120
  it "lookup signed bits by ignoring endian" do
121
- r.lookup("sbit2", {endian: :big}).to_s.must_equal "BinData::Sbit2"
122
- r.lookup("sbit3le", {endian: :big}).to_s.must_equal "BinData::Sbit3le"
123
- r.lookup("sbit2", {endian: :little}).to_s.must_equal "BinData::Sbit2"
124
- r.lookup("sbit3le", {endian: :little}).to_s.must_equal "BinData::Sbit3le"
121
+ _(r.lookup("sbit2", {endian: :big}).to_s).must_equal "BinData::Sbit2"
122
+ _(r.lookup("sbit3le", {endian: :big}).to_s).must_equal "BinData::Sbit3le"
123
+ _(r.lookup("sbit2", {endian: :little}).to_s).must_equal "BinData::Sbit2"
124
+ _(r.lookup("sbit3le", {endian: :little}).to_s).must_equal "BinData::Sbit3le"
125
125
  end
126
126
  end
127
127
 
@@ -134,15 +134,15 @@ describe BinData::Registry, "with endian specific types" do
134
134
  end
135
135
 
136
136
  it "lookup little endian types" do
137
- r.lookup('a', {endian: :little}).must_equal A
137
+ _(r.lookup('a', {endian: :little})).must_equal A
138
138
  end
139
139
 
140
140
  it "lookup big endian types" do
141
- r.lookup('b', {endian: :big}).must_equal B
141
+ _(r.lookup('b', {endian: :big})).must_equal B
142
142
  end
143
143
 
144
144
  it "does not lookup types with non existent endian" do
145
- lambda {
145
+ _ {
146
146
  r.lookup('a', {endian: :big})
147
147
  }.must_raise BinData::UnRegisteredTypeError
148
148
  end
@@ -151,7 +151,7 @@ describe BinData::Registry, "with endian specific types" do
151
151
  r.register('c', C)
152
152
  r.register('c_le', D)
153
153
 
154
- r.lookup('c', {endian: :little}).must_equal C
154
+ _(r.lookup('c', {endian: :little})).must_equal C
155
155
  end
156
156
  end
157
157
 
@@ -164,18 +164,18 @@ describe BinData::Registry, "with search_prefix" do
164
164
  end
165
165
 
166
166
  it "lookup single search_prefix" do
167
- r.lookup('f', {search_prefix: :a}).must_equal A
167
+ _(r.lookup('f', {search_prefix: :a})).must_equal A
168
168
  end
169
169
 
170
170
  it "lookup single search_prefix with endian" do
171
- r.lookup('f', {search_prefix: :a, endian: :little}).must_equal A
171
+ _(r.lookup('f', {search_prefix: :a, endian: :little})).must_equal A
172
172
  end
173
173
 
174
174
  it "lookup multiple search_prefix" do
175
- r.lookup('f', {search_prefix: [:x, :a]}).must_equal A
175
+ _(r.lookup('f', {search_prefix: [:x, :a]})).must_equal A
176
176
  end
177
177
 
178
178
  it "lookup first match in search_prefix" do
179
- r.lookup('f', {search_prefix: [:a, :b]}).must_equal A
179
+ _(r.lookup('f', {search_prefix: [:a, :b]})).must_equal A
180
180
  end
181
181
  end
data/test/rest_test.rb CHANGED
@@ -6,23 +6,23 @@ describe BinData::Rest do
6
6
  let(:obj) { BinData::Rest.new }
7
7
 
8
8
  it "initial state" do
9
- obj.must_equal ""
9
+ _(obj).must_equal ""
10
10
  end
11
11
 
12
12
  it "reads till end of stream" do
13
13
  data = "abcdefghij"
14
- obj.read(data).must_equal data
14
+ _(obj.read(data)).must_equal data
15
15
  end
16
16
 
17
17
  it "allows setting value for completeness" do
18
18
  obj.assign("123")
19
- obj.must_equal "123"
20
- obj.to_binary_s.must_equal_binary "123"
19
+ _(obj).must_equal "123"
20
+ _(obj.to_binary_s).must_equal_binary "123"
21
21
  end
22
22
 
23
23
  it "accepts BinData::BasePrimitive parameters" do
24
24
  rest = BinData::Rest.new(assert: "abc")
25
- lambda {
25
+ _ {
26
26
  rest.read("xyz")
27
27
  }.must_raise BinData::ValidityError
28
28
  end
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
4
+
5
+ describe BinData::Section do
6
+ it "transforms data byte at a time" do
7
+ require 'bindata/transform/xor'
8
+
9
+ obj = BinData::Section.new(transform: -> { BinData::Transform::Xor.new(0xff) },
10
+ type: [:string, read_length: 5])
11
+
12
+ _(obj.read("\x97\x9A\x93\x93\x90")).must_equal "hello"
13
+ end
14
+
15
+ begin
16
+ require 'brotli'
17
+ it "transform brotli" do
18
+ require 'bindata/transform/brotli'
19
+
20
+ class BrotliRecord < BinData::Record
21
+ int32le :len, value: -> { s.num_bytes }
22
+ section :s, transform: -> { BinData::Transform::Brotli.new(len) } do
23
+ int32le :str_len, value: -> { str.length }
24
+ string :str, read_length: :str_len
25
+
26
+ end
27
+ end
28
+
29
+ obj = BrotliRecord.new
30
+ data = "highly compressible" * 100
31
+ obj.s.str = data
32
+ _(obj.len).must_be :<, (data.length / 10)
33
+
34
+ str = obj.to_binary_s
35
+ obj = BrotliRecord.read(str)
36
+ _(obj.s.str).must_equal data
37
+ end
38
+ rescue LoadError; end
39
+
40
+ begin
41
+ require 'extlz4'
42
+ it "transform lz4" do
43
+ require 'bindata/transform/lz4'
44
+
45
+ class LZ4Record < BinData::Record
46
+ int32le :len, value: -> { s.num_bytes }
47
+ section :s, transform: -> { BinData::Transform::LZ4.new(len) } do
48
+ int32le :str_len, value: -> { str.length }
49
+ string :str, read_length: :str_len
50
+
51
+ end
52
+ end
53
+
54
+ obj = LZ4Record.new
55
+ data = "highly compressible" * 100
56
+ obj.s.str = data
57
+ _(obj.len).must_be :<, (data.length / 10)
58
+
59
+ str = obj.to_binary_s
60
+ obj = LZ4Record.read(str)
61
+ _(obj.s.str).must_equal data
62
+ end
63
+ rescue LoadError; end
64
+
65
+ it "transform zlib" do
66
+ require 'bindata/transform/zlib'
67
+
68
+ class ZlibRecord < BinData::Record
69
+ int32le :len, value: -> { s.num_bytes }
70
+ section :s, transform: -> { BinData::Transform::Zlib.new(len) } do
71
+ int32le :str_len, value: -> { str.length }
72
+ string :str, read_length: :str_len
73
+
74
+ end
75
+ end
76
+
77
+ obj = ZlibRecord.new
78
+ data = "highly compressible" * 100
79
+ obj.s.str = data
80
+ _(obj.len).must_be :<, (data.length / 10)
81
+
82
+ str = obj.to_binary_s
83
+ obj = ZlibRecord.read(str)
84
+ _(obj.s.str).must_equal data
85
+ end
86
+
87
+ begin
88
+ require 'zstd-ruby'
89
+ it "transform zstd" do
90
+ require 'bindata/transform/zstd'
91
+
92
+ class ZstdRecord < BinData::Record
93
+ int32le :len, value: -> { s.num_bytes }
94
+ section :s, transform: -> { BinData::Transform::Zstd.new(len) } do
95
+ int32le :str_len, value: -> { str.length }
96
+ string :str, read_length: :str_len
97
+
98
+ end
99
+ end
100
+
101
+ obj = ZstdRecord.new
102
+ data = "highly compressible" * 100
103
+ obj.s.str = data
104
+ _(obj.len).must_be :<, (data.length / 10)
105
+
106
+ str = obj.to_binary_s
107
+ obj = ZstdRecord.read(str)
108
+ _(obj.s.str).must_equal data
109
+ end
110
+ rescue LoadError; end
111
+ end
data/test/skip_test.rb CHANGED
@@ -6,7 +6,7 @@ describe BinData::Skip, "when instantiating" do
6
6
  describe "with no mandatory parameters supplied" do
7
7
  it "raises an error" do
8
8
  args = {}
9
- lambda { BinData::Skip.new(args) }.must_raise ArgumentError
9
+ _ { BinData::Skip.new(args) }.must_raise ArgumentError
10
10
  end
11
11
  end
12
12
  end
@@ -16,23 +16,23 @@ describe BinData::Skip, "with :length" do
16
16
  let(:io) { StringIO.new("abcdefghij") }
17
17
 
18
18
  it "initial state" do
19
- obj.must_equal ""
20
- obj.to_binary_s.must_equal_binary "\000" * 5
19
+ _(obj).must_equal ""
20
+ _(obj.to_binary_s).must_equal_binary "\000" * 5
21
21
  end
22
22
 
23
23
  it "skips bytes" do
24
24
  obj.read(io)
25
- io.pos.must_equal 5
25
+ _(io.pos).must_equal 5
26
26
  end
27
27
 
28
28
  it "has expected binary representation after setting value" do
29
29
  obj.assign("123")
30
- obj.to_binary_s.must_equal_binary "\000" * 5
30
+ _(obj.to_binary_s).must_equal_binary "\000" * 5
31
31
  end
32
32
 
33
33
  it "has expected binary representation after reading" do
34
34
  obj.read(io)
35
- obj.to_binary_s.must_equal_binary "\000" * 5
35
+ _(obj.to_binary_s).must_equal_binary "\000" * 5
36
36
  end
37
37
  end
38
38
 
@@ -46,55 +46,75 @@ describe BinData::Skip, "with :to_abs_offset" do
46
46
  fields = [ skip_obj ]
47
47
  obj = BinData::Struct.new(fields: fields)
48
48
  obj.read(io)
49
- io.pos.must_equal 5
49
+ _(io.pos).must_equal 5
50
50
  end
51
51
 
52
52
  it "reads skipping in place" do
53
53
  fields = [ [:string, :a, { read_length: 5 }], skip_obj ]
54
54
  obj = BinData::Struct.new(fields: fields)
55
55
  obj.read(io)
56
- io.pos.must_equal 5
56
+ _(io.pos).must_equal 5
57
57
  end
58
58
 
59
59
  it "does not read skipping backwards" do
60
60
  fields = [ [:string, :a, { read_length: 10 }], skip_obj ]
61
61
  obj = BinData::Struct.new(fields: fields)
62
62
 
63
- lambda {
63
+ _ {
64
64
  obj.read(io)
65
- }.must_raise BinData::ValidityError
65
+ }.must_raise ArgumentError
66
66
  end
67
67
 
68
68
  it "writes skipping forward" do
69
69
  fields = [ skip_obj ]
70
70
  obj = BinData::Struct.new(fields: fields)
71
- obj.to_binary_s.must_equal "\000\000\000\000\000"
71
+ _(obj.to_binary_s).must_equal "\000\000\000\000\000"
72
72
  end
73
73
 
74
74
  it "reads skipping in place" do
75
75
  fields = [ [:string, :a, { value: "abcde" }], skip_obj ]
76
76
  obj = BinData::Struct.new(fields: fields)
77
- obj.to_binary_s.must_equal "abcde"
77
+ _(obj.to_binary_s).must_equal "abcde"
78
78
  end
79
79
 
80
80
  it "does not write skipping backwards" do
81
81
  fields = [ [:string, :a, { value: "abcdefghij" }], skip_obj ]
82
82
  obj = BinData::Struct.new(fields: fields)
83
- lambda {
83
+ _ {
84
84
  obj.to_binary_s
85
- }.must_raise BinData::ValidityError
85
+ }.must_raise ArgumentError
86
86
  end
87
87
  end
88
88
 
89
89
  describe BinData::Skip, "with :until_valid" do
90
90
  let(:io) { StringIO.new("abcdefghij") }
91
91
 
92
+ it "doesn't skip when writing" do
93
+ skip_obj = [:string, { read_length: 1, assert: "f" }]
94
+ args = { until_valid: skip_obj }
95
+ obj = BinData::Skip.new(args)
96
+ _(obj.to_binary_s).must_equal ""
97
+ end
98
+
92
99
  it "skips to valid match" do
93
100
  skip_obj = [:string, { read_length: 1, assert: "f" }]
94
101
  fields = [ [:skip, :s, { until_valid: skip_obj }] ]
95
102
  obj = BinData::Struct.new(fields: fields)
96
103
  obj.read(io)
97
- io.pos.must_equal 5
104
+ _(io.pos).must_equal 5
105
+ end
106
+
107
+ it "won't skip on unseekable stream" do
108
+ rd, wr = IO::pipe
109
+ unseekable_io = BinData::IO::Read.new(rd)
110
+ wr.write io
111
+ wr.close
112
+
113
+ skip_obj = [:string, { read_length: 1, assert: "f" }]
114
+ fields = [ [:skip, :s, { until_valid: skip_obj }] ]
115
+ obj = BinData::Struct.new(fields: fields)
116
+ _ {obj.read(unseekable_io)}.must_raise IOError
117
+ rd.close
98
118
  end
99
119
 
100
120
  it "doesn't skip when validator doesn't assert" do
@@ -102,36 +122,61 @@ describe BinData::Skip, "with :until_valid" do
102
122
  fields = [ [:skip, :s, { until_valid: skip_obj }] ]
103
123
  obj = BinData::Struct.new(fields: fields)
104
124
  obj.read(io)
105
- io.pos.must_equal 0
125
+ _(io.pos).must_equal 0
106
126
  end
107
127
 
108
- it "raises EOFError when no match" do
128
+ it "raises IOError when no match" do
109
129
  skip_obj = [:string, { read_length: 1, assert: "X" }]
110
130
  fields = [ [:skip, :s, { until_valid: skip_obj }] ]
111
131
  obj = BinData::Struct.new(fields: fields)
112
- lambda {
132
+ _ {
113
133
  obj.read(io)
114
- }.must_raise EOFError
134
+ }.must_raise IOError
115
135
  end
116
136
 
117
137
  it "raises IOError when validator reads beyond stream" do
118
138
  skip_obj = [:string, { read_length: 30 }]
119
139
  fields = [ [:skip, :s, { until_valid: skip_obj }] ]
120
140
  obj = BinData::Struct.new(fields: fields)
121
- lambda {
141
+ _ {
122
142
  obj.read(io)
123
143
  }.must_raise IOError
124
144
  end
125
145
 
126
- class DSLSkip < BinData::Record
146
+ it "uses block form" do
147
+ class DSLSkip < BinData::Record
148
+ skip :s do
149
+ string read_length: 1, assert: "f"
150
+ end
151
+ string :a, read_length: 1
152
+ end
153
+
154
+ obj = DSLSkip.read(io)
155
+ _(obj.a).must_equal "f"
156
+ end
157
+ end
158
+
159
+ describe BinData::Skip, "with :until_valid" do
160
+ class SkipSearch < BinData::Record
127
161
  skip :s do
128
- string read_length: 1, assert: "f"
162
+ uint8
163
+ uint8 asserted_value: 1
164
+ uint8 :a
165
+ uint8 :b
166
+ virtual assert: -> { a == b }
129
167
  end
130
- string :a, read_length: 1
168
+ array :data, type: :uint8, initial_length: 4
131
169
  end
132
170
 
133
- it "uses block form" do
134
- obj = DSLSkip.read(io)
135
- obj.a.must_equal "f"
171
+ let(:io) { BinData::IO.create_string_io("\x0f" * 10 + "\x00\x01\x02\x03\x00" + "\x02\x01\x03\x03" + "\x06") }
172
+
173
+ it "finds valid match" do
174
+ obj = SkipSearch.read(io)
175
+ _(obj.data).must_equal [2, 1, 3, 3]
176
+ end
177
+
178
+ it "match is at expected offset" do
179
+ obj = SkipSearch.read(io)
180
+ _(obj.data.rel_offset).must_equal 15
136
181
  end
137
182
  end