| Kevin Clark | f18b643 | 2008-06-18 01:07:10 +0000 | [diff] [blame] | 1 | require File.dirname(__FILE__) + '/spec_helper' | 
 | 2 | require 'thrift/protocol/binaryprotocol' | 
 | 3 |  | 
| Kevin Clark | 356f861 | 2008-06-18 01:08:05 +0000 | [diff] [blame^] | 4 | class ThriftBinaryProtocolSpec < Spec::ExampleGroup | 
| Kevin Clark | f18b643 | 2008-06-18 01:07:10 +0000 | [diff] [blame] | 5 |   include Thrift | 
 | 6 |  | 
 | 7 |   describe BinaryProtocol do | 
 | 8 |     before(:each) do | 
 | 9 |       @trans = mock("MockTransport", :null_object => true) | 
 | 10 |       @prot = BinaryProtocol.new(@trans) | 
 | 11 |     end | 
 | 12 |  | 
 | 13 |     it "should define the proper VERSION_1 and VERSION_MASK" do | 
 | 14 |       BinaryProtocol::VERSION_MASK.should == 0xffff0000 | 
 | 15 |       BinaryProtocol::VERSION_1.should == 0x80010000 | 
 | 16 |     end | 
 | 17 |  | 
 | 18 |     it "should write the message header" do | 
 | 19 |       @prot.should_receive(:write_i32).with(BinaryProtocol::VERSION_1 | MessageTypes::CALL).ordered | 
 | 20 |       @prot.should_receive(:write_string).with('testMessage').ordered | 
 | 21 |       @prot.should_receive(:write_i32).with(17).ordered | 
 | 22 |       @prot.write_message_begin('testMessage', MessageTypes::CALL, 17) | 
 | 23 |     end | 
 | 24 |  | 
 | 25 |     # message footer is a noop | 
 | 26 |  | 
 | 27 |     it "should write the field header" do | 
 | 28 |       @prot.should_receive(:write_byte).with(Types::DOUBLE).ordered | 
 | 29 |       @prot.should_receive(:write_i16).with(3).ordered | 
 | 30 |       @prot.write_field_begin('foo', Types::DOUBLE, 3) | 
 | 31 |     end | 
 | 32 |  | 
 | 33 |     # field footer is a noop | 
 | 34 |  | 
 | 35 |     it "should write the STOP field" do | 
 | 36 |       @prot.should_receive(:write_byte).with(Types::STOP) | 
 | 37 |       @prot.write_field_stop | 
 | 38 |     end | 
 | 39 |  | 
 | 40 |     it "should write the map header" do | 
 | 41 |       @prot.should_receive(:write_byte).with(Types::STRING).ordered | 
 | 42 |       @prot.should_receive(:write_byte).with(Types::LIST).ordered | 
 | 43 |       @prot.should_receive(:write_i32).with(17).ordered | 
 | 44 |       @prot.write_map_begin(Types::STRING, Types::LIST, 17) | 
 | 45 |     end | 
 | 46 |  | 
 | 47 |     # map footer is a noop | 
 | 48 |  | 
 | 49 |     it "should write the list header" do | 
 | 50 |       @prot.should_receive(:write_byte).with(Types::I16).ordered | 
 | 51 |       @prot.should_receive(:write_i32).with(42).ordered | 
 | 52 |       @prot.write_list_begin(Types::I16, 42) | 
 | 53 |     end | 
 | 54 |  | 
 | 55 |     # list footer is a noop | 
 | 56 |  | 
 | 57 |     it "should write the set header" do | 
 | 58 |       @prot.should_receive(:write_byte).with(Types::BOOL).ordered | 
 | 59 |       @prot.should_receive(:write_i32).with(2).ordered | 
 | 60 |       @prot.write_set_begin(Types::BOOL, 2) | 
 | 61 |     end | 
 | 62 |  | 
 | 63 |     it "should write a bool" do | 
 | 64 |       @prot.should_receive(:write_byte).with(1).ordered | 
 | 65 |       @prot.write_bool(true) | 
 | 66 |       @prot.should_receive(:write_byte).with(0).ordered | 
 | 67 |       @prot.write_bool(false) | 
 | 68 |     end | 
 | 69 |  | 
 | 70 |     it "should write a byte" do | 
