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-module(test_thrift_compact_protocol).
21-include_lib("eunit/include/eunit.hrl").
22-include("thrift_constants.hrl").
23-include("thrift_protocol.hrl").
24
25
26new(Transport) -> thrift_compact_protocol:new(Transport).
27new() ->
28  {ok, Transport} = thrift_membuffer_transport:new(),
29  thrift_compact_protocol:new(Transport).
30
31new_test() ->
32  new(thrift_membuffer_transport:new()).
33
34write(This, Value) -> thrift_protocol:write(This, Value).
35read(This, Type) -> thrift_protocol:read(This, Type).
36
37str(This0, Value0) ->
38  {This1, ok} = write(This0, {string, Value0}),
39  {This2, {ok, Value1}} = read(This1, string),
40  ?assertEqual(Value0, binary_to_list(Value1)),
41  {This2, ok}.
42string_test() ->
43  {ok, This0} = new(),
44  {This1, ok} = str(This0, "aaa"),
45  {This2, ok} = str(This1, ""),
46  {This2, ok}.
47
48round_trip(This0, Type, Value0) ->
49  {This1, ok} = write(This0, {Type, Value0}),
50  {This2, {ok, Value1}} = read(This1, Type),
51  ?assertEqual(Value0, Value1),
52  {This2, ok}.
53
54bool_test() ->
55  {ok, This0} = new(),
56  {This1, ok} = round_trip(This0, bool, true),
57  {This2, ok} = round_trip(This1, bool, false),
58  {This2, ok}.
59
60byte(This0, Value0) -> round_trip(This0, byte, Value0).
61byte_test() ->
62  {ok, This0} = new(),
63  {This1, ok} = byte(This0, 0),
64  {This2, ok} = byte(This1, 42),
65  {This3, ok} = byte(This2, -1),
66  {This4, ok} = byte(This3, -128),
67  {This4, ok}.
68
69i16(This0, Value0) -> round_trip(This0, i16, Value0).
70i16_test() ->
71  {ok, This0} = new(),
72  {This1, ok} = i16(This0, 0),
73  {This2, ok} = i16(This1, 42),
74  {This3, ok} = i16(This2, 30000),
75  {This4, ok} = i16(This3, -1),
76  {This5, ok} = i16(This4, -128),
77  {This6, ok} = i16(This5, -30000),
78  {This6, ok}.
79
80i32(This0, Value0) -> round_trip(This0, i32, Value0).
81i32_test() ->
82  {ok, This0} = new(),
83  {This1, ok} = i32(This0, 0),
84  {This2, ok} = i32(This1, 42),
85  {This3, ok} = i32(This2, 30000),
86  {This4, ok} = i32(This3, 2000000002),
87  {This5, ok} = i32(This4, -1),
88  {This6, ok} = i32(This5, -128),
89  {This7, ok} = i32(This6, -30000),
90  {This8, ok} = i32(This7, -2000000002),
91  {This8, ok}.
92
93i64(This0, Value0) -> round_trip(This0, i64, Value0).
94i64_test() ->
95  {ok, This0} = new(),
96  {This1, ok} = i64(This0, 0),
97  {This2, ok} = i64(This1, 42),
98  {This3, ok} = i64(This2, 30000),
99  {This4, ok} = i64(This3, 2000000002),
100  {This5, ok} = i64(This4, 100000000000000064),
101  {This6, ok} = i64(This5, -1),
102  {This7, ok} = i64(This6, -128),
103  {This8, ok} = i64(This7, -30000),
104  {This9, ok} = i64(This8, -2000000002),
105  {This10, ok} = i64(This9, -100000000000000064),
106  {This10, ok}.
107
108struct_test() ->
109  {ok, P0} = new(),
110  {P1, ok} = write(P0, #protocol_message_begin{ name = "Message1", type = ?tType_I8, seqid = 3}),
111  {P2, ok} = write(P1, #protocol_struct_begin{}),
112  {P3, ok} = write(P2, #protocol_field_begin{ name = "field1", type = ?tType_I8, id = 1}),
113  {P4, ok} = write(P3, {byte, 42}),
114  {P5, ok} = write(P4, field_end),
115  {P6, ok} = write(P5, #protocol_field_begin{ name = "field2", type = ?tType_I8, id = 14}),
116  {P7, ok} = write(P6, {byte, 3}),
117  {P8, ok} = write(P7, field_end),
118  {P9, ok} = write(P8, #protocol_field_begin{ name = "field3", type = ?tType_I8, id = 42}),
119  {P10, ok} = write(P9, {byte, 8}),
120  {P11, ok} = write(P10, field_end),
121  {P12, ok} = write(P11, field_stop),
122  {P13, ok} = write(P12, struct_end),
123  {P14, ok} = write(P13, message_end),
124
125  {P15, #protocol_message_begin{ name = "Message1", type = ?tType_I8, seqid = 3}} = read(P14, message_begin),
126  {P16, ok} = read(P15, struct_begin),
127  {P17, #protocol_field_begin{ type = ?tType_I8, id = 1 }} = read(P16, field_begin),
128  {P18, {ok, 42}} = read(P17, byte),
129  {P19, ok} = read(P18, field_end),
130  {P20, #protocol_field_begin{ type = ?tType_I8, id = 14 }} = read(P19, field_begin),
131  {P21, {ok, 3}} = read(P20, byte),
132  {P22, ok} = read(P21, field_end),
133  {P23, #protocol_field_begin{ type = ?tType_I8, id = 42 }} = read(P22, field_begin),
134  {P24, {ok, 8}} = read(P23, byte),
135  {P25, ok} = read(P24, field_end),
136  {P26, #protocol_field_begin{ type = ?tType_STOP}} = read(P25, field_begin),
137  {P27, ok} = read(P26, struct_end),
138  {P28, ok} = read(P27, message_end),
139  {P28, ok}.
140
141bool_field_test() ->
142  {ok, P0} = new(),
143  {P1, ok} = write(P0, #protocol_message_begin{ name = "Message1", type = ?tType_I8, seqid = 3}),
144  {P2, ok} = write(P1, #protocol_struct_begin{}),
145  {P3, ok} = write(P2, #protocol_field_begin{ name = "field1", type = ?tType_BOOL, id = 1}),
146  {P4, ok} = write(P3, {bool, true}),
147  {P5, ok} = write(P4, field_end),
148  {P6, ok} = write(P5, #protocol_field_begin{ name = "field2", type = ?tType_BOOL, id = 14}),
149  {P7, ok} = write(P6, {bool, false}),
150  {P8, ok} = write(P7, field_end),
151  {P9, ok} = write(P8, #protocol_field_begin{ name = "field3", type = ?tType_BOOL, id = 42}),
152  {P10, ok} = write(P9, {bool, true}),
153  {P11, ok} = write(P10, field_end),
154  {P12, ok} = write(P11, field_stop),
155  {P13, ok} = write(P12, struct_end),
156  {P14, ok} = write(P13, message_end),
157
158  {P15, #protocol_message_begin{ name = "Message1", type = ?tType_I8, seqid = 3}} = read(P14, message_begin),
159  {P16, ok} = read(P15, struct_begin),
160  {P17, #protocol_field_begin{ type = ?tType_BOOL, id = 1 }} = read(P16, field_begin),
161  {P18, {ok, true}} = read(P17, bool),
162  {P19, ok} = read(P18, field_end),
163  {P20, #protocol_field_begin{ type = ?tType_BOOL, id = 14 }} = read(P19, field_begin),
164  {P21, {ok, false}} = read(P20, bool),
165  {P22, ok} = read(P21, field_end),
166  {P23, #protocol_field_begin{ type = ?tType_BOOL, id = 42 }} = read(P22, field_begin),
167  {P24, {ok, true}} = read(P23, bool),
168  {P25, ok} = read(P24, field_end),
169  {P26, #protocol_field_begin{ type = ?tType_STOP}} = read(P25, field_begin),
170  {P27, ok} = read(P26, struct_end),
171  {P28, ok} = read(P27, message_end),
172  {P28, ok}.
173
174nesting_test() ->
175  {ok, P0} = new(),
176  {P1, ok} = write(P0, #protocol_message_begin{ name = "Message1", type = ?tType_I8, seqid = 3}),
177  {P2, ok} = write(P1, #protocol_struct_begin{}),
178  {P3, ok} = write(P2, #protocol_field_begin{ name = "field1", type = ?tType_BOOL, id = 14}),
179  {P4, ok} = write(P3, {bool, true}),
180  {P5, ok} = write(P4, field_end),
181
182  {P6, ok} = write(P5, #protocol_field_begin{ name = "field2", type = ?tType_STRUCT, id = 28}),
183  {P7, ok} = write(P6, #protocol_struct_begin{}),
184  {P8, ok} = write(P7, #protocol_field_begin{ name = "field2_1", type = ?tType_BOOL, id = 30000}),
185  {P9, ok} = write(P8, {bool, false}),
186  {P10, ok} = write(P9, field_end),
187  {P11, ok} = write(P10, field_stop),
188  {P12, ok} = write(P11, struct_end),
189  {P13, ok} = write(P12, field_end),
190
191  {P14, ok} = write(P13, #protocol_field_begin{ name = "field3", type = ?tType_BOOL, id = 42}),
192  {P15, ok} = write(P14, {bool, true}),
193  {P16, ok} = write(P15, field_end),
194  {P17, ok} = write(P16, field_stop),
195  {P18, ok} = write(P17, struct_end),
196  {P19, ok} = write(P18, message_end),
197
198  {P20, #protocol_message_begin{ name = "Message1", type = ?tType_I8, seqid = 3}} = read(P19, message_begin),
199  {P21, ok} = read(P20, struct_begin),
200  {P22, #protocol_field_begin{ type = ?tType_BOOL, id = 14 }} = read(P21, field_begin),
201  {P23, {ok, true}} = read(P22, bool),
202  {P24, ok} = read(P23, field_end),
203
204  {P25, #protocol_field_begin{ type = ?tType_STRUCT, id = 28 }} = read(P24, field_begin),
205  {P26, ok} = read(P25, struct_begin),
206  {P27, #protocol_field_begin{ type = ?tType_BOOL, id = 30000 }} = read(P26, field_begin),
207  {P28, {ok, false}} = read(P27, bool),
208  {P29, ok} = read(P28, field_end),
209  {P30, #protocol_field_begin{ type = ?tType_STOP }} = read(P29, field_begin),
210  {P31, ok} = read(P30, struct_end),
211  {P32, ok} = read(P31, field_end),
212
213  {P33, #protocol_field_begin{ type = ?tType_BOOL, id = 42 }} = read(P32, field_begin),
214  {P34, {ok, true}} = read(P33, bool),
215  {P35, ok} = read(P34, field_end),
216  {P36, #protocol_field_begin{ type = ?tType_STOP }} = read(P35, field_begin),
217  {P37, ok} = read(P36, struct_end),
218  {P38, ok} = read(P37, message_end),
219  {P38, ok}.
220