bindata 1.2.2 → 1.3.1

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.

Potentially problematic release.


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

Files changed (52) hide show
  1. data/ChangeLog +12 -0
  2. data/NEWS +53 -0
  3. data/Rakefile +2 -1
  4. data/examples/NBT.txt +149 -0
  5. data/examples/ip_address.rb +1 -2
  6. data/examples/list.rb +124 -0
  7. data/examples/nbt.rb +195 -0
  8. data/lib/bindata.rb +4 -3
  9. data/lib/bindata/alignment.rb +86 -0
  10. data/lib/bindata/array.rb +21 -29
  11. data/lib/bindata/base.rb +82 -81
  12. data/lib/bindata/base_primitive.rb +66 -48
  13. data/lib/bindata/choice.rb +18 -28
  14. data/lib/bindata/deprecated.rb +17 -0
  15. data/lib/bindata/dsl.rb +25 -15
  16. data/lib/bindata/int.rb +2 -2
  17. data/lib/bindata/io.rb +8 -6
  18. data/lib/bindata/offset.rb +91 -0
  19. data/lib/bindata/primitive.rb +22 -11
  20. data/lib/bindata/record.rb +40 -10
  21. data/lib/bindata/sanitize.rb +15 -30
  22. data/lib/bindata/string.rb +16 -17
  23. data/lib/bindata/stringz.rb +0 -1
  24. data/lib/bindata/struct.rb +17 -6
  25. data/lib/bindata/trace.rb +52 -0
  26. data/lib/bindata/wrapper.rb +28 -6
  27. data/manual.haml +56 -10
  28. data/manual.md +318 -113
  29. data/spec/alignment_spec.rb +61 -0
  30. data/spec/array_spec.rb +139 -178
  31. data/spec/base_primitive_spec.rb +86 -111
  32. data/spec/base_spec.rb +200 -172
  33. data/spec/bits_spec.rb +45 -53
  34. data/spec/choice_spec.rb +91 -87
  35. data/spec/deprecated_spec.rb +36 -14
  36. data/spec/float_spec.rb +16 -68
  37. data/spec/int_spec.rb +26 -27
  38. data/spec/io_spec.rb +105 -105
  39. data/spec/lazy_spec.rb +50 -50
  40. data/spec/primitive_spec.rb +36 -36
  41. data/spec/record_spec.rb +134 -134
  42. data/spec/registry_spec.rb +34 -38
  43. data/spec/rest_spec.rb +8 -11
  44. data/spec/skip_spec.rb +9 -17
  45. data/spec/spec_common.rb +4 -0
  46. data/spec/string_spec.rb +92 -115
  47. data/spec/stringz_spec.rb +41 -74
  48. data/spec/struct_spec.rb +132 -153
  49. data/spec/system_spec.rb +115 -60
  50. data/spec/wrapper_spec.rb +63 -31
  51. data/tasks/pkg.rake +1 -1
  52. metadata +15 -7
@@ -4,7 +4,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), "spec_common"))
4
4
  require 'bindata/lazy'
5
5
 
6
6
  # A mock data object with customizable fields.
7
- class MockDataObject
7
+ class MockBinDataObject
8
8
  def initialize(methods = {}, params = {}, parent = nil)
9
9
  meta = class << self ; self; end
10
10
  methods.each do |k,v|
@@ -28,49 +28,49 @@ end
28
28
  LE = BinData::LazyEvaluator
29
29
 
30
30
  describe BinData::LazyEvaluator, "with no parents" do
31
- before(:each) do
31
+ let(:obj) {
32
32
  methods = {:m1 => 'm1', :com => 'mC'}
33
33
  params = {:p1 => 'p1', :com => 'pC'}
34
- @obj = MockDataObject.new(methods, params)
35
- end
34
+ MockBinDataObject.new(methods, params)
35
+ }
36
36
 
37
37
  it "should evaluate raw value when instantiated" do
38
- le = LE.new(@obj)
38
+ le = LE.new(obj)
39
39
  le.lazy_eval(5).should == 5
40
40
  end
41
41
 
42
42
  it "should evaluate raw value" do
43
- LE.eval(@obj, 5).should == 5
43
+ LE.eval(obj, 5).should == 5
44
44
  end
45
45
 
46
46
  it "should evaluate value" do
47
- LE.eval(@obj, lambda { 5 }).should == 5
47
+ LE.eval(obj, lambda { 5 }).should == 5
48
48
  end
49
49
 
50
50
  it "should evaluate overrides" do
51
- LE.eval(@obj, lambda { o1 }, :o1 => 'o1').should == 'o1'
51
+ LE.eval(obj, lambda { o1 }, :o1 => 'o1').should == 'o1'
52
52
  end
53
53
 
54
54
  it "should not resolve any unknown methods" do
