| 30 |
ashish |
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 |
|
|
|
20 |
require File.dirname(__FILE__) + '/spec_helper'
|
|
|
21 |
|
|
|
22 |
class ThriftBaseProtocolSpec < Spec::ExampleGroup
|
|
|
23 |
include Thrift
|
|
|
24 |
|
|
|
25 |
before(:each) do
|
|
|
26 |
@trans = mock("MockTransport")
|
|
|
27 |
@prot = BaseProtocol.new(@trans)
|
|
|
28 |
end
|
|
|
29 |
|
|
|
30 |
describe BaseProtocol do
|
|
|
31 |
# most of the methods are stubs, so we can ignore them
|
|
|
32 |
|
|
|
33 |
it "should make trans accessible" do
|
|
|
34 |
@prot.trans.should eql(@trans)
|
|
|
35 |
end
|
|
|
36 |
|
|
|
37 |
it "should write out a field nicely" do
|
|
|
38 |
@prot.should_receive(:write_field_begin).with('field', 'type', 'fid').ordered
|
|
|
39 |
@prot.should_receive(:write_type).with('type', 'value').ordered
|
|
|
40 |
@prot.should_receive(:write_field_end).ordered
|
|
|
41 |
@prot.write_field('field', 'type', 'fid', 'value')
|
|
|
42 |
end
|
|
|
43 |
|
|
|
44 |
it "should write out the different types" do
|
|
|
45 |
@prot.should_receive(:write_bool).with('bool').ordered
|
|
|
46 |
@prot.should_receive(:write_byte).with('byte').ordered
|
|
|
47 |
@prot.should_receive(:write_double).with('double').ordered
|
|
|
48 |
@prot.should_receive(:write_i16).with('i16').ordered
|
|
|
49 |
@prot.should_receive(:write_i32).with('i32').ordered
|
|
|
50 |
@prot.should_receive(:write_i64).with('i64').ordered
|
|
|
51 |
@prot.should_receive(:write_string).with('string').ordered
|
|
|
52 |
struct = mock('Struct')
|
|
|
53 |
struct.should_receive(:write).with(@prot).ordered
|
|
|
54 |
@prot.write_type(Types::BOOL, 'bool')
|
|
|
55 |
@prot.write_type(Types::BYTE, 'byte')
|
|
|
56 |
@prot.write_type(Types::DOUBLE, 'double')
|
|
|
57 |
@prot.write_type(Types::I16, 'i16')
|
|
|
58 |
@prot.write_type(Types::I32, 'i32')
|
|
|
59 |
@prot.write_type(Types::I64, 'i64')
|
|
|
60 |
@prot.write_type(Types::STRING, 'string')
|
|
|
61 |
@prot.write_type(Types::STRUCT, struct)
|
|
|
62 |
# all other types are not implemented
|
|
|
63 |
[Types::STOP, Types::VOID, Types::MAP, Types::SET, Types::LIST].each do |type|
|
|
|
64 |
lambda { @prot.write_type(type, type.to_s) }.should raise_error(NotImplementedError)
|
|
|
65 |
end
|
|
|
66 |
end
|
|
|
67 |
|
|
|
68 |
it "should read the different types" do
|
|
|
69 |
@prot.should_receive(:read_bool).ordered
|
|
|
70 |
@prot.should_receive(:read_byte).ordered
|
|
|
71 |
@prot.should_receive(:read_i16).ordered
|
|
|
72 |
@prot.should_receive(:read_i32).ordered
|
|
|
73 |
@prot.should_receive(:read_i64).ordered
|
|
|
74 |
@prot.should_receive(:read_double).ordered
|
|
|
75 |
@prot.should_receive(:read_string).ordered
|
|
|
76 |
@prot.read_type(Types::BOOL)
|
|
|
77 |
@prot.read_type(Types::BYTE)
|
|
|
78 |
@prot.read_type(Types::I16)
|
|
|
79 |
@prot.read_type(Types::I32)
|
|
|
80 |
@prot.read_type(Types::I64)
|
|
|
81 |
@prot.read_type(Types::DOUBLE)
|
|
|
82 |
@prot.read_type(Types::STRING)
|
|
|
83 |
# all other types are not implemented
|
|
|
84 |
[Types::STOP, Types::VOID, Types::MAP, Types::SET, Types::LIST].each do |type|
|
|
|
85 |
lambda { @prot.read_type(type) }.should raise_error(NotImplementedError)
|
|
|
86 |
end
|
|
|
87 |
end
|
|
|
88 |
|
|
|
89 |
it "should skip the basic types" do
|
|
|
90 |
@prot.should_receive(:read_bool).ordered
|
|
|
91 |
@prot.should_receive(:read_byte).ordered
|
|
|
92 |
@prot.should_receive(:read_i16).ordered
|
|
|
93 |
@prot.should_receive(:read_i32).ordered
|
|
|
94 |
@prot.should_receive(:read_i64).ordered
|
|
|
95 |
@prot.should_receive(:read_double).ordered
|
|
|
96 |
@prot.should_receive(:read_string).ordered
|
|
|
97 |
@prot.skip(Types::BOOL)
|
|
|
98 |
@prot.skip(Types::BYTE)
|
|
|
99 |
@prot.skip(Types::I16)
|
|
|
100 |
@prot.skip(Types::I32)
|
|
|
101 |
@prot.skip(Types::I64)
|
|
|
102 |
@prot.skip(Types::DOUBLE)
|
|
|
103 |
@prot.skip(Types::STRING)
|
|
|
104 |
@prot.skip(Types::STOP) # should do absolutely nothing
|
|
|
105 |
end
|
|
|
106 |
|
|
|
107 |
it "should skip structs" do
|
|
|
108 |
real_skip = @prot.method(:skip)
|
|
|
109 |
@prot.should_receive(:read_struct_begin).ordered
|
|
|
110 |
@prot.should_receive(:read_field_begin).exactly(4).times.and_return(
|
|
|
111 |
['field 1', Types::STRING, 1],
|
|
|
112 |
['field 2', Types::I32, 2],
|
|
|
113 |
['field 3', Types::MAP, 3],
|
|
|
114 |
[nil, Types::STOP, 0]
|
|
|
115 |
)
|
|
|
116 |
@prot.should_receive(:read_field_end).exactly(3).times
|
|
|
117 |
@prot.should_receive(:read_string).exactly(3).times
|
|
|
118 |
@prot.should_receive(:read_i32).ordered
|
|
|
119 |
@prot.should_receive(:read_map_begin).ordered.and_return([Types::STRING, Types::STRING, 1])
|
|
|
120 |
# @prot.should_receive(:read_string).exactly(2).times
|
|
|
121 |
@prot.should_receive(:read_map_end).ordered
|
|
|
122 |
@prot.should_receive(:read_struct_end).ordered
|
|
|
123 |
real_skip.call(Types::STRUCT)
|
|
|
124 |
end
|
|
|
125 |
|
|
|
126 |
it "should skip maps" do
|
|
|
127 |
real_skip = @prot.method(:skip)
|
|
|
128 |
@prot.should_receive(:read_map_begin).ordered.and_return([Types::STRING, Types::STRUCT, 1])
|
|
|
129 |
@prot.should_receive(:read_string).ordered
|
|
|
130 |
@prot.should_receive(:read_struct_begin).ordered.and_return(["some_struct"])
|
|
|
131 |
@prot.should_receive(:read_field_begin).ordered.and_return([nil, Types::STOP, nil]);
|
|
|
132 |
@prot.should_receive(:read_struct_end).ordered
|
|
|
133 |
@prot.should_receive(:read_map_end).ordered
|
|
|
134 |
real_skip.call(Types::MAP)
|
|
|
135 |
end
|
|
|
136 |
|
|
|
137 |
it "should skip sets" do
|
|
|
138 |
real_skip = @prot.method(:skip)
|
|
|
139 |
@prot.should_receive(:read_set_begin).ordered.and_return([Types::I64, 9])
|
|
|
140 |
@prot.should_receive(:read_i64).ordered.exactly(9).times
|
|
|
141 |
@prot.should_receive(:read_set_end)
|
|
|
142 |
real_skip.call(Types::SET)
|
|
|
143 |
end
|
|
|
144 |
|
|
|
145 |
it "should skip lists" do
|
|
|
146 |
real_skip = @prot.method(:skip)
|
|
|
147 |
@prot.should_receive(:read_list_begin).ordered.and_return([Types::DOUBLE, 11])
|
|
|
148 |
@prot.should_receive(:read_double).ordered.exactly(11).times
|
|
|
149 |
@prot.should_receive(:read_list_end)
|
|
|
150 |
real_skip.call(Types::LIST)
|
|
|
151 |
end
|
|
|
152 |
end
|
|
|
153 |
|
|
|
154 |
describe BaseProtocolFactory do
|
|
|
155 |
it "should raise NotImplementedError" do
|
|
|
156 |
# returning nil since Protocol is just an abstract class
|
|
|
157 |
lambda {BaseProtocolFactory.new.get_protocol(mock("MockTransport"))}.should raise_error(NotImplementedError)
|
|
|
158 |
end
|
|
|
159 |
end
|
|
|
160 |
end
|