THRIFT-1766 [Ruby] Provide support for binary types
Patch: Nathan Beyer
diff --git a/lib/rb/spec/base_protocol_spec.rb b/lib/rb/spec/base_protocol_spec.rb
index c0f9cfc..ec50c48 100644
--- a/lib/rb/spec/base_protocol_spec.rb
+++ b/lib/rb/spec/base_protocol_spec.rb
@@ -33,14 +33,21 @@
       @prot.trans.should eql(@trans)
     end
 
-    it "should write out a field nicely" do
+    it 'should write out a field nicely (deprecated write_field signature)' do
       @prot.should_receive(:write_field_begin).with('field', 'type', 'fid').ordered
-      @prot.should_receive(:write_type).with('type', 'value').ordered
+      @prot.should_receive(:write_type).with({:name => 'field', :type => 'type'}, 'value').ordered
       @prot.should_receive(:write_field_end).ordered
       @prot.write_field('field', 'type', 'fid', 'value')
     end
 
-    it "should write out the different types" do
+    it 'should write out a field nicely' do
+      @prot.should_receive(:write_field_begin).with('field', 'type', 'fid').ordered
+      @prot.should_receive(:write_type).with({:name => 'field', :type => 'type', :binary => false}, 'value').ordered
+      @prot.should_receive(:write_field_end).ordered
+      @prot.write_field({:name => 'field', :type => 'type', :binary => false}, 'fid', 'value')
+    end
+
+    it 'should write out the different types (deprecated write_type signature)' do
       @prot.should_receive(:write_bool).with('bool').ordered
       @prot.should_receive(:write_byte).with('byte').ordered
       @prot.should_receive(:write_double).with('double').ordered
@@ -60,11 +67,37 @@
       @prot.write_type(Thrift::Types::STRUCT, struct)
       # all other types are not implemented
       [Thrift::Types::STOP, Thrift::Types::VOID, Thrift::Types::MAP, Thrift::Types::SET, Thrift::Types::LIST].each do |type|
-        lambda { @prot.write_type(type, type.to_s) }.should raise_error(NotImplementedError)
+        expect { @prot.write_type(type, type.to_s) }.to raise_error(NotImplementedError)
       end
     end
 
-    it "should read the different types" do
+    it 'should write out the different types' do
+      @prot.should_receive(:write_bool).with('bool').ordered
+      @prot.should_receive(:write_byte).with('byte').ordered
+      @prot.should_receive(:write_double).with('double').ordered
+      @prot.should_receive(:write_i16).with('i16').ordered
+      @prot.should_receive(:write_i32).with('i32').ordered
+      @prot.should_receive(:write_i64).with('i64').ordered
+      @prot.should_receive(:write_string).with('string').ordered
+      @prot.should_receive(:write_binary).with('binary').ordered
+      struct = mock('Struct')
+      struct.should_receive(:write).with(@prot).ordered
+      @prot.write_type({:type => Thrift::Types::BOOL}, 'bool')
+      @prot.write_type({:type => Thrift::Types::BYTE}, 'byte')
+      @prot.write_type({:type => Thrift::Types::DOUBLE}, 'double')
+      @prot.write_type({:type => Thrift::Types::I16}, 'i16')
+      @prot.write_type({:type => Thrift::Types::I32}, 'i32')
+      @prot.write_type({:type => Thrift::Types::I64}, 'i64')
+      @prot.write_type({:type => Thrift::Types::STRING}, 'string')
+      @prot.write_type({:type => Thrift::Types::STRING, :binary => true}, 'binary')
+      @prot.write_type({:type => Thrift::Types::STRUCT}, struct)
+      # all other types are not implemented
+      [Thrift::Types::STOP, Thrift::Types::VOID, Thrift::Types::MAP, Thrift::Types::SET, Thrift::Types::LIST].each do |type|
+        expect { @prot.write_type({:type => type}, type.to_s) }.to raise_error(NotImplementedError)
+      end
+    end
+
+    it 'should read the different types (deprecated read_type signature)' do
       @prot.should_receive(:read_bool).ordered
       @prot.should_receive(:read_byte).ordered
       @prot.should_receive(:read_i16).ordered
@@ -80,8 +113,33 @@
       @prot.read_type(Thrift::Types::DOUBLE)
       @prot.read_type(Thrift::Types::STRING)
       # all other types are not implemented
