1# encoding: UTF-8 2# 3# Licensed to the Apache Software Foundation (ASF) under one 4# or more contributor license agreements. See the NOTICE file 5# distributed with this work for additional information 6# regarding copyright ownership. The ASF licenses this file 7# to you under the Apache License, Version 2.0 (the 8# "License"); you may not use this file except in compliance 9# with the License. You may obtain a copy of the License at 10# 11# http://www.apache.org/licenses/LICENSE-2.0 12# 13# Unless required by applicable law or agreed to in writing, 14# software distributed under the License is distributed on an 15# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16# KIND, either express or implied. See the License for the 17# specific language governing permissions and limitations 18# under the License. 19# 20 21require 'spec_helper' 22 23describe Thrift::CompactProtocol do 24 TESTS = { 25 :byte => (-127..127).to_a, 26 :i16 => (0..14).map {|shift| [1 << shift, -(1 << shift)]}.flatten.sort, 27 :i32 => (0..30).map {|shift| [1 << shift, -(1 << shift)]}.flatten.sort, 28 :i64 => (0..62).map {|shift| [1 << shift, -(1 << shift)]}.flatten.sort, 29 :string => ["", "1", "short", "fourteen123456", "fifteen12345678", "unicode characters: \u20AC \u20AD", "1" * 127, "1" * 3000], 30 :binary => ["", "\001", "\001" * 5, "\001" * 14, "\001" * 15, "\001" * 127, "\001" * 3000], 31 :double => [0.0, 1.0, -1.0, 1.1, -1.1, 10000000.1, 1.0/0.0, -1.0/0.0], 32 :bool => [true, false] 33 } 34 35 it "should encode and decode naked primitives correctly" do 36 TESTS.each_pair do |primitive_type, test_values| 37 test_values.each do |value| 38 # puts "testing #{value}" if primitive_type == :i64 39 trans = Thrift::MemoryBufferTransport.new 40 proto = Thrift::CompactProtocol.new(trans) 41 42 proto.send(writer(primitive_type), value) 43 # puts "buf: #{trans.inspect_buffer}" if primitive_type == :i64 44 read_back = proto.send(reader(primitive_type)) 45 expect(read_back).to eq(value) 46 end 47 end 48 end 49 50 it "should encode and decode primitives in fields correctly" do 51 TESTS.each_pair do |primitive_type, test_values| 52 final_primitive_type = primitive_type == :binary ? :string : primitive_type 53 thrift_type = Thrift::Types.const_get(final_primitive_type.to_s.upcase) 54 # puts primitive_type 55 test_values.each do |value| 56 trans = Thrift::MemoryBufferTransport.new 57 proto = Thrift::CompactProtocol.new(trans) 58 59 proto.write_field_begin(nil, thrift_type, 15) 60 proto.send(writer(primitive_type), value) 61 proto.write_field_end 62 63 proto = Thrift::CompactProtocol.new(trans) 64 name, type, id = proto.read_field_begin 65 expect(type).to eq(thrift_type) 66 expect(id).to eq(15) 67 read_back = proto.send(reader(primitive_type)) 68 expect(read_back).to eq(value) 69 proto.read_field_end 70 end 71 end 72 end 73 74 it "should encode and decode a monster struct correctly" do 75 trans = Thrift::MemoryBufferTransport.new 76 proto = Thrift::CompactProtocol.new(trans) 77 78 struct = Thrift::Test::CompactProtoTestStruct.new 79 # sets and maps don't hash well... not sure what to do here. 80 struct.write(proto) 81 82 struct2 = Thrift::Test::CompactProtoTestStruct.new 83 struct2.read(proto) 84 expect(struct2).to eq(struct) 85 end 86 87 it "should make method calls correctly" do 88 client_out_trans = Thrift::MemoryBufferTransport.new 89 client_out_proto = Thrift::CompactProtocol.new(client_out_trans) 90 91 client_in_trans = Thrift::MemoryBufferTransport.new 92 client_in_proto = Thrift::CompactProtocol.new(client_in_trans) 93 94 processor = Thrift::Test::Srv::Processor.new(JankyHandler.new) 95 96 client = Thrift::Test::Srv::Client.new(client_in_proto, client_out_proto) 97 client.send_Janky(1) 98 # puts client_out_trans.inspect_buffer 99 processor.process(client_out_proto, client_in_proto) 100 expect(client.recv_Janky).to eq(2) 101 end 102 103 it "should deal with fields following fields that have non-delta ids" do 104 brcp = Thrift::Test::BreaksRubyCompactProtocol.new( 105 :field1 => "blah", 106 :field2 => Thrift::Test::BigFieldIdStruct.new( 107 :field1 => "string1", 108 :field2 => "string2"), 109 :field3 => 3) 110 ser = Thrift::Serializer.new(Thrift::CompactProtocolFactory.new) 111 bytes = ser.serialize(brcp) 112 113 deser = Thrift::Deserializer.new(Thrift::CompactProtocolFactory.new) 114 brcp2 = Thrift::Test::BreaksRubyCompactProtocol.new 115 deser.deserialize(brcp2, bytes) 116 expect(brcp2).to eq(brcp) 117 end 118 119 it "should deserialize an empty map to an empty hash" do 120 struct = Thrift::Test::SingleMapTestStruct.new(:i32_map => {}) 121 ser = Thrift::Serializer.new(Thrift::CompactProtocolFactory.new) 122 bytes = ser.serialize(struct) 123 124 deser = Thrift::Deserializer.new(Thrift::CompactProtocolFactory.new) 125 struct2 = Thrift::Test::SingleMapTestStruct.new 126 deser.deserialize(struct2, bytes) 127 expect(struct).to eq(struct2) 128 end 129 130 it "should provide a reasonable to_s" do 131 trans = Thrift::MemoryBufferTransport.new 132 expect(Thrift::CompactProtocol.new(trans).to_s).to eq("compact(memory)") 133 end 134 135 class JankyHandler 136 def Janky(i32arg) 137 i32arg * 2 138 end 139 end 140 141 def writer(sym) 142 "write_#{sym.to_s}" 143 end 144 145 def reader(sym) 146 "read_#{sym.to_s}" 147 end 148end 149 150describe Thrift::CompactProtocolFactory do 151 it "should create a CompactProtocol" do 152 expect(Thrift::CompactProtocolFactory.new.get_protocol(double("MockTransport"))).to be_instance_of(Thrift::CompactProtocol) 153 end 154 155 it "should provide a reasonable to_s" do 156 expect(Thrift::CompactProtocolFactory.new.to_s).to eq("compact") 157 end 158end 159