1<?php
2
3require_once('test_base.php');
4require_once('test_util.php');
5
6use Foo\TestMessage;
7use Google\Protobuf\Any;
8use Google\Protobuf\Api;
9use Google\Protobuf\BoolValue;
10use Google\Protobuf\BytesValue;
11use Google\Protobuf\DoubleValue;
12use Google\Protobuf\Duration;
13use Google\Protobuf\Enum;
14use Google\Protobuf\EnumValue;
15use Google\Protobuf\Field;
16use Google\Protobuf\FieldMask;
17use Google\Protobuf\Field\Cardinality;
18use Google\Protobuf\Field\Kind;
19use Google\Protobuf\FloatValue;
20use Google\Protobuf\GPBEmpty;
21use Google\Protobuf\Int32Value;
22use Google\Protobuf\Int64Value;
23use Google\Protobuf\ListValue;
24use Google\Protobuf\Method;
25use Google\Protobuf\Mixin;
26use Google\Protobuf\NullValue;
27use Google\Protobuf\Option;
28use Google\Protobuf\SourceContext;
29use Google\Protobuf\StringValue;
30use Google\Protobuf\Struct;
31use Google\Protobuf\Syntax;
32use Google\Protobuf\Timestamp;
33use Google\Protobuf\Type;
34use Google\Protobuf\UInt32Value;
35use Google\Protobuf\UInt64Value;
36use Google\Protobuf\Value;
37
38class NotMessage {}
39
40class WellKnownTest extends TestBase {
41
42    public function testEmpty()
43    {
44        $msg = new GPBEmpty();
45        $this->assertTrue($msg instanceof \Google\Protobuf\Internal\Message);
46    }
47
48    public function testImportDescriptorProto()
49    {
50        $msg = new TestImportDescriptorProto();
51        $this->assertTrue(true);
52    }
53
54    public function testAny()
55    {
56        // Create embed message
57        $embed = new TestMessage();
58        $this->setFields($embed);
59        $data = $embed->serializeToString();
60
61        // Set any via normal setter.
62        $any = new Any();
63
64        $this->assertSame(
65            $any, $any->setTypeUrl("type.googleapis.com/foo.TestMessage"));
66        $this->assertSame("type.googleapis.com/foo.TestMessage",
67                          $any->getTypeUrl());
68
69        $this->assertSame($any, $any->setValue($data));
70        $this->assertSame($data, $any->getValue());
71
72        // Test unpack.
73        $msg = $any->unpack();
74        $this->assertTrue($msg instanceof TestMessage);
75        $this->expectFields($msg);
76
77        // Test pack.
78        $any = new Any();
79        $any->pack($embed);
80        $this->assertSame($data, $any->getValue());
81        $this->assertSame("type.googleapis.com/foo.TestMessage", $any->getTypeUrl());
82
83        // Test is.
84        $this->assertTrue($any->is(TestMessage::class));
85        $this->assertFalse($any->is(Any::class));
86    }
87
88    /**
89     * @expectedException Exception
90     */
91    public function testAnyUnpackInvalidTypeUrl()
92    {
93        $any = new Any();
94        $any->setTypeUrl("invalid");
95        $any->unpack();
96    }
97
98    /**
99     * @expectedException Exception
100     */
101    public function testAnyUnpackMessageNotAdded()
102    {
103        $any = new Any();
104        $any->setTypeUrl("type.googleapis.com/MessageNotAdded");
105        $any->unpack();
106    }
107
108    /**
109     * @expectedException Exception
110     */
111    public function testAnyUnpackDecodeError()
112    {
113        $any = new Any();
114        $any->setTypeUrl("type.googleapis.com/foo.TestMessage");
115        $any->setValue("abc");
116        $any->unpack();
117    }
118
119    public function testApi()
120    {
121        $m = new Api();
122
123        $m->setName("a");
124        $this->assertSame("a", $m->getName());
125
126        $m->setMethods([new Method()]);
127        $this->assertSame(1, count($m->getMethods()));
128
129        $m->setOptions([new Option()]);
130        $this->assertSame(1, count($m->getOptions()));
131
132        $m->setVersion("a");
133        $this->assertSame("a", $m->getVersion());
134
135        $m->setSourceContext(new SourceContext());
136        $this->assertFalse(is_null($m->getSourceContext()));
137
138        $m->setMixins([new Mixin()]);
139        $this->assertSame(1, count($m->getMixins()));
140
141        $m->setSyntax(Syntax::SYNTAX_PROTO2);
142        $this->assertSame(Syntax::SYNTAX_PROTO2, $m->getSyntax());
143
144        $m = new Method();
145
146        $m->setName("a");
147        $this->assertSame("a", $m->getName());
148
149        $m->setRequestTypeUrl("a");
150        $this->assertSame("a", $m->getRequestTypeUrl());
151
152        $m->setRequestStreaming(true);
153        $this->assertSame(true, $m->getRequestStreaming());
154
155        $m->setResponseTypeUrl("a");
156        $this->assertSame("a", $m->getResponseTypeUrl());
157
158        $m->setResponseStreaming(true);
159        $this->assertSame(true, $m->getResponseStreaming());
160
161        $m->setOptions([new Option()]);
162        $this->assertSame(1, count($m->getOptions()));
163
164        $m = new Mixin();
165
166        $m->setName("a");
167        $this->assertSame("a", $m->getName());
168
169        $m->setRoot("a");
170        $this->assertSame("a", $m->getRoot());
171    }
172
173    public function testEnum()
174    {
175        $m = new Enum();
176
177        $m->setName("a");
178        $this->assertSame("a", $m->getName());
179
180        $m->setEnumvalue([new EnumValue()]);
181        $this->assertSame(1, count($m->getEnumvalue()));
182
183        $m->setOptions([new Option()]);
184        $this->assertSame(1, count($m->getOptions()));
185
186        $m->setSourceContext(new SourceContext());
187        $this->assertFalse(is_null($m->getSourceContext()));
188
189        $m->setSyntax(Syntax::SYNTAX_PROTO2);
190        $this->assertSame(Syntax::SYNTAX_PROTO2, $m->getSyntax());
191    }
192
193    public function testEnumValue()
194    {
195        $m = new EnumValue();
196
197        $m->setName("a");
198        $this->assertSame("a", $m->getName());
199
200        $m->setNumber(1);
201        $this->assertSame(1, $m->getNumber());
202
203        $m->setOptions([new Option()]);
204        $this->assertSame(1, count($m->getOptions()));
205    }
206
207    public function testField()
208    {
209        $m = new Field();
210
211        $m->setKind(Kind::TYPE_DOUBLE);
212        $this->assertSame(Kind::TYPE_DOUBLE, $m->getKind());
213
214        $m->setCardinality(Cardinality::CARDINALITY_OPTIONAL);
215        $this->assertSame(Cardinality::CARDINALITY_OPTIONAL, $m->getCardinality());
216
217        $m->setNumber(1);
218        $this->assertSame(1, $m->getNumber());
219
220        $m->setName("a");
221        $this->assertSame("a", $m->getName());
222
223        $m->setTypeUrl("a");
224        $this->assertSame("a", $m->getTypeUrl());
225
226        $m->setOneofIndex(1);
227        $this->assertSame(1, $m->getOneofIndex());
228
229        $m->setPacked(true);
230        $this->assertSame(true, $m->getPacked());
231
232        $m->setOptions([new Option()]);
233        $this->assertSame(1, count($m->getOptions()));
234
235        $m->setJsonName("a");
236        $this->assertSame("a", $m->getJsonName());
237
238        $m->setDefaultValue("a");
239        $this->assertSame("a", $m->getDefaultValue());
240    }
241
242    public function testFieldMask()
243    {
244        $m = new FieldMask();
245        $m->setPaths(["a"]);
246        $this->assertSame(1, count($m->getPaths()));
247    }
248
249    public function testOption()
250    {
251        $m = new Option();
252
253        $m->setName("a");
254        $this->assertSame("a", $m->getName());
255
256        $m->setValue(new Any());
257        $this->assertFalse(is_null($m->getValue()));
258    }
259
260    public function testSourceContext()
261    {
262        $m = new SourceContext();
263        $m->setFileName("a");
264        $this->assertSame("a", $m->getFileName());
265    }
266
267    public function testStruct()
268    {
269        $m = new ListValue();
270        $m->setValues([new Value()]);
271        $this->assertSame(1, count($m->getValues()));
272
273        $m = new Value();
274
275        $m->setNullValue(NullValue::NULL_VALUE);
276        $this->assertSame(NullValue::NULL_VALUE, $m->getNullValue());
277        $this->assertSame("null_value", $m->getKind());
278
279        $m->setNumberValue(1.0);
280        $this->assertSame(1.0, $m->getNumberValue());
281        $this->assertSame("number_value", $m->getKind());
282
283        $m->setStringValue("a");
284        $this->assertSame("a", $m->getStringValue());
285        $this->assertSame("string_value", $m->getKind());
286
287        $m->setBoolValue(true);
288        $this->assertSame(true, $m->getBoolValue());
289        $this->assertSame("bool_value", $m->getKind());
290
291        $m->setStructValue(new Struct());
292        $this->assertFalse(is_null($m->getStructValue()));
293        $this->assertSame("struct_value", $m->getKind());
294
295        $m->setListValue(new ListValue());
296        $this->assertFalse(is_null($m->getListValue()));
297        $this->assertSame("list_value", $m->getKind());
298
299        $m = new Struct();
300        $m->setFields(array("a"=>new Value()));
301        $this->assertSame(1, count($m->getFields()));
302    }
303
304    public function testTimestamp()
305    {
306        $timestamp = new Timestamp();
307
308        $timestamp->setSeconds(1);
309        $timestamp->setNanos(2);
310        $this->assertEquals(1, $timestamp->getSeconds());
311        $this->assertSame(2, $timestamp->getNanos());
312
313        date_default_timezone_set('UTC');
314        $from = new DateTime('2011-01-01T15:03:01.012345UTC');
315        $timestamp->fromDateTime($from);
316        $this->assertEquals($from->format('U'), $timestamp->getSeconds());
317        $this->assertEquals(1000 * $from->format('u'), $timestamp->getNanos());
318
319        $to = $timestamp->toDateTime();
320        $this->assertSame(\DateTime::class, get_class($to));
321        $this->assertSame($from->format('U'), $to->format('U'));
322        $this->assertSame($from->format('u'), $to->format('u'));
323    }
324
325    public function testType()
326    {
327        $m = new Type();
328
329        $m->setName("a");
330        $this->assertSame("a", $m->getName());
331
332        $m->setFields([new Field()]);
333        $this->assertSame(1, count($m->getFields()));
334
335        $m->setOneofs(["a"]);
336        $this->assertSame(1, count($m->getOneofs()));
337
338        $m->setOptions([new Option()]);
339        $this->assertSame(1, count($m->getOptions()));
340
341        $m->setSourceContext(new SourceContext());
342        $this->assertFalse(is_null($m->getSourceContext()));
343
344        $m->setSyntax(Syntax::SYNTAX_PROTO2);
345        $this->assertSame(Syntax::SYNTAX_PROTO2, $m->getSyntax());
346    }
347
348    public function testDuration()
349    {
350        $duration = new Duration();
351
352        $duration->setSeconds(1);
353        $duration->setNanos(2);
354        $this->assertEquals(1, $duration->getSeconds());
355        $this->assertSame(2, $duration->getNanos());
356    }
357
358    public function testWrappers()
359    {
360        $m = new DoubleValue();
361        $m->setValue(1.0);
362        $this->assertSame(1.0, $m->getValue());
363
364        $m = new FloatValue();
365        $m->setValue(1.0);
366        $this->assertSame(1.0, $m->getValue());
367
368        $m = new Int64Value();
369        $m->setValue(1);
370        $this->assertEquals(1, $m->getValue());
371
372        $m = new UInt64Value();
373        $m->setValue(1);
374        $this->assertEquals(1, $m->getValue());
375
376        $m = new Int32Value();
377        $m->setValue(1);
378        $this->assertSame(1, $m->getValue());
379
380        $m = new UInt32Value();
381        $m->setValue(1);
382        $this->assertSame(1, $m->getValue());
383
384        $m = new BoolValue();
385        $m->setValue(true);
386        $this->assertSame(true, $m->getValue());
387
388        $m = new StringValue();
389        $m->setValue("a");
390        $this->assertSame("a", $m->getValue());
391
392        $m = new BytesValue();
393        $m->setValue("a");
394        $this->assertSame("a", $m->getValue());
395    }
396
397    /**
398     * @dataProvider enumNameValueConversionDataProvider
399     */
400    public function testEnumNameValueConversion($class)
401    {
402        $reflectionClass = new ReflectionClass($class);
403        $constants = $reflectionClass->getConstants();
404        foreach ($constants as $k => $v) {
405            $this->assertSame($k, $class::name($v));
406            $this->assertSame($v, $class::value($k));
407        }
408    }
409
410    public function enumNameValueConversionDataProvider()
411    {
412        return [
413            ['\Google\Protobuf\Field\Cardinality'],
414            ['\Google\Protobuf\Field\Kind'],
415            ['\Google\Protobuf\NullValue'],
416            ['\Google\Protobuf\Syntax'],
417        ];
418    }
419}
420