| Kevin Clark | 5ae0384 | 2008-06-18 01:07:37 +0000 | [diff] [blame] | 71 |       # byte is small enough, let's check -128..127 | 
 | 72 |       (-128..127).each do |i| | 
 | 73 |         @trans.should_receive(:write).with([i].pack('c')).ordered | 
| Kevin Clark | f18b643 | 2008-06-18 01:07:10 +0000 | [diff] [blame] | 74 |       end | 
| Kevin Clark | 5ae0384 | 2008-06-18 01:07:37 +0000 | [diff] [blame] | 75 |       (-128..127).each do |i| | 
 | 76 |         @prot.write_byte(i) | 
 | 77 |       end | 
 | 78 |       # now try out of signed range | 
 | 79 |       lambda { @prot.write_byte(224) }.should raise_error(RangeError) | 
| Kevin Clark | f18b643 | 2008-06-18 01:07:10 +0000 | [diff] [blame] | 80 |     end | 
 | 81 |  | 
 | 82 |     it "should write an i16" do | 
 | 83 |       # try a random scattering of values | 
| Kevin Clark | 5ae0384 | 2008-06-18 01:07:37 +0000 | [diff] [blame] | 84 |       # include the signed i16 minimum/maximum | 
| Kevin Clark | f18b643 | 2008-06-18 01:07:10 +0000 | [diff] [blame] | 85 |       @trans.should_receive(:write).with("\200\000").ordered | 
 | 86 |       @trans.should_receive(:write).with("\374\000").ordered | 
 | 87 |       @trans.should_receive(:write).with("\000\021").ordered | 
 | 88 |       @trans.should_receive(:write).with("\000\000").ordered | 
 | 89 |       @trans.should_receive(:write).with("\330\360").ordered | 
 | 90 |       @trans.should_receive(:write).with("\006\273").ordered | 
| Kevin Clark | 5ae0384 | 2008-06-18 01:07:37 +0000 | [diff] [blame] | 91 |       @trans.should_receive(:write).with("\177\377").ordered | 
 | 92 |       [-2**15, -1024, 17, 0, -10000, 1723, 2**15-1].each do |i| | 
| Kevin Clark | f18b643 | 2008-06-18 01:07:10 +0000 | [diff] [blame] | 93 |         @prot.write_i16(i) | 
 | 94 |       end | 
| Kevin Clark | 5ae0384 | 2008-06-18 01:07:37 +0000 | [diff] [blame] | 95 |       # and try something out of signed range | 
 | 96 |       lambda { @prot.write_i16(2**15 + 5) }.should raise_error(RangeError) | 
| Kevin Clark | f18b643 | 2008-06-18 01:07:10 +0000 | [diff] [blame] | 97 |     end | 
 | 98 |  | 
 | 99 |     it "should write an i32" do | 
 | 100 |       # try a random scattering of values | 
| Kevin Clark | 5ae0384 | 2008-06-18 01:07:37 +0000 | [diff] [blame] | 101 |       # include the signed i32 minimum/maximum | 
| Kevin Clark | f18b643 | 2008-06-18 01:07:10 +0000 | [diff] [blame] | 102 |       @trans.should_receive(:write).with("\200\000\000\000").ordered | 
 | 103 |       @trans.should_receive(:write).with("\377\376\037\r").ordered | 
 | 104 |       @trans.should_receive(:write).with("\377\377\366\034").ordered | 
 | 105 |       @trans.should_receive(:write).with("\377\377\377\375").ordered | 
 | 106 |       @trans.should_receive(:write).with("\000\000\000\000").ordered | 
 | 107 |       @trans.should_receive(:write).with("\000#\340\203").ordered | 
 | 108 |       @trans.should_receive(:write).with("\000\0000+").ordered | 
| Kevin Clark | 5ae0384 | 2008-06-18 01:07:37 +0000 | [diff] [blame] | 109 |       @trans.should_receive(:write).with("\177\377\377\377").ordered | 
 | 110 |       [-2**31, -123123, -2532, -3, 0, 2351235, 12331, 2**31-1].each do |i| | 