-      [Thrift::Types::STOP, Thrift::Types::VOID, Thrift::Types::MAP, Thrift::Types::SET, Thrift::Types::LIST].each do |type|
-        lambda { @prot.read_type(type) }.should raise_error(NotImplementedError)
+      [Thrift::Types::STOP, Thrift::Types::VOID, Thrift::Types::MAP,
+       Thrift::Types::SET, Thrift::Types::LIST, Thrift::Types::STRUCT].each do |type|
+        expect { @prot.read_type(type) }.to raise_error(NotImplementedError)
+      end
+    end
+
+    it 'should read the different types' do
+      @prot.should_receive(:read_bool).ordered
+      @prot.should_receive(:read_byte).ordered
+      @prot.should_receive(:read_i16).ordered
+      @prot.should_receive(:read_i32).ordered
+      @prot.should_receive(:read_i64).ordered
+      @prot.should_receive(:read_double).ordered
+      @prot.should_receive(:read_string).ordered
+      @prot.should_receive(:read_binary).ordered
+      @prot.read_type({:type => Thrift::Types::BOOL})
+      @prot.read_type({:type => Thrift::Types::BYTE})
+      @prot.read_type({:type => Thrift::Types::I16})
+      @prot.read_type({:type => Thrift::Types::I32})
+      @prot.read_type({:type => Thrift::Types::I64})
+      @prot.read_type({:type => Thrift::Types::DOUBLE})
+      @prot.read_type({:type => Thrift::Types::STRING})
+      @prot.read_type({:type => Thrift::Types::STRING, :binary => true})
+      # all other types are not implemented
+      [Thrift::Types::STOP, Thrift::Types::VOID, Thrift::Types::MAP,
+       Thrift::Types::SET, Thrift::Types::LIST, Thrift::Types::STRUCT].each do |type|
+        expect { @prot.read_type({:type => type}) }.to raise_error(NotImplementedError)
       end
     end
 
diff --git a/lib/rb/spec/binary_protocol_spec_shared.rb b/lib/rb/spec/binary_protocol_spec_shared.rb
index c49ff1f..c615b58 100644
--- a/lib/rb/spec/binary_protocol_spec_shared.rb
+++ b/lib/rb/spec/binary_protocol_spec_shared.rb
@@ -219,6 +219,14 @@
       a.encoding.should == Encoding::BINARY
       a.unpack('C*').should == [0x00, 0x00, 0x00, 0x07, 0x61, 0x62, 0x63, 0x20, 0xE2, 0x82, 0xAC]
     end
+
+    it 'should write a binary string' do
+      buffer = [0, 1, 2, 3].pack('C*')
+      @prot.write_binary(buffer)
+      a = @trans.read(@trans.available)
+      a.encoding.should == Encoding::BINARY
+      a.unpack('C*').should == [0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03]
+    end
   else
     it 'should write a string' do
       str = 'abc'
@@ -226,6 +234,13 @@
       a = @trans.read(@trans.available)
       a.unpack('C*').should == [0x00, 0x00, 0x00, 0x03, 0x61, 0x62, 0x63]
     end
+
+    it 'should write a binary string' do
+      buffer = [0, 1, 2, 3].pack('C*')
+      @prot.write_binary(buffer)
+      a = @trans.read(@trans.available)
+      a.unpack('C*').should == [0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03]
+    end
   end
 
   it "should error gracefully when trying to write a nil string" do
@@ -342,6 +357,14 @@
       a.should == "\u20AC".encode('UTF-8')
       a.encoding.should == Encoding::UTF_8
     end
+
+    it 'should read a binary string' do
+      buffer = [0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03].pack('C*')
+      @trans.write(buffer)
+      a = @prot.read_binary
+      a.should == [0x00, 0x01, 0x02, 0x03].pack('C*')
+      a.encoding.should == Encoding::BINARY
+    end
   else
     it 'should read a string' do
       # i32 of value 3, followed by three characters/UTF-8 bytes 'a', 'b', 'c'
@@ -349,6 +372,13 @@
       @trans.write(buffer)
       @prot.read_string.should == 'abc'
     end
+
+    it 'should read a binary string' do
+      buffer = [0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03].pack('C*')
+      @trans.write(buffer)
+      a = @prot.read_binary
+      a.should == [0x00, 0x01, 0x02, 0x03].pack('C*')
+    end
   end
 
   it "should perform a complete rpc with no args or return" do
diff --git a/lib/rb/spec/compact_protocol_spec.rb b/lib/rb/spec/compact_protocol_spec.rb
index 91dfe44..daad583 100644
--- a/lib/rb/spec/compact_protocol_spec.rb
+++ b/lib/rb/spec/compact_protocol_spec.rb
@@ -134,12 +134,10 @@
   end
   
   def writer(sym)
-    sym = sym == :binary ? :string : sym
     "write_#{sym.to_s}"
   end
   
   def reader(sym)
-    sym = sym == :binary ? :string : sym
     "read_#{sym.to_s}"
   end
-end
\ No newline at end of file
+end