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
data/spec/base_spec.rb DELETED
@@ -1,376 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require File.expand_path(File.join(File.dirname(__FILE__), "spec_common"))
4
- require 'bindata/base'
5
-
6
- class BaseStub < BinData::Base
7
- # Override to avoid NotImplemented errors
8
- def clear; end
9
- def clear?; end
10
- def assign(x); @data = x; end
11
- def snapshot; @data; end
12
- def do_read(io) end
13
- def do_write(io) end
14
- def do_num_bytes; end
15
- end
16
-
17
- describe BinData::Base, "all subclasses" do
18
- class SubClassOfBase < BinData::Base
19
- expose_methods_for_testing
20
- end
21
-
22
- subject { SubClassOfBase.new }
23
-
24
- it "raises errors on unimplemented methods" do
25
- expect { subject.clear }.to raise_error(NotImplementedError)
26
- expect { subject.clear? }.to raise_error(NotImplementedError)
27
- expect { subject.assign(nil) }.to raise_error(NotImplementedError)
28
- expect { subject.snapshot }.to raise_error(NotImplementedError)
29
- expect { subject.do_read(nil) }.to raise_error(NotImplementedError)
30
- expect { subject.do_write(nil) }.to raise_error(NotImplementedError)
31
- expect { subject.do_num_bytes }.to raise_error(NotImplementedError)
32
- end
33
- end
34
-
35
- describe BinData::Base, "with parameters" do
36
- it "raises error when parameter name is invalid" do
37
- expect {
38
- class InvalidParameterNameBase < BinData::Base
39
- optional_parameter :eval # i.e. Kernel#eval
40
- end
41
- }.to raise_error(NameError)
42
- end
43
-
44
- it "raises an error when parameter has nil value" do
45
- expect { BaseStub.new(:a => nil) }.to raise_error(ArgumentError)
46
- end
47
-
48
- it "converts parameter keys to symbols" do
49
- subject = BaseStub.new('a' => 3)
50
- subject.should have_parameter(:a)
51
- end
52
- end
53
-
54
- describe BinData::Base, "with mandatory parameters" do
55
- class MandatoryBase < BaseStub
56
- mandatory_parameter :p1
57
- mandatory_parameter :p2
58
- end
59
-
60
- it "ensures that all mandatory parameters are present" do
61
- params = {:p1 => "a", :p2 => "b" }
62
- expect { MandatoryBase.new(params) }.not_to raise_error
63
- end
64
-
65
- it "fails when only some mandatory parameters are present" do
66
- params = {:p1 => "a", :xx => "b" }
67
- expect { MandatoryBase.new(params) }.to raise_error(ArgumentError)
68
- end
69
-
70
- it "fails when no mandatory parameters are present" do
71
- expect { MandatoryBase.new() }.to raise_error(ArgumentError)
72
- end
73
- end
74
-
75
- describe BinData::Base, "with default parameters" do
76
- class DefaultBase < BaseStub
77
- default_parameter :p1 => "a"
78
- end
79
-
80
- it "uses default parameters when not specified" do
81
- subject = DefaultBase.new
82
- subject.eval_parameter(:p1).should == "a"
83
- end
84
-
85
- it "can override default parameters" do
86
- subject = DefaultBase.new(:p1 => "b")
87
- subject.eval_parameter(:p1).should == "b"
88
- end
89
- end
90
-
91
- describe BinData::Base, "with mutually exclusive parameters" do
92
- class MutexParamBase < BaseStub
93
- optional_parameters :p1, :p2
94
- mutually_exclusive_parameters :p1, :p2
95
- end
96
-
97
- it "does not fail when neither of those parameters are present" do
98
- expect { MutexParamBase.new }.not_to raise_error
99
- end
100
-
101
- it "does not fail when only one of those parameters is present" do
102
- expect { MutexParamBase.new(:p1 => "a") }.not_to raise_error
103
- expect { MutexParamBase.new(:p2 => "b") }.not_to raise_error
104
- end
105
-
106
- it "fails when both those parameters are present" do
107
- expect { MutexParamBase.new(:p1 => "a", :p2 => "b") }.to raise_error(ArgumentError)
108
- end
109
- end
110
-
111
- describe BinData::Base, "with multiple parameters" do
112
- class WithParamBase < BaseStub
113
- mandatory_parameter :p1
114
- default_parameter :p2 => 2
115
- optional_parameter :p3
116
- end
117
-
118
- it "identifies internally accepted parameters" do
119
- accepted = WithParamBase.accepted_parameters.all
120
- accepted.should include(:p1)
121
- accepted.should include(:p2)
122
- accepted.should include(:p3)
123
- accepted.should_not include(:xx)
124
- end
125
-
126
- context "examining parameters" do
127
- subject {
128
- params = {:p1 => 1, :p3 => :xx, :p4 => lambda { 4 }}
129
- WithParamBase.new(params)
130
- }
131
-
132
- it "evaluates parameters" do
133
- subject.eval_parameter(:p1).should == 1
134
- subject.eval_parameter(:p2).should == 2
135
- expect { subject.eval_parameter(:p3) }.to raise_error(NoMethodError)
136
- subject.eval_parameter(:p4).should == 4
137
- end
138
-
139
- it "gets parameters without evaluating" do
140
- subject.get_parameter(:p1).should == 1
141
- subject.get_parameter(:p2).should == 2
142
- subject.get_parameter(:p3).should == :xx
143
- subject.get_parameter(:p4).should respond_to(:arity)
144
- end
145
-
146
- it "has parameters" do
147
- subject.should have_parameter(:p1)
148
- subject.should have_parameter(:p2)
149
- subject.should have_parameter(:p3)
150
- subject.should have_parameter(:p4)
151
- end
152
- end
153
- end
154
-
155
- describe BinData::Base, "when initializing" do
156
- class BaseInit < BaseStub
157
- class << self
158
- attr_accessor :calls
159
- def recorded_calls(&block)
160
- self.calls = []
161
- block.call
162
- calls
163
- end
164
- end
165
-
166
- def initialize_instance
167
- self.class.calls << :initialize_instance
168
- end
169
-
170
- def initialize_shared_instance
171
- self.class.calls << :initialize_shared_instance
172
- end
173
- end
174
-
175
- it "calls both #initialize_xxx methods" do
176
- BaseInit.recorded_calls {
177
- BaseInit.new
178
- }.should == [:initialize_shared_instance, :initialize_instance]
179
- end
180
-
181
- context "as a factory" do
182
- subject { BaseInit.new(:check_offset => 1) }
183
-
184
- describe "#new" do
185
- it "calls #initialize_instance" do
186
- obj = subject
187
-
188
- BaseInit.recorded_calls {
189
- obj.new
190
- }.should == [:initialize_instance]
191
- end
192
-
193
- it "copies parameters" do
194
- obj = subject.new
195
- obj.eval_parameter(:check_offset).should == 1
196
- end
197
-
198
- it "performs action for :check_offset" do
199
- obj = subject.new
200
- expect {
201
- obj.read("abc")
202
- }.to raise_error(BinData::ValidityError)
203
- end
204
-
205
- it "assigns value" do
206
- obj = subject.new(3)
207
- obj.snapshot.should == 3
208
- end
209
-
210
- it "sets parent" do
211
- obj = subject.new(3, "p")
212
- obj.parent.should == "p"
213
- end
214
- end
215
- end
216
- end
217
-
218
- describe BinData::Base, "as black box" do
219
- context "class methods" do
220
- it "returns bindata_name" do
221
- BaseStub.bindata_name.should == "base_stub"
222
- end
223
-
224
- it "instantiates self for ::read" do
225
- BaseStub.read("").class.should == BaseStub
226
- end
227
- end
228
-
229
- it "accesses parent" do
230
- parent = BaseStub.new
231
- child = BaseStub.new(nil, parent)
232
- child.parent.should == parent
233
- end
234
-
235
- subject { BaseStub.new }
236
-
237
- it "returns self for #read" do
238
- subject.read("").should == subject
239
- end
240
-
241
- it "returns self for #write" do
242
- subject.write("").should == subject
243
- end
244
-
245
- it "forwards #inspect to snapshot" do
246
- subject.stub(:snapshot).and_return([1, 2, 3])
247
- subject.inspect.should == subject.snapshot.inspect
248
- end
249
-
250
- it "forwards #to_s to snapshot" do
251
- subject.stub(:snapshot).and_return([1, 2, 3])
252
- subject.to_s.should == subject.snapshot.to_s
253
- end
254
-
255
- it "pretty prints object as snapshot" do
256
- subject.stub(:snapshot).and_return([1, 2, 3])
257
- actual_io = StringIO.new
258
- expected_io = StringIO.new
259
-
260
- require 'pp'
261
- PP.pp(subject, actual_io)
262
- PP.pp(subject.snapshot, expected_io)
263
-
264
- actual_io.value.should == expected_io.value
265
- end
266
-
267
- it "writes the same as to_binary_s" do
268
- class WriteToSBase < BaseStub
269
- def do_write(io) io.writebytes("abc"); end
270
- end
271
-
272
- subject = WriteToSBase.new
273
- io = StringIO.new
274
- subject.write(io)
275
- io.value.should == subject.to_binary_s
276
- end
277
- end
278
-
279
- describe BinData::Base, "as white box" do
280
- subject { BaseStub.new }
281
-
282
- it "forwards read to do_read" do
283
- subject.should_receive(:clear).ordered
284
- subject.should_receive(:do_read).ordered
285
- subject.read(nil)
286
- end
287
-
288
- it "forwards write to do_write" do
289
- subject.should_receive(:do_write)
290
- subject.write(nil)
291
- end
292
-
293
- it "forwards num_bytes to do_num_bytes" do
294
- subject.should_receive(:do_num_bytes).and_return(42)
295
- subject.num_bytes.should == 42
296
- end
297
-
298
- it "rounds up fractional num_bytes" do
299
- subject.should_receive(:do_num_bytes).and_return(42.1)
300
- subject.num_bytes.should == 43
301
- end
302
- end
303
-
304
- describe BinData::Base, "checking offsets" do
305
- class TenByteOffsetBase < BaseStub
306
- def self.create(params)
307
- obj = self.new
308
- obj.initialize_child(params)
309
- obj
310
- end
311
-
312
- def initialize_child(params)
313
- @child = BaseStub.new(params, self)
314
- end
315
-
316
- def do_read(io)
317
- io.seekbytes(10)
318
- @child.do_read(io)
319
- end
320
- end
321
-
322
- let(:io) { StringIO.new("12345678901234567890") }
323
-
324
- context "with :check_offset" do
325
- it "fails when offset is incorrect" do
326
- io.seek(2)
327
- subject = TenByteOffsetBase.create(:check_offset => 8)
328
- expect { subject.read(io) }.to raise_error(BinData::ValidityError)
329
- end
330
-
331
- it "succeeds when offset is correct" do
332
- io.seek(3)
333
- subject = TenByteOffsetBase.create(:check_offset => 10)
334
- expect { subject.read(io) }.not_to raise_error
335
- end
336
-
337
- it "fails when :check_offset fails" do
338
- io.seek(4)
339
- subject = TenByteOffsetBase.create(:check_offset => lambda { offset == 11 } )
340
- expect { subject.read(io) }.to raise_error(BinData::ValidityError)
341
- end
342
-
343
- it "succeeds when :check_offset succeeds" do
344
- io.seek(5)
345
- subject = TenByteOffsetBase.create(:check_offset => lambda { offset == 10 } )
346
- expect { subject.read(io) }.not_to raise_error
347
- end
348
- end
349
-
350
- context "with :adjust_offset" do
351
- it "is mutually exclusive with :check_offset" do
352
- params = { :check_offset => 8, :adjust_offset => 8 }
353
- expect { TenByteOffsetBase.create(params) }.to raise_error(ArgumentError)
354
- end
355
-
356
- it "adjust offset when incorrect" do
357
- io.seek(2)
358
- subject = TenByteOffsetBase.create(:adjust_offset => 13)
359
- subject.read(io)
360
- io.pos.should == (2 + 13)
361
- end
362
-
363
- it "succeeds when offset is correct" do
364
- io.seek(3)
365
- subject = TenByteOffsetBase.create(:adjust_offset => 10)
366
- expect { subject.read(io) }.not_to raise_error
367
- io.pos.should == (3 + 10)
368
- end
369
-
370
- it "fails if cannot adjust offset" do
371
- io.seek(4)
372
- subject = TenByteOffsetBase.create(:adjust_offset => -5)
373
- expect { subject.read(io) }.to raise_error(BinData::ValidityError)
374
- end
375
- end
376
- end
data/spec/choice_spec.rb DELETED
@@ -1,263 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require File.expand_path(File.join(File.dirname(__FILE__), "spec_common"))
4
- require File.expand_path(File.join(File.dirname(__FILE__), "example"))
5
- require 'bindata/choice'
6
- require 'bindata/int'
7
-
8
- class Chooser
9
- attr_accessor :choice
10
- end
11
-
12
- class BinData::Choice
13
- def set_chooser(chooser)
14
- @chooser = chooser
15
- end
16
- def choice=(s)
17
- @chooser.choice = s
18
- end
19
- end
20
-
21
- def create_choice(choices, options = {})
22
- chooser = Chooser.new
23
- params = {:choices => choices, :selection => lambda { chooser.choice } }.merge(options)
24
- choice = BinData::Choice.new(params)
25
- choice.set_chooser(chooser)
26
- choice
27
- end
28
-
29
- describe BinData::Choice, "when instantiating" do
30
- it "ensures mandatory parameters are supplied" do
31
- args = {}
32
- expect { BinData::Choice.new(args) }.to raise_error(ArgumentError)
33
-
34
- args = {:selection => 1}
35
- expect { BinData::Choice.new(args) }.to raise_error(ArgumentError)
36
-
37
- args = {:choices => []}
38
- expect { BinData::Choice.new(args) }.to raise_error(ArgumentError)
39
- end
40
-
41
- it "fails when a given type is unknown" do
42
- args = {:choices => [:does_not_exist], :selection => 0}
43
- expect { BinData::Choice.new(args) }.to raise_error(BinData::UnRegisteredTypeError)
44
- end
45
-
46
- it "fails when a given type is unknown" do
47
- args = {:choices => {0 => :does_not_exist}, :selection => 0}
48
- expect { BinData::Choice.new(args) }.to raise_error(BinData::UnRegisteredTypeError)
49
- end
50
-
51
- it "fails when :choices Hash has a symbol as key" do
52
- args = {:choices => {:a => :example_single}, :selection => 0}
53
- expect { BinData::Choice.new(args) }.to raise_error(ArgumentError)
54
- end
55
-
56
- it "fails when :choices Hash has a nil key" do
57
- args = {:choices => {nil => :example_single}, :selection => 0}
58
- expect { BinData::Choice.new(args) }.to raise_error(ArgumentError)
59
- end
60
- end
61
-
62
- shared_examples "Choice initialized with array or hash" do
63
- it "can select the choice" do
64
- subject.choice = 3
65
- subject.should == 30
66
- end
67
-
68
- it "shows the current selection" do
69
- subject.choice = 3
70
- subject.selection.should == 3
71
- end
72
-
73
- it "forwards #snapshot" do
74
- subject.choice = 3
75
- subject.snapshot.should == 30
76
- end
77
-
78
- it "can change the choice" do
79
- subject.choice = 3
80
-
81
- subject.choice = 7
82
- subject.should == 70
83
- end
84
-
85
- it "fails if no choice has been set" do
86
- expect { subject.to_s }.to raise_error(IndexError)
87
- end
88
-
89
- it "will not select an invalid choice" do
90
- subject.choice = 99
91
- expect { subject.to_s }.to raise_error(IndexError)
92
- end
93
-
94
- it "will not select a nil choice" do
95
- subject.choice = 1
96
- expect { subject.to_s }.to raise_error(IndexError)
97
- end
98
-
99
- it "handles missing methods correctly" do
100
- subject.choice = 3
101
-
102
- subject.should respond_to(:value)
103
- subject.should_not respond_to(:does_not_exist)
104
- expect { subject.does_not_exist }.to raise_error(NoMethodError)
105
- end
106
-
107
- it "delegates methods to the selected single choice" do
108
- subject.choice = 5
109
- subject.num_bytes.should == ExampleSingle.new.num_bytes
110
- end
111
- end
112
-
113
- describe BinData::Choice, "with sparse choices array" do
114
- include_examples "Choice initialized with array or hash"
115
-
116
- subject {
117
- choices = [nil, nil, nil,
118
- [:example_single, {:value => 30}], nil,
119
- [:example_single, {:value => 50}], nil,
120
- [:example_single, {:value => 70}]]
121
- create_choice(choices)
122
- }
123
- end
124
-
125
- describe BinData::Choice, "with choices hash" do
126
- include_examples "Choice initialized with array or hash"
127
-
128
- subject {
129
- choices = {3 => [:example_single, {:value => 30}],
130
- 5 => [:example_single, {:value => 50}],
131
- 7 => [:example_single, {:value => 70}]}
132
- create_choice(choices)
133
- }
134
- end
135
-
136
- describe BinData::Choice, "with single values" do
137
- subject {
138
- choices = {3 => :example_single,
139
- 5 => :example_single,
140
- 7 => :example_single}
141
- create_choice(choices)
142
- }
143
-
144
- it "assigns raw values" do
145
- subject.choice = 3
146
- subject.assign(254)
147
- subject.should == 254
148
- end
149
-
150
- it "assigns Single values" do
151
- obj = ExampleSingle.new(11)
152
-
153
- subject.choice = 3
154
- subject.assign(obj)
155
- subject.should == 11
156
- end
157
-
158
- it "clears" do
159
- subject.choice = 3
160
- subject.assign(254)
161
-
162
- subject.clear
163
- subject.should be_zero
164
- end
165
-
166
- it "clears all possible choices" do
167
- subject.choice = 3
168
- subject.assign(10)
169
- subject.choice = 5
170
- subject.assign(11)
171
-
172
- subject.clear
173
-
174
- subject.choice = 3
175
- subject.should be_zero
176
- end
177
-
178
- it "is clear on initialisation" do
179
- subject.choice = 3
180
-
181
- subject.should be_clear
182
- end
183
-
184
- it "is not clear after assignment" do
185
- subject.choice = 3
186
- subject.assign(254)
187
-
188
- subject.should_not be_clear
189
- end
190
-
191
- it "does not copy value when changing selection" do
192
- subject.choice = 3
193
- subject.assign(254)
194
-
195
- subject.choice = 7
196
- subject.should_not == 254
197
- end
198
-
199
- it "behaves as value" do
200
- subject.choice = 3
201
- subject.assign(5)
202
-
203
- (subject + 1).should == 6
204
- (1 + subject).should == 6
205
- end
206
- end
207
-
208
- describe BinData::Choice, "with copy_on_change => true" do
209
- subject {
210
- choices = {3 => :example_single,
211
- 5 => :example_single,
212
- 7 => :example_single}
213
- create_choice(choices, :copy_on_change => true)
214
- }
215
-
216
- it "copies value when changing selection" do
217
- subject.choice = 3
218
- subject.assign(254)
219
-
220
- subject.choice = 7
221
- subject.should == 254
222
- end
223
- end
224
-
225
- describe BinData::Choice, "with :default" do
226
- let(:choices) { { "a" => :int8, :default => :int16be } }
227
-
228
- it "selects for existing case" do
229
- subject = BinData::Choice.new(:selection => "a", :choices => choices)
230
- subject.num_bytes.should == 1
231
- end
232
-
233
- it "selects for default case" do
234
- subject = BinData::Choice.new(:selection => "other", :choices => choices)
235
- subject.num_bytes.should == 2
236
- end
237
- end
238
-
239
- describe BinData::Choice, "subclassed with default parameters" do
240
- class DerivedChoice < BinData::Choice
241
- endian :big
242
- default_parameter :selection => 'a'
243
-
244
- uint16 'a'
245
- uint32 'b'
246
- uint64 :default
247
- end
248
-
249
- it "sets initial selection" do
250
- subject = DerivedChoice.new
251
- subject.num_bytes.should == 2
252
- end
253
-
254
- it "overides default parameter" do
255
- subject = DerivedChoice.new(:selection => 'b')
256
- subject.num_bytes.should == 4
257
- end
258
-
259
- it "selects default selection" do
260
- subject = DerivedChoice.new(:selection => 'z')
261
- subject.num_bytes.should == 8
262
- end
263
- end