55
- lambda { LE.eval(@obj, lambda { unknown }) }.should raise_error(NameError)
56
- lambda { LE.eval(@obj, lambda { m1 }) }.should raise_error(NameError)
57
- lambda { LE.eval(@obj, lambda { p1 }) }.should raise_error(NameError)
55
+ lambda { LE.eval(obj, lambda { unknown }) }.should raise_error(NameError)
56
+ lambda { LE.eval(obj, lambda { m1 }) }.should raise_error(NameError)
57
+ lambda { LE.eval(obj, lambda { p1 }) }.should raise_error(NameError)
58
58
  end
59
59
 
60
60
  it "should not have a parent" do
61
- LE.eval(@obj, lambda { parent }).should be_nil
61
+ LE.eval(obj, lambda { parent }).should be_nil
62
62
  end
63
63
 
64
64
  it "should not resolve #index" do
65
- lambda { LE.eval(@obj, lambda { index }) }.should raise_error(NoMethodError)
65
+ lambda { LE.eval(obj, lambda { index }) }.should raise_error(NoMethodError)
66
66
  end
67
67
  end
68
68
 
69
69
  describe BinData::LazyEvaluator, "with one parent" do
70
- before(:each) do
70
+ let(:obj) {
71
71
  parent_methods = {:m1 => 'Pm1', :com => 'PmC', :mm => 3}
72
72
  parent_params = {:p1 => 'Pp1', :com => 'PpC'}
73
- parent_obj = MockDataObject.new(parent_methods, parent_params)
73
+ parent_obj = MockBinDataObject.new(parent_methods, parent_params)
74
74
 
75
75
  def parent_obj.echo(a1, a2)
76
76
  [a1, a2]
@@ -78,59 +78,59 @@ describe BinData::LazyEvaluator, "with one parent" do
78
78
 
79
79
  methods = {:m1 => 'm1', :com => 'mC'}
80
80
  params = {:p1 => 'p1', :com => 'pC'}
81
- @obj = MockDataObject.new(methods, params, parent_obj)
82
- end
81
+ MockBinDataObject.new(methods, params, parent_obj)
82
+ }
83
83
 
84
84
  it "should evaluate raw value" do
85
- LE.eval(@obj, 5).should == 5
85
+ LE.eval(obj, 5).should == 5
86
86
  end
87
87
 
88
88
  it "should evaluate value" do
89
- LE.eval(@obj, lambda { 5 }).should == 5
89
+ LE.eval(obj, lambda { 5 }).should == 5
90
90
  end
91
91
 
92
92
  it "should evaluate overrides before params" do
93
- LE.eval(@obj, lambda { p1 }, :p1 => 'o1').should == 'o1'
93
+ LE.eval(obj, lambda { p1 }, :p1 => 'o1').should == 'o1'
94
94
  end
95
95
 
96
96
  it "should evaluate overrides before methods" do
97
- LE.eval(@obj, lambda { m1 }, :m1 => 'o1').should == 'o1'
97
+ LE.eval(obj, lambda { m1 }, :m1 => 'o1').should == 'o1'
98
98
  end
99
99
 
100
100
  it "should not resolve any unknown methods" do
101
- lambda { LE.eval(@obj, lambda { unknown }) }.should raise_error(NameError)
101
+ lambda { LE.eval(obj, lambda { unknown }) }.should raise_error(NameError)
102
102
  end
103
103
 
104
104
  it "should resolve parameters in the parent" do
105
- LE.eval(@obj, lambda { p1 }).should == 'Pp1'
105
+ LE.eval(obj, lambda { p1 }).should == 'Pp1'
106
106
  end
107
107
 
108
108
  it "should resolve methods in the parent" do
109
- LE.eval(@obj, lambda { m1 }).should == 'Pm1'
109
+ LE.eval(obj, lambda { m1 }).should == 'Pm1'
110
110
  end
111
111
 
112
112
  it "should invoke methods in the parent" do
113
- LE.eval(@obj, lambda { echo(p1, m1) }).should == ['Pp1', 'Pm1']
113
+ LE.eval(obj, lambda { echo(p1, m1) }).should == ['Pp1', 'Pm1']
114
114
  end
115
115
 
116
116
  it "should resolve parameters in preference to methods in the parent" do
117
- LE.eval(@obj, lambda { com }).should == 'PpC'
117
+ LE.eval(obj, lambda { com }).should == 'PpC'
118
118
  end
119
119
 
120
120
  it "should have a parent" do
121
- LE.eval(@obj, lambda { parent }).should_not be_nil
121
+ LE.eval(obj, lambda { parent }).should_not be_nil
122
122
  end
123
123
 
124
124
  it "should not resolve #index" do
125
- lambda { LE.eval(@obj, lambda { index }) }.should raise_error(NoMethodError)
125
+ lambda { LE.eval(obj, lambda { index }) }.should raise_error(NoMethodError)
126
126
  end
