1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc.  All rights reserved.
3// https://developers.google.com/protocol-buffers/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9//     * Redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer.
11//     * Redistributions in binary form must reproduce the above
12// copyright notice, this list of conditions and the following disclaimer
13// in the documentation and/or other materials provided with the
14// distribution.
15//     * Neither the name of Google Inc. nor the names of its
16// contributors may be used to endorse or promote products derived from
17// this software without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31#ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_EXPECTING_OBJECTWRITER_H__
32#define GOOGLE_PROTOBUF_UTIL_CONVERTER_EXPECTING_OBJECTWRITER_H__
33
34// An implementation of ObjectWriter that automatically sets the
35// gmock expectations for the response to a method. Every method
36// returns the object itself for chaining.
37//
38// Usage:
39//   // Setup
40//   MockObjectWriter mock;
41//   ExpectingObjectWriter ow(&mock);
42//
43//   // Set expectation
44//   ow.StartObject("")
45//       ->RenderString("key", "value")
46//     ->EndObject();
47//
48//   // Actual testing
49//   mock.StartObject(StringPiece())
50//         ->RenderString("key", "value")
51//       ->EndObject();
52
53#include <google/protobuf/stubs/common.h>
54#include <google/protobuf/util/internal/object_writer.h>
55#include <gmock/gmock.h>
56
57namespace google {
58namespace protobuf {
59namespace util {
60namespace converter {
61
62using testing::IsEmpty;
63using testing::NanSensitiveDoubleEq;
64using testing::NanSensitiveFloatEq;
65using testing::Return;
66using testing::StrEq;
67using testing::TypedEq;
68
69class MockObjectWriter : public ObjectWriter {
70 public:
71  MockObjectWriter() {}
72
73  MOCK_METHOD1(StartObject, ObjectWriter*(StringPiece));
74  MOCK_METHOD0(EndObject, ObjectWriter*());
75  MOCK_METHOD1(StartList, ObjectWriter*(StringPiece));
76  MOCK_METHOD0(EndList, ObjectWriter*());
77  MOCK_METHOD2(RenderBool, ObjectWriter*(StringPiece, bool));
78  MOCK_METHOD2(RenderInt32, ObjectWriter*(StringPiece, int32));
79  MOCK_METHOD2(RenderUint32, ObjectWriter*(StringPiece, uint32));
80  MOCK_METHOD2(RenderInt64, ObjectWriter*(StringPiece, int64));
81  MOCK_METHOD2(RenderUint64, ObjectWriter*(StringPiece, uint64));
82  MOCK_METHOD2(RenderDouble, ObjectWriter*(StringPiece, double));
83  MOCK_METHOD2(RenderFloat, ObjectWriter*(StringPiece, float));
84  MOCK_METHOD2(RenderString, ObjectWriter*(StringPiece, StringPiece));
85  MOCK_METHOD2(RenderBytes, ObjectWriter*(StringPiece, StringPiece));
86  MOCK_METHOD1(RenderNull, ObjectWriter*(StringPiece));
87};
88
89class ExpectingObjectWriter : public ObjectWriter {
90 public:
91  explicit ExpectingObjectWriter(MockObjectWriter* mock) : mock_(mock) {}
92
93  virtual ObjectWriter* StartObject(StringPiece name) {
94    (name.empty()
95         ? EXPECT_CALL(*mock_, StartObject(IsEmpty()))
96         : EXPECT_CALL(*mock_, StartObject(StrEq(name.ToString()))))
97        .WillOnce(Return(mock_))
98        .RetiresOnSaturation();
99    return this;
100  }
101
102  virtual ObjectWriter* EndObject() {
103    EXPECT_CALL(*mock_, EndObject())
104        .WillOnce(Return(mock_))
105        .RetiresOnSaturation();
106    return this;
107  }
108
109  virtual ObjectWriter* StartList(StringPiece name) {
110    (name.empty()
111         ? EXPECT_CALL(*mock_, StartList(IsEmpty()))
112         : EXPECT_CALL(*mock_, StartList(StrEq(name.ToString()))))
113        .WillOnce(Return(mock_))
114        .RetiresOnSaturation();
115    return this;
116  }
117
118  virtual ObjectWriter* EndList() {
119    EXPECT_CALL(*mock_, EndList())
120        .WillOnce(Return(mock_))
121        .RetiresOnSaturation();
122    return this;
123  }
124
125  virtual ObjectWriter* RenderBool(StringPiece name, bool value) {
126    (name.empty()
127         ? EXPECT_CALL(*mock_, RenderBool(IsEmpty(), TypedEq<bool>(value)))
128         : EXPECT_CALL(*mock_, RenderBool(StrEq(name.ToString()),
129                                          TypedEq<bool>(value))))
130        .WillOnce(Return(mock_))
131        .RetiresOnSaturation();
132    return this;
133  }
134
135  virtual ObjectWriter* RenderInt32(StringPiece name, int32 value) {
136    (name.empty()
137         ? EXPECT_CALL(*mock_, RenderInt32(IsEmpty(), TypedEq<int32>(value)))
138         : EXPECT_CALL(*mock_, RenderInt32(StrEq(name.ToString()),
139                                           TypedEq<int32>(value))))
140        .WillOnce(Return(mock_))
141        .RetiresOnSaturation();
142    return this;
143  }
144
145  virtual ObjectWriter* RenderUint32(StringPiece name, uint32 value) {
146    (name.empty()
147         ? EXPECT_CALL(*mock_, RenderUint32(IsEmpty(), TypedEq<uint32>(value)))
148         : EXPECT_CALL(*mock_, RenderUint32(StrEq(name.ToString()),
149                                            TypedEq<uint32>(value))))
150        .WillOnce(Return(mock_))
151        .RetiresOnSaturation();
152    return this;
153  }
154
155  virtual ObjectWriter* RenderInt64(StringPiece name, int64 value) {
156    (name.empty()
157         ? EXPECT_CALL(*mock_, RenderInt64(IsEmpty(), TypedEq<int64>(value)))
158         : EXPECT_CALL(*mock_, RenderInt64(StrEq(name.ToString()),
159                                           TypedEq<int64>(value))))
160        .WillOnce(Return(mock_))
161        .RetiresOnSaturation();
162    return this;
163  }
164
165  virtual ObjectWriter* RenderUint64(StringPiece name, uint64 value) {
166    (name.empty()
167         ? EXPECT_CALL(*mock_, RenderUint64(IsEmpty(), TypedEq<uint64>(value)))
168         : EXPECT_CALL(*mock_, RenderUint64(StrEq(name.ToString()),
169                                            TypedEq<uint64>(value))))
170        .WillOnce(Return(mock_))
171        .RetiresOnSaturation();
172    return this;
173  }
174
175  virtual ObjectWriter* RenderDouble(StringPiece name, double value) {
176    (name.empty()
177         ? EXPECT_CALL(*mock_, RenderDouble(IsEmpty(),
178                                            NanSensitiveDoubleEq(value)))
179         : EXPECT_CALL(*mock_, RenderDouble(StrEq(name.ToString()),
180                                            NanSensitiveDoubleEq(value))))
181        .WillOnce(Return(mock_))
182        .RetiresOnSaturation();
183    return this;
184  }
185
186  virtual ObjectWriter* RenderFloat(StringPiece name, float value) {
187    (name.empty()
188         ? EXPECT_CALL(*mock_, RenderFloat(IsEmpty(),
189                                           NanSensitiveFloatEq(value)))
190         : EXPECT_CALL(*mock_, RenderFloat(StrEq(name.ToString()),
191                                           NanSensitiveFloatEq(value))))
192        .WillOnce(Return(mock_))
193        .RetiresOnSaturation();
194    return this;
195  }
196
197  virtual ObjectWriter* RenderString(StringPiece name, StringPiece value) {
198    (name.empty()
199         ? EXPECT_CALL(*mock_, RenderString(IsEmpty(),
200               TypedEq<StringPiece>(value.ToString())))
201         : EXPECT_CALL(*mock_, RenderString(StrEq(name.ToString()),
202               TypedEq<StringPiece>(value.ToString()))))
203        .WillOnce(Return(mock_))
204        .RetiresOnSaturation();
205    return this;
206  }
207  virtual ObjectWriter* RenderBytes(StringPiece name, StringPiece value) {
208    (name.empty()
209         ? EXPECT_CALL(*mock_, RenderBytes(IsEmpty(), TypedEq<StringPiece>(
210                                                          value.ToString())))
211         : EXPECT_CALL(*mock_,
212                       RenderBytes(StrEq(name.ToString()),
213                                   TypedEq<StringPiece>(value.ToString()))))
214        .WillOnce(Return(mock_))
215        .RetiresOnSaturation();
216    return this;
217  }
218
219  virtual ObjectWriter* RenderNull(StringPiece name) {
220    (name.empty() ? EXPECT_CALL(*mock_, RenderNull(IsEmpty()))
221                  : EXPECT_CALL(*mock_, RenderNull(StrEq(name.ToString())))
222                        .WillOnce(Return(mock_))
223                        .RetiresOnSaturation());
224    return this;
225  }
226
227 private:
228  MockObjectWriter* mock_;
229
230  GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ExpectingObjectWriter);
231};
232
233}  // namespace converter
234}  // namespace util
235}  // namespace protobuf
236
237}  // namespace google
238#endif  // GOOGLE_PROTOBUF_UTIL_CONVERTER_EXPECTING_OBJECTWRITER_H__
239