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
20package tests
21
22import (
23	"bytes"
24	"context"
25	"testing"
26
27	"github.com/golang/mock/gomock"
28
29	"github.com/apache/thrift/lib/go/test/gopath/src/optionalfieldstest"
30	"github.com/apache/thrift/lib/go/thrift"
31)
32
33func TestIsSetReturnFalseOnCreation(t *testing.T) {
34	ao := optionalfieldstest.NewAllOptional()
35	if ao.IsSetS() {
36		t.Errorf("Optional field S is set on initialization")
37	}
38	if ao.IsSetI() {
39		t.Errorf("Optional field I is set on initialization")
40	}
41	if ao.IsSetB() {
42		t.Errorf("Optional field B is set on initialization")
43	}
44	if ao.IsSetS2() {
45		t.Errorf("Optional field S2 is set on initialization")
46	}
47	if ao.IsSetI2() {
48		t.Errorf("Optional field I2 is set on initialization")
49	}
50	if ao.IsSetB2() {
51		t.Errorf("Optional field B2 is set on initialization")
52	}
53	if ao.IsSetAa() {
54		t.Errorf("Optional field Aa is set on initialization")
55	}
56	if ao.IsSetL() {
57		t.Errorf("Optional field L is set on initialization")
58	}
59	if ao.IsSetL2() {
60		t.Errorf("Optional field L2 is set on initialization")
61	}
62	if ao.IsSetM() {
63		t.Errorf("Optional field M is set on initialization")
64	}
65	if ao.IsSetM2() {
66		t.Errorf("Optional field M2 is set on initialization")
67	}
68	if ao.IsSetBin() {
69		t.Errorf("Optional field Bin is set on initialization")
70	}
71	if ao.IsSetBin2() {
72		t.Errorf("Optional field Bin2 is set on initialization")
73	}
74}
75
76func TestDefaultValuesOnCreation(t *testing.T) {
77	ao := optionalfieldstest.NewAllOptional()
78	if ao.GetS() != "DEFAULT" {
79		t.Errorf("Unexpected default value %#v for field S", ao.GetS())
80	}
81	if ao.GetI() != 42 {
82		t.Errorf("Unexpected default value %#v for field I", ao.GetI())
83	}
84	if ao.GetB() != false {
85		t.Errorf("Unexpected default value %#v for field B", ao.GetB())
86	}
87	if ao.GetS2() != "" {
88		t.Errorf("Unexpected default value %#v for field S2", ao.GetS2())
89	}
90	if ao.GetI2() != 0 {
91		t.Errorf("Unexpected default value %#v for field I2", ao.GetI2())
92	}
93	if ao.GetB2() != false {
94		t.Errorf("Unexpected default value %#v for field B2", ao.GetB2())
95	}
96	if l := ao.GetL(); len(l) != 0 {
97		t.Errorf("Unexpected default value %#v for field L", l)
98	}
99	if l := ao.GetL2(); len(l) != 2 || l[0] != 1 || l[1] != 2 {
100		t.Errorf("Unexpected default value %#v for field L2", l)
101	}
102	//FIXME: should we return empty map here?
103	if m := ao.GetM(); m != nil {
104		t.Errorf("Unexpected default value %#v for field M", m)
105	}
106	if m := ao.GetM2(); len(m) != 2 || m[1] != 2 || m[3] != 4 {
107		t.Errorf("Unexpected default value %#v for field M2", m)
108	}
109	if bv := ao.GetBin(); bv != nil {
110		t.Errorf("Unexpected default value %#v for field Bin", bv)
111	}
112	if bv := ao.GetBin2(); !bytes.Equal(bv, []byte("asdf")) {
113		t.Errorf("Unexpected default value %#v for field Bin2", bv)
114	}
115}
116
117func TestInitialValuesOnCreation(t *testing.T) {
118	ao := optionalfieldstest.NewAllOptional()
119	if ao.S != "DEFAULT" {
120		t.Errorf("Unexpected initial value %#v for field S", ao.S)
121	}
122	if ao.I != 42 {
123		t.Errorf("Unexpected initial value %#v for field I", ao.I)
124	}
125	if ao.B != false {
126		t.Errorf("Unexpected initial value %#v for field B", ao.B)
127	}
128	if ao.S2 != nil {
129		t.Errorf("Unexpected initial value %#v for field S2", ao.S2)
130	}
131	if ao.I2 != nil {
132		t.Errorf("Unexpected initial value %#v for field I2", ao.I2)
133	}
134	if ao.B2 != nil {
135		t.Errorf("Unexpected initial value %#v for field B2", ao.B2)
136	}
137	if ao.L != nil || len(ao.L) != 0 {
138		t.Errorf("Unexpected initial value %#v for field L", ao.L)
139	}
140	if ao.L2 != nil {
141		t.Errorf("Unexpected initial value %#v for field L2", ao.L2)
142	}
143	if ao.M != nil {
144		t.Errorf("Unexpected initial value %#v for field M", ao.M)
145	}
146	if ao.M2 != nil {
147		t.Errorf("Unexpected initial value %#v for field M2", ao.M2)
148	}
149	if ao.Bin != nil || len(ao.Bin) != 0 {
150		t.Errorf("Unexpected initial value %#v for field Bin", ao.Bin)
151	}
152	if !bytes.Equal(ao.Bin2, []byte("asdf")) {
153		t.Errorf("Unexpected initial value %#v for field Bin2", ao.Bin2)
154	}
155}
156
157func TestIsSetReturnTrueAfterUpdate(t *testing.T) {
158	ao := optionalfieldstest.NewAllOptional()
159	ao.S = "somevalue"
160	ao.I = 123
161	ao.B = true
162	ao.Aa = optionalfieldstest.NewStructA()
163	if !ao.IsSetS() {
164		t.Errorf("Field S should be set")
165	}
166	if !ao.IsSetI() {
167		t.Errorf("Field I should be set")
168	}
169	if !ao.IsSetB() {
170		t.Errorf("Field B should be set")
171	}
172	if !ao.IsSetAa() {
173		t.Errorf("Field aa should be set")
174	}
175}
176
177func TestListNotEmpty(t *testing.T) {
178	ao := optionalfieldstest.NewAllOptional()
179	ao.L = []int64{1, 2, 3}
180	if !ao.IsSetL() {
181		t.Errorf("Field L should be set")
182	}
183}
184
185//Make sure that optional fields are not being serialized
186func TestNoOptionalUnsetFieldsOnWire(t *testing.T) {
187	mockCtrl := gomock.NewController(t)
188	defer mockCtrl.Finish()
189	proto := NewMockTProtocol(mockCtrl)
190	gomock.InOrder(
191		proto.EXPECT().WriteStructBegin(context.Background(), "all_optional").Return(nil),
192		proto.EXPECT().WriteFieldStop(context.Background()).Return(nil),
193		proto.EXPECT().WriteStructEnd(context.Background()).Return(nil),
194	)
195	ao := optionalfieldstest.NewAllOptional()
196	ao.Write(context.Background(), proto)
197}
198
199func TestNoSetToDefaultFieldsOnWire(t *testing.T) {
200	mockCtrl := gomock.NewController(t)
201	defer mockCtrl.Finish()
202	proto := NewMockTProtocol(mockCtrl)
203	gomock.InOrder(
204		proto.EXPECT().WriteStructBegin(context.Background(), "all_optional").Return(nil),
205		proto.EXPECT().WriteFieldStop(context.Background()).Return(nil),
206		proto.EXPECT().WriteStructEnd(context.Background()).Return(nil),
207	)
208	ao := optionalfieldstest.NewAllOptional()
209	ao.I = 42
210	ao.Write(context.Background(), proto)
211}
212
213//Make sure that only one field is being serialized when set to non-default
214func TestOneISetFieldOnWire(t *testing.T) {
215	mockCtrl := gomock.NewController(t)
216	defer mockCtrl.Finish()
217	proto := NewMockTProtocol(mockCtrl)
218	gomock.InOrder(
219		proto.EXPECT().WriteStructBegin(context.Background(), "all_optional").Return(nil),
220		proto.EXPECT().WriteFieldBegin(context.Background(), "i", thrift.TType(thrift.I64), int16(2)).Return(nil),
221		proto.EXPECT().WriteI64(context.Background(), int64(123)).Return(nil),
222		proto.EXPECT().WriteFieldEnd(context.Background()).Return(nil),
223		proto.EXPECT().WriteFieldStop(context.Background()).Return(nil),
224		proto.EXPECT().WriteStructEnd(context.Background()).Return(nil),
225	)
226	ao := optionalfieldstest.NewAllOptional()
227	ao.I = 123
228	ao.Write(context.Background(), proto)
229}
230
231func TestOneLSetFieldOnWire(t *testing.T) {
232	mockCtrl := gomock.NewController(t)
233	defer mockCtrl.Finish()
234	proto := NewMockTProtocol(mockCtrl)
235	gomock.InOrder(
236		proto.EXPECT().WriteStructBegin(context.Background(), "all_optional").Return(nil),
237		proto.EXPECT().WriteFieldBegin(context.Background(), "l", thrift.TType(thrift.LIST), int16(9)).Return(nil),
238		proto.EXPECT().WriteListBegin(context.Background(), thrift.TType(thrift.I64), 2).Return(nil),
239		proto.EXPECT().WriteI64(context.Background(), int64(1)).Return(nil),
240		proto.EXPECT().WriteI64(context.Background(), int64(2)).Return(nil),
241		proto.EXPECT().WriteListEnd(context.Background()).Return(nil),
242		proto.EXPECT().WriteFieldEnd(context.Background()).Return(nil),
243		proto.EXPECT().WriteFieldStop(context.Background()).Return(nil),
244		proto.EXPECT().WriteStructEnd(context.Background()).Return(nil),
245	)
246	ao := optionalfieldstest.NewAllOptional()
247	ao.L = []int64{1, 2}
248	ao.Write(context.Background(), proto)
249}
250
251func TestOneBinSetFieldOnWire(t *testing.T) {
252	mockCtrl := gomock.NewController(t)
253	defer mockCtrl.Finish()
254	proto := NewMockTProtocol(mockCtrl)
255	gomock.InOrder(
256		proto.EXPECT().WriteStructBegin(context.Background(), "all_optional").Return(nil),
257		proto.EXPECT().WriteFieldBegin(context.Background(), "bin", thrift.TType(thrift.STRING), int16(13)).Return(nil),
258		proto.EXPECT().WriteBinary(context.Background(), []byte("somebytestring")).Return(nil),
259		proto.EXPECT().WriteFieldEnd(context.Background()).Return(nil),
260		proto.EXPECT().WriteFieldStop(context.Background()).Return(nil),
261		proto.EXPECT().WriteStructEnd(context.Background()).Return(nil),
262	)
263	ao := optionalfieldstest.NewAllOptional()
264	ao.Bin = []byte("somebytestring")
265	ao.Write(context.Background(), proto)
266}
267
268func TestOneEmptyBinSetFieldOnWire(t *testing.T) {
269	mockCtrl := gomock.NewController(t)
270	defer mockCtrl.Finish()
271	proto := NewMockTProtocol(mockCtrl)
272	gomock.InOrder(
273		proto.EXPECT().WriteStructBegin(context.Background(), "all_optional").Return(nil),
274		proto.EXPECT().WriteFieldBegin(context.Background(), "bin", thrift.TType(thrift.STRING), int16(13)).Return(nil),
275		proto.EXPECT().WriteBinary(context.Background(), []byte{}).Return(nil),
276		proto.EXPECT().WriteFieldEnd(context.Background()).Return(nil),
277		proto.EXPECT().WriteFieldStop(context.Background()).Return(nil),
278		proto.EXPECT().WriteStructEnd(context.Background()).Return(nil),
279	)
280	ao := optionalfieldstest.NewAllOptional()
281	ao.Bin = []byte{}
282	ao.Write(context.Background(), proto)
283}
284