127
127
  end
128
128
 
129
129
  describe BinData::LazyEvaluator, "with nested parents" do
130
- before(:each) do
130
+ let(:obj) {
131
131
  pparent_methods = {:m1 => 'PPm1', :m2 => 'PPm2', :com => 'PPmC'}
132
132
  pparent_params = {:p1 => 'PPp1', :p2 => 'PPp2', :com => 'PPpC'}
133
- pparent_obj = MockDataObject.new(pparent_methods, pparent_params)
133
+ pparent_obj = MockBinDataObject.new(pparent_methods, pparent_params)
134
134
 
135
135
  def pparent_obj.echo(arg)
136
136
  ["PP", arg]
@@ -142,7 +142,7 @@ describe BinData::LazyEvaluator, "with nested parents" do
142
142
 
143
143
  parent_methods = {:m1 => 'Pm1', :com => 'PmC', :sym1 => :m2, :sym2 => lambda { m2 }}
144
144
  parent_params = {:p1 => 'Pp1', :com => 'PpC'}
145
- parent_obj = MockDataObject.new(parent_methods, parent_params, pparent_obj)
145
+ parent_obj = MockBinDataObject.new(parent_methods, parent_params, pparent_obj)
146
146
 
147
147
  def parent_obj.echo(arg)
148
148
  ["P", arg]
@@ -150,62 +150,62 @@ describe BinData::LazyEvaluator, "with nested parents" do
150
150
 
151
151
  methods = {:m1 => 'm1', :com => 'mC'}
152
152
  params = {:p1 => 'p1', :com => 'pC'}
153
- @obj = MockDataObject.new(methods, params, parent_obj)
154
- end
153
+ MockBinDataObject.new(methods, params, parent_obj)
154
+ }
155
155
 
156
156
  it "should accept symbols as a shortcut to lambdas" do
157
- LE.eval(@obj, :p1).should == 'Pp1'
158
- LE.eval(@obj, :p2).should == 'PPp2'
159
- LE.eval(@obj, :m1).should == 'Pm1'
160
- LE.eval(@obj, :m2).should == 'PPm2'
157
+ LE.eval(obj, :p1).should == 'Pp1'
158
+ LE.eval(obj, :p2).should == 'PPp2'
159
+ LE.eval(obj, :m1).should == 'Pm1'
160
+ LE.eval(obj, :m2).should == 'PPm2'
161
161
  end
162
162
 
163
163
  it "should not resolve any unknown methods" do
164
- lambda { LE.eval(@obj, lambda { unknown }) }.should raise_error(NameError)
164
+ lambda { LE.eval(obj, lambda { unknown }) }.should raise_error(NameError)
165
165
  end
166
166
 
167
167
  it "should resolve parameters in the parent" do
168
- LE.eval(@obj, lambda { p1 }).should == 'Pp1'
168
+ LE.eval(obj, lambda { p1 }).should == 'Pp1'
169
169
  end
170
170
 
171
171
  it "should resolve methods in the parent" do
172
- LE.eval(@obj, lambda { m1 }).should == 'Pm1'
172
+ LE.eval(obj, lambda { m1 }).should == 'Pm1'
173
173
  end
174
174
 
175
175
  it "should resolve parameters in the parent's parent" do
176
- LE.eval(@obj, lambda { p2 }).should == 'PPp2'
176
+ LE.eval(obj, lambda { p2 }).should == 'PPp2'
177
177
  end
178
178
 
179
179
  it "should resolve methods in the parent's parent" do
180
- LE.eval(@obj, lambda { m2 }).should == 'PPm2'
180
+ LE.eval(obj, lambda { m2 }).should == 'PPm2'
181
181
  end
182
182
 
183
183
  it "should invoke methods in the parent" do
184
- LE.eval(@obj, lambda { echo(m1) }).should == ['P', 'Pm1']
184
+ LE.eval(obj, lambda { echo(m1) }).should == ['P', 'Pm1']
185
185
  end
186
186
 
187
187
  it "should invoke methods in the parent's parent" do
188
- LE.eval(@obj, lambda { parent.echo(m1) }, { :m1 => 'o1'}).should == ['PP', 'o1']
188
+ LE.eval(obj, lambda { parent.echo(m1) }, { :m1 => 'o1'}).should == ['PP', 'o1']
189
189
  end
190
190
 
191
191
  it "should invoke methods in the parent's parent" do
192
- LE.eval(@obj, lambda { echo2(m1) }).should == ['PP2', 'Pm1']
192
+ LE.eval(obj, lambda { echo2(m1) }).should == ['PP2', 'Pm1']
193
193
  end
194
194
 
195
195
  it "should resolve parameters in preference to methods in the parent" do
196
- LE.eval(@obj, lambda { com }).should == 'PpC'
196
+ LE.eval(obj, lambda { com }).should == 'PpC'
197
197
  end
