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.
- data/ChangeLog.rdoc +7 -0
- data/NEWS.rdoc +11 -0
- data/Rakefile +6 -1
- data/bindata.gemspec +2 -1
- data/doc/manual.md +17 -9
- data/examples/gzip.rb +2 -2
- data/examples/list.rb +2 -2
- data/lib/bindata/alignment.rb +4 -9
- data/lib/bindata/array.rb +57 -51
- data/lib/bindata/base.rb +13 -110
- data/lib/bindata/base_primitive.rb +130 -75
- data/lib/bindata/bits.rb +5 -7
- data/lib/bindata/choice.rb +24 -32
- data/lib/bindata/dsl.rb +1 -6
- data/lib/bindata/framework.rb +81 -0
- data/lib/bindata/int.rb +5 -7
- data/lib/bindata/name.rb +28 -0
- data/lib/bindata/offset.rb +42 -53
- data/lib/bindata/params.rb +33 -38
- data/lib/bindata/struct.rb +2 -6
- data/lib/bindata/trace.rb +16 -16
- data/lib/bindata/version.rb +1 -1
- data/lib/bindata/virtual.rb +3 -3
- data/{spec/alignment_spec.rb → test/alignment_test.rb} +17 -16
- data/test/array_test.rb +371 -0
- data/test/base_primitive_test.rb +312 -0
- data/test/base_test.rb +183 -0
- data/{spec/bits_spec.rb → test/bits_test.rb} +59 -59
- data/test/choice_test.rb +260 -0
- data/{spec/spec_common.rb → test/common.rb} +33 -18
- data/test/count_bytes_remaining_test.rb +41 -0
- data/{spec/deprecated_spec.rb → test/deprecated_test.rb} +5 -7
- data/test/float_test.rb +72 -0
- data/{spec/int_spec.rb → test/int_test.rb} +34 -43
- data/{spec/io_spec.rb → test/io_test.rb} +70 -71
- data/{spec/lazy_spec.rb → test/lazy_test.rb} +38 -39
- data/test/offset_test.rb +93 -0
- data/test/params_test.rb +144 -0
- data/{spec/primitive_spec.rb → test/primitive_test.rb} +42 -54
- data/{spec/record_spec.rb → test/record_test.rb} +133 -154
- data/test/registry_test.rb +104 -0
- data/test/rest_test.rb +29 -0
- data/test/skip_test.rb +28 -0
- data/{spec/string_spec.rb → test/string_test.rb} +96 -97
- data/test/stringz_test.rb +127 -0
- data/{spec/struct_spec.rb → test/struct_test.rb} +119 -120
- data/{spec/system_spec.rb → test/system_test.rb} +66 -106
- metadata +39 -38
- data/lib/a.rb +0 -24
- data/spec/array_spec.rb +0 -331
- data/spec/base_primitive_spec.rb +0 -238
- data/spec/base_spec.rb +0 -376
- data/spec/choice_spec.rb +0 -263
- data/spec/count_bytes_remaining_spec.rb +0 -38
- data/spec/example.rb +0 -21
- data/spec/float_spec.rb +0 -37
- data/spec/registry_spec.rb +0 -108
- data/spec/rest_spec.rb +0 -26
- data/spec/skip_spec.rb +0 -27
- data/spec/stringz_spec.rb +0 -118
- 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
|