Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Side by Side Diff: third_party/google-endpoints/endpoints/test/message_parser_test.py

Issue 2666783008: Add google-endpoints to third_party/. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2016 Google Inc. All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 """Tests for message_parser."""
16
17 import difflib
18 import json
19 import unittest
20
21 import endpoints.message_parser as message_parser
22 from protorpc import message_types
23 from protorpc import messages
24
25 import test_util
26
27
28 package = 'TestPackage'
29
30
31 class ModuleInterfaceTest(test_util.ModuleInterfaceTest,
32 unittest.TestCase):
33
34 MODULE = message_parser
35
36
37 def _assertSchemaEqual(expected, actual, testcase):
38 """Utility method to dump diffs if the schema aren't equal.
39
40 Args:
41 expected: object, the expected results.
42 actual: object, the actual results.
43 testcase: unittest.TestCase, the test case this assertion is used within.
44 """
45 if expected != actual:
46 expected_text = json.dumps(expected, indent=2, sort_keys=True)
47 actual_text = json.dumps(actual, indent=2, sort_keys=True)
48 diff = difflib.unified_diff(expected_text.splitlines(True),
49 actual_text.splitlines(True),
50 fromfile='expected.schema',
51 tofile='actual.schema')
52 diff_text = ''.join(list(diff))
53 testcase.fail('Schema differs from expected:\n%s' % diff_text)
54
55
56 class SelfReference(messages.Message):
57 """This must be at top level to be found by MessageField."""
58 self = messages.MessageField('SelfReference', 1)
59
60
61 class MessageTypeToJsonSchemaTest(unittest.TestCase):
62
63 def testSelfReferenceMessageField(self):
64 """MessageFields should be recursively parsed."""
65
66 parser = message_parser.MessageTypeToJsonSchema()
67 parser.add_message(SelfReference)
68 schemas = parser.schemas()
69 self.assertEquals(1, len(schemas))
70 self.assertTrue(package + 'SelfReference' in schemas)
71
72 def testRecursiveDescent(self):
73 """MessageFields should be recursively parsed."""
74
75 class C(messages.Message):
76 text = messages.StringField(1, required=True)
77
78 class B(messages.Message):
79 c = messages.MessageField(C, 1)
80
81 class A(messages.Message):
82 b = messages.MessageField(B, 1, repeated=True)
83
84 parser = message_parser.MessageTypeToJsonSchema()
85 parser.add_message(A)
86 schemas = parser.schemas()
87 self.assertEquals(3, len(schemas))
88 self.assertTrue(package + 'A' in schemas)
89 self.assertTrue(package + 'B' in schemas)
90 self.assertTrue(package + 'C' in schemas)
91
92 def testRepeatedAndRequired(self):
93 """Repeated and required fields should show up as such in the schema."""
94
95 class AllFields(messages.Message):
96 """Documentation for AllFields."""
97 string = messages.StringField(1)
98 string_required = messages.StringField(2, required=True)
99 string_default_required = messages.StringField(3, required=True,
100 default='Foo')
101 string_repeated = messages.StringField(4, repeated=True)
102
103 class SimpleEnum(messages.Enum):
104 """Simple enumeration type."""
105 VAL1 = 1
106 VAL2 = 2
107
108 enum_value = messages.EnumField(SimpleEnum, 5, default=SimpleEnum.VAL2)
109
110 parser = message_parser.MessageTypeToJsonSchema()
111 parser.add_message(AllFields)
112 schemas = parser.schemas()
113
114 expected = {
115 package + 'AllFields': {
116 'type': 'object',
117 'id': package + 'AllFields',
118 'description': 'Documentation for AllFields.',
119 'properties': {
120 'string': {
121 'type': 'string'
122 },
123 'string_required': {
124 'type': 'string',
125 'required': True
126 },
127 'string_default_required': {
128 'type': 'string',
129 'required': True,
130 'default': 'Foo'
131 },
132 'string_repeated': {
133 'items': {
134 'type': 'string',
135 },
136 'type': 'array'
137 },
138 'enum_value': {
139 'default': 'VAL2',
140 'type': 'string',
141 'enum': ['VAL1', 'VAL2']
142 },
143 }
144 }
145 }
146 _assertSchemaEqual(expected, schemas, self)
147
148 def testAllFieldTypes(self):
149 """Test all the Field types that ProtoRPC supports."""
150
151 class AllTypes(messages.Message):
152 """Contains all field types."""
153
154 class SimpleEnum(messages.Enum):
155 """Simple enumeration type."""
156 VAL1 = 1
157 VAL2 = 2
158
159 bool_value = messages.BooleanField(1, variant=messages.Variant.BOOL)
160 bytes_value = messages.BytesField(2, variant=messages.Variant.BYTES)
161 double_value = messages.FloatField(3, variant=messages.Variant.DOUBLE)
162 enum_value = messages.EnumField(SimpleEnum, 4)
163 float_value = messages.FloatField(5, variant=messages.Variant.FLOAT)
164 int32_value = messages.IntegerField(6, variant=messages.Variant.INT32)
165 int64_value = messages.IntegerField(7, variant=messages.Variant.INT64)
166 string_value = messages.StringField(8, variant=messages.Variant.STRING)
167 uint32_value = messages.IntegerField(9, variant=messages.Variant.UINT32)
168 uint64_value = messages.IntegerField(10, variant=messages.Variant.UINT64)
169 int_value = messages.IntegerField(11) # Default variant is INT64.
170 datetime_value = message_types.DateTimeField(12)
171 repeated_datetime_value = message_types.DateTimeField(13, repeated=True)
172
173 parser = message_parser.MessageTypeToJsonSchema()
174 parser.add_message(AllTypes)
175 schemas = parser.schemas()
176
177 expected = {
178 package + 'AllTypes': {
179 'type': 'object',
180 'id': package + 'AllTypes',
181 'description': 'Contains all field types.',
182 'properties': {
183 'bool_value': {'type': 'boolean'},
184 'bytes_value': {'type': 'string', 'format': 'byte'},
185 'double_value': {'type': 'number', 'format': 'double'},
186 'enum_value': {'type': 'string', 'enum': ['VAL1', 'VAL2']},
187 'float_value': {'type': 'number', 'format': 'float'},
188 'int32_value': {'type': 'integer', 'format': 'int32'},
189 'int64_value': {'type': 'string', 'format': 'int64'},
190 'string_value': {'type': 'string'},
191 'uint32_value': {'type': 'integer', 'format': 'uint32'},
192 'uint64_value': {'type': 'string', 'format': 'uint64'},
193 'int_value': {'type': 'string', 'format': 'int64'},
194 'datetime_value': {'type': 'string', 'format': 'date-time'},
195 'repeated_datetime_value':
196 {'items': {'type': 'string', 'format': 'date-time'},
197 'type': 'array'}
198 }
199 }
200 }
201
202 _assertSchemaEqual(expected, schemas, self)
203
204 def testLargeEnum(self):
205 """Test that an enum with lots of values works."""
206
207 class MyMessage(messages.Message):
208 """Documentation for MyMessage."""
209
210 class LargeEnum(messages.Enum):
211 """Large enumeration type, in a strange order."""
212 ALL = 1000
213 AND = 1050
214 BAR = 4
215 BIND = 3141
216 DARKNESS = 2123
217 FOO = 3
218 IN = 1200
219 ONE = 5
220 RING = 6
221 RULE = 8
222 THE = 1500
223 THEM1 = 9
224 THEM2 = 10000
225 TO = 7
226 VAL1 = 1
227 VAL2 = 2
228
229 enum_value = messages.EnumField(LargeEnum, 1)
230
231 parser = message_parser.MessageTypeToJsonSchema()
232 parser.add_message(MyMessage)
233 schemas = parser.schemas()
234
235 expected = {
236 package + 'MyMessage': {
237 'type': 'object',
238 'id': package + 'MyMessage',
239 'description': 'Documentation for MyMessage.',
240 'properties': {
241 'enum_value': {
242 'type': 'string',
243 'enum': ['VAL1', 'VAL2', 'FOO', 'BAR',
244 'ONE', 'RING', 'TO', 'RULE', 'THEM1', 'ALL',
245 'AND', 'IN', 'THE', 'DARKNESS', 'BIND', 'THEM2']
246 },
247 }
248 }
249 }
250 _assertSchemaEqual(expected, schemas, self)
251
252 def testEmptyMessage(self):
253 """Test the empty edge case."""
254
255 class NoFields(messages.Message):
256 pass
257
258 parser = message_parser.MessageTypeToJsonSchema()
259 parser.add_message(NoFields)
260 schemas = parser.schemas()
261
262 expected = {
263 package + 'NoFields': {
264 'type': 'object',
265 'id': package + 'NoFields',
266 'properties': {
267 }
268 }
269 }
270
271 _assertSchemaEqual(expected, schemas, self)
272
273 def testRefForMessage(self):
274
275 class NoFields(messages.Message):
276 pass
277
278 parser = message_parser.MessageTypeToJsonSchema()
279
280 self.assertRaises(KeyError, parser.ref_for_message_type, NoFields)
281
282 parser.add_message(NoFields)
283 self.assertEqual(package + 'NoFields',
284 parser.ref_for_message_type(NoFields))
285
286 def testMessageFieldDocsAndArrayRef(self):
287 """Descriptions for MessageFields and a reference in an array."""
288
289 class B(messages.Message):
290 """A description of B."""
291 pass
292
293 class A(messages.Message):
294 b = messages.MessageField(B, 1, repeated=True)
295
296 parser = message_parser.MessageTypeToJsonSchema()
297 parser.add_message(A)
298 schemas = parser.schemas()
299
300 expected = {
301 package + 'A': {
302 'type': 'object',
303 'id': package + 'A',
304 'properties': {
305 'b': {
306 'type': 'array',
307 'description': 'A description of B.',
308 'items': {
309 '$ref': package + 'B'
310 }
311 }
312 }
313 },
314 package + 'B': {
315 'type': 'object',
316 'id': package + 'B',
317 'description': 'A description of B.',
318 'properties': {}
319 }
320 }
321
322 _assertSchemaEqual(expected, schemas, self)
323
324 def testNormalizeSchemaName(self):
325
326 class _1_lower_case_name_(messages.Message):
327 pass
328
329 parser = message_parser.MessageTypeToJsonSchema()
330 # Test _, numbers, and case fixing.
331 self.assertEqual(
332 package + '1LowerCaseName',
333 parser.add_message(_1_lower_case_name_))
334
335 def testNormalizeSchemaNameCollision(self):
336
337 class A(messages.Message):
338 pass
339
340 class A_(messages.Message):
341 pass
342
343 parser = message_parser.MessageTypeToJsonSchema()
344 parser.add_message(A)
345 self.assertRaises(KeyError, parser.add_message, A_)
346
347
348 if __name__ == '__main__':
349 unittest.main()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698