bindata 1.5.1 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bindata might be problematic. Click here for more details.

Files changed (61) hide show
  1. data/ChangeLog.rdoc +7 -0
  2. data/NEWS.rdoc +11 -0
  3. data/Rakefile +6 -1
  4. data/bindata.gemspec +2 -1
  5. data/doc/manual.md +17 -9
  6. data/examples/gzip.rb +2 -2
  7. data/examples/list.rb +2 -2
  8. data/lib/bindata/alignment.rb +4 -9
  9. data/lib/bindata/array.rb +57 -51
  10. data/lib/bindata/base.rb +13 -110
  11. data/lib/bindata/base_primitive.rb +130 -75
  12. data/lib/bindata/bits.rb +5 -7
  13. data/lib/bindata/choice.rb +24 -32
  14. data/lib/bindata/dsl.rb +1 -6
  15. data/lib/bindata/framework.rb +81 -0
  16. data/lib/bindata/int.rb +5 -7
  17. data/lib/bindata/name.rb +28 -0
  18. data/lib/bindata/offset.rb +42 -53
  19. data/lib/bindata/params.rb +33 -38
  20. data/lib/bindata/struct.rb +2 -6
  21. data/lib/bindata/trace.rb +16 -16
  22. data/lib/bindata/version.rb +1 -1
  23. data/lib/bindata/virtual.rb +3 -3
  24. data/{spec/alignment_spec.rb → test/alignment_test.rb} +17 -16
  25. data/test/array_test.rb +371 -0
  26. data/test/base_primitive_test.rb +312 -0
  27. data/test/base_test.rb +183 -0
  28. data/{spec/bits_spec.rb → test/bits_test.rb} +59 -59
  29. data/test/choice_test.rb +260 -0
  30. data/{spec/spec_common.rb → test/common.rb} +33 -18
  31. data/test/count_bytes_remaining_test.rb +41 -0
  32. data/{spec/deprecated_spec.rb → test/deprecated_test.rb} +5 -7
  33. data/test/float_test.rb +72 -0
  34. data/{spec/int_spec.rb → test/int_test.rb} +34 -43
  35. data/{spec/io_spec.rb → test/io_test.rb} +70 -71
  36. data/{spec/lazy_spec.rb → test/lazy_test.rb} +38 -39
  37. data/test/offset_test.rb +93 -0
  38. data/test/params_test.rb +144 -0
  39. data/{spec/primitive_spec.rb → test/primitive_test.rb} +42 -54
  40. data/{spec/record_spec.rb → test/record_test.rb} +133 -154
  41. data/test/registry_test.rb +104 -0
  42. data/test/rest_test.rb +29 -0
  43. data/test/skip_test.rb +28 -0
  44. data/{spec/string_spec.rb → test/string_test.rb} +96 -97
  45. data/test/stringz_test.rb +127 -0
  46. data/{spec/struct_spec.rb → test/struct_test.rb} +119 -120
  47. data/{spec/system_spec.rb → test/system_test.rb} +66 -106
  48. metadata +39 -38
  49. data/lib/a.rb +0 -24
  50. data/spec/array_spec.rb +0 -331
  51. data/spec/base_primitive_spec.rb +0 -238
  52. data/spec/base_spec.rb +0 -376
  53. data/spec/choice_spec.rb +0 -263
  54. data/spec/count_bytes_remaining_spec.rb +0 -38
  55. data/spec/example.rb +0 -21
  56. data/spec/float_spec.rb +0 -37
  57. data/spec/registry_spec.rb +0 -108
  58. data/spec/rest_spec.rb +0 -26
  59. data/spec/skip_spec.rb +0 -27
  60. data/spec/stringz_spec.rb +0 -118
  61. data/tasks/rspec.rake +0 -17
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.join(File.dirname(__FILE__), "common"))
4
+
5
+ describe BinData::Stringz, "when empty" do
6
+ let(:obj) { BinData::Stringz.new }
7
+
8
+ it "initial state" do
9
+ obj.value.must_equal ""
10
+ obj.num_bytes.must_equal 1
11
+ obj.to_binary_s.must_equal "\0"
12
+ end
13
+ end
14
+
15
+ describe BinData::Stringz, "with value set" do
16
+ let(:obj) { BinData::Stringz.new("abcd") }
17
+
18
+ it "initial state" do
19
+ obj.value.must_equal "abcd"
20
+ obj.num_bytes.must_equal 5
21
+ obj.to_binary_s.must_equal "abcd\0"
22
+ end
23
+ end
24
+
25
+ describe BinData::Stringz, "when reading" do
26
+ let(:obj) { BinData::Stringz.new }
27
+
28
+ it "stops at the first zero byte" do
29
+ io = StringIO.new("abcd\0xyz\0")
30
+ obj.read(io)
31
+ io.pos.must_equal 5
32
+ obj.must_equal "abcd"
33
+ end
34
+
35
+ it "handles a zero length string" do
36
+ io = StringIO.new("\0abcd")
37
+ obj.read(io)
38
+ io.pos.must_equal 1
39
+ obj.must_equal ""
40
+ end
41
+
42
+ it "fails if no zero byte is found" do
43
+ lambda {obj.read("abcd") }.must_raise EOFError
44
+ end
45
+ end
46
+
47
+ describe BinData::Stringz, "when setting the value" do
48
+ let(:obj) { BinData::Stringz.new }
49
+
50
+ it "includes the zero byte in num_bytes total" do
51
+ obj.assign("abcd")
52
+ obj.num_bytes.must_equal 5
53
+ end
54
+
55
+ it "accepts empty strings" do
56
+ obj.assign("")
57
+ obj.must_equal ""
58
+ end
59
+
60
+ it "accepts strings that aren't zero terminated" do
61
+ obj.assign("abcd")
62
+ obj.must_equal "abcd"
63
+ end
64
+
65
+ it "accepts strings that are zero terminated" do
66
+ obj.assign("abcd\0")
67
+ obj.must_equal "abcd"
68
+ end
69
+
70
+ it "accepts up to the first zero byte" do
71
+ obj.assign("abcd\0xyz\0")
72
+ obj.must_equal "abcd"
73
+ end
74
+ end
75
+
76
+ describe BinData::Stringz, "with max_length" do
77
+ let(:obj) { BinData::Stringz.new(:max_length => 5) }
78
+
79
+ it "reads less than max_length" do
80
+ io = StringIO.new("abc\0xyz")
81
+ obj.read(io)
82
+ obj.must_equal "abc"
83
+ end
84
+
85
+ it "reads exactly max_length" do
86
+ io = StringIO.new("abcd\0xyz")
87
+ obj.read(io)
88
+ obj.must_equal "abcd"
89
+ end
90
+
91
+ it "reads no more than max_length" do
92
+ io = StringIO.new("abcdefg\0xyz")
93
+ obj.read(io)
94
+ io.pos.must_equal 5
95
+ obj.must_equal "abcd"
96
+ end
97
+
98
+ it "accepts values less than max_length" do
99
+ obj.assign("abc")
100
+ obj.must_equal "abc"
101
+ end
102
+
103
+ it "accepts values exactly max_length" do
104
+ obj.assign("abcd")
105
+ obj.must_equal "abcd"
106
+ end
107
+
108
+ it "trims values greater than max_length" do
109
+ obj.assign("abcde")
110
+ obj.must_equal "abcd"
111
+ end
112
+
113
+ it "writes values greater than max_length" do
114
+ obj.assign("abcde")
115
+ obj.to_binary_s.must_equal "abcd\0"
116
+ end
117
+
118
+ it "writes values less than max_length" do
119
+ obj.assign("abc")
120
+ obj.to_binary_s.must_equal "abc\0"
121
+ end
122
+
123
+ it "writes values exactly max_length" do
124
+ obj.assign("abcd")
125
+ obj.to_binary_s.must_equal "abcd\0"
126
+ end
127
+ end
@@ -1,48 +1,47 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require File.expand_path(File.join(File.dirname(__FILE__), "spec_common"))
4
- require 'bindata'
3
+ require File.expand_path(File.join(File.dirname(__FILE__), "common"))
5
4
 