| Kevin Clark | f18b643 | 2008-06-18 01:07:10 +0000 | [diff] [blame] | 111 |         @prot.write_i32(i) | 
 | 112 |       end | 
| Kevin Clark | 5ae0384 | 2008-06-18 01:07:37 +0000 | [diff] [blame] | 113 |       # try something out of signed range | 
 | 114 |       lambda { @prot.write_i32(2 ** 31 + 5) }.should raise_error(RangeError) | 
| Kevin Clark | f18b643 | 2008-06-18 01:07:10 +0000 | [diff] [blame] | 115 |     end | 
 | 116 |  | 
 | 117 |     it "should write an i64" do | 
 | 118 |       # try a random scattering of values | 
| Kevin Clark | 5ae0384 | 2008-06-18 01:07:37 +0000 | [diff] [blame] | 119 |       # try the signed i64 minimum/maximum | 
| Kevin Clark | f18b643 | 2008-06-18 01:07:10 +0000 | [diff] [blame] | 120 |       @trans.should_receive(:write).with("\200\000\000\000\000\000\000\000").ordered | 
 | 121 |       @trans.should_receive(:write).with("\377\377\364\303\035\244+]").ordered | 
 | 122 |       @trans.should_receive(:write).with("\377\377\377\377\376\231:\341").ordered | 
 | 123 |       @trans.should_receive(:write).with("\377\377\377\377\377\377\377\026").ordered | 
 | 124 |       @trans.should_receive(:write).with("\000\000\000\000\000\000\000\000").ordered | 
 | 125 |       @trans.should_receive(:write).with("\000\000\000\000\000\000\004\317").ordered | 
 | 126 |       @trans.should_receive(:write).with("\000\000\000\000\000#\340\204").ordered | 
 | 127 |       @trans.should_receive(:write).with("\000\000\000\002\340\311~\365").ordered | 
| Kevin Clark | 5ae0384 | 2008-06-18 01:07:37 +0000 | [diff] [blame] | 128 |       @trans.should_receive(:write).with("\177\377\377\377\377\377\377\377").ordered | 
 | 129 |       [-2**63, -12356123612323, -23512351, -234, 0, 1231, 2351236, 12361236213, 2**63-1].each do |i| | 
| Kevin Clark | f18b643 | 2008-06-18 01:07:10 +0000 | [diff] [blame] | 130 |         @prot.write_i64(i) | 
 | 131 |       end | 
| Kevin Clark | 5ae0384 | 2008-06-18 01:07:37 +0000 | [diff] [blame] | 132 |       # try something out of signed range | 
 | 133 |       lambda { @prot.write_i64(2 ** 63 + 5) }.should raise_error(RangeError) | 
| Kevin Clark | f18b643 | 2008-06-18 01:07:10 +0000 | [diff] [blame] | 134 |     end | 
 | 135 |  | 
 | 136 |     it "should write a double" do | 
| Kevin Clark | 5ae0384 | 2008-06-18 01:07:37 +0000 | [diff] [blame] | 137 |       # try a random scattering of values, including min/max | 
| Kevin Clark | f18b643 | 2008-06-18 01:07:10 +0000 | [diff] [blame] | 138 |       @trans.should_receive(:write).with("\000\020\000\000\000\000\000\000").ordered | 
 | 139 |       @trans.should_receive(:write).with("\300\223<\234\355\221hs").ordered | 
 | 140 |       @trans.should_receive(:write).with("\300\376\0173\256\024z\341").ordered | 
 | 141 |       @trans.should_receive(:write).with("\3007<2\336\372v\324").ordered | 
 | 142 |       @trans.should_receive(:write).with("\000\000\000\000\000\000\000\000").ordered | 
 | 143 |       @trans.should_receive(:write).with("@\310\037\220\365\302\217\\").ordered | 
 | 144 |       @trans.should_receive(:write).with("@\200Y\327\n=p\244").ordered | 
 | 145 |       @trans.should_receive(:write).with("\177\357\377\377\377\377\377\377").ordered | 
 | 146 |       [Float::MIN, -1231.15325, -123123.23, -23.23515123, 0, 12351.1325, 523.23, Float::MAX].each do |f| | 
 | 147 |         @prot.write_double(f) | 
 | 148 |       end | 
 | 149 |     end | 
 | 150 |  | 
 | 151 |     it "should write a string" do | 
 | 152 |       str = "hello world" | 
 | 153 |       @prot.should_receive(:write_i32).with(str.length).ordered | 
 | 154 |       @trans.should_receive(:write).with(str).ordered | 
 | 155 |       @prot.write_string(str) | 
 | 156 |     end | 
