1# 2# Licensed to the Apache Software Foundation (ASF) under one 3# or more contributor license agreements. See the NOTICE file 4# distributed with this work for additional information 5# regarding copyright ownership. The ASF licenses this file 6# to you under the Apache License, Version 2.0 (the 7# "License"); you may not use this file except in compliance 8# with the License. You may obtain a copy of the License at 9# 10# http://www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, 13# software distributed under the License is distributed on an 14# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15# KIND, either express or implied. See the License for the 16# specific language governing permissions and limitations 17# under the License. 18# 19 20require 'spec_helper' 21 22describe 'BaseProtocol' do 23 24 before(:each) do 25 @trans = double("MockTransport") 26 @prot = Thrift::BaseProtocol.new(@trans) 27 end 28 29 describe Thrift::BaseProtocol do 30 # most of the methods are stubs, so we can ignore them 31 32 it "should provide a reasonable to_s" do 33 expect(@trans).to receive(:to_s).once.and_return("trans") 34 expect(@prot.to_s).to eq("trans") 35 end 36 37 it "should make trans accessible" do 38 expect(@prot.trans).to eql(@trans) 39 end 40 41 it 'should write out a field nicely (deprecated write_field signature)' do 42 expect(@prot).to receive(:write_field_begin).with('field', 'type', 'fid').ordered 43 expect(@prot).to receive(:write_type).with({:name => 'field', :type => 'type'}, 'value').ordered 44 expect(@prot).to receive(:write_field_end).ordered 45 @prot.write_field('field', 'type', 'fid', 'value') 46 end 47 48 it 'should write out a field nicely' do 49 expect(@prot).to receive(:write_field_begin).with('field', 'type', 'fid').ordered 50 expect(@prot).to receive(:write_type).with({:name => 'field', :type => 'type', :binary => false}, 'value').ordered 51 expect(@prot).to receive(:write_field_end).ordered 52 @prot.write_field({:name => 'field', :type => 'type', :binary => false}, 'fid', 'value') 53 end 54 55 it 'should write out the different types (deprecated write_type signature)' do 56 expect(@prot).to receive(:write_bool).with('bool').ordered 57 expect(@prot).to receive(:write_byte).with('byte').ordered 58 expect(@prot).to receive(:write_double).with('double').ordered 59 expect(@prot).to receive(:write_i16).with('i16').ordered 60 expect(@prot).to receive(:write_i32).with('i32').ordered 61 expect(@prot).to receive(:write_i64).with('i64').ordered 62 expect(@prot).to receive(:write_string).with('string').ordered 63 struct = double('Struct') 64 expect(struct).to receive(:write).with(@prot).ordered 65 @prot.write_type(Thrift::Types::BOOL, 'bool') 66 @prot.write_type(Thrift::Types::BYTE, 'byte') 67 @prot.write_type(Thrift::Types::DOUBLE, 'double') 68 @prot.write_type(Thrift::Types::I16, 'i16') 69 @prot.write_type(Thrift::Types::I32, 'i32') 70 @prot.write_type(Thrift::Types::I64, 'i64') 71 @prot.write_type(Thrift::Types::STRING, 'string') 72 @prot.write_type(Thrift::Types::STRUCT, struct) 73 # all other types are not implemented 74 [Thrift::Types::STOP, Thrift::Types::VOID, Thrift::Types::MAP, Thrift::Types::SET, Thrift::Types::LIST].each do |type| 75 expect { @prot.write_type(type, type.to_s) }.to raise_error(NotImplementedError) 76 end 77 end 78 79 it 'should write out the different types' do 80 expect(@prot).to receive(:write_bool).with('bool').ordered 81 expect(@prot).to receive(:write_byte).with('byte').ordered 82 expect(@prot).to receive(:write_double).with('double').ordered 83 expect(@prot).to receive(:write_i16).with('i16').ordered 84 expect(@prot).to receive(:write_i32).with('i32').ordered 85 expect(@prot).to receive(:write_i64).with('i64').ordered 86 expect(@prot).to receive(:write_string).with('string').ordered 87 expect(@prot).to receive(:write_binary).with('binary').ordered 88 struct = double('Struct') 89 expect(struct).to receive(:write).with(@prot).ordered 90 @prot.write_type({:type => Thrift::Types::BOOL}, 'bool') 91 @prot.write_type({:type => Thrift::Types::BYTE}, 'byte') 92 @prot.write_type({:type => Thrift::Types::DOUBLE}, 'double') 93 @prot.write_type({:type => Thrift::Types::I16}, 'i16') 94 @prot.write_type({:type => Thrift::Types::I32}, 'i32') 95 @prot.write_type({:type => Thrift::Types::I64}, 'i64') 96 @prot.write_type({:type => Thrift::Types::STRING}, 'string') 97 @prot.write_type({:type => Thrift::Types::STRING, :binary => true}, 'binary') 98 @prot.write_type({:type => Thrift::Types::STRUCT}, struct) 99 # all other types are not implemented 100 [Thrift::Types::STOP, Thrift::Types::VOID, Thrift::Types::MAP, Thrift::Types::SET, Thrift::Types::LIST].each do |type| 101 expect { @prot.write_type({:type => type}, type.to_s) }.to raise_error(NotImplementedError) 102 end 103 end 104 105 it 'should read the different types (deprecated read_type signature)' do 106 expect(@prot).to receive(:read_bool).ordered 107 expect(@prot).to receive(:read_byte).ordered 108 expect(@prot).to receive(:read_i16).ordered 109 expect(@prot).to receive(:read_i32).ordered 110 expect(@prot).to receive(:read_i64).ordered 111 expect(@prot).to receive(:read_double).ordered 112 expect(@prot).to receive(:read_string).ordered 113 @prot.read_type(Thrift::Types::BOOL) 114 @prot.read_type(Thrift::Types::BYTE) 115 @prot.read_type(Thrift::Types::I16) 116 @prot.read_type(Thrift::Types::I32) 117 @prot.read_type(Thrift::Types::I64) 118 @prot.read_type(Thrift::Types::DOUBLE) 119 @prot.read_type(Thrift::Types::STRING) 120 # all other types are not implemented 121 [Thrift::Types::STOP, Thrift::Types::VOID, Thrift::Types::MAP, 122 Thrift::Types::SET, Thrift::Types::LIST, Thrift::Types::STRUCT].each do |type| 123 expect { @prot.read_type(type) }.to raise_error(NotImplementedError) 124 end 125 end 126 127 it 'should read the different types' do 128 expect(@prot).to receive(:read_bool).ordered 129 expect(@prot).to receive(:read_byte).ordered 130 expect(@prot).to receive(:read_i16).ordered 131 expect(@prot).to receive(:read_i32).ordered 132 expect(@prot).to receive(:read_i64).ordered 133 expect(@prot).to receive(:read_double).ordered 134 expect(@prot).to receive(:read_string).ordered 135 expect(@prot).to receive(:read_binary).ordered 136 @prot.read_type({:type => Thrift::Types::BOOL}) 137 @prot.read_type({:type => Thrift::Types::BYTE}) 138 @prot.read_type({:type => Thrift::Types::I16}) 139 @prot.read_type({:type => Thrift::Types::I32}) 140 @prot.read_type({:type => Thrift::Types::I64}) 141 @prot.read_type({:type => Thrift::Types::DOUBLE}) 142 @prot.read_type({:type => Thrift::Types::STRING}) 143 @prot.read_type({:type => Thrift::Types::STRING, :binary => true}) 144 # all other types are not implemented 145 [Thrift::Types::STOP, Thrift::Types::VOID, Thrift::Types::MAP, 146 Thrift::Types::SET, Thrift::Types::LIST, Thrift::Types::STRUCT].each do |type| 147 expect { @prot.read_type({:type => type}) }.to raise_error(NotImplementedError) 148 end 149 end 150 151 it "should skip the basic types" do 152 expect(@prot).to receive(:read_bool).ordered 153 expect(@prot).to receive(:read_byte).ordered 154 expect(@prot).to receive(:read_i16).ordered 155 expect(@prot).to receive(:read_i32).ordered 156 expect(@prot).to receive(:read_i64).ordered 157 expect(@prot).to receive(:read_double).ordered 158 expect(@prot).to receive(:read_string).ordered 159 @prot.skip(Thrift::Types::BOOL) 160 @prot.skip(Thrift::Types::BYTE) 161 @prot.skip(Thrift::Types::I16) 162 @prot.skip(Thrift::Types::I32) 163 @prot.skip(Thrift::Types::I64) 164 @prot.skip(Thrift::Types::DOUBLE) 165 @prot.skip(Thrift::Types::STRING) 166 end 167 168 it "should skip structs" do 169 real_skip = @prot.method(:skip) 170 expect(@prot).to receive(:read_struct_begin).ordered 171 expect(@prot).to receive(:read_field_begin).exactly(4).times.and_return( 172 ['field 1', Thrift::Types::STRING, 1], 173 ['field 2', Thrift::Types::I32, 2], 174 ['field 3', Thrift::Types::MAP, 3], 175 [nil, Thrift::Types::STOP, 0] 176 ) 177 expect(@prot).to receive(:read_field_end).exactly(3).times 178 expect(@prot).to receive(:read_string).exactly(3).times 179 expect(@prot).to receive(:read_i32).ordered 180 expect(@prot).to receive(:read_map_begin).ordered.and_return([Thrift::Types::STRING, Thrift::Types::STRING, 1]) 181 # @prot.should_receive(:read_string).exactly(2).times 182 expect(@prot).to receive(:read_map_end).ordered 183 expect(@prot).to receive(:read_struct_end).ordered 184 real_skip.call(Thrift::Types::STRUCT) 185 end 186 187 it "should skip maps" do 188 real_skip = @prot.method(:skip) 189 expect(@prot).to receive(:read_map_begin).ordered.and_return([Thrift::Types::STRING, Thrift::Types::STRUCT, 1]) 190 expect(@prot).to receive(:read_string).ordered 191 expect(@prot).to receive(:read_struct_begin).ordered.and_return(["some_struct"]) 192 expect(@prot).to receive(:read_field_begin).ordered.and_return([nil, Thrift::Types::STOP, nil]); 193 expect(@prot).to receive(:read_struct_end).ordered 194 expect(@prot).to receive(:read_map_end).ordered 195 real_skip.call(Thrift::Types::MAP) 196 end 197 198 it "should skip sets" do 199 real_skip = @prot.method(:skip) 200 expect(@prot).to receive(:read_set_begin).ordered.and_return([Thrift::Types::I64, 9]) 201 expect(@prot).to receive(:read_i64).ordered.exactly(9).times 202 expect(@prot).to receive(:read_set_end) 203 real_skip.call(Thrift::Types::SET) 204 end 205 206 it "should skip lists" do 207 real_skip = @prot.method(:skip) 208 expect(@prot).to receive(:read_list_begin).ordered.and_return([Thrift::Types::DOUBLE, 11]) 209 expect(@prot).to receive(:read_double).ordered.exactly(11).times 210 expect(@prot).to receive(:read_list_end) 211 real_skip.call(Thrift::Types::LIST) 212 end 213 end 214 215 describe Thrift::BaseProtocolFactory do 216 it "should raise NotImplementedError" do 217 # returning nil since Protocol is just an abstract class 218 expect {Thrift::BaseProtocolFactory.new.get_protocol(double("MockTransport"))}.to raise_error(NotImplementedError) 219 end 220 221 it "should provide a reasonable to_s" do 222 expect(Thrift::BaseProtocolFactory.new.to_s).to eq("base") 223 end 224 end 225end 226