6
5
  describe BinData::Struct, "when initializing" do
7
6
  it "fails on non registered types" do
8
7
  params = {:fields => [[:non_registered_type, :a]]}
9
- expect {
8
+ lambda {
10
9
  BinData::Struct.new(params)
11
- }.to raise_error(BinData::UnRegisteredTypeError)
10
+ }.must_raise BinData::UnRegisteredTypeError
12
11
  end
13
12
 
14
13
  it "fails on duplicate names" do
15
14
  params = {:fields => [[:int8, :a], [:int8, :b], [:int8, :a]]}
16
- expect {
15
+ lambda {
17
16
  BinData::Struct.new(params)
18
- }.to raise_error(NameError)
17
+ }.must_raise NameError
19
18
  end
20
19
 
21
20
  it "fails on reserved names" do
22
21
  # note that #invert is from Hash.instance_methods
23
22
  params = {:fields => [[:int8, :a], [:int8, :invert]]}
24
- expect {
23
+ lambda {
25
24
  BinData::Struct.new(params)
26
- }.to raise_error(NameError)
25
+ }.must_raise NameError
27
26
  end
28
27
 
29
28
  it "fails when field name shadows an existing method" do
30
29
  params = {:fields => [[:int8, :object_id]]}
31
- expect {
30
+ lambda {
32
31
  BinData::Struct.new(params)
33
- }.to raise_error(NameError)
32
+ }.must_raise NameError
34
33
  end