| Kevin Clark | 5ae0384 | 2008-06-18 01:07:37 +0000 | [diff] [blame] | 157 |  | 
 | 158 |     it "should read a message header" do | 
 | 159 |       @prot.should_receive(:read_i32).and_return(BinaryProtocol::VERSION_1 | MessageTypes::REPLY, 42) | 
 | 160 |       @prot.should_receive(:read_string).and_return('testMessage') | 
 | 161 |       @prot.read_message_begin.should == ['testMessage', MessageTypes::REPLY, 42] | 
 | 162 |     end | 
 | 163 |  | 
 | 164 |     # message header is a noop | 
 | 165 |  | 
 | 166 |     it "should read a field header" do | 
 | 167 |       @prot.should_receive(:read_byte).ordered.and_return(Types::STRING) | 
 | 168 |       @prot.should_receive(:read_i16).ordered.and_return(3) | 
 | 169 |       @prot.read_field_begin.should == [nil, Types::STRING, 3] | 
 | 170 |     end | 
 | 171 |  | 
 | 172 |     # field footer is a noop | 
 | 173 |  | 
 | 174 |     it "should read a stop field" do | 
 | 175 |       @prot.should_receive(:read_byte).and_return(Types::STOP) | 
 | 176 |       @prot.should_not_receive(:read_i16) | 
 | 177 |       @prot.read_field_begin.should == [nil, Types::STOP, 0] | 
 | 178 |     end | 
 | 179 |  | 
 | 180 |     it "should read a map header" do | 
 | 181 |       @prot.should_receive(:read_byte).and_return(Types::DOUBLE, Types::I64) | 
 | 182 |       @prot.should_receive(:read_i32).and_return(42) | 
 | 183 |       @prot.read_map_begin.should == [Types::DOUBLE, Types::I64, 42] | 
 | 184 |     end | 
 | 185 |  | 
 | 186 |     # map footer is a noop | 
 | 187 |  | 
 | 188 |     it "should read a list header" do | 
 | 189 |       @prot.should_receive(:read_byte).ordered.and_return(Types::STRING) | 
 | 190 |       @prot.should_receive(:read_i32).and_return(17) | 
 | 191 |       @prot.read_list_begin.should == [Types::STRING, 17] | 
 | 192 |     end | 
 | 193 |  | 
 | 194 |     # list footer is a noop | 
 | 195 |  | 
 | 196 |     it "should read a set header" do | 
 | 197 |       @prot.should_receive(:read_byte).ordered.and_return(Types::MAP) | 
 | 198 |       @prot.should_receive(:read_i32).ordered.and_return(42) | 
 | 199 |       @prot.read_set_begin.should == [Types::MAP, 42] | 
 | 200 |     end | 
 | 201 |  | 
 | 202 |     # set footer is a noop | 
 | 203 |  | 
 | 204 |     it "should read a bool" do | 
 | 205 |       @prot.should_receive(:read_byte).and_return(1, 0) | 
 | 206 |       @prot.read_bool.should == true | 
 | 207 |       @prot.read_bool.should == false | 
 | 208 |     end | 
 | 209 |  | 
 | 210 |     it "should read a byte" do | 
 | 211 |       # try a scattering of values, including min/max | 
 | 212 |       @trans.should_receive(:read_all).with(1).and_return( | 
 | 213 |         "\200", "\307", "\375", | 
 | 214 |         "\000", "\021", "\030", "\177" | 
 | 215 |       ) | 
 | 216 |       [-128, -57, -3, 0, 17, 24, 127].each do |i| | 
 | 217 |         @prot.read_byte.should == i | 
 | 218 |       end | 
 | 219 |     end | 
 | 220 |  | 
 | 221 |     it "should read an i16" do | 
 | 222 |       # try a scattering of values, including min/max | 
 | 223 |       @trans.should_receive(:read_all).with(2).and_return( | 
 | 224 |         "\200\000", "\353\213", "\376\237", | 
 | 225 |         "\000\000", "\005\367", "\b\272", "\177\377" | 
 | 226 |       ) | 
 | 227 |       [-2**15, -5237, -353, 0, 1527, 2234, 2**15-1].each do |i| | 
 | 228 |         @prot.read_i16.should == i | 
 | 229 |       end | 
 | 230 |     end | 
 | 231 |  | 
 | 232 |     it "should read an i32" do | 
 | 233 |       # try a scattering of values, including min/max | 
 | 234 |       @trans.should_receive(:read_all).with(4).and_return( | 
 | 235 |         "\200\000\000\000", "\377\374i\213", "\377\377\347\244", | 
 | 236 |         "\000\000\000\000", "\000\000\t/", "\000\001\340\363", "\177\377\377\377" | 
 | 237 |       ) | 
 | 238 |       [-2**31, -235125, -6236, 0, 2351, 123123, 2**31-1].each do |i| | 
 | 239 |         @prot.read_i32.should == i | 
 | 240 |       end | 
 | 241 |     end | 
 | 242 |  | 
 | 243 |     it "should read an i64" do | 
 | 244 |       # try a scattering of values, including min/max | 
 | 245 |       @trans.should_receive(:read_all).with(8).and_return( | 
 | 246 |         "\200\000\000\000\000\000\000\000", "\377\377\377\377\370\243Z\b", | 
 | 247 |         "\377\377\377\377\377\377\3476", "\000\000\000\000\000\000\000\000", | 
 | 248 |         "\000\000\000\000\000\000\000 ", "\000\000\000\000\213\332\t\223", | 
 | 249 |         "\177\377\377\377\377\377\377\377" | 
 | 250 |       ) | 
 | 251 |       [-2**63, -123512312, -6346, 0, 32, 2346322323, 2**63-1].each do |i| | 
 | 252 |         @prot.read_i64.should == i | 
 | 253 |       end | 
 | 254 |     end | 
 | 255 |  | 
 | 256 |     it "should read a double" do | 
 | 257 |       # try a random scattering of values, including min/max | 
 | 258 |       @trans.should_receive(:read_all).with(8).and_return( | 
 | 259 |         "\000\020\000\000\000\000\000\000", "\301\f9\370\374\362\317\226", | 
 | 260 |         "\300t3\274x \243\016", "\000\000\000\000\000\000\000\000", "@^\317\fCo\301Y", | 
 | 261 |         "AA\360A\217\317@\260", "\177\357\377\377\377\377\377\377" | 
 | 262 |       ) | 
 | 263 |       [Float::MIN, -231231.12351, -323.233513, 0, 123.2351235, 2351235.12351235, Float::MAX].each do |f| | 
 | 264 |         @prot.read_double.should == f | 
 | 265 |       end | 
 | 266 |     end | 
 | 267 |  | 
 | 268 |     it "should read a string" do | 
 | 269 |       str = "hello world" | 
 | 270 |       @prot.should_receive(:read_i32).and_return(str.length) | 
 | 271 |       @trans.should_receive(:read_all).with(str.length).and_return(str) | 
 | 272 |       @prot.read_string.should == str | 
 | 273 |     end | 
| Kevin Clark | f18b643 | 2008-06-18 01:07:10 +0000 | [diff] [blame] | 274 |   end | 
| Kevin Clark | e977a63 | 2008-06-18 01:07:50 +0000 | [diff] [blame] | 275 |  | 
 | 276 |   describe BinaryProtocolFactory do | 
 | 277 |     it "should create a BinaryProtocol" do | 
 | 278 |       BinaryProtocolFactory.new.get_protocol(mock("MockTransport")).should be_instance_of BinaryProtocol | 
 | 279 |     end | 
 | 280 |   end | 
| Kevin Clark | f18b643 | 2008-06-18 01:07:10 +0000 | [diff] [blame] | 281 | end |