198
198
 
199
199
  it "should resolve methods in the parent explicitly" do
200
- LE.eval(@obj, lambda { parent.m1 }).should == 'PPm1'
200
+ LE.eval(obj, lambda { parent.m1 }).should == 'PPm1'
201
201
  end
202
202
 
203
203
  it "should cascade lambdas " do
204
- LE.eval(@obj, lambda { sym1 }).should == 'PPm2'
205
- LE.eval(@obj, lambda { sym2 }).should == 'PPm2'
204
+ LE.eval(obj, lambda { sym1 }).should == 'PPm2'
205
+ LE.eval(obj, lambda { sym2 }).should == 'PPm2'
206
206
  end
207
207
 
208
208
  it "should not resolve #index" do
209
- lambda { LE.eval(@obj, lambda { index }) }.should raise_error(NoMethodError)
209
+ lambda { LE.eval(obj, lambda { index }) }.should raise_error(NoMethodError)
210
210
  end
211
211
  end
@@ -3,18 +3,16 @@
3
3
  require File.expand_path(File.join(File.dirname(__FILE__), "spec_common"))
4
4
  require 'bindata'
5
5
 
6
- describe BinData::Primitive, "when subclassing" do
6
+ describe BinData::Primitive, "all subclasses" do
7
7
  class SubClassOfPrimitive < BinData::Primitive
8
8
  expose_methods_for_testing
9
9
  end
10
10
 
11
- before(:each) do
12
- @obj = SubClassOfPrimitive.new
13
- end
11
+ subject { SubClassOfPrimitive.new }
14
12
 
15
13
  it "should raise errors on unimplemented methods" do
16
- lambda { @obj.set(nil) }.should raise_error(NotImplementedError)
17
- lambda { @obj.get }.should raise_error(NotImplementedError)
14
+ lambda { subject.set(nil) }.should raise_error(NotImplementedError)
15
+ lambda { subject.get }.should raise_error(NotImplementedError)
18
16
  end
19
17
  end
20
18
 
@@ -70,47 +68,50 @@ describe BinData::Primitive do
70
68
  def set(v); self.a = v; end
71
69
  end
72
70
 
73
- before(:each) do
74
- @obj = PrimitiveWithEndian.new
75
- end
71
+ subject { PrimitiveWithEndian.new }
76
72
 
77
- it "should support endian" do
78
- @obj.value = 5
79
- @obj.to_binary_s.should == "\x05\x00"
73
+ it "should assign value" do
74
+ subject.value = 5
75
+ subject.value.should == 5
80
76
  end
81
77
 
82
- it "should set value" do
83
- @obj.value = 5
84
- @obj.to_binary_s.should == "\x05\x00"
78
+ it "should produce binary string" do
79
+ subject.assign(5)
80
+ subject.to_binary_s.should == "\x05\x00"
85
81
  end
86
82
 
87
83
  it "should read value" do
88
- @obj.read("\x00\x01")
89
- @obj.value.should == 0x100
84
+ subject.read("\x00\x01")
85
+ subject.should == 0x100
90
86
  end
91
87
 
92
88
  it "should accept standard parameters" do
93
- obj = PrimitiveWithEndian.new(:initial_value => 2)
94
- obj.to_binary_s.should == "\x02\x00"
89
+ subject = PrimitiveWithEndian.new(:initial_value => 2)
90
+ subject.to_binary_s.should == "\x02\x00"
95
91
  end
96
92
 
97
93
  it "should return num_bytes" do
98
- @obj.num_bytes.should == 2
94
+ subject.num_bytes.should == 2
99
95
  end
100
96
 
101
97
  it "should raise error on missing methods" do
102
98
  lambda {
103
- @obj.does_not_exist
99
+ subject.does_not_exist
104
100
  }.should raise_error(NoMethodError)
105
101
  end
106
102
 
107
103
  it "should use read value whilst reading" do
108
- obj = PrimitiveWithEndian.new(:value => 2)
109
- obj.read "\x05\x00"
110
- obj.value.should == 2
104
+ subject = PrimitiveWithEndian.new(:value => 2)
105
+ subject.read "\x05\x00"
106
+ subject.should == 2
107
+
108
+ subject.stub(:reading?).and_return(true)
109
+ subject.should == 5
110
+ end
111
111
 
112
- def obj.reading?; true; end
113
- obj.value.should == 5
112
+ it "should behave as primitive" do
113
+ subject.assign(5)
114
+ (2 + subject).should == 7
114
115
  end
115
116
  end
116
117
 
@@ -122,8 +123,8 @@ describe BinData::Primitive, "requiring custom parameters" do
122
123
  end
123
124
 
124
125
  it "should pass parameters correctly" do
125
- obj = PrimitiveWithCustom.new(:iv => 5)
126
- obj.value.should == 5
126
+ subject = PrimitiveWithCustom.new(:iv => 5)
127
+ subject.should == 5
127
128
  end
128
129
  end
129
130
 
@@ -141,8 +142,8 @@ describe BinData::Primitive, "with custom mandatory parameters" do
141
142
  end
142
143
 
143
144
  it "should use mandatory parameter" do
144
- obj = MandatoryPrimitive.new(:arg1 => 5)
145
- obj.value.should == 5
145
+ subject = MandatoryPrimitive.new(:arg1 => 5)
146
+ subject.should == 5
146
147
  end
147
148
  end
148
149
 
@@ -160,13 +161,13 @@ describe BinData::Primitive, "with custom default parameters" do
160
161
  end
161
162
 
162
163
  it "should use default parameter" do
163
- obj = DefaultPrimitive.new
164
- obj.value.should == 5
164
+ subject = DefaultPrimitive.new
165
+ subject.should == 5
165
166
  end
166
167
 
167
168
  it "should be able to override default parameter" do
168
- obj = DefaultPrimitive.new(:arg1 => 7)
169
- obj.value.should == 7
169
+ subject = DefaultPrimitive.new(:arg1 => 7)
170
+ subject.should == 7
170
171
  end
171
172
  end
172
173
 
@@ -181,8 +182,7 @@ describe BinData::Primitive, "derived classes" do
181
182
  end
182
183
 
183
184
  it "should derive" do
184
- a = ChildDerivedPrimitive.new
185
- a.value = 7
185
+ a = ChildDerivedPrimitive.new(7)
186
186
  a.to_binary_s.should == "\000\007"
187
187
  end
188
188
  end