35
34
 
36
35
  it "fails on unknown endian" do
37
36
  params = {:endian => 'bad value', :fields => []}
38
- expect {
37
+ lambda {
39
38
  BinData::Struct.new(params)
40
- }.to raise_error(ArgumentError)
39
+ }.must_raise ArgumentError
41
40
  end
42
41
  end
43
42
 
44
43
  describe BinData::Struct, "with anonymous fields" do
45
- subject {
44
+ let(:obj) {
46
45
  params = { :fields => [
47
46
  [:int8, :a, {:initial_value => 5}],
48
47
  [:int8, nil],
@@ -52,23 +51,23 @@ describe BinData::Struct, "with anonymous fields" do
52
51
  }
53
52
 
54
53
  it "only shows non anonymous fields" do
55
- subject.field_names.should == ["a"]
54
+ obj.field_names.must_equal ["a"]
56
55
  end
57
56
 
58
57
  it "does not include anonymous fields in snapshot" do
59
- subject.a = 5
60
- subject.snapshot.should == {"a" => 5}
58
+ obj.a = 5
59
+ obj.snapshot.must_equal({"a" => 5})
61
60
  end
62
61
 
63
62
  it "writes anonymous fields" do
64
- subject.read("\001\002\003")
65
- subject.a.clear
66
- subject.to_binary_s.should == "\005\002\005"
63
+ obj.read("\001\002\003")
64
+ obj.a.clear
65
+ obj.to_binary_s.must_equal "\005\002\005"
67
66
  end
68
67
  end
69
68
 
70
69
  describe BinData::Struct, "with hidden fields" do
71
- subject {
70
+ let(:obj) {
72
71
  params = { :hide => [:b, :c],
73
72
  :fields => [
74
73
  [:int8, :a],
@@ -79,102 +78,102 @@ describe BinData::Struct, "with hidden fields" do
79
78
  }
80
79
 
81
80
  it "only shows fields that aren't hidden" do
82
- subject.field_names.should == ["a", "d"]
81
+ obj.field_names.must_equal ["a", "d"]
83
82
  end
84
83
 
85
84
  it "accesses hidden fields directly" do
86
- subject.b.should == 5
87
- subject.c = 15
88
- subject.c.should == 15
85
+ obj.b.must_equal 5
86
+ obj.c = 15
87
+ obj.c.must_equal 15
89
88
 
90
- subject.should respond_to(:b=)
89
+ obj.must_respond_to :b=
91
90
  end
92
91
 
93
92
  it "does not include hidden fields in snapshot" do
94
- subject.b = 7
95
- subject.snapshot.should == {"a" => 0, "d" => 7}
93
+ obj.b = 7
94
+ obj.snapshot.must_equal({"a" => 0, "d" => 7})
96
95
  end
97
96
 
98
97
  it "detects hidden fields with has_key?" do
99
- subject.should have_key("b")
98
+ assert obj.has_key?("b")
100
99
  end
101
100
  end
102
101
 
103
102
  describe BinData::Struct, "with multiple fields" do
104
103
  let(:params) { { :fields => [ [:int8, :a], [:int8, :b] ] } }
105
- subject { BinData::Struct.new({:a => 1, :b => 2}, params) }
104
+ let(:obj) { BinData::Struct.new({:a => 1, :b => 2}, params) }
106
105
 
107
- its(:field_names) { should == ["a", "b"] }
108
- its(:to_binary_s) { should == "\x01\x02" }
106
+ specify { obj.field_names.must_equal ["a", "b"] }
107
+ specify { obj.to_binary_s.must_equal "\x01\x02" }
109
108
 
110
109
  it "returns num_bytes" do
111
- subject.a.num_bytes.should == 1
112
- subject.b.num_bytes.should == 1
113
- subject.num_bytes.should == 2
110
+ obj.a.num_bytes.must_equal 1
111
+ obj.b.num_bytes.must_equal 1
112
+ obj.num_bytes.must_equal 2
114
113
  end
115
114
 
116
115
  it "identifies accepted parameters" do
117
- BinData::Struct.accepted_parameters.all.should include(:fields)
118
- BinData::Struct.accepted_parameters.all.should include(:hide)
119
- BinData::Struct.accepted_parameters.all.should include(:endian)
116
+ BinData::Struct.accepted_parameters.all.must_include :fields
117
+ BinData::Struct.accepted_parameters.all.must_include :hide
118
+ BinData::Struct.accepted_parameters.all.must_include :endian
120
119
  end
121
120
 
122
121
  it "clears" do
123
- subject.a = 6
124
- subject.clear
125
- subject.should be_clear
122
+ obj.a = 6
123
+ obj.clear
124
+ assert obj.clear?
126
125
  end
127
126
 
128
127
  it "clears individual elements" do
129
- subject.a = 6
130
- subject.b = 7
131
- subject.a.clear
132
- subject.a.should be_clear
133
- subject.b.should_not be_clear
128
+ obj.a = 6
129
+ obj.b = 7
130
+ obj.a.clear
131
+ assert obj.a.clear?
132
+ refute obj.b.clear?
134
133
  end
135
134
 
136
135
  it "reads elements dynamically" do
137
- subject[:a].should == 1
136
+ obj[:a].must_equal 1
138
137
  end
139
138
 
140
139
  it "writes elements dynamically" do
141
- subject[:a] = 2
142
- subject.a.should == 2
140
+ obj[:a] = 2
141
+ obj.a.must_equal 2
143
142
  end
144
143
 
145
144
  it "implements has_key?" do
146
- subject.should have_key("a")
145
+ assert obj.has_key?("a")
147
146
  end
148
147
 
149
148
  it "reads ordered" do
150
- subject.read("\x03\x04")
149
+ obj.read("\x03\x04")
151
150
 
152
- subject.a.should == 3
153
- subject.b.should == 4
151
+ obj.a.must_equal 3
152
+ obj.b.must_equal 4
154
153
  end
155
154
 
156
155
  it "returns a snapshot" do
157
- snap = subject.snapshot
158
- snap.a.should == 1
159
- snap.b.should == 2
160
- snap.should == { "a" => 1, "b" => 2 }
156
+ snap = obj.snapshot
157
+ snap.a.must_equal 1
158
+ snap.b.must_equal 2
159
+ snap.must_equal({ "a" => 1, "b" => 2 })
161
160
  end
162
161
 
163
162
  it "assigns from partial hash" do
164
- subject.assign("a" => 3)
165
- subject.a.should == 3
166
- subject.b.should == 0
163
+ obj.assign("a" => 3)
164
+ obj.a.must_equal 3
165
+ obj.b.must_equal 0
167
166
  end
168
167
 
169
168
  it "assigns from hash" do
170
- subject.assign("a" => 3, "b" => 4)
171
- subject.a.should == 3
172
- subject.b.should == 4
169
+ obj.assign("a" => 3, "b" => 4)
170
+ obj.a.must_equal 3
171
+ obj.b.must_equal 4
173
172
  end
174
173
 
175
174
  it "assigns from nil" do
176
- subject.assign(nil)
177
- subject.should be_clear
175
+ obj.assign(nil)
176
+ assert obj.clear?
178
177
  end
179
178
 
180
179
  it "assigns from Struct" do
@@ -182,9 +181,9 @@ describe BinData::Struct, "with multiple fields" do
182
181
  src.a = 3
183
182
  src.b = 4
184
183
 
185
- subject.assign(src)
186
- subject.a.should == 3
187
- subject.b.should == 4
184
+ obj.assign(src)
185
+ obj.a.must_equal 3
186
+ obj.b.must_equal 4
188
187
  end
189
188
 
190
189
  it "assigns from snapshot" do
@@ -192,36 +191,36 @@ describe BinData::Struct, "with multiple fields" do
192
191
  src.a = 3
193
192
  src.b = 4
194
193
 
195
- subject.assign(src.snapshot)
196
- subject.a.should == 3
197
- subject.b.should == 4
194
+ obj.assign(src.snapshot)
195
+ obj.a.must_equal 3
196
+ obj.b.must_equal 4
198
197
  end
199
198
 
200
199
  it "fails on unknown method call" do
201
- expect { subject.does_not_exist }.to raise_error(NoMethodError)
200
+ lambda { obj.does_not_exist }.must_raise NoMethodError
202
201
  end
203
202
 
204
- context "#snapshot" do
203
+ describe "#snapshot" do
205
204
  it "has ordered #keys" do
206
- subject.snapshot.keys.should == ["a", "b"]
205
+ obj.snapshot.keys.must_equal ["a", "b"]
207
206
  end
208
207
 
209
208
  it "has ordered #each" do
210
209
  keys = []
211
- subject.snapshot.each { |el| keys << el[0] }
212
- keys.should == ["a", "b"]
210
+ obj.snapshot.each { |el| keys << el[0] }
211
+ keys.must_equal ["a", "b"]
213
212
  end
214
213
 
215
214
  it "has ordered #each_pair" do
216
215
  keys = []
217
- subject.snapshot.each_pair { |k, v| keys << k }
218
- keys.should == ["a", "b"]
216
+ obj.snapshot.each_pair { |k, v| keys << k }
217
+ keys.must_equal ["a", "b"]
219
218
  end
220
219
  end
221
220
  end
222
221
 
223
222
  describe BinData::Struct, "with nested structs" do
224
- subject {
223
+ let(:obj) {
225
224
  inner1 = [ [:int8, :w, {:initial_value => 3}],
226
225
  [:int8, :x, {:value => :the_val}] ]
227
226
 
@@ -235,32 +234,32 @@ describe BinData::Struct, "with nested structs" do
235
234
  BinData::Struct.new(params)
236
235
  }
237
236
 
238
- its(:field_names) { should == ["a", "b", "c"] }
237
+ specify { obj.field_names.must_equal ["a", "b", "c"] }
239
238
 
240
239
  it "returns num_bytes" do
241
- subject.b.num_bytes.should == 2
242
- subject.c.num_bytes.should == 2
243
- subject.num_bytes.should == 5
240
+ obj.b.num_bytes.must_equal 2
241
+ obj.c.num_bytes.must_equal 2
242
+ obj.num_bytes.must_equal 5
244
243
  end
245
244
 
246
245
  it "accesses nested fields" do
247
- subject.a.should == 6
248
- subject.b.w.should == 3
249
- subject.b.x.should == 6
250
- subject.c.y.should == 3
251
- subject.c.z.should == 0
246
+ obj.a.must_equal 6
247
+ obj.b.w.must_equal 3
248
+ obj.b.x.must_equal 6
249
+ obj.c.y.must_equal 3
250
+ obj.c.z.must_equal 0
252
251
  end
253
252
 
254
253
  it "returns correct offset" do
255
- subject.b.offset.should == 1
256
- subject.b.w.offset.should == 1
257
- subject.c.offset.should == 3
258
- subject.c.z.offset.should == 4
254
+ obj.b.offset.must_equal 1
255
+ obj.b.w.offset.must_equal 1
256
+ obj.c.offset.must_equal 3
257
+ obj.c.z.offset.must_equal 4
259
258
  end
260
259
  end
261
260
 
262
261
  describe BinData::Struct, "with an endian defined" do
263
- subject {
262
+ let(:obj) {
264
263
  BinData::Struct.new(:endian => :little,
265
264
  :fields => [
266
265
  [:uint16, :a],
@@ -280,44 +279,44 @@ describe BinData::Struct, "with an endian defined" do
280
279
  }
281
280
 
282
281
  it "uses correct endian" do
283
- subject.a = 1
284
- subject.b = 2.0
285
- subject.c[0] = 3
286
- subject.c[1] = 4
287
- subject.d = 5
288
- subject.e.f = 6
289
- subject.e.g = 7
290
- subject.h.i.j = 8
282
+ obj.a = 1
283
+ obj.b = 2.0
284
+ obj.c[0] = 3
285
+ obj.c[1] = 4
286
+ obj.d = 5
287
+ obj.e.f = 6
288
+ obj.e.g = 7
289
+ obj.h.i.j = 8
291
290
 
292
291
  expected = [1, 2.0, 3, 4, 5, 6, 7, 8].pack('veCCVvNv')
293
292
 
294
- subject.to_binary_s.should == expected
293
+ obj.to_binary_s.must_equal expected
295
294
  end
296
295
  end
297
296
 
298
297
  describe BinData::Struct, "with bit fields" do
299
- subject {
298
+ let(:obj) {
300
299
  params = { :fields => [ [:bit1le, :a], [:bit2le, :b], [:uint8, :c], [:bit1le, :d] ] }
301
300
  BinData::Struct.new({:a => 1, :b => 2, :c => 3, :d => 1}, params)
302
301
  }
303
302
 
304
- its(:num_bytes) { should == 3 }
305
- its(:to_binary_s) { should == [0b0000_0101, 3, 1].pack("C*") }
303
+ specify { obj.num_bytes.must_equal 3 }
304
+ specify { obj.to_binary_s.must_equal [0b0000_0101, 3, 1].pack("C*") }
306
305
 
307
306
  it "reads" do
308
307
  str = [0b0000_0110, 5, 0].pack("C*")
309
- subject.read(str)
310
- subject.a.should == 0
311
- subject.b.should == 3
312
- subject.c.should == 5
313
- subject.d.should == 0
308
+ obj.read(str)
309
+ obj.a.must_equal 0
310
+ obj.b.must_equal 3
311
+ obj.c.must_equal 5
312
+ obj.d.must_equal 0
314
313
  end
315
314
 
316
315
  it "has correct offsets" do
317
- subject.a.offset.should == 0
318
- subject.b.offset.should == 0
319
- subject.c.offset.should == 1
320
- subject.d.offset.should == 2
316
+ obj.a.offset.must_equal 0
317
+ obj.b.offset.must_equal 0
318
+ obj.c.offset.must_equal 1
319
+ obj.d.offset.must_equal 2
321
320
  end
322
321
  end
323
322
 
@@ -329,13 +328,13 @@ describe BinData::Struct, "with nested endian" do
329
328
  :fields => [[:int16, :a],
330
329
  [:struct, :s, nested_params],
331
330
  [:int16, :d]] }
332
- subject = BinData::Struct.new(params)
333
- subject.read("\x00\x01\x02\x00\x03\x00\x00\x04")
331
+ obj = BinData::Struct.new(params)
332
+ obj.read("\x00\x01\x02\x00\x03\x00\x00\x04")
334
333
 
335
- subject.a.should == 1
336
- subject.s.b.should == 2
337
- subject.s.c.should == 3
338
- subject.d.should == 4
334
+ obj.a.must_equal 1
335
+ obj.s.b.must_equal 2
336
+ obj.s.c.must_equal 3
337
+ obj.d.must_equal 4
339
338
  end
340
339
  end
341
340
 
@@ -345,6 +344,6 @@ describe BinData::Struct, "with dynamically named types" do
345
344
 
346
345
  obj = BinData::Struct.new(:fields => [[:my_struct, :v]])
347
346
 
348
- obj.v.a.should == 3
347
+ obj.v.a.must_equal 3
349
348
  end
350
349
  end