bindata 0.6.0 → 0.7.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 +7 -0
- data/README +4 -0
- data/TODO +0 -5
- data/lib/bindata.rb +1 -1
- data/lib/bindata/array.rb +96 -11
- data/lib/bindata/base.rb +16 -13
- data/lib/bindata/lazy.rb +32 -28
- data/lib/bindata/single.rb +9 -6
- data/lib/bindata/struct.rb +1 -2
- data/spec/array_spec.rb +124 -25
- data/spec/base_spec.rb +34 -34
- data/spec/choice_spec.rb +11 -11
- data/spec/float_spec.rb +16 -16
- data/spec/int_spec.rb +6 -6
- data/spec/lazy_spec.rb +58 -54
- data/spec/registry_spec.rb +9 -9
- data/spec/single_spec.rb +41 -41
- data/spec/spec_common.rb +1 -1
- data/spec/string_spec.rb +41 -41
- data/spec/stringz_spec.rb +32 -32
- data/spec/struct_spec.rb +33 -33
- metadata +2 -2
data/spec/registry_spec.rb
CHANGED
@@ -3,16 +3,16 @@
|
|
3
3
|
require File.expand_path(File.dirname(__FILE__)) + '/spec_common'
|
4
4
|
require 'bindata/registry'
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
describe "The Registry" do
|
7
|
+
before(:each) do
|
8
8
|
@r = BinData::Registry.instance
|
9
9
|
end
|
10
10
|
|
11
|
-
|
11
|
+
it "should be a singleton" do
|
12
12
|
BinData::Registry.instance.should equal(BinData::Registry.instance)
|
13
13
|
end
|
14
14
|
|
15
|
-
|
15
|
+
it "should lookup registered names" do
|
16
16
|
A = Class.new
|
17
17
|
B = Class.new
|
18
18
|
@r.register('ASubClass', A)
|
@@ -22,23 +22,23 @@ context "The Registry" do
|
|
22
22
|
@r.lookup('another_sub_class').should eql(B)
|
23
23
|
end
|
24
24
|
|
25
|
-
|
25
|
+
it "should not lookup unregistered names" do
|
26
26
|
@r.lookup('a_non_existent_sub_class').should be_nil
|
27
27
|
end
|
28
28
|
|
29
|
-
|
29
|
+
it "should convert CamelCase to underscores" do
|
30
30
|
@r.register('CamelCase', A).should eql('camel_case')
|
31
31
|
end
|
32
32
|
|
33
|
-
|
33
|
+
it "should convert adjacent caps camelCase to underscores" do
|
34
34
|
@r.register('XYZCamelCase', A).should eql('xyz_camel_case')
|
35
35
|
end
|
36
36
|
|
37
|
-
|
37
|
+
it "should ignore the outer nestings of classes" do
|
38
38
|
@r.register('A::B::C', A).should eql('c')
|
39
39
|
end
|
40
40
|
|
41
|
-
|
41
|
+
it "should allow overriding of registered classes" do
|
42
42
|
@r.register('A', A)
|
43
43
|
@r.register('A', B)
|
44
44
|
|
data/spec/single_spec.rb
CHANGED
@@ -12,8 +12,8 @@ class ConcreteSingle < BinData::Single
|
|
12
12
|
def in_read?() @in_read end
|
13
13
|
end
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
describe "The sample implementation of Single" do
|
16
|
+
it "should have symmetric IO" do
|
17
17
|
io = StringIO.new
|
18
18
|
data = ConcreteSingle.new
|
19
19
|
data.value = 42
|
@@ -26,26 +26,26 @@ context "The sample implementation of Single" do
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
|
30
|
-
|
29
|
+
describe "The class Single" do
|
30
|
+
it "should register subclasses" do
|
31
31
|
BinData::Single.lookup(:concrete_single).should eql(ConcreteSingle)
|
32
32
|
end
|
33
33
|
|
34
|
-
|
34
|
+
it "should read and return a value" do
|
35
35
|
io = StringIO.new([123456].pack("V"))
|
36
36
|
ConcreteSingle.read(io).should eql(123456)
|
37
37
|
data = ConcreteSingle.new
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
|
42
|
-
|
41
|
+
describe "A Single object" do
|
42
|
+
it "should conform to rule 1 for returning a value" do
|
43
43
|
data = ConcreteSingle.new(:value => 5)
|
44
44
|
data.should_not be_in_read
|
45
45
|
data.value.should eql(5)
|
46
46
|
end
|
47
47
|
|
48
|
-
|
48
|
+
it "should conform to rule 2 for returning a value" do
|
49
49
|
io = StringIO.new([42].pack("V"))
|
50
50
|
data = ConcreteSingle.new(:value => 5)
|
51
51
|
data.do_read(io)
|
@@ -53,26 +53,26 @@ context "A Single object" do
|
|
53
53
|
data.value.should eql(42)
|
54
54
|
end
|
55
55
|
|
56
|
-
|
56
|
+
it "should conform to rule 3 for returning a value" do
|
57
57
|
data = ConcreteSingle.new(:initial_value => 5)
|
58
58
|
data.should be_clear
|
59
59
|
data.value.should eql(5)
|
60
60
|
end
|
61
61
|
|
62
|
-
|
62
|
+
it "should conform to rule 4 for returning a value" do
|
63
63
|
data = ConcreteSingle.new(:initial_value => 5)
|
64
64
|
data.value = 17
|
65
65
|
data.should_not be_clear
|
66
66
|
data.value.should eql(17)
|
67
67
|
end
|
68
68
|
|
69
|
-
|
69
|
+
it "should conform to rule 5 for returning a value" do
|
70
70
|
data = ConcreteSingle.new
|
71
71
|
data.should be_clear
|
72
72
|
data.value.should eql(0)
|
73
73
|
end
|
74
74
|
|
75
|
-
|
75
|
+
it "should conform to rule 6 for returning a value" do
|
76
76
|
data = ConcreteSingle.new
|
77
77
|
data.value = 8
|
78
78
|
data.should_not be_clear
|
@@ -80,130 +80,130 @@ context "A Single object" do
|
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
|
-
|
84
|
-
|
83
|
+
describe "A new Single object" do
|
84
|
+
before(:each) do
|
85
85
|
@data = ConcreteSingle.new
|
86
86
|
end
|
87
87
|
|
88
|
-
|
88
|
+
it "should not allow both :initial_value and :value" do
|
89
89
|
params = {:initial_value => 1, :value => 2}
|
90
90
|
lambda { ConcreteSingle.new(params) }.should raise_error(ArgumentError)
|
91
91
|
end
|
92
92
|
|
93
|
-
|
93
|
+
it "should have a sensible value" do
|
94
94
|
@data.value.should eql(0)
|
95
95
|
end
|
96
96
|
|
97
|
-
|
97
|
+
it "should allowing setting and retrieving value" do
|
98
98
|
@data.value = 5
|
99
99
|
@data.value.should eql(5)
|
100
100
|
end
|
101
101
|
|
102
|
-
|
102
|
+
it "should be clear" do
|
103
103
|
@data.should be_clear
|
104
104
|
end
|
105
105
|
|
106
|
-
|
106
|
+
it "should not be clear after setting value" do
|
107
107
|
@data.value = 5
|
108
108
|
@data.should_not be_clear
|
109
109
|
end
|
110
110
|
|
111
|
-
|
111
|
+
it "should not be clear after reading" do
|
112
112
|
io = StringIO.new([123456].pack("V"))
|
113
113
|
@data.read(io)
|
114
114
|
@data.should_not be_clear
|
115
115
|
end
|
116
116
|
|
117
|
-
|
117
|
+
it "should return num_bytes" do
|
118
118
|
@data.num_bytes.should eql(4)
|
119
119
|
end
|
120
120
|
|
121
|
-
|
121
|
+
it "should not contain any field names" do
|
122
122
|
@data.field_names.should be_empty
|
123
123
|
end
|
124
124
|
|
125
|
-
|
125
|
+
it "should return a snapshot" do
|
126
126
|
@data.value = 5
|
127
127
|
@data.snapshot.should eql(5)
|
128
128
|
end
|
129
129
|
end
|
130
130
|
|
131
|
-
|
132
|
-
|
131
|
+
describe "A Single with :initial_value" do
|
132
|
+
before(:each) do
|
133
133
|
@data = ConcreteSingle.new(:initial_value => 5)
|
134
134
|
end
|
135
135
|
|
136
|
-
|
136
|
+
it "should return that initial value before reading or being set" do
|
137
137
|
@data.value.should eql(5)
|
138
138
|
end
|
139
139
|
|
140
|
-
|
140
|
+
it "should forget :initial_value after being set" do
|
141
141
|
@data.value = 17
|
142
142
|
@data.value.should_not eql(5)
|
143
143
|
end
|
144
144
|
|
145
|
-
|
145
|
+
it "should forget :initial_value after reading" do
|
146
146
|
io = StringIO.new([56].pack("V"))
|
147
147
|
@data.read(io)
|
148
148
|
@data.value.should_not eql(5)
|
149
149
|
end
|
150
150
|
|
151
|
-
|
151
|
+
it "should remember :initial_value after being cleared" do
|
152
152
|
@data.value = 17
|
153
153
|
@data.clear
|
154
154
|
@data.value.should eql(5)
|
155
155
|
end
|
156
156
|
end
|
157
157
|
|
158
|
-
|
159
|
-
|
158
|
+
describe "A Single with :value" do
|
159
|
+
before(:each) do
|
160
160
|
@data = ConcreteSingle.new(:value => 5)
|
161
161
|
end
|
162
162
|
|
163
|
-
|
163
|
+
it "should return that :value" do
|
164
164
|
@data.value.should eql(5)
|
165
165
|
end
|
166
166
|
|
167
|
-
|
167
|
+
it "should change during reading" do
|
168
168
|
io = StringIO.new([56].pack("V"))
|
169
169
|
@data.do_read(io)
|
170
170
|
@data.value.should eql(56)
|
171
171
|
@data.done_read
|
172
172
|
end
|
173
173
|
|
174
|
-
|
174
|
+
it "should not change after reading" do
|
175
175
|
io = StringIO.new([56].pack("V"))
|
176
176
|
@data.read(io)
|
177
177
|
@data.value.should eql(5)
|
178
178
|
end
|
179
179
|
|
180
|
-
|
180
|
+
it "should not be able to change the value" do
|
181
181
|
@data.value = 17
|
182
182
|
@data.value.should eql(5)
|
183
183
|
end
|
184
184
|
end
|
185
185
|
|
186
|
-
|
187
|
-
|
186
|
+
describe "A Single with :check_value" do
|
187
|
+
before(:each) do
|
188
188
|
@io = StringIO.new([34].pack("V"))
|
189
189
|
end
|
190
190
|
|
191
|
-
|
191
|
+
it "should succeed when check_value is non boolean and correct" do
|
192
192
|
data = ConcreteSingle.new(:check_value => 34)
|
193
193
|
lambda { data.read(@io) }.should_not raise_error
|
194
194
|
end
|
195
195
|
|
196
|
-
|
196
|
+
it "should fail when check_value is non boolean and incorrect" do
|
197
197
|
data = ConcreteSingle.new(:check_value => lambda { 123 * 5 })
|
198
198
|
lambda { data.read(@io) }.should raise_error(BinData::ValidityError)
|
199
199
|
end
|
200
200
|
|
201
|
-
|
201
|
+
it "should succeed when check_value is boolean and true" do
|
202
202
|
data = ConcreteSingle.new(:check_value => lambda { (value % 2) == 0})
|
203
203
|
lambda { data.read(@io) }.should_not raise_error
|
204
204
|
end
|
205
205
|
|
206
|
-
|
206
|
+
it "should fail when check_value is boolean and false" do
|
207
207
|
data = ConcreteSingle.new(:check_value => lambda { value > 100 })
|
208
208
|
lambda { data.read(@io) }.should raise_error(BinData::ValidityError)
|
209
209
|
end
|
data/spec/spec_common.rb
CHANGED
data/spec/string_spec.rb
CHANGED
@@ -3,53 +3,53 @@
|
|
3
3
|
require File.expand_path(File.dirname(__FILE__)) + '/spec_common'
|
4
4
|
require 'bindata/string'
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
describe "Test mutual exclusion of parameters" do
|
7
|
+
it ":value and :initial_value" do
|
8
8
|
params = {:value => "", :initial_value => ""}
|
9
9
|
lambda { BinData::String.new(params) }.should raise_error(ArgumentError)
|
10
10
|
end
|
11
11
|
|
12
|
-
|
12
|
+
it ":length and :initial_length" do
|
13
13
|
params = {:length => 5, :initial_length => 5}
|
14
14
|
lambda { BinData::String.new(params) }.should raise_error(ArgumentError)
|
15
15
|
end
|
16
16
|
|
17
|
-
|
17
|
+
it ":initial_value and :initial_length" do
|
18
18
|
params = {:initial_value => "", :initial_length => 5}
|
19
19
|
lambda { BinData::String.new(params) }.should raise_error(ArgumentError)
|
20
20
|
end
|
21
21
|
|
22
|
-
|
22
|
+
it ":value and :length" do
|
23
23
|
params = {:value => "", :length => 5}
|
24
24
|
lambda { BinData::String.new(params) }.should raise_error(ArgumentError)
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
|
29
|
-
|
28
|
+
describe "A String with :initial_length" do
|
29
|
+
before(:each) do
|
30
30
|
@str = BinData::String.new(:initial_length => 5)
|
31
31
|
end
|
32
32
|
|
33
|
-
|
33
|
+
it "should set num_bytes" do
|
34
34
|
@str.num_bytes.should eql(5)
|
35
35
|
end
|
36
36
|
|
37
|
-
|
37
|
+
it "should fill value with pad_char" do
|
38
38
|
@str.value.should eql("\0\0\0\0\0")
|
39
39
|
end
|
40
40
|
|
41
|
-
|
41
|
+
it "should read :initial_length bytes" do
|
42
42
|
io = StringIO.new("abcdefghij")
|
43
43
|
@str.read(io)
|
44
44
|
@str.value.should eql("abcde")
|
45
45
|
end
|
46
46
|
|
47
|
-
|
47
|
+
it "should forget :initial_length after value is set" do
|
48
48
|
@str.value = "abc"
|
49
49
|
@str.num_bytes.should eql(3)
|
50
50
|
end
|
51
51
|
|
52
|
-
|
52
|
+
it "should remember :initial_length after value is cleared" do
|
53
53
|
@str.value = "abc"
|
54
54
|
@str.num_bytes.should eql(3)
|
55
55
|
@str.clear
|
@@ -57,70 +57,70 @@ context "A String with :initial_length" do
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
|
61
|
-
|
60
|
+
describe "A String with :length" do
|
61
|
+
before(:each) do
|
62
62
|
@str = BinData::String.new(:length => 5)
|
63
63
|
end
|
64
64
|
|
65
|
-
|
65
|
+
it "should set num_bytes" do
|
66
66
|
@str.num_bytes.should eql(5)
|
67
67
|
end
|
68
68
|
|
69
|
-
|
69
|
+
it "should fill value with pad_char" do
|
70
70
|
@str.value.should eql("\0\0\0\0\0")
|
71
71
|
end
|
72
72
|
|
73
|
-
|
73
|
+
it "should retain :length after value is set" do
|
74
74
|
@str.value = "abcdefghij"
|
75
75
|
@str.num_bytes.should eql(5)
|
76
76
|
end
|
77
77
|
|
78
|
-
|
78
|
+
it "should read :length bytes" do
|
79
79
|
io = StringIO.new("abcdefghij")
|
80
80
|
@str.read(io)
|
81
81
|
@str.value.should eql("abcde")
|
82
82
|
end
|
83
83
|
|
84
|
-
|
84
|
+
it "should pad values less than :length" do
|
85
85
|
@str.value = "abc"
|
86
86
|
@str.value.should eql("abc\0\0")
|
87
87
|
end
|
88
88
|
|
89
|
-
|
89
|
+
it "should accept values exactly :length" do
|
90
90
|
@str.value = "abcde"
|
91
91
|
@str.value.should eql("abcde")
|
92
92
|
end
|
93
93
|
|
94
|
-
|
94
|
+
it "should truncate values greater than :length" do
|
95
95
|
@str.value = "abcdefg"
|
96
96
|
@str.value.should eql("abcde")
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
100
|
-
|
101
|
-
|
100
|
+
describe "A String with :initial_length and :value" do
|
101
|
+
before(:each) do
|
102
102
|
@str = BinData::String.new(:initial_length => 5, :value => "abcdefghij")
|
103
103
|
end
|
104
104
|
|
105
|
-
|
105
|
+
it "should use :initial_length before value is read" do
|
106
106
|
@str.num_bytes.should eql(5)
|
107
107
|
@str.value.should eql("abcde")
|
108
108
|
end
|
109
109
|
|
110
|
-
|
110
|
+
it "should use :initial_length for reading" do
|
111
111
|
io = StringIO.new("ABCDEFGHIJKLMNOPQRST")
|
112
112
|
@str.read(io)
|
113
113
|
io.pos.should eql(5)
|
114
114
|
end
|
115
115
|
|
116
|
-
|
116
|
+
it "should forget :initial_length after reading" do
|
117
117
|
io = StringIO.new("ABCDEFGHIJKLMNOPQRST")
|
118
118
|
@str.read(io)
|
119
119
|
@str.num_bytes.should eql(10)
|
120
120
|
@str.value.should eql("abcdefghij")
|
121
121
|
end
|
122
122
|
|
123
|
-
|
123
|
+
it "should return read value before calling done_read" do
|
124
124
|
io = StringIO.new("ABCDEFGHIJKLMNOPQRST")
|
125
125
|
|
126
126
|
@str.do_read(io)
|
@@ -131,17 +131,17 @@ context "A String with :initial_length and :value" do
|
|
131
131
|
end
|
132
132
|
end
|
133
133
|
|
134
|
-
|
135
|
-
|
134
|
+
describe "A String with :length and :initial_value" do
|
135
|
+
before(:each) do
|
136
136
|
@str = BinData::String.new(:length => 5, :initial_value => "abcdefghij")
|
137
137
|
end
|
138
138
|
|
139
|
-
|
139
|
+
it "should apply :length to :initial_value" do
|
140
140
|
@str.num_bytes.should eql(5)
|
141
141
|
@str.value.should eql("abcde")
|
142
142
|
end
|
143
143
|
|
144
|
-
|
144
|
+
it "should forget :initial_value after reading" do
|
145
145
|
io = StringIO.new("ABCDEFGHIJKLMNOPQRST")
|
146
146
|
@str.read(io)
|
147
147
|
io.pos.should eql(5)
|
@@ -150,27 +150,27 @@ context "A String with :length and :initial_value" do
|
|
150
150
|
end
|
151
151
|
end
|
152
152
|
|
153
|
-
|
154
|
-
|
153
|
+
describe "A String with :pad_char" do
|
154
|
+
it "should accept a numeric value for :pad_char" do
|
155
155
|
@str = BinData::String.new(:length => 5, :pad_char => 6)
|
156
156
|
@str.value = "abc"
|
157
157
|
@str.value.should eql("abc\x06\x06")
|
158
158
|
end
|
159
159
|
|
160
|
-
|
160
|
+
it "should accept a character for :pad_char" do
|
161
161
|
@str = BinData::String.new(:length => 5, :pad_char => "R")
|
162
162
|
@str.value = "abc"
|
163
163
|
@str.value.should eql("abcRR")
|
164
164
|
end
|
165
165
|
|
166
|
-
|
166
|
+
it "should not accept a string for :pad_char" do
|
167
167
|
params = {:length => 5, :pad_char => "RR"}
|
168
168
|
lambda { BinData::String.new(params) }.should raise_error(ArgumentError)
|
169
169
|
end
|
170
170
|
end
|
171
171
|
|
172
|
-
|
173
|
-
|
172
|
+
describe "A String with :trim_value" do
|
173
|
+
it "set false is the default" do
|
174
174
|
str1 = BinData::String.new(:length => 5)
|
175
175
|
str2 = BinData::String.new(:length => 5, :trim_value => false)
|
176
176
|
str1.value = "abc"
|
@@ -179,25 +179,25 @@ context "A String with :trim_value" do
|
|
179
179
|
str2.value.should eql("abc\0\0")
|
180
180
|
end
|
181
181
|
|
182
|
-
|
182
|
+
it "should trim the value" do
|
183
183
|
str = BinData::String.new(:pad_char => 'R', :trim_value => true)
|
184
184
|
str.value = "abcRR"
|
185
185
|
str.value.should eql("abc")
|
186
186
|
end
|
187
187
|
|
188
|
-
|
188
|
+
it "should not affect num_bytes" do
|
189
189
|
str = BinData::String.new(:pad_char => 'R', :trim_value => true)
|
190
190
|
str.value = "abcRR"
|
191
191
|
str.num_bytes.should eql(5)
|
192
192
|
end
|
193
193
|
|
194
|
-
|
194
|
+
it "should trim if last char is :pad_char" do
|
195
195
|
str = BinData::String.new(:pad_char => 'R', :trim_value => true)
|
196
196
|
str.value = "abcRR"
|
197
197
|
str.value.should eql("abc")
|
198
198
|
end
|
199
199
|
|
200
|
-
|
200
|
+
it "should not trim if value contains :pad_char not at the end" do
|
201
201
|
str = BinData::String.new(:pad_char => 'R', :trim_value => true)
|
202
202
|
str.value = "abcRRde"
|
203
203
|
str.value.should eql("abcRRde")
|