@@ -53,7 +53,7 @@ describe BinData::Record, "when defining with errors" do
53
53
  lambda {
54
54
  class MalformedNameRecord < BinData::Record
55
55
  int8 :a
56
- int8 45
56
+ int8 "45"
57
57
  end
58
58
  }.should raise_error_on_line(NameError, 3) { |err|
59
59
  err.message.should == "field '45' is an illegal fieldname in #{MalformedNameRecord}"
@@ -108,59 +108,56 @@ describe BinData::Record, "with anonymous fields" do
108
108
  class AnonymousRecord < BinData::Record
109
109
  int8 'a', :initial_value => 10
110
110
  int8 ''
111
+ int8 nil
111
112
  int8
112
113
  int8 :value => :a
113
114
  end
114
115
 
115
- before(:each) do
116
- @obj = AnonymousRecord.new
117
- end
116
+ subject { AnonymousRecord.new }
118
117
 
119
118
  it "should only show non anonymous fields" do
120
- @obj.field_names.should == ["a"]
119
+ subject.field_names.should == ["a"]
121
120
  end
122
121
 
123
122
  it "should not include anonymous fields in snapshot" do
124
- @obj.a = 5
125
- @obj.snapshot.should == {"a" => 5}
123
+ subject.a = 5
124
+ subject.snapshot.should == {"a" => 5}
126
125
  end
127
126
 
128
127
  it "should write anonymous fields" do
129
- str = "\001\002\003\004"
130
- @obj.read(str)
131
- @obj.a.clear
132
- @obj.to_binary_s.should == "\012\002\003\012"
128
+ str = "\001\002\003\004\005"
129
+ subject.read(str)
130
+ subject.a.clear
131
+ subject.to_binary_s.should == "\012\002\003\004\012"
133
132
  end
134
133
  end
135
134
 
136
135
  describe BinData::Record, "with hidden fields" do
137
136
  class HiddenRecord < BinData::Record
138
- hide :b, 'c'
137
+ hide :b, :c
139
138
  int8 :a
140
139
  int8 'b', :initial_value => 10
141
140
  int8 :c
142
141
  int8 :d, :value => :b
143
142
  end
144
143
 
145
- before(:each) do
146
- @obj = HiddenRecord.new
147
- end
144
+ subject { HiddenRecord.new }
148
145
 
149
146
  it "should only show fields that aren't hidden" do
150
- @obj.field_names.should == ["a", "d"]
147
+ subject.field_names.should == ["a", "d"]
151
148
  end
152
149
 
153
150
  it "should be able to access hidden fields directly" do
154
- @obj.b.should == 10
155
- @obj.c = 15
156
- @obj.c.should == 15
151
+ subject.b.should == 10
152
+ subject.c = 15
153
+ subject.c.should == 15
157
154
 
158
- @obj.should respond_to(:b=)
155
+ subject.should respond_to(:b=)
159
156
  end
160
157
 
161
158
  it "should not include hidden fields in snapshot" do
162
- @obj.b = 5
163
- @obj.snapshot.should == {"a" => 0, "d" => 5}
159
+ subject.b = 5
160
+ subject.snapshot.should == {"a" => 0, "d" => 5}
164
161
  end
165
162
  end
166
163
 
@@ -170,16 +167,12 @@ describe BinData::Record, "with multiple fields" do
170
167
  int8 :b
171
168
  end
172
169
 
173
- before(:each) do
174
- @obj = MultiFieldRecord.new
175
- @obj.a = 1
176
- @obj.b = 2
177
- end
170
+ subject { MultiFieldRecord.new(:a => 1, :b => 2) }
178
171
 
179
172
  it "should return num_bytes" do
180
- @obj.a.num_bytes.should == 1
181
- @obj.b.num_bytes.should == 1
182
- @obj.num_bytes.should == 2
173
+ subject.a.num_bytes.should == 1
174
+ subject.b.num_bytes.should == 1
175
+ subject.num_bytes.should == 2
183
176
  end
184
177
 
185
178
  it "should identify accepted parameters" do
@@ -188,43 +181,43 @@ describe BinData::Record, "with multiple fields" do
188
181
  end
189
182
 
190
183
  it "should clear" do
191
- @obj.a = 6
192
- @obj.clear
193
- @obj.should be_clear
184
+ subject.a = 6
185
+ subject.clear
186
+ subject.should be_clear
194
187
  end
195
188
 
196
189
  it "should clear individual elements" do
197
- @obj.a = 6
198
- @obj.b = 7
199
- @obj.a.clear
200
- @obj.a.should be_clear
201
- @obj.b.should_not be_clear
190
+ subject.a = 6
191
+ subject.b = 7
192
+ subject.a.clear
193
+ subject.a.should be_clear
194
+ subject.b.should_not be_clear
202
195
  end
203
196
 
204
197
  it "should write ordered" do
205
- @obj.to_binary_s.should == "\x01\x02"
198
+ subject.to_binary_s.should == "\x01\x02"
206
199
  end
207
200
 
208
201
  it "should read ordered" do
209
- @obj.read("\x03\x04")
202
+ subject.read("\x03\x04")
210
203
 
211
- @obj.a.should == 3
212
- @obj.b.should == 4
204
+ subject.a.should == 3
205
+ subject.b.should == 4
213
206
  end
214
207
 
215
208
  it "should return a snapshot" do
216
- snap = @obj.snapshot
209
+ snap = subject.snapshot
217
210
  snap.a.should == 1
218
211
  snap.b.should == 2
219
212
  snap.should == { "a" => 1, "b" => 2 }
220
213
  end
221
214
 
222
215
  it "should return field_names" do
223
- @obj.field_names.should == ["a", "b"]
216
+ subject.field_names.should == ["a", "b"]
224
217
  end
225
218
 
226
219
  it "should fail on unknown method call" do
227
- lambda { @obj.does_not_exist }.should raise_error(NoMethodError)
220
+ lambda { subject.does_not_exist }.should raise_error(NoMethodError)
228
221
  end
229
222
  end
230
223
 
@@ -242,39 +235,45 @@ describe BinData::Record, "with nested structs" do
242
235
  end
243
236
  end
244
237
 
245
- before(:each) do
246
- @obj = NestedStructRecord.new
247
- end
238
+ subject { NestedStructRecord.new }
248
239
 
249
240
  it "should included nested field names" do
250
- @obj.field_names.should == ["a", "b", "c"]
241
+ subject.field_names.should == ["a", "b", "c"]
251
242
  end
252
243
 
253
244
  it "should hide nested field names" do
254
- @obj.b.field_names.should == ["x"]
245
+ subject.b.field_names.should == ["x"]
255
246
  end
256
247
 
257
248
  it "should access nested fields" do
258
- @obj.a.should == 6
259
- @obj.b.w.should == 3
260
- @obj.b.x.should == 6
261
- @obj.c.y.should == 3
249
+ subject.a.should == 6
250
+ subject.b.w.should == 3
251
+ subject.b.x.should == 6
252
+ subject.c.y.should == 3
262
253
  end
263
254
 
264
255
  it "should return correct offset" do
265
- @obj.offset.should == 0
266
- @obj.b.offset.should == 1
267
- @obj.b.w.offset.should == 1
268
- @obj.c.offset.should == 3
269
- @obj.c.z.offset.should == 4
256
+ subject.offset.should == 0
257
+ subject.b.offset.should == 1
258
+ subject.b.w.offset.should == 1
259
+ subject.c.offset.should == 3
260
+ subject.c.z.offset.should == 4
270
261
  end
271
262
 
272
263
  it "should return correct rel_offset" do
273
- @obj.rel_offset.should == 0
274
- @obj.b.rel_offset.should == 1
275
- @obj.b.w.rel_offset.should == 0
276
- @obj.c.rel_offset.should == 3
277
- @obj.c.z.rel_offset.should == 1
264
+ subject.rel_offset.should == 0
265
+ subject.b.rel_offset.should == 1
266
+ subject.b.w.rel_offset.should == 0
267
+ subject.c.rel_offset.should == 3
268
+ subject.c.z.rel_offset.should == 1
269
+ end
270
+
271
+ it "should assign nested fields" do
272
+ subject.assign(:a => 2, :b => {:w => 4})
273
+ subject.a.should == 2
274
+ subject.b.w.should == 4
275
+ subject.b.x.should == 2
276
+ subject.c.y.should == 4
278
277
  end
279
278
  end
280
279
 
@@ -285,12 +284,10 @@ describe BinData::Record, "with nested array of primitives" do
285
284
  end
286
285
  end
287
286
 
288
- before(:each) do
289
- @obj = NestedPrimitiveArrayRecord.new
290
- end
287
+ subject { NestedPrimitiveArrayRecord.new }
291
288
 
292
289
  it "should use block as :type" do
293
- @obj.snapshot.should == {"a" => [0, 1, 2]}
290
+ subject.snapshot.should == {"a" => [0, 1, 2]}
294
291
  end
295
292
  end
296
293
 
@@ -302,31 +299,38 @@ describe BinData::Record, "with nested array of structs" do
302
299
  end
303
300
  end
304
301
 
305
- before(:each) do
306
- @obj = NestedStructArrayRecord.new
307
- end
302
+ subject { NestedStructArrayRecord.new }
308
303
 
309
304
  it "should use block as struct for :type" do
310
- @obj.a[0].b = 2
311
- @obj.snapshot.should == {"a" => [{"b" => 2, "c" => 0}]}
305
+ subject.a[0].b = 2
306
+ subject.snapshot.should == {"a" => [{"b" => 2, "c" => 0}]}
312
307
  end
313
308
  end
314
309
 
315
- describe BinData::Record, "with nested choice without names" do
316
- class NestedChoiceRecord < BinData::Record
310
+ describe BinData::Record, "with nested choice with implied keys" do
311
+ class NestedChoiceWithImpliedKeysRecord < BinData::Record
317
312
  choice :a, :selection => 1 do
318
313
  uint8 :value => 1
319
314
  uint8 :value => 2
320
315
  end
321
316
  end
322
317
 
323
- before(:each) do
324
- @obj = NestedChoiceRecord.new
325
- end
318
+ subject { NestedChoiceWithImpliedKeysRecord.new }
319
+
320
+ its(:a) { should == 2 }
321
+ end
326
322
 
327
- it "should select choices by index" do
328
- @obj.a.should == 2
323
+ describe BinData::Record, "with nested choice with explicit keys" do
324
+ class NestedChoiceWithKeysRecord < BinData::Record
325
+ choice :a, :selection => 5 do
326
+ uint8 3, :value => 1
327
+ uint8 5, :value => 2
328
+ end
329
329
  end
330
+
331
+ subject { NestedChoiceWithKeysRecord.new }
332
+
333
+ its(:a) { should == 2 }
330
334
  end
331
335
 
332
336
  describe BinData::Record, "with nested choice with names" do
@@ -337,13 +341,9 @@ describe BinData::Record, "with nested choice with names" do
337
341
  end
338
342
  end
339
343
 
340
- before(:each) do
341
- @obj = NestedChoiceWithNamesRecord.new
342
- end
344
+ subject { NestedChoiceWithNamesRecord.new }
343
345
 
344
- it "should select choices by name" do
345
- @obj.a.should == 1
346
- end
346
+ its(:a) { should == 1 }
347
347
  end
348
348
 
349
349
  describe BinData::Record, "with an endian defined" do
@@ -371,23 +371,21 @@ describe BinData::Record, "with an endian defined" do
371
371
  end
372
372
  end
373
373
 
374
- before(:each) do
375
- @obj = RecordWithEndian.new
376
- end
374
+ subject { RecordWithEndian.new }
377
375
 
378
376
  it "should use correct endian" do
379
- @obj.a = 1
380
- @obj.b = 2.0
381
- @obj.c[0] = 3
382
- @obj.c[1] = 4
383
- @obj.d = 5
384
- @obj.e.f = 6
385
- @obj.e.g = 7
386
- @obj.h.i.j = 8
377
+ subject.a = 1
378
+ subject.b = 2.0
379
+ subject.c[0] = 3
380
+ subject.c[1] = 4
381
+ subject.d = 5
382
+ subject.e.f = 6
383
+ subject.e.g = 7
384
+ subject.h.i.j = 8
387
385
 
388
386
  expected = [1, 2.0, 3, 4, 5, 6, 7, 8].pack('veCCVvNn')
389
387
 
390
- @obj.to_binary_s.should == expected
388
+ subject.to_binary_s.should == expected
391
389
  end
392
390
  end
393
391
 
@@ -400,30 +398,30 @@ describe BinData::Record, "defined recursively" do
400
398
  end
401
399
 
402
400
  it "should be able to be created" do
403
- obj = RecursiveRecord.new
401
+ subject = RecursiveRecord.new
404
402
  end
405
403
 
406
404
  it "should read" do
407
405
  str = "\x00\x01\x01\x00\x02\x01\x00\x03\x00"
408
- obj = RecursiveRecord.read(str)
409
- obj.val.should == 1
410
- obj.nxt.val.should == 2
411
- obj.nxt.nxt.val.should == 3
406
+ subject = RecursiveRecord.read(str)
407
+ subject.val.should == 1
408
+ subject.nxt.val.should == 2
409
+ subject.nxt.nxt.val.should == 3
412
410
  end
413
411
 
414
412
  it "should be assignable on demand" do
415
- obj = RecursiveRecord.new
416
- obj.val = 13
417
- obj.nxt.val = 14
418
- obj.nxt.nxt.val = 15
413
+ subject = RecursiveRecord.new
414
+ subject.val = 13
415
+ subject.nxt.val = 14
416
+ subject.nxt.nxt.val = 15
419
417
  end
420
418
 
421
419
  it "should write" do
422
- obj = RecursiveRecord.new
423
- obj.val = 5
424
- obj.nxt.val = 6
425
- obj.nxt.nxt.val = 7
426
- obj.to_binary_s.should == "\x00\x05\x01\x00\x06\x01\x00\x07\x00"
420
+ subject = RecursiveRecord.new
421
+ subject.val = 5
422
+ subject.nxt.val = 6
423
+ subject.nxt.nxt.val = 7
424
+ subject.to_binary_s.should == "\x00\x05\x01\x00\x06\x01\x00\x07\x00"
427
425
  end
428
426
  end
429
427
 
@@ -439,8 +437,8 @@ describe BinData::Record, "with custom mandatory parameters" do
439
437
  end
440
438
 
441
439
  it "should use mandatory parameter" do
442
- obj = MandatoryRecord.new(:arg1 => 5)
443
- obj.a.should == 5
440
+ subject = MandatoryRecord.new(:arg1 => 5)
441
+ subject.a.should == 5
444
442
  end
445
443
  end
446
444
 
@@ -449,6 +447,7 @@ describe BinData::Record, "with custom default parameters" do
449
447
  default_parameter :arg1 => 5
450
448
 
451
449
  uint8 :a, :value => :arg1
450
+ uint8 :b
452
451
  end
453
452
 
454
453
  it "should not raise error if default parameter is not supplied" do
@@ -456,13 +455,24 @@ describe BinData::Record, "with custom default parameters" do
456
455
  end
457
456
 
458
457
  it "should use default parameter" do
459
- obj = DefaultRecord.new
460
- obj.a.should == 5
458
+ subject = DefaultRecord.new
459
+ subject.a.should == 5
461
460
  end
462
461
 
463
462
  it "should be able to override default parameter" do
464
- obj = DefaultRecord.new(:arg1 => 7)
465
- obj.a.should == 7
463
+ subject = DefaultRecord.new(:arg1 => 7)
464
+ subject.a.should == 7
465
+ end
466
+
467
+ it "should accept values" do
468
+ subject = DefaultRecord.new(:b => 2)
469
+ subject.b.should == 2
470
+ end
471
+
472
+ it "should accept values and parameters" do
473
+ subject = DefaultRecord.new({:b => 2}, :arg1 => 3)
474
+ subject.a.should == 3
475
+ subject.b.should == 2
466
476
  end
467
477
  end
468
478
 
@@ -473,25 +483,15 @@ describe BinData::Record, "with :onlyif" do
473
483
  uint8 :c, :initial_value => 7, :onlyif => lambda { a != 3 }
474
484
  end
475
485
 
476
- before(:each) do
477
- @obj = OnlyIfRecord.new
478
- end
486
+ subject { OnlyIfRecord.new }
479
487
 
480
- it "should have correct num_bytes" do
481
- @obj.num_bytes.should == 2
482
- end
483
-
484
- it "should have expected snapshot" do
485
- @obj.snapshot.should == {"a" => 3, "b" => 5}
486
- end
488
+ its(:num_bytes) { should == 2 }
489
+ its(:snapshot) { should == {"a" => 3, "b" => 5} }
490
+ its(:to_binary_s) { should == "\x03\x05" }
487
491
 
488
492
  it "should read as expected" do
489
- @obj.read("\x01\x02")
490
- @obj.snapshot.should == {"a" => 1, "c" => 2}
491
- end
492
-
493
- it "should write as expected" do
494
- @obj.to_binary_s.should == "\x03\x05"
493
+ subject.read("\x01\x02")
494
+ subject.snapshot.should == {"a" => 1, "c" => 2}
495
495
  end
496
496
  end
497
497