Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
P
protobuf
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
protobuf
Commits
3f6f73b7
Commit
3f6f73b7
authored
Feb 13, 2017
by
Jie Luo
Committed by
GitHub
Feb 13, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2701 from anandolee/master
Add csharp compatibility tests against v3.0.0
parents
ed423c2c
7288689d
Hide whitespace changes
Inline
Side-by-side
Showing
37 changed files
with
7901 additions
and
1 deletion
+7901
-1
unittest_issues.proto
...y_tests/v3.0.0/protos/csharp/protos/unittest_issues.proto
+126
-0
map_unittest_proto3.proto
....0.0/protos/src/google/protobuf/map_unittest_proto3.proto
+120
-0
unittest_import_proto3.proto
...0/protos/src/google/protobuf/unittest_import_proto3.proto
+68
-0
unittest_import_public_proto3.proto
...s/src/google/protobuf/unittest_import_public_proto3.proto
+42
-0
unittest_proto3.proto
...s/v3.0.0/protos/src/google/protobuf/unittest_proto3.proto
+388
-0
unittest_well_known_types.proto
...rotos/src/google/protobuf/unittest_well_known_types.proto
+114
-0
ByteStringTest.cs
...y_tests/v3.0.0/src/Google.Protobuf.Test/ByteStringTest.cs
+172
-0
CodedInputStreamExtensions.cs
....0/src/Google.Protobuf.Test/CodedInputStreamExtensions.cs
+53
-0
CodedInputStreamTest.cs
...s/v3.0.0/src/Google.Protobuf.Test/CodedInputStreamTest.cs
+599
-0
CodedOutputStreamTest.cs
.../v3.0.0/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
+420
-0
MapFieldTest.cs
....0.0/src/Google.Protobuf.Test/Collections/MapFieldTest.cs
+532
-0
RepeatedFieldTest.cs
...src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs
+746
-0
PropertyInfoExtensionsTest.cs
...Protobuf.Test/Compatibility/PropertyInfoExtensionsTest.cs
+98
-0
TypeExtensionsTest.cs
.../Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs
+117
-0
DeprecatedMemberTest.cs
...s/v3.0.0/src/Google.Protobuf.Test/DeprecatedMemberTest.cs
+55
-0
EqualityTester.cs
...y_tests/v3.0.0/src/Google.Protobuf.Test/EqualityTester.cs
+64
-0
FieldCodecTest.cs
...y_tests/v3.0.0/src/Google.Protobuf.Test/FieldCodecTest.cs
+196
-0
GeneratedMessageTest.cs
...s/v3.0.0/src/Google.Protobuf.Test/GeneratedMessageTest.cs
+724
-0
Google.Protobuf.Test.xproj
...3.0.0/src/Google.Protobuf.Test/Google.Protobuf.Test.xproj
+20
-0
IssuesTest.cs
...ility_tests/v3.0.0/src/Google.Protobuf.Test/IssuesTest.cs
+82
-0
JsonParserTest.cs
...y_tests/v3.0.0/src/Google.Protobuf.Test/JsonParserTest.cs
+940
-0
JsonTokenizerTest.cs
...ests/v3.0.0/src/Google.Protobuf.Test/JsonTokenizerTest.cs
+408
-0
DescriptorsTest.cs
....0/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs
+259
-0
FieldAccessTest.cs
....0/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs
+218
-0
TypeRegistryTest.cs
...0/src/Google.Protobuf.Test/Reflection/TypeRegistryTest.cs
+94
-0
SampleEnum.cs
...ility_tests/v3.0.0/src/Google.Protobuf.Test/SampleEnum.cs
+42
-0
SampleMessages.cs
...y_tests/v3.0.0/src/Google.Protobuf.Test/SampleMessages.cs
+100
-0
TestCornerCases.cs
..._tests/v3.0.0/src/Google.Protobuf.Test/TestCornerCases.cs
+62
-0
ForeignMessagePartial.cs
.../Google.Protobuf.Test/TestProtos/ForeignMessagePartial.cs
+45
-0
AnyTest.cs
...v3.0.0/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs
+116
-0
DurationTest.cs
...0/src/Google.Protobuf.Test/WellKnownTypes/DurationTest.cs
+132
-0
FieldMaskTest.cs
.../src/Google.Protobuf.Test/WellKnownTypes/FieldMaskTest.cs
+62
-0
TimestampTest.cs
.../src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs
+115
-0
WrappersTest.cs
...0/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
+421
-0
project.json
...bility_tests/v3.0.0/src/Google.Protobuf.Test/project.json
+45
-0
test.sh
csharp/compatibility_tests/v3.0.0/test.sh
+102
-0
tests.sh
tests.sh
+4
-1
No files found.
csharp/compatibility_tests/v3.0.0/protos/csharp/protos/unittest_issues.proto
0 → 100644
View file @
3f6f73b7
syntax
=
"proto3"
;
// These proto descriptors have at one time been reported as an issue or defect.
// They are kept here to replicate the issue, and continue to verify the fix.
// Issue: Non-"Google.Protobuffers" namespace will ensure that protobuffer library types are qualified
option
csharp_namespace
=
"UnitTest.Issues.TestProtos"
;
package
unittest_issues
;
option
optimize_for
=
SPEED
;
// Issue 307: when generating doubly-nested types, any references
// should be of the form A.Types.B.Types.C.
message
Issue307
{
message
NestedOnce
{
message
NestedTwice
{
}
}
}
// Old issue 13: http://code.google.com/p/protobuf-csharp-port/issues/detail?id=13
// New issue 309: https://github.com/google/protobuf/issues/309
// message A {
// optional int32 _A = 1;
// }
// message B {
// optional int32 B_ = 1;
// }
//message AB {
// optional int32 a_b = 1;
//}
// Similar issue with numeric names
// Java code failed too, so probably best for this to be a restriction.
// See https://github.com/google/protobuf/issues/308
// message NumberField {
// optional int32 _01 = 1;
// }
// issue 19 - negative enum values
enum
NegativeEnum
{
NEGATIVE_ENUM_ZERO
=
0
;
FiveBelow
=
-
5
;
MinusOne
=
-
1
;
}
message
NegativeEnumMessage
{
NegativeEnum
value
=
1
;
repeated
NegativeEnum
values
=
2
[
packed
=
false
];
repeated
NegativeEnum
packed_values
=
3
[
packed
=
true
];
}
// Issue 21: http://code.google.com/p/protobuf-csharp-port/issues/detail?id=21
// Decorate fields with [deprecated=true] as [System.Obsolete]
message
DeprecatedChild
{
}
enum
DeprecatedEnum
{
DEPRECATED_ZERO
=
0
;
one
=
1
;
}
message
DeprecatedFieldsMessage
{
int32
PrimitiveValue
=
1
[
deprecated
=
true
];
repeated
int32
PrimitiveArray
=
2
[
deprecated
=
true
];
DeprecatedChild
MessageValue
=
3
[
deprecated
=
true
];
repeated
DeprecatedChild
MessageArray
=
4
[
deprecated
=
true
];
DeprecatedEnum
EnumValue
=
5
[
deprecated
=
true
];
repeated
DeprecatedEnum
EnumArray
=
6
[
deprecated
=
true
];
}
// Issue 45: http://code.google.com/p/protobuf-csharp-port/issues/detail?id=45
message
ItemField
{
int32
item
=
1
;
}
message
ReservedNames
{
// Force a nested type called Types
message
SomeNestedType
{
}
int32
types
=
1
;
int32
descriptor
=
2
;
}
message
TestJsonFieldOrdering
{
// These fields are deliberately not declared in numeric
// order, and the oneof fields aren't contiguous either.
// This allows for reasonably robust tests of JSON output
// ordering.
// TestFieldOrderings in unittest_proto3.proto is similar,
// but doesn't include oneofs.
// TODO: Consider adding oneofs to TestFieldOrderings, although
// that will require fixing other tests in multiple platforms.
// Alternatively, consider just adding this to
// unittest_proto3.proto if multiple platforms want it.
int32
plain_int32
=
4
;
oneof
o1
{
string
o1_string
=
2
;
int32
o1_int32
=
5
;
}
string
plain_string
=
1
;
oneof
o2
{
int32
o2_int32
=
6
;
string
o2_string
=
3
;
}
}
message
TestJsonName
{
// Message for testing the effects for of the json_name option
string
name
=
1
;
string
description
=
2
[
json_name
=
"desc"
];
string
guid
=
3
[
json_name
=
"exid"
];
}
csharp/compatibility_tests/v3.0.0/protos/src/google/protobuf/map_unittest_proto3.proto
0 → 100644
View file @
3f6f73b7
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This file is mostly equivalent to map_unittest.proto, but imports
// unittest_proto3.proto instead of unittest.proto, so that it only
// uses proto3 messages. This makes it suitable for testing
// implementations which only support proto3.
// The TestRequiredMessageMap message has been removed as there are no
// required fields in proto3.
syntax
=
"proto3"
;
option
cc_enable_arenas
=
true
;
option
csharp_namespace
=
"Google.Protobuf.TestProtos"
;
import
"google/protobuf/unittest_proto3.proto"
;
// We don't put this in a package within proto2 because we need to make sure
// that the generated code doesn't depend on being in the proto2 namespace.
// In map_test_util.h we do "using namespace unittest = protobuf_unittest".
package
protobuf_unittest
;
// Tests maps.
message
TestMap
{
map
<
int32
,
int32
>
map_int32_int32
=
1
;
map
<
int64
,
int64
>
map_int64_int64
=
2
;
map
<
uint32
,
uint32
>
map_uint32_uint32
=
3
;
map
<
uint64
,
uint64
>
map_uint64_uint64
=
4
;
map
<
sint32
,
sint32
>
map_sint32_sint32
=
5
;
map
<
sint64
,
sint64
>
map_sint64_sint64
=
6
;
map
<
fixed32
,
fixed32
>
map_fixed32_fixed32
=
7
;
map
<
fixed64
,
fixed64
>
map_fixed64_fixed64
=
8
;
map
<
sfixed32
,
sfixed32
>
map_sfixed32_sfixed32
=
9
;
map
<
sfixed64
,
sfixed64
>
map_sfixed64_sfixed64
=
10
;
map
<
int32
,
float
>
map_int32_float
=
11
;
map
<
int32
,
double
>
map_int32_double
=
12
;
map
<
bool
,
bool
>
map_bool_bool
=
13
;
map
<
string
,
string
>
map_string_string
=
14
;
map
<
int32
,
bytes
>
map_int32_bytes
=
15
;
map
<
int32
,
MapEnum
>
map_int32_enum
=
16
;
map
<
int32
,
ForeignMessage
>
map_int32_foreign_message
=
17
;
}
message
TestMapSubmessage
{
TestMap
test_map
=
1
;
}
message
TestMessageMap
{
map
<
int32
,
TestAllTypes
>
map_int32_message
=
1
;
}
// Two map fields share the same entry default instance.
message
TestSameTypeMap
{
map
<
int32
,
int32
>
map1
=
1
;
map
<
int32
,
int32
>
map2
=
2
;
}
enum
MapEnum
{
MAP_ENUM_FOO
=
0
;
MAP_ENUM_BAR
=
1
;
MAP_ENUM_BAZ
=
2
;
}
message
TestArenaMap
{
map
<
int32
,
int32
>
map_int32_int32
=
1
;
map
<
int64
,
int64
>
map_int64_int64
=
2
;
map
<
uint32
,
uint32
>
map_uint32_uint32
=
3
;
map
<
uint64
,
uint64
>
map_uint64_uint64
=
4
;
map
<
sint32
,
sint32
>
map_sint32_sint32
=
5
;
map
<
sint64
,
sint64
>
map_sint64_sint64
=
6
;
map
<
fixed32
,
fixed32
>
map_fixed32_fixed32
=
7
;
map
<
fixed64
,
fixed64
>
map_fixed64_fixed64
=
8
;
map
<
sfixed32
,
sfixed32
>
map_sfixed32_sfixed32
=
9
;
map
<
sfixed64
,
sfixed64
>
map_sfixed64_sfixed64
=
10
;
map
<
int32
,
float
>
map_int32_float
=
11
;
map
<
int32
,
double
>
map_int32_double
=
12
;
map
<
bool
,
bool
>
map_bool_bool
=
13
;
map
<
int32
,
MapEnum
>
map_int32_enum
=
14
;
map
<
int32
,
ForeignMessage
>
map_int32_foreign_message
=
15
;
}
// Previously, message containing enum called Type cannot be used as value of
// map field.
message
MessageContainingEnumCalledType
{
enum
Type
{
TYPE_FOO
=
0
;
}
map
<
int32
,
MessageContainingEnumCalledType
>
type
=
1
;
}
// Previously, message cannot contain map field called "entry".
message
MessageContainingMapCalledEntry
{
map
<
int32
,
int32
>
entry
=
1
;
}
csharp/compatibility_tests/v3.0.0/protos/src/google/protobuf/unittest_import_proto3.proto
0 → 100644
View file @
3f6f73b7
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// A proto file which is imported by unittest_proto3.proto to test importing.
syntax
=
"proto3"
;
// We don't put this in a package within proto2 because we need to make sure
// that the generated code doesn't depend on being in the proto2 namespace.
// In test_util.h we do
// "using namespace unittest_import = protobuf_unittest_import".
package
protobuf_unittest_import
;
option
optimize_for
=
SPEED
;
option
cc_enable_arenas
=
true
;
// Exercise the java_package option.
option
java_package
=
"com.google.protobuf.test"
;
option
csharp_namespace
=
"Google.Protobuf.TestProtos"
;
// Do not set a java_outer_classname here to verify that Proto2 works without
// one.
// Test public import
import
public
"google/protobuf/unittest_import_public_proto3.proto"
;
message
ImportMessage
{
int32
d
=
1
;
}
enum
ImportEnum
{
IMPORT_ENUM_UNSPECIFIED
=
0
;
IMPORT_FOO
=
7
;
IMPORT_BAR
=
8
;
IMPORT_BAZ
=
9
;
}
csharp/compatibility_tests/v3.0.0/protos/src/google/protobuf/unittest_import_public_proto3.proto
0 → 100644
View file @
3f6f73b7
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: liujisi@google.com (Pherl Liu)
syntax
=
"proto3"
;
package
protobuf_unittest_import
;
option
java_package
=
"com.google.protobuf.test"
;
option
csharp_namespace
=
"Google.Protobuf.TestProtos"
;
message
PublicImportMessage
{
int32
e
=
1
;
}
csharp/compatibility_tests/v3.0.0/protos/src/google/protobuf/unittest_proto3.proto
0 → 100644
View file @
3f6f73b7
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// A proto file we will use for unit testing.
syntax
=
"proto3"
;
// Some generic_services option(s) added automatically.
// See: http://go/proto2-generic-services-default
option
cc_generic_services
=
true
;
// auto-added
option
java_generic_services
=
true
;
// auto-added
option
py_generic_services
=
true
;
// auto-added
option
cc_enable_arenas
=
true
;
option
csharp_namespace
=
"Google.Protobuf.TestProtos"
;
import
"google/protobuf/unittest_import_proto3.proto"
;
// We don't put this in a package within proto2 because we need to make sure
// that the generated code doesn't depend on being in the proto2 namespace.
// In test_util.h we do "using namespace unittest = protobuf_unittest".
package
protobuf_unittest
;
// Protos optimized for SPEED use a strict superset of the generated code
// of equivalent ones optimized for CODE_SIZE, so we should optimize all our
// tests for speed unless explicitly testing code size optimization.
option
optimize_for
=
SPEED
;
option
java_outer_classname
=
"UnittestProto"
;
// This proto includes every type of field in both singular and repeated
// forms.
message
TestAllTypes
{
message
NestedMessage
{
// The field name "b" fails to compile in proto1 because it conflicts with
// a local variable named "b" in one of the generated methods. Doh.
// This file needs to compile in proto1 to test backwards-compatibility.
int32
bb
=
1
;
}
enum
NestedEnum
{
NESTED_ENUM_UNSPECIFIED
=
0
;
FOO
=
1
;
BAR
=
2
;
BAZ
=
3
;
NEG
=
-
1
;
// Intentionally negative.
}
// Singular
int32
single_int32
=
1
;
int64
single_int64
=
2
;
uint32
single_uint32
=
3
;
uint64
single_uint64
=
4
;
sint32
single_sint32
=
5
;
sint64
single_sint64
=
6
;
fixed32
single_fixed32
=
7
;
fixed64
single_fixed64
=
8
;
sfixed32
single_sfixed32
=
9
;
sfixed64
single_sfixed64
=
10
;
float
single_float
=
11
;
double
single_double
=
12
;
bool
single_bool
=
13
;
string
single_string
=
14
;
bytes
single_bytes
=
15
;
NestedMessage
single_nested_message
=
18
;
ForeignMessage
single_foreign_message
=
19
;
protobuf_unittest_import.ImportMessage
single_import_message
=
20
;
NestedEnum
single_nested_enum
=
21
;
ForeignEnum
single_foreign_enum
=
22
;
protobuf_unittest_import.ImportEnum
single_import_enum
=
23
;
// Defined in unittest_import_public.proto
protobuf_unittest_import.PublicImportMessage
single_public_import_message
=
26
;
// Repeated
repeated
int32
repeated_int32
=
31
;
repeated
int64
repeated_int64
=
32
;
repeated
uint32
repeated_uint32
=
33
;
repeated
uint64
repeated_uint64
=
34
;
repeated
sint32
repeated_sint32
=
35
;
repeated
sint64
repeated_sint64
=
36
;
repeated
fixed32
repeated_fixed32
=
37
;
repeated
fixed64
repeated_fixed64
=
38
;
repeated
sfixed32
repeated_sfixed32
=
39
;
repeated
sfixed64
repeated_sfixed64
=
40
;
repeated
float
repeated_float
=
41
;
repeated
double
repeated_double
=
42
;
repeated
bool
repeated_bool
=
43
;
repeated
string
repeated_string
=
44
;
repeated
bytes
repeated_bytes
=
45
;
repeated
NestedMessage
repeated_nested_message
=
48
;
repeated
ForeignMessage
repeated_foreign_message
=
49
;
repeated
protobuf_unittest_import.ImportMessage
repeated_import_message
=
50
;
repeated
NestedEnum
repeated_nested_enum
=
51
;
repeated
ForeignEnum
repeated_foreign_enum
=
52
;
repeated
protobuf_unittest_import.ImportEnum
repeated_import_enum
=
53
;
// Defined in unittest_import_public.proto
repeated
protobuf_unittest_import.PublicImportMessage
repeated_public_import_message
=
54
;
// For oneof test
oneof
oneof_field
{
uint32
oneof_uint32
=
111
;
NestedMessage
oneof_nested_message
=
112
;
string
oneof_string
=
113
;
bytes
oneof_bytes
=
114
;
}
}
// This proto includes a recusively nested message.
message
NestedTestAllTypes
{
NestedTestAllTypes
child
=
1
;
TestAllTypes
payload
=
2
;
repeated
NestedTestAllTypes
repeated_child
=
3
;
}
message
TestDeprecatedFields
{
int32
deprecated_int32
=
1
[
deprecated
=
true
];
}
// Define these after TestAllTypes to make sure the compiler can handle
// that.
message
ForeignMessage
{
int32
c
=
1
;
}
enum
ForeignEnum
{
FOREIGN_UNSPECIFIED
=
0
;
FOREIGN_FOO
=
4
;
FOREIGN_BAR
=
5
;
FOREIGN_BAZ
=
6
;
}
message
TestReservedFields
{
reserved
2
,
15
,
9
to
11
;
reserved
"bar"
,
"baz"
;
}
// Test that we can use NestedMessage from outside TestAllTypes.
message
TestForeignNested
{
TestAllTypes.NestedMessage
foreign_nested
=
1
;
}
// Test that really large tag numbers don't break anything.
message
TestReallyLargeTagNumber
{
// The largest possible tag number is 2^28 - 1, since the wire format uses
// three bits to communicate wire type.
int32
a
=
1
;
int32
bb
=
268435455
;
}
message
TestRecursiveMessage
{
TestRecursiveMessage
a
=
1
;
int32
i
=
2
;
}
// Test that mutual recursion works.
message
TestMutualRecursionA
{
TestMutualRecursionB
bb
=
1
;
}
message
TestMutualRecursionB
{
TestMutualRecursionA
a
=
1
;
int32
optional_int32
=
2
;
}
// Test an enum that has multiple values with the same number.
enum
TestEnumWithDupValue
{
TEST_ENUM_WITH_DUP_VALUE_UNSPECIFIED
=
0
;
option
allow_alias
=
true
;
FOO1
=
1
;
BAR1
=
2
;
BAZ
=
3
;
FOO2
=
1
;
BAR2
=
2
;
}
// Test an enum with large, unordered values.
enum
TestSparseEnum
{
TEST_SPARSE_ENUM_UNSPECIFIED
=
0
;
SPARSE_A
=
123
;
SPARSE_B
=
62374
;
SPARSE_C
=
12589234
;
SPARSE_D
=
-
15
;
SPARSE_E
=
-
53452
;
// In proto3, value 0 must be the first one specified
// SPARSE_F = 0;
SPARSE_G
=
2
;
}
// Test message with CamelCase field names. This violates Protocol Buffer
// standard style.
message
TestCamelCaseFieldNames
{
int32
PrimitiveField
=
1
;
string
StringField
=
2
;
ForeignEnum
EnumField
=
3
;
ForeignMessage
MessageField
=
4
;
repeated
int32
RepeatedPrimitiveField
=
7
;
repeated
string
RepeatedStringField
=
8
;
repeated
ForeignEnum
RepeatedEnumField
=
9
;
repeated
ForeignMessage
RepeatedMessageField
=
10
;
}
// We list fields out of order, to ensure that we're using field number and not
// field index to determine serialization order.
message
TestFieldOrderings
{
string
my_string
=
11
;
int64
my_int
=
1
;
float
my_float
=
101
;
message
NestedMessage
{
int64
oo
=
2
;
// The field name "b" fails to compile in proto1 because it conflicts with
// a local variable named "b" in one of the generated methods. Doh.
// This file needs to compile in proto1 to test backwards-compatibility.
int32
bb
=
1
;
}
NestedMessage
single_nested_message
=
200
;
}
message
SparseEnumMessage
{
TestSparseEnum
sparse_enum
=
1
;
}
// Test String and Bytes: string is for valid UTF-8 strings
message
OneString
{
string
data
=
1
;
}
message
MoreString
{
repeated
string
data
=
1
;
}
message
OneBytes
{
bytes
data
=
1
;
}
message
MoreBytes
{
bytes
data
=
1
;
}
// Test int32, uint32, int64, uint64, and bool are all compatible
message
Int32Message
{
int32
data
=
1
;
}
message
Uint32Message
{
uint32
data
=
1
;
}
message
Int64Message
{
int64
data
=
1
;
}
message
Uint64Message
{
uint64
data
=
1
;
}
message
BoolMessage
{
bool
data
=
1
;
}
// Test oneofs.
message
TestOneof
{
oneof
foo
{
int32
foo_int
=
1
;
string
foo_string
=
2
;
TestAllTypes
foo_message
=
3
;
}
}
// Test messages for packed fields
message
TestPackedTypes
{
repeated
int32
packed_int32
=
90
[
packed
=
true
];
repeated
int64
packed_int64
=
91
[
packed
=
true
];
repeated
uint32
packed_uint32
=
92
[
packed
=
true
];
repeated
uint64
packed_uint64
=
93
[
packed
=
true
];
repeated
sint32
packed_sint32
=
94
[
packed
=
true
];
repeated
sint64
packed_sint64
=
95
[
packed
=
true
];
repeated
fixed32
packed_fixed32
=
96
[
packed
=
true
];
repeated
fixed64
packed_fixed64
=
97
[
packed
=
true
];
repeated
sfixed32
packed_sfixed32
=
98
[
packed
=
true
];
repeated
sfixed64
packed_sfixed64
=
99
[
packed
=
true
];
repeated
float
packed_float
=
100
[
packed
=
true
];
repeated
double
packed_double
=
101
[
packed
=
true
];
repeated
bool
packed_bool
=
102
[
packed
=
true
];
repeated
ForeignEnum
packed_enum
=
103
[
packed
=
true
];
}
// A message with the same fields as TestPackedTypes, but without packing. Used
// to test packed <-> unpacked wire compatibility.
message
TestUnpackedTypes
{
repeated
int32
unpacked_int32
=
90
[
packed
=
false
];
repeated
int64
unpacked_int64
=
91
[
packed
=
false
];
repeated
uint32
unpacked_uint32
=
92
[
packed
=
false
];
repeated
uint64
unpacked_uint64
=
93
[
packed
=
false
];
repeated
sint32
unpacked_sint32
=
94
[
packed
=
false
];
repeated
sint64
unpacked_sint64
=
95
[
packed
=
false
];
repeated
fixed32
unpacked_fixed32
=
96
[
packed
=
false
];
repeated
fixed64
unpacked_fixed64
=
97
[
packed
=
false
];
repeated
sfixed32
unpacked_sfixed32
=
98
[
packed
=
false
];
repeated
sfixed64
unpacked_sfixed64
=
99
[
packed
=
false
];
repeated
float
unpacked_float
=
100
[
packed
=
false
];
repeated
double
unpacked_double
=
101
[
packed
=
false
];
repeated
bool
unpacked_bool
=
102
[
packed
=
false
];
repeated
ForeignEnum
unpacked_enum
=
103
[
packed
=
false
];
}
message
TestRepeatedScalarDifferentTagSizes
{
// Parsing repeated fixed size values used to fail. This message needs to be
// used in order to get a tag of the right size; all of the repeated fields
// in TestAllTypes didn't trigger the check.
repeated
fixed32
repeated_fixed32
=
12
;
// Check for a varint type, just for good measure.
repeated
int32
repeated_int32
=
13
;
// These have two-byte tags.
repeated
fixed64
repeated_fixed64
=
2046
;
repeated
int64
repeated_int64
=
2047
;
// Three byte tags.
repeated
float
repeated_float
=
262142
;
repeated
uint64
repeated_uint64
=
262143
;
}
message
TestCommentInjectionMessage
{
// */ <- This should not close the generated doc comment
string
a
=
1
;
}
// Test that RPC services work.
message
FooRequest
{}
message
FooResponse
{}
message
FooClientMessage
{}
message
FooServerMessage
{}
service
TestService
{
rpc
Foo
(
FooRequest
)
returns
(
FooResponse
);
rpc
Bar
(
BarRequest
)
returns
(
BarResponse
);
}
message
BarRequest
{}
message
BarResponse
{}
csharp/compatibility_tests/v3.0.0/protos/src/google/protobuf/unittest_well_known_types.proto
0 → 100644
View file @
3f6f73b7
syntax
=
"proto3"
;
package
protobuf_unittest
;
option
csharp_namespace
=
"Google.Protobuf.TestProtos"
;
option
java_multiple_files
=
true
;
option
java_package
=
"com.google.protobuf.test"
;
import
"google/protobuf/any.proto"
;
import
"google/protobuf/api.proto"
;
import
"google/protobuf/duration.proto"
;
import
"google/protobuf/empty.proto"
;
import
"google/protobuf/field_mask.proto"
;
import
"google/protobuf/source_context.proto"
;
import
"google/protobuf/struct.proto"
;
import
"google/protobuf/timestamp.proto"
;
import
"google/protobuf/type.proto"
;
import
"google/protobuf/wrappers.proto"
;
// Test that we can include all well-known types.
// Each wrapper type is included separately, as languages
// map handle different wrappers in different ways.
message
TestWellKnownTypes
{
google.protobuf.Any
any_field
=
1
;
google.protobuf.Api
api_field
=
2
;
google.protobuf.Duration
duration_field
=
3
;
google.protobuf.Empty
empty_field
=
4
;
google.protobuf.FieldMask
field_mask_field
=
5
;
google.protobuf.SourceContext
source_context_field
=
6
;
google.protobuf.Struct
struct_field
=
7
;
google.protobuf.Timestamp
timestamp_field
=
8
;
google.protobuf.Type
type_field
=
9
;
google.protobuf.DoubleValue
double_field
=
10
;
google.protobuf.FloatValue
float_field
=
11
;
google.protobuf.Int64Value
int64_field
=
12
;
google.protobuf.UInt64Value
uint64_field
=
13
;
google.protobuf.Int32Value
int32_field
=
14
;
google.protobuf.UInt32Value
uint32_field
=
15
;
google.protobuf.BoolValue
bool_field
=
16
;
google.protobuf.StringValue
string_field
=
17
;
google.protobuf.BytesValue
bytes_field
=
18
;
// Part of struct, but useful to be able to test separately
google.protobuf.Value
value_field
=
19
;
}
// A repeated field for each well-known type.
message
RepeatedWellKnownTypes
{
repeated
google.protobuf.Any
any_field
=
1
;
repeated
google.protobuf.Api
api_field
=
2
;
repeated
google.protobuf.Duration
duration_field
=
3
;
repeated
google.protobuf.Empty
empty_field
=
4
;
repeated
google.protobuf.FieldMask
field_mask_field
=
5
;
repeated
google.protobuf.SourceContext
source_context_field
=
6
;
repeated
google.protobuf.Struct
struct_field
=
7
;
repeated
google.protobuf.Timestamp
timestamp_field
=
8
;
repeated
google.protobuf.Type
type_field
=
9
;
// These don't actually make a lot of sense, but they're not prohibited...
repeated
google.protobuf.DoubleValue
double_field
=
10
;
repeated
google.protobuf.FloatValue
float_field
=
11
;
repeated
google.protobuf.Int64Value
int64_field
=
12
;
repeated
google.protobuf.UInt64Value
uint64_field
=
13
;
repeated
google.protobuf.Int32Value
int32_field
=
14
;
repeated
google.protobuf.UInt32Value
uint32_field
=
15
;
repeated
google.protobuf.BoolValue
bool_field
=
16
;
repeated
google.protobuf.StringValue
string_field
=
17
;
repeated
google.protobuf.BytesValue
bytes_field
=
18
;
}
message
OneofWellKnownTypes
{
oneof
oneof_field
{
google.protobuf.Any
any_field
=
1
;
google.protobuf.Api
api_field
=
2
;
google.protobuf.Duration
duration_field
=
3
;
google.protobuf.Empty
empty_field
=
4
;
google.protobuf.FieldMask
field_mask_field
=
5
;
google.protobuf.SourceContext
source_context_field
=
6
;
google.protobuf.Struct
struct_field
=
7
;
google.protobuf.Timestamp
timestamp_field
=
8
;
google.protobuf.Type
type_field
=
9
;
google.protobuf.DoubleValue
double_field
=
10
;
google.protobuf.FloatValue
float_field
=
11
;
google.protobuf.Int64Value
int64_field
=
12
;
google.protobuf.UInt64Value
uint64_field
=
13
;
google.protobuf.Int32Value
int32_field
=
14
;
google.protobuf.UInt32Value
uint32_field
=
15
;
google.protobuf.BoolValue
bool_field
=
16
;
google.protobuf.StringValue
string_field
=
17
;
google.protobuf.BytesValue
bytes_field
=
18
;
}
}
// A map field for each well-known type. We only
// need to worry about the value part of the map being the
// well-known types, as messages can't be map keys.
message
MapWellKnownTypes
{
map
<
int32
,
google.protobuf.Any
>
any_field
=
1
;
map
<
int32
,
google.protobuf.Api
>
api_field
=
2
;
map
<
int32
,
google.protobuf.Duration
>
duration_field
=
3
;
map
<
int32
,
google.protobuf.Empty
>
empty_field
=
4
;
map
<
int32
,
google.protobuf.FieldMask
>
field_mask_field
=
5
;
map
<
int32
,
google.protobuf.SourceContext
>
source_context_field
=
6
;
map
<
int32
,
google.protobuf.Struct
>
struct_field
=
7
;
map
<
int32
,
google.protobuf.Timestamp
>
timestamp_field
=
8
;
map
<
int32
,
google.protobuf.Type
>
type_field
=
9
;
map
<
int32
,
google.protobuf.DoubleValue
>
double_field
=
10
;
map
<
int32
,
google.protobuf.FloatValue
>
float_field
=
11
;
map
<
int32
,
google.protobuf.Int64Value
>
int64_field
=
12
;
map
<
int32
,
google.protobuf.UInt64Value
>
uint64_field
=
13
;
map
<
int32
,
google.protobuf.Int32Value
>
int32_field
=
14
;
map
<
int32
,
google.protobuf.UInt32Value
>
uint32_field
=
15
;
map
<
int32
,
google.protobuf.BoolValue
>
bool_field
=
16
;
map
<
int32
,
google.protobuf.StringValue
>
string_field
=
17
;
map
<
int32
,
google.protobuf.BytesValue
>
bytes_field
=
18
;
}
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/ByteStringTest.cs
0 → 100644
View file @
3f6f73b7
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
System
;
using
System.Text
;
using
NUnit.Framework
;
namespace
Google.Protobuf
{
public
class
ByteStringTest
{
[
Test
]
public
void
Equality
()
{
ByteString
b1
=
ByteString
.
CopyFrom
(
1
,
2
,
3
);
ByteString
b2
=
ByteString
.
CopyFrom
(
1
,
2
,
3
);
ByteString
b3
=
ByteString
.
CopyFrom
(
1
,
2
,
4
);
ByteString
b4
=
ByteString
.
CopyFrom
(
1
,
2
,
3
,
4
);
EqualityTester
.
AssertEquality
(
b1
,
b1
);
EqualityTester
.
AssertEquality
(
b1
,
b2
);
EqualityTester
.
AssertInequality
(
b1
,
b3
);
EqualityTester
.
AssertInequality
(
b1
,
b4
);
EqualityTester
.
AssertInequality
(
b1
,
null
);
#pragma warning disable 1718 // Deliberately calling ==(b1, b1) and !=(b1, b1)
Assert
.
IsTrue
(
b1
==
b1
);
Assert
.
IsTrue
(
b1
==
b2
);
Assert
.
IsFalse
(
b1
==
b3
);
Assert
.
IsFalse
(
b1
==
b4
);
Assert
.
IsFalse
(
b1
==
null
);
Assert
.
IsTrue
((
ByteString
)
null
==
null
);
Assert
.
IsFalse
(
b1
!=
b1
);
Assert
.
IsFalse
(
b1
!=
b2
);
#pragma warning disable 1718
Assert
.
IsTrue
(
b1
!=
b3
);
Assert
.
IsTrue
(
b1
!=
b4
);
Assert
.
IsTrue
(
b1
!=
null
);
Assert
.
IsFalse
((
ByteString
)
null
!=
null
);
}
[
Test
]
public
void
EmptyByteStringHasZeroSize
()
{
Assert
.
AreEqual
(
0
,
ByteString
.
Empty
.
Length
);
}
[
Test
]
public
void
CopyFromStringWithExplicitEncoding
()
{
ByteString
bs
=
ByteString
.
CopyFrom
(
"AB"
,
Encoding
.
Unicode
);
Assert
.
AreEqual
(
4
,
bs
.
Length
);
Assert
.
AreEqual
(
65
,
bs
[
0
]);
Assert
.
AreEqual
(
0
,
bs
[
1
]);
Assert
.
AreEqual
(
66
,
bs
[
2
]);
Assert
.
AreEqual
(
0
,
bs
[
3
]);
}
[
Test
]
public
void
IsEmptyWhenEmpty
()
{
Assert
.
IsTrue
(
ByteString
.
CopyFromUtf8
(
""
).
IsEmpty
);
}
[
Test
]
public
void
IsEmptyWhenNotEmpty
()
{
Assert
.
IsFalse
(
ByteString
.
CopyFromUtf8
(
"X"
).
IsEmpty
);
}
[
Test
]
public
void
CopyFromByteArrayCopiesContents
()
{
byte
[]
data
=
new
byte
[
1
];
data
[
0
]
=
10
;
ByteString
bs
=
ByteString
.
CopyFrom
(
data
);
Assert
.
AreEqual
(
10
,
bs
[
0
]);
data
[
0
]
=
5
;
Assert
.
AreEqual
(
10
,
bs
[
0
]);
}
[
Test
]
public
void
ToByteArrayCopiesContents
()
{
ByteString
bs
=
ByteString
.
CopyFromUtf8
(
"Hello"
);
byte
[]
data
=
bs
.
ToByteArray
();
Assert
.
AreEqual
((
byte
)
'H'
,
data
[
0
]);
Assert
.
AreEqual
((
byte
)
'H'
,
bs
[
0
]);
data
[
0
]
=
0
;
Assert
.
AreEqual
(
0
,
data
[
0
]);
Assert
.
AreEqual
((
byte
)
'H'
,
bs
[
0
]);
}
[
Test
]
public
void
CopyFromUtf8UsesUtf8
()
{
ByteString
bs
=
ByteString
.
CopyFromUtf8
(
"\u20ac"
);
Assert
.
AreEqual
(
3
,
bs
.
Length
);
Assert
.
AreEqual
(
0xe2
,
bs
[
0
]);
Assert
.
AreEqual
(
0x82
,
bs
[
1
]);
Assert
.
AreEqual
(
0xac
,
bs
[
2
]);
}
[
Test
]
public
void
CopyFromPortion
()
{
byte
[]
data
=
new
byte
[]
{
0
,
1
,
2
,
3
,
4
,
5
,
6
};
ByteString
bs
=
ByteString
.
CopyFrom
(
data
,
2
,
3
);
Assert
.
AreEqual
(
3
,
bs
.
Length
);
Assert
.
AreEqual
(
2
,
bs
[
0
]);
Assert
.
AreEqual
(
3
,
bs
[
1
]);
}
[
Test
]
public
void
ToStringUtf8
()
{
ByteString
bs
=
ByteString
.
CopyFromUtf8
(
"\u20ac"
);
Assert
.
AreEqual
(
"\u20ac"
,
bs
.
ToStringUtf8
());
}
[
Test
]
public
void
ToStringWithExplicitEncoding
()
{
ByteString
bs
=
ByteString
.
CopyFrom
(
"\u20ac"
,
Encoding
.
Unicode
);
Assert
.
AreEqual
(
"\u20ac"
,
bs
.
ToString
(
Encoding
.
Unicode
));
}
[
Test
]
public
void
FromBase64_WithText
()
{
byte
[]
data
=
new
byte
[]
{
0
,
1
,
2
,
3
,
4
,
5
,
6
};
string
base64
=
Convert
.
ToBase64String
(
data
);
ByteString
bs
=
ByteString
.
FromBase64
(
base64
);
Assert
.
AreEqual
(
data
,
bs
.
ToByteArray
());
}
[
Test
]
public
void
FromBase64_Empty
()
{
// Optimization which also fixes issue 61.
Assert
.
AreSame
(
ByteString
.
Empty
,
ByteString
.
FromBase64
(
""
));
}
}
}
\ No newline at end of file
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedInputStreamExtensions.cs
0 → 100644
View file @
3f6f73b7
#
region
Copyright
notice
and
license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
NUnit.Framework
;
namespace
Google.Protobuf
{
internal
static
class
CodedInputStreamExtensions
{
public
static
void
AssertNextTag
(
this
CodedInputStream
input
,
uint
expectedTag
)
{
uint
tag
=
input
.
ReadTag
();
Assert
.
AreEqual
(
expectedTag
,
tag
);
}
public
static
T
ReadMessage
<
T
>(
this
CodedInputStream
stream
,
MessageParser
<
T
>
parser
)
where
T
:
IMessage
<
T
>
{
var
message
=
parser
.
CreateTemplate
();
stream
.
ReadMessage
(
message
);
return
message
;
}
}
}
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedInputStreamTest.cs
0 → 100644
View file @
3f6f73b7
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
System
;
using
System.IO
;
using
Google.Protobuf.TestProtos
;
using
NUnit.Framework
;
namespace
Google.Protobuf
{
public
class
CodedInputStreamTest
{
/// <summary>
/// Helper to construct a byte array from a bunch of bytes. The inputs are
/// actually ints so that I can use hex notation and not get stupid errors
/// about precision.
/// </summary>
private
static
byte
[]
Bytes
(
params
int
[]
bytesAsInts
)
{
byte
[]
bytes
=
new
byte
[
bytesAsInts
.
Length
];
for
(
int
i
=
0
;
i
<
bytesAsInts
.
Length
;
i
++)
{
bytes
[
i
]
=
(
byte
)
bytesAsInts
[
i
];
}
return
bytes
;
}
/// <summary>
/// Parses the given bytes using ReadRawVarint32() and ReadRawVarint64()
/// </summary>
private
static
void
AssertReadVarint
(
byte
[]
data
,
ulong
value
)
{
CodedInputStream
input
=
new
CodedInputStream
(
data
);
Assert
.
AreEqual
((
uint
)
value
,
input
.
ReadRawVarint32
());
input
=
new
CodedInputStream
(
data
);
Assert
.
AreEqual
(
value
,
input
.
ReadRawVarint64
());
Assert
.
IsTrue
(
input
.
IsAtEnd
);
// Try different block sizes.
for
(
int
bufferSize
=
1
;
bufferSize
<=
16
;
bufferSize
*=
2
)
{
input
=
new
CodedInputStream
(
new
SmallBlockInputStream
(
data
,
bufferSize
));
Assert
.
AreEqual
((
uint
)
value
,
input
.
ReadRawVarint32
());
input
=
new
CodedInputStream
(
new
SmallBlockInputStream
(
data
,
bufferSize
));
Assert
.
AreEqual
(
value
,
input
.
ReadRawVarint64
());
Assert
.
IsTrue
(
input
.
IsAtEnd
);
}
// Try reading directly from a MemoryStream. We want to verify that it
// doesn't read past the end of the input, so write an extra byte - this
// lets us test the position at the end.
MemoryStream
memoryStream
=
new
MemoryStream
();
memoryStream
.
Write
(
data
,
0
,
data
.
Length
);
memoryStream
.
WriteByte
(
0
);
memoryStream
.
Position
=
0
;
Assert
.
AreEqual
((
uint
)
value
,
CodedInputStream
.
ReadRawVarint32
(
memoryStream
));
Assert
.
AreEqual
(
data
.
Length
,
memoryStream
.
Position
);
}
/// <summary>
/// Parses the given bytes using ReadRawVarint32() and ReadRawVarint64() and
/// expects them to fail with an InvalidProtocolBufferException whose
/// description matches the given one.
/// </summary>
private
static
void
AssertReadVarintFailure
(
InvalidProtocolBufferException
expected
,
byte
[]
data
)
{
CodedInputStream
input
=
new
CodedInputStream
(
data
);
var
exception
=
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
input
.
ReadRawVarint32
());
Assert
.
AreEqual
(
expected
.
Message
,
exception
.
Message
);
input
=
new
CodedInputStream
(
data
);
exception
=
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
input
.
ReadRawVarint64
());
Assert
.
AreEqual
(
expected
.
Message
,
exception
.
Message
);
// Make sure we get the same error when reading directly from a Stream.
exception
=
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
CodedInputStream
.
ReadRawVarint32
(
new
MemoryStream
(
data
)));
Assert
.
AreEqual
(
expected
.
Message
,
exception
.
Message
);
}
[
Test
]
public
void
ReadVarint
()
{
AssertReadVarint
(
Bytes
(
0x00
),
0
);
AssertReadVarint
(
Bytes
(
0x01
),
1
);
AssertReadVarint
(
Bytes
(
0x7f
),
127
);
// 14882
AssertReadVarint
(
Bytes
(
0xa2
,
0x74
),
(
0x22
<<
0
)
|
(
0x74
<<
7
));
// 2961488830
AssertReadVarint
(
Bytes
(
0xbe
,
0xf7
,
0x92
,
0x84
,
0x0b
),
(
0x3e
<<
0
)
|
(
0x77
<<
7
)
|
(
0x12
<<
14
)
|
(
0x04
<<
21
)
|
(
0x0bL
<<
28
));
// 64-bit
// 7256456126
AssertReadVarint
(
Bytes
(
0xbe
,
0xf7
,
0x92
,
0x84
,
0x1b
),
(
0x3e
<<
0
)
|
(
0x77
<<
7
)
|
(
0x12
<<
14
)
|
(
0x04
<<
21
)
|
(
0x1bL
<<
28
));
// 41256202580718336
AssertReadVarint
(
Bytes
(
0x80
,
0xe6
,
0xeb
,
0x9c
,
0xc3
,
0xc9
,
0xa4
,
0x49
),
(
0x00
<<
0
)
|
(
0x66
<<
7
)
|
(
0x6b
<<
14
)
|
(
0x1c
<<
21
)
|
(
0x43L
<<
28
)
|
(
0x49L
<<
35
)
|
(
0x24L
<<
42
)
|
(
0x49L
<<
49
));
// 11964378330978735131
AssertReadVarint
(
Bytes
(
0x9b
,
0xa8
,
0xf9
,
0xc2
,
0xbb
,
0xd6
,
0x80
,
0x85
,
0xa6
,
0x01
),
(
0x1b
<<
0
)
|
(
0x28
<<
7
)
|
(
0x79
<<
14
)
|
(
0x42
<<
21
)
|
(
0x3bU
L
<<
28
)
|
(
0x56U
L
<<
35
)
|
(
0x00U
L
<<
42
)
|
(
0x05U
L
<<
49
)
|
(
0x26U
L
<<
56
)
|
(
0x01U
L
<<
63
));
// Failures
AssertReadVarintFailure
(
InvalidProtocolBufferException
.
MalformedVarint
(),
Bytes
(
0x80
,
0x80
,
0x80
,
0x80
,
0x80
,
0x80
,
0x80
,
0x80
,
0x80
,
0x80
,
0x00
));
AssertReadVarintFailure
(
InvalidProtocolBufferException
.
TruncatedMessage
(),
Bytes
(
0x80
));
}
/// <summary>
/// Parses the given bytes using ReadRawLittleEndian32() and checks
/// that the result matches the given value.
/// </summary>
private
static
void
AssertReadLittleEndian32
(
byte
[]
data
,
uint
value
)
{
CodedInputStream
input
=
new
CodedInputStream
(
data
);
Assert
.
AreEqual
(
value
,
input
.
ReadRawLittleEndian32
());
Assert
.
IsTrue
(
input
.
IsAtEnd
);
// Try different block sizes.
for
(
int
blockSize
=
1
;
blockSize
<=
16
;
blockSize
*=
2
)
{
input
=
new
CodedInputStream
(
new
SmallBlockInputStream
(
data
,
blockSize
));
Assert
.
AreEqual
(
value
,
input
.
ReadRawLittleEndian32
());
Assert
.
IsTrue
(
input
.
IsAtEnd
);
}
}
/// <summary>
/// Parses the given bytes using ReadRawLittleEndian64() and checks
/// that the result matches the given value.
/// </summary>
private
static
void
AssertReadLittleEndian64
(
byte
[]
data
,
ulong
value
)
{
CodedInputStream
input
=
new
CodedInputStream
(
data
);
Assert
.
AreEqual
(
value
,
input
.
ReadRawLittleEndian64
());
Assert
.
IsTrue
(
input
.
IsAtEnd
);
// Try different block sizes.
for
(
int
blockSize
=
1
;
blockSize
<=
16
;
blockSize
*=
2
)
{
input
=
new
CodedInputStream
(
new
SmallBlockInputStream
(
data
,
blockSize
));
Assert
.
AreEqual
(
value
,
input
.
ReadRawLittleEndian64
());
Assert
.
IsTrue
(
input
.
IsAtEnd
);
}
}
[
Test
]
public
void
ReadLittleEndian
()
{
AssertReadLittleEndian32
(
Bytes
(
0x78
,
0x56
,
0x34
,
0x12
),
0x12345678
);
AssertReadLittleEndian32
(
Bytes
(
0xf0
,
0xde
,
0xbc
,
0x9a
),
0x9abcdef0
);
AssertReadLittleEndian64
(
Bytes
(
0xf0
,
0xde
,
0xbc
,
0x9a
,
0x78
,
0x56
,
0x34
,
0x12
),
0x123456789abcdef0L
);
AssertReadLittleEndian64
(
Bytes
(
0x78
,
0x56
,
0x34
,
0x12
,
0xf0
,
0xde
,
0xbc
,
0x9a
),
0x9abcdef012345678U
L
);
}
[
Test
]
public
void
DecodeZigZag32
()
{
Assert
.
AreEqual
(
0
,
CodedInputStream
.
DecodeZigZag32
(
0
));
Assert
.
AreEqual
(-
1
,
CodedInputStream
.
DecodeZigZag32
(
1
));
Assert
.
AreEqual
(
1
,
CodedInputStream
.
DecodeZigZag32
(
2
));
Assert
.
AreEqual
(-
2
,
CodedInputStream
.
DecodeZigZag32
(
3
));
Assert
.
AreEqual
(
0x3FFFFFFF
,
CodedInputStream
.
DecodeZigZag32
(
0x7FFFFFFE
));
Assert
.
AreEqual
(
unchecked
((
int
)
0xC0000000
),
CodedInputStream
.
DecodeZigZag32
(
0x7FFFFFFF
));
Assert
.
AreEqual
(
0x7FFFFFFF
,
CodedInputStream
.
DecodeZigZag32
(
0xFFFFFFFE
));
Assert
.
AreEqual
(
unchecked
((
int
)
0x80000000
),
CodedInputStream
.
DecodeZigZag32
(
0xFFFFFFFF
));
}
[
Test
]
public
void
DecodeZigZag64
()
{
Assert
.
AreEqual
(
0
,
CodedInputStream
.
DecodeZigZag64
(
0
));
Assert
.
AreEqual
(-
1
,
CodedInputStream
.
DecodeZigZag64
(
1
));
Assert
.
AreEqual
(
1
,
CodedInputStream
.
DecodeZigZag64
(
2
));
Assert
.
AreEqual
(-
2
,
CodedInputStream
.
DecodeZigZag64
(
3
));
Assert
.
AreEqual
(
0x000000003FFFFFFFL
,
CodedInputStream
.
DecodeZigZag64
(
0x000000007FFFFFFEL
));
Assert
.
AreEqual
(
unchecked
((
long
)
0xFFFFFFFFC0000000L
),
CodedInputStream
.
DecodeZigZag64
(
0x000000007FFFFFFFL
));
Assert
.
AreEqual
(
0x000000007FFFFFFFL
,
CodedInputStream
.
DecodeZigZag64
(
0x00000000FFFFFFFEL
));
Assert
.
AreEqual
(
unchecked
((
long
)
0xFFFFFFFF80000000L
),
CodedInputStream
.
DecodeZigZag64
(
0x00000000FFFFFFFFL
));
Assert
.
AreEqual
(
0x7FFFFFFFFFFFFFFFL
,
CodedInputStream
.
DecodeZigZag64
(
0xFFFFFFFFFFFFFFFEL
));
Assert
.
AreEqual
(
unchecked
((
long
)
0x8000000000000000L
),
CodedInputStream
.
DecodeZigZag64
(
0xFFFFFFFFFFFFFFFFL
));
}
[
Test
]
public
void
ReadWholeMessage_VaryingBlockSizes
()
{
TestAllTypes
message
=
SampleMessages
.
CreateFullTestAllTypes
();
byte
[]
rawBytes
=
message
.
ToByteArray
();
Assert
.
AreEqual
(
rawBytes
.
Length
,
message
.
CalculateSize
());
TestAllTypes
message2
=
TestAllTypes
.
Parser
.
ParseFrom
(
rawBytes
);
Assert
.
AreEqual
(
message
,
message2
);
// Try different block sizes.
for
(
int
blockSize
=
1
;
blockSize
<
256
;
blockSize
*=
2
)
{
message2
=
TestAllTypes
.
Parser
.
ParseFrom
(
new
SmallBlockInputStream
(
rawBytes
,
blockSize
));
Assert
.
AreEqual
(
message
,
message2
);
}
}
[
Test
]
public
void
ReadHugeBlob
()
{
// Allocate and initialize a 1MB blob.
byte
[]
blob
=
new
byte
[
1
<<
20
];
for
(
int
i
=
0
;
i
<
blob
.
Length
;
i
++)
{
blob
[
i
]
=
(
byte
)
i
;
}
// Make a message containing it.
var
message
=
new
TestAllTypes
{
SingleBytes
=
ByteString
.
CopyFrom
(
blob
)
};
// Serialize and parse it. Make sure to parse from an InputStream, not
// directly from a ByteString, so that CodedInputStream uses buffered
// reading.
TestAllTypes
message2
=
TestAllTypes
.
Parser
.
ParseFrom
(
message
.
ToByteString
());
Assert
.
AreEqual
(
message
,
message2
);
}
[
Test
]
public
void
ReadMaliciouslyLargeBlob
()
{
MemoryStream
ms
=
new
MemoryStream
();
CodedOutputStream
output
=
new
CodedOutputStream
(
ms
);
uint
tag
=
WireFormat
.
MakeTag
(
1
,
WireFormat
.
WireType
.
LengthDelimited
);
output
.
WriteRawVarint32
(
tag
);
output
.
WriteRawVarint32
(
0x7FFFFFFF
);
output
.
WriteRawBytes
(
new
byte
[
32
]);
// Pad with a few random bytes.
output
.
Flush
();
ms
.
Position
=
0
;
CodedInputStream
input
=
new
CodedInputStream
(
ms
);
Assert
.
AreEqual
(
tag
,
input
.
ReadTag
());
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
input
.
ReadBytes
());
}
internal
static
TestRecursiveMessage
MakeRecursiveMessage
(
int
depth
)
{
if
(
depth
==
0
)
{
return
new
TestRecursiveMessage
{
I
=
5
};
}
else
{
return
new
TestRecursiveMessage
{
A
=
MakeRecursiveMessage
(
depth
-
1
)
};
}
}
internal
static
void
AssertMessageDepth
(
TestRecursiveMessage
message
,
int
depth
)
{
if
(
depth
==
0
)
{
Assert
.
IsNull
(
message
.
A
);
Assert
.
AreEqual
(
5
,
message
.
I
);
}
else
{
Assert
.
IsNotNull
(
message
.
A
);
AssertMessageDepth
(
message
.
A
,
depth
-
1
);
}
}
[
Test
]
public
void
MaliciousRecursion
()
{
ByteString
data64
=
MakeRecursiveMessage
(
64
).
ToByteString
();
ByteString
data65
=
MakeRecursiveMessage
(
65
).
ToByteString
();
AssertMessageDepth
(
TestRecursiveMessage
.
Parser
.
ParseFrom
(
data64
),
64
);
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
TestRecursiveMessage
.
Parser
.
ParseFrom
(
data65
));
CodedInputStream
input
=
CodedInputStream
.
CreateWithLimits
(
new
MemoryStream
(
data64
.
ToByteArray
()),
1000000
,
63
);
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
TestRecursiveMessage
.
Parser
.
ParseFrom
(
input
));
}
[
Test
]
public
void
SizeLimit
()
{
// Have to use a Stream rather than ByteString.CreateCodedInput as SizeLimit doesn't
// apply to the latter case.
MemoryStream
ms
=
new
MemoryStream
(
SampleMessages
.
CreateFullTestAllTypes
().
ToByteArray
());
CodedInputStream
input
=
CodedInputStream
.
CreateWithLimits
(
ms
,
16
,
100
);
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
TestAllTypes
.
Parser
.
ParseFrom
(
input
));
}
/// <summary>
/// Tests that if we read an string that contains invalid UTF-8, no exception
/// is thrown. Instead, the invalid bytes are replaced with the Unicode
/// "replacement character" U+FFFD.
/// </summary>
[
Test
]
public
void
ReadInvalidUtf8
()
{
MemoryStream
ms
=
new
MemoryStream
();
CodedOutputStream
output
=
new
CodedOutputStream
(
ms
);
uint
tag
=
WireFormat
.
MakeTag
(
1
,
WireFormat
.
WireType
.
LengthDelimited
);
output
.
WriteRawVarint32
(
tag
);
output
.
WriteRawVarint32
(
1
);
output
.
WriteRawBytes
(
new
byte
[]
{
0x80
});
output
.
Flush
();
ms
.
Position
=
0
;
CodedInputStream
input
=
new
CodedInputStream
(
ms
);
Assert
.
AreEqual
(
tag
,
input
.
ReadTag
());
string
text
=
input
.
ReadString
();
Assert
.
AreEqual
(
'\
ufffd
'
,
text
[
0
]);
}
/// <summary>
/// A stream which limits the number of bytes it reads at a time.
/// We use this to make sure that CodedInputStream doesn't screw up when
/// reading in small blocks.
/// </summary>
private
sealed
class
SmallBlockInputStream
:
MemoryStream
{
private
readonly
int
blockSize
;
public
SmallBlockInputStream
(
byte
[]
data
,
int
blockSize
)
:
base
(
data
)
{
this
.
blockSize
=
blockSize
;
}
public
override
int
Read
(
byte
[]
buffer
,
int
offset
,
int
count
)
{
return
base
.
Read
(
buffer
,
offset
,
Math
.
Min
(
count
,
blockSize
));
}
}
[
Test
]
public
void
TestNegativeEnum
()
{
byte
[]
bytes
=
{
0xFE
,
0xFF
,
0xFF
,
0xFF
,
0xFF
,
0xFF
,
0xFF
,
0xFF
,
0xFF
,
0x01
};
CodedInputStream
input
=
new
CodedInputStream
(
bytes
);
Assert
.
AreEqual
((
int
)
SampleEnum
.
NegativeValue
,
input
.
ReadEnum
());
Assert
.
IsTrue
(
input
.
IsAtEnd
);
}
//Issue 71: CodedInputStream.ReadBytes go to slow path unnecessarily
[
Test
]
public
void
TestSlowPathAvoidance
()
{
using
(
var
ms
=
new
MemoryStream
())
{
CodedOutputStream
output
=
new
CodedOutputStream
(
ms
);
output
.
WriteTag
(
1
,
WireFormat
.
WireType
.
LengthDelimited
);
output
.
WriteBytes
(
ByteString
.
CopyFrom
(
new
byte
[
100
]));
output
.
WriteTag
(
2
,
WireFormat
.
WireType
.
LengthDelimited
);
output
.
WriteBytes
(
ByteString
.
CopyFrom
(
new
byte
[
100
]));
output
.
Flush
();
ms
.
Position
=
0
;
CodedInputStream
input
=
new
CodedInputStream
(
ms
,
new
byte
[
ms
.
Length
/
2
],
0
,
0
);
uint
tag
=
input
.
ReadTag
();
Assert
.
AreEqual
(
1
,
WireFormat
.
GetTagFieldNumber
(
tag
));
Assert
.
AreEqual
(
100
,
input
.
ReadBytes
().
Length
);
tag
=
input
.
ReadTag
();
Assert
.
AreEqual
(
2
,
WireFormat
.
GetTagFieldNumber
(
tag
));
Assert
.
AreEqual
(
100
,
input
.
ReadBytes
().
Length
);
}
}
[
Test
]
public
void
Tag0Throws
()
{
var
input
=
new
CodedInputStream
(
new
byte
[]
{
0
});
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
input
.
ReadTag
());
}
[
Test
]
public
void
SkipGroup
()
{
// Create an output stream with a group in:
// Field 1: string "field 1"
// Field 2: group containing:
// Field 1: fixed int32 value 100
// Field 2: string "ignore me"
// Field 3: nested group containing
// Field 1: fixed int64 value 1000
// Field 3: string "field 3"
var
stream
=
new
MemoryStream
();
var
output
=
new
CodedOutputStream
(
stream
);
output
.
WriteTag
(
1
,
WireFormat
.
WireType
.
LengthDelimited
);
output
.
WriteString
(
"field 1"
);
// The outer group...
output
.
WriteTag
(
2
,
WireFormat
.
WireType
.
StartGroup
);
output
.
WriteTag
(
1
,
WireFormat
.
WireType
.
Fixed32
);
output
.
WriteFixed32
(
100
);
output
.
WriteTag
(
2
,
WireFormat
.
WireType
.
LengthDelimited
);
output
.
WriteString
(
"ignore me"
);
// The nested group...
output
.
WriteTag
(
3
,
WireFormat
.
WireType
.
StartGroup
);
output
.
WriteTag
(
1
,
WireFormat
.
WireType
.
Fixed64
);
output
.
WriteFixed64
(
1000
);
// Note: Not sure the field number is relevant for end group...
output
.
WriteTag
(
3
,
WireFormat
.
WireType
.
EndGroup
);
// End the outer group
output
.
WriteTag
(
2
,
WireFormat
.
WireType
.
EndGroup
);
output
.
WriteTag
(
3
,
WireFormat
.
WireType
.
LengthDelimited
);
output
.
WriteString
(
"field 3"
);
output
.
Flush
();
stream
.
Position
=
0
;
// Now act like a generated client
var
input
=
new
CodedInputStream
(
stream
);
Assert
.
AreEqual
(
WireFormat
.
MakeTag
(
1
,
WireFormat
.
WireType
.
LengthDelimited
),
input
.
ReadTag
());
Assert
.
AreEqual
(
"field 1"
,
input
.
ReadString
());
Assert
.
AreEqual
(
WireFormat
.
MakeTag
(
2
,
WireFormat
.
WireType
.
StartGroup
),
input
.
ReadTag
());
input
.
SkipLastField
();
// Should consume the whole group, including the nested one.
Assert
.
AreEqual
(
WireFormat
.
MakeTag
(
3
,
WireFormat
.
WireType
.
LengthDelimited
),
input
.
ReadTag
());
Assert
.
AreEqual
(
"field 3"
,
input
.
ReadString
());
}
[
Test
]
public
void
SkipGroup_WrongEndGroupTag
()
{
// Create an output stream with:
// Field 1: string "field 1"
// Start group 2
// Field 3: fixed int32
// End group 4 (should give an error)
var
stream
=
new
MemoryStream
();
var
output
=
new
CodedOutputStream
(
stream
);
output
.
WriteTag
(
1
,
WireFormat
.
WireType
.
LengthDelimited
);
output
.
WriteString
(
"field 1"
);
// The outer group...
output
.
WriteTag
(
2
,
WireFormat
.
WireType
.
StartGroup
);
output
.
WriteTag
(
3
,
WireFormat
.
WireType
.
Fixed32
);
output
.
WriteFixed32
(
100
);
output
.
WriteTag
(
4
,
WireFormat
.
WireType
.
EndGroup
);
output
.
Flush
();
stream
.
Position
=
0
;
// Now act like a generated client
var
input
=
new
CodedInputStream
(
stream
);
Assert
.
AreEqual
(
WireFormat
.
MakeTag
(
1
,
WireFormat
.
WireType
.
LengthDelimited
),
input
.
ReadTag
());
Assert
.
AreEqual
(
"field 1"
,
input
.
ReadString
());
Assert
.
AreEqual
(
WireFormat
.
MakeTag
(
2
,
WireFormat
.
WireType
.
StartGroup
),
input
.
ReadTag
());
Assert
.
Throws
<
InvalidProtocolBufferException
>(
input
.
SkipLastField
);
}
[
Test
]
public
void
RogueEndGroupTag
()
{
// If we have an end-group tag without a leading start-group tag, generated
// code will just call SkipLastField... so that should fail.
var
stream
=
new
MemoryStream
();
var
output
=
new
CodedOutputStream
(
stream
);
output
.
WriteTag
(
1
,
WireFormat
.
WireType
.
EndGroup
);
output
.
Flush
();
stream
.
Position
=
0
;
var
input
=
new
CodedInputStream
(
stream
);
Assert
.
AreEqual
(
WireFormat
.
MakeTag
(
1
,
WireFormat
.
WireType
.
EndGroup
),
input
.
ReadTag
());
Assert
.
Throws
<
InvalidProtocolBufferException
>(
input
.
SkipLastField
);
}
[
Test
]
public
void
EndOfStreamReachedWhileSkippingGroup
()
{
var
stream
=
new
MemoryStream
();
var
output
=
new
CodedOutputStream
(
stream
);
output
.
WriteTag
(
1
,
WireFormat
.
WireType
.
StartGroup
);
output
.
WriteTag
(
2
,
WireFormat
.
WireType
.
StartGroup
);
output
.
WriteTag
(
2
,
WireFormat
.
WireType
.
EndGroup
);
output
.
Flush
();
stream
.
Position
=
0
;
// Now act like a generated client
var
input
=
new
CodedInputStream
(
stream
);
input
.
ReadTag
();
Assert
.
Throws
<
InvalidProtocolBufferException
>(
input
.
SkipLastField
);
}
[
Test
]
public
void
RecursionLimitAppliedWhileSkippingGroup
()
{
var
stream
=
new
MemoryStream
();
var
output
=
new
CodedOutputStream
(
stream
);
for
(
int
i
=
0
;
i
<
CodedInputStream
.
DefaultRecursionLimit
+
1
;
i
++)
{
output
.
WriteTag
(
1
,
WireFormat
.
WireType
.
StartGroup
);
}
for
(
int
i
=
0
;
i
<
CodedInputStream
.
DefaultRecursionLimit
+
1
;
i
++)
{
output
.
WriteTag
(
1
,
WireFormat
.
WireType
.
EndGroup
);
}
output
.
Flush
();
stream
.
Position
=
0
;
// Now act like a generated client
var
input
=
new
CodedInputStream
(
stream
);
Assert
.
AreEqual
(
WireFormat
.
MakeTag
(
1
,
WireFormat
.
WireType
.
StartGroup
),
input
.
ReadTag
());
Assert
.
Throws
<
InvalidProtocolBufferException
>(
input
.
SkipLastField
);
}
[
Test
]
public
void
Construction_Invalid
()
{
Assert
.
Throws
<
ArgumentNullException
>(()
=>
new
CodedInputStream
((
byte
[])
null
));
Assert
.
Throws
<
ArgumentNullException
>(()
=>
new
CodedInputStream
(
null
,
0
,
0
));
Assert
.
Throws
<
ArgumentNullException
>(()
=>
new
CodedInputStream
((
Stream
)
null
));
Assert
.
Throws
<
ArgumentOutOfRangeException
>(()
=>
new
CodedInputStream
(
new
byte
[
10
],
100
,
0
));
Assert
.
Throws
<
ArgumentOutOfRangeException
>(()
=>
new
CodedInputStream
(
new
byte
[
10
],
5
,
10
));
}
[
Test
]
public
void
CreateWithLimits_InvalidLimits
()
{
var
stream
=
new
MemoryStream
();
Assert
.
Throws
<
ArgumentOutOfRangeException
>(()
=>
CodedInputStream
.
CreateWithLimits
(
stream
,
0
,
1
));
Assert
.
Throws
<
ArgumentOutOfRangeException
>(()
=>
CodedInputStream
.
CreateWithLimits
(
stream
,
1
,
0
));
}
[
Test
]
public
void
Dispose_DisposesUnderlyingStream
()
{
var
memoryStream
=
new
MemoryStream
();
Assert
.
IsTrue
(
memoryStream
.
CanRead
);
using
(
var
cis
=
new
CodedInputStream
(
memoryStream
))
{
}
Assert
.
IsFalse
(
memoryStream
.
CanRead
);
// Disposed
}
[
Test
]
public
void
Dispose_WithLeaveOpen
()
{
var
memoryStream
=
new
MemoryStream
();
Assert
.
IsTrue
(
memoryStream
.
CanRead
);
using
(
var
cis
=
new
CodedInputStream
(
memoryStream
,
true
))
{
}
Assert
.
IsTrue
(
memoryStream
.
CanRead
);
// We left the stream open
}
}
}
\ No newline at end of file
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
0 → 100644
View file @
3f6f73b7
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
System
;
using
System.IO
;
using
Google.Protobuf.TestProtos
;
using
NUnit.Framework
;
namespace
Google.Protobuf
{
public
class
CodedOutputStreamTest
{
/// <summary>
/// Writes the given value using WriteRawVarint32() and WriteRawVarint64() and
/// checks that the result matches the given bytes
/// </summary>
private
static
void
AssertWriteVarint
(
byte
[]
data
,
ulong
value
)
{
// Only do 32-bit write if the value fits in 32 bits.
if
((
value
>>
32
)
==
0
)
{
MemoryStream
rawOutput
=
new
MemoryStream
();
CodedOutputStream
output
=
new
CodedOutputStream
(
rawOutput
);
output
.
WriteRawVarint32
((
uint
)
value
);
output
.
Flush
();
Assert
.
AreEqual
(
data
,
rawOutput
.
ToArray
());
// Also try computing size.
Assert
.
AreEqual
(
data
.
Length
,
CodedOutputStream
.
ComputeRawVarint32Size
((
uint
)
value
));
}
{
MemoryStream
rawOutput
=
new
MemoryStream
();
CodedOutputStream
output
=
new
CodedOutputStream
(
rawOutput
);
output
.
WriteRawVarint64
(
value
);
output
.
Flush
();
Assert
.
AreEqual
(
data
,
rawOutput
.
ToArray
());
// Also try computing size.
Assert
.
AreEqual
(
data
.
Length
,
CodedOutputStream
.
ComputeRawVarint64Size
(
value
));
}
// Try different buffer sizes.
for
(
int
bufferSize
=
1
;
bufferSize
<=
16
;
bufferSize
*=
2
)
{
// Only do 32-bit write if the value fits in 32 bits.
if
((
value
>>
32
)
==
0
)
{
MemoryStream
rawOutput
=
new
MemoryStream
();
CodedOutputStream
output
=
new
CodedOutputStream
(
rawOutput
,
bufferSize
);
output
.
WriteRawVarint32
((
uint
)
value
);
output
.
Flush
();
Assert
.
AreEqual
(
data
,
rawOutput
.
ToArray
());
}
{
MemoryStream
rawOutput
=
new
MemoryStream
();
CodedOutputStream
output
=
new
CodedOutputStream
(
rawOutput
,
bufferSize
);
output
.
WriteRawVarint64
(
value
);
output
.
Flush
();
Assert
.
AreEqual
(
data
,
rawOutput
.
ToArray
());
}
}
}
/// <summary>
/// Tests WriteRawVarint32() and WriteRawVarint64()
/// </summary>
[
Test
]
public
void
WriteVarint
()
{
AssertWriteVarint
(
new
byte
[]
{
0x00
},
0
);
AssertWriteVarint
(
new
byte
[]
{
0x01
},
1
);
AssertWriteVarint
(
new
byte
[]
{
0x7f
},
127
);
// 14882
AssertWriteVarint
(
new
byte
[]
{
0xa2
,
0x74
},
(
0x22
<<
0
)
|
(
0x74
<<
7
));
// 2961488830
AssertWriteVarint
(
new
byte
[]
{
0xbe
,
0xf7
,
0x92
,
0x84
,
0x0b
},
(
0x3e
<<
0
)
|
(
0x77
<<
7
)
|
(
0x12
<<
14
)
|
(
0x04
<<
21
)
|
(
0x0bL
<<
28
));
// 64-bit
// 7256456126
AssertWriteVarint
(
new
byte
[]
{
0xbe
,
0xf7
,
0x92
,
0x84
,
0x1b
},
(
0x3e
<<
0
)
|
(
0x77
<<
7
)
|
(
0x12
<<
14
)
|
(
0x04
<<
21
)
|
(
0x1bL
<<
28
));
// 41256202580718336
AssertWriteVarint
(
new
byte
[]
{
0x80
,
0xe6
,
0xeb
,
0x9c
,
0xc3
,
0xc9
,
0xa4
,
0x49
},
(
0x00
<<
0
)
|
(
0x66
<<
7
)
|
(
0x6b
<<
14
)
|
(
0x1c
<<
21
)
|
(
0x43U
L
<<
28
)
|
(
0x49L
<<
35
)
|
(
0x24U
L
<<
42
)
|
(
0x49U
L
<<
49
));
// 11964378330978735131
AssertWriteVarint
(
new
byte
[]
{
0x9b
,
0xa8
,
0xf9
,
0xc2
,
0xbb
,
0xd6
,
0x80
,
0x85
,
0xa6
,
0x01
},
unchecked
((
ulong
)
((
0x1b
<<
0
)
|
(
0x28
<<
7
)
|
(
0x79
<<
14
)
|
(
0x42
<<
21
)
|
(
0x3bL
<<
28
)
|
(
0x56L
<<
35
)
|
(
0x00L
<<
42
)
|
(
0x05L
<<
49
)
|
(
0x26L
<<
56
)
|
(
0x01L
<<
63
))));
}
/// <summary>
/// Parses the given bytes using WriteRawLittleEndian32() and checks
/// that the result matches the given value.
/// </summary>
private
static
void
AssertWriteLittleEndian32
(
byte
[]
data
,
uint
value
)
{
MemoryStream
rawOutput
=
new
MemoryStream
();
CodedOutputStream
output
=
new
CodedOutputStream
(
rawOutput
);
output
.
WriteRawLittleEndian32
(
value
);
output
.
Flush
();
Assert
.
AreEqual
(
data
,
rawOutput
.
ToArray
());
// Try different buffer sizes.
for
(
int
bufferSize
=
1
;
bufferSize
<=
16
;
bufferSize
*=
2
)
{
rawOutput
=
new
MemoryStream
();
output
=
new
CodedOutputStream
(
rawOutput
,
bufferSize
);
output
.
WriteRawLittleEndian32
(
value
);
output
.
Flush
();
Assert
.
AreEqual
(
data
,
rawOutput
.
ToArray
());
}
}
/// <summary>
/// Parses the given bytes using WriteRawLittleEndian64() and checks
/// that the result matches the given value.
/// </summary>
private
static
void
AssertWriteLittleEndian64
(
byte
[]
data
,
ulong
value
)
{
MemoryStream
rawOutput
=
new
MemoryStream
();
CodedOutputStream
output
=
new
CodedOutputStream
(
rawOutput
);
output
.
WriteRawLittleEndian64
(
value
);
output
.
Flush
();
Assert
.
AreEqual
(
data
,
rawOutput
.
ToArray
());
// Try different block sizes.
for
(
int
blockSize
=
1
;
blockSize
<=
16
;
blockSize
*=
2
)
{
rawOutput
=
new
MemoryStream
();
output
=
new
CodedOutputStream
(
rawOutput
,
blockSize
);
output
.
WriteRawLittleEndian64
(
value
);
output
.
Flush
();
Assert
.
AreEqual
(
data
,
rawOutput
.
ToArray
());
}
}
/// <summary>
/// Tests writeRawLittleEndian32() and writeRawLittleEndian64().
/// </summary>
[
Test
]
public
void
WriteLittleEndian
()
{
AssertWriteLittleEndian32
(
new
byte
[]
{
0x78
,
0x56
,
0x34
,
0x12
},
0x12345678
);
AssertWriteLittleEndian32
(
new
byte
[]
{
0xf0
,
0xde
,
0xbc
,
0x9a
},
0x9abcdef0
);
AssertWriteLittleEndian64
(
new
byte
[]
{
0xf0
,
0xde
,
0xbc
,
0x9a
,
0x78
,
0x56
,
0x34
,
0x12
},
0x123456789abcdef0L
);
AssertWriteLittleEndian64
(
new
byte
[]
{
0x78
,
0x56
,
0x34
,
0x12
,
0xf0
,
0xde
,
0xbc
,
0x9a
},
0x9abcdef012345678U
L
);
}
[
Test
]
public
void
WriteWholeMessage_VaryingBlockSizes
()
{
TestAllTypes
message
=
SampleMessages
.
CreateFullTestAllTypes
();
byte
[]
rawBytes
=
message
.
ToByteArray
();
// Try different block sizes.
for
(
int
blockSize
=
1
;
blockSize
<
256
;
blockSize
*=
2
)
{
MemoryStream
rawOutput
=
new
MemoryStream
();
CodedOutputStream
output
=
new
CodedOutputStream
(
rawOutput
,
blockSize
);
message
.
WriteTo
(
output
);
output
.
Flush
();
Assert
.
AreEqual
(
rawBytes
,
rawOutput
.
ToArray
());
}
}
[
Test
]
public
void
EncodeZigZag32
()
{
Assert
.
AreEqual
(
0u
,
CodedOutputStream
.
EncodeZigZag32
(
0
));
Assert
.
AreEqual
(
1u
,
CodedOutputStream
.
EncodeZigZag32
(-
1
));
Assert
.
AreEqual
(
2u
,
CodedOutputStream
.
EncodeZigZag32
(
1
));
Assert
.
AreEqual
(
3u
,
CodedOutputStream
.
EncodeZigZag32
(-
2
));
Assert
.
AreEqual
(
0x7FFFFFFEu
,
CodedOutputStream
.
EncodeZigZag32
(
0x3FFFFFFF
));
Assert
.
AreEqual
(
0x7FFFFFFFu
,
CodedOutputStream
.
EncodeZigZag32
(
unchecked
((
int
)
0xC0000000
)));
Assert
.
AreEqual
(
0xFFFFFFFEu
,
CodedOutputStream
.
EncodeZigZag32
(
0x7FFFFFFF
));
Assert
.
AreEqual
(
0xFFFFFFFFu
,
CodedOutputStream
.
EncodeZigZag32
(
unchecked
((
int
)
0x80000000
)));
}
[
Test
]
public
void
EncodeZigZag64
()
{
Assert
.
AreEqual
(
0u
,
CodedOutputStream
.
EncodeZigZag64
(
0
));
Assert
.
AreEqual
(
1u
,
CodedOutputStream
.
EncodeZigZag64
(-
1
));
Assert
.
AreEqual
(
2u
,
CodedOutputStream
.
EncodeZigZag64
(
1
));
Assert
.
AreEqual
(
3u
,
CodedOutputStream
.
EncodeZigZag64
(-
2
));
Assert
.
AreEqual
(
0x000000007FFFFFFEu
L
,
CodedOutputStream
.
EncodeZigZag64
(
unchecked
((
long
)
0x000000003FFFFFFFU
L
)));
Assert
.
AreEqual
(
0x000000007FFFFFFFu
L
,
CodedOutputStream
.
EncodeZigZag64
(
unchecked
((
long
)
0xFFFFFFFFC0000000U
L
)));
Assert
.
AreEqual
(
0x00000000FFFFFFFEu
L
,
CodedOutputStream
.
EncodeZigZag64
(
unchecked
((
long
)
0x000000007FFFFFFFU
L
)));
Assert
.
AreEqual
(
0x00000000FFFFFFFFu
L
,
CodedOutputStream
.
EncodeZigZag64
(
unchecked
((
long
)
0xFFFFFFFF80000000U
L
)));
Assert
.
AreEqual
(
0xFFFFFFFFFFFFFFFEL
,
CodedOutputStream
.
EncodeZigZag64
(
unchecked
((
long
)
0x7FFFFFFFFFFFFFFFU
L
)));
Assert
.
AreEqual
(
0xFFFFFFFFFFFFFFFFL
,
CodedOutputStream
.
EncodeZigZag64
(
unchecked
((
long
)
0x8000000000000000U
L
)));
}
[
Test
]
public
void
RoundTripZigZag32
()
{
// Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1)
// were chosen semi-randomly via keyboard bashing.
Assert
.
AreEqual
(
0
,
CodedInputStream
.
DecodeZigZag32
(
CodedOutputStream
.
EncodeZigZag32
(
0
)));
Assert
.
AreEqual
(
1
,
CodedInputStream
.
DecodeZigZag32
(
CodedOutputStream
.
EncodeZigZag32
(
1
)));
Assert
.
AreEqual
(-
1
,
CodedInputStream
.
DecodeZigZag32
(
CodedOutputStream
.
EncodeZigZag32
(-
1
)));
Assert
.
AreEqual
(
14927
,
CodedInputStream
.
DecodeZigZag32
(
CodedOutputStream
.
EncodeZigZag32
(
14927
)));
Assert
.
AreEqual
(-
3612
,
CodedInputStream
.
DecodeZigZag32
(
CodedOutputStream
.
EncodeZigZag32
(-
3612
)));
}
[
Test
]
public
void
RoundTripZigZag64
()
{
Assert
.
AreEqual
(
0
,
CodedInputStream
.
DecodeZigZag64
(
CodedOutputStream
.
EncodeZigZag64
(
0
)));
Assert
.
AreEqual
(
1
,
CodedInputStream
.
DecodeZigZag64
(
CodedOutputStream
.
EncodeZigZag64
(
1
)));
Assert
.
AreEqual
(-
1
,
CodedInputStream
.
DecodeZigZag64
(
CodedOutputStream
.
EncodeZigZag64
(-
1
)));
Assert
.
AreEqual
(
14927
,
CodedInputStream
.
DecodeZigZag64
(
CodedOutputStream
.
EncodeZigZag64
(
14927
)));
Assert
.
AreEqual
(-
3612
,
CodedInputStream
.
DecodeZigZag64
(
CodedOutputStream
.
EncodeZigZag64
(-
3612
)));
Assert
.
AreEqual
(
856912304801416L
,
CodedInputStream
.
DecodeZigZag64
(
CodedOutputStream
.
EncodeZigZag64
(
856912304801416L
)));
Assert
.
AreEqual
(-
75123905439571256L
,
CodedInputStream
.
DecodeZigZag64
(
CodedOutputStream
.
EncodeZigZag64
(-
75123905439571256L
)));
}
[
Test
]
public
void
TestNegativeEnumNoTag
()
{
Assert
.
AreEqual
(
10
,
CodedOutputStream
.
ComputeInt32Size
(-
2
));
Assert
.
AreEqual
(
10
,
CodedOutputStream
.
ComputeEnumSize
((
int
)
SampleEnum
.
NegativeValue
));
byte
[]
bytes
=
new
byte
[
10
];
CodedOutputStream
output
=
new
CodedOutputStream
(
bytes
);
output
.
WriteEnum
((
int
)
SampleEnum
.
NegativeValue
);
Assert
.
AreEqual
(
0
,
output
.
SpaceLeft
);
Assert
.
AreEqual
(
"FE-FF-FF-FF-FF-FF-FF-FF-FF-01"
,
BitConverter
.
ToString
(
bytes
));
}
[
Test
]
public
void
TestCodedInputOutputPosition
()
{
byte
[]
content
=
new
byte
[
110
];
for
(
int
i
=
0
;
i
<
content
.
Length
;
i
++)
content
[
i
]
=
(
byte
)
i
;
byte
[]
child
=
new
byte
[
120
];
{
MemoryStream
ms
=
new
MemoryStream
(
child
);
CodedOutputStream
cout
=
new
CodedOutputStream
(
ms
,
20
);
// Field 11: numeric value: 500
cout
.
WriteTag
(
11
,
WireFormat
.
WireType
.
Varint
);
Assert
.
AreEqual
(
1
,
cout
.
Position
);
cout
.
WriteInt32
(
500
);
Assert
.
AreEqual
(
3
,
cout
.
Position
);
//Field 12: length delimited 120 bytes
cout
.
WriteTag
(
12
,
WireFormat
.
WireType
.
LengthDelimited
);
Assert
.
AreEqual
(
4
,
cout
.
Position
);
cout
.
WriteBytes
(
ByteString
.
CopyFrom
(
content
));
Assert
.
AreEqual
(
115
,
cout
.
Position
);
// Field 13: fixed numeric value: 501
cout
.
WriteTag
(
13
,
WireFormat
.
WireType
.
Fixed32
);
Assert
.
AreEqual
(
116
,
cout
.
Position
);
cout
.
WriteSFixed32
(
501
);
Assert
.
AreEqual
(
120
,
cout
.
Position
);
cout
.
Flush
();
}
byte
[]
bytes
=
new
byte
[
130
];
{
CodedOutputStream
cout
=
new
CodedOutputStream
(
bytes
);
// Field 1: numeric value: 500
cout
.
WriteTag
(
1
,
WireFormat
.
WireType
.
Varint
);
Assert
.
AreEqual
(
1
,
cout
.
Position
);
cout
.
WriteInt32
(
500
);
Assert
.
AreEqual
(
3
,
cout
.
Position
);
//Field 2: length delimited 120 bytes
cout
.
WriteTag
(
2
,
WireFormat
.
WireType
.
LengthDelimited
);
Assert
.
AreEqual
(
4
,
cout
.
Position
);
cout
.
WriteBytes
(
ByteString
.
CopyFrom
(
child
));
Assert
.
AreEqual
(
125
,
cout
.
Position
);
// Field 3: fixed numeric value: 500
cout
.
WriteTag
(
3
,
WireFormat
.
WireType
.
Fixed32
);
Assert
.
AreEqual
(
126
,
cout
.
Position
);
cout
.
WriteSFixed32
(
501
);
Assert
.
AreEqual
(
130
,
cout
.
Position
);
cout
.
Flush
();
}
// Now test Input stream:
{
CodedInputStream
cin
=
new
CodedInputStream
(
new
MemoryStream
(
bytes
),
new
byte
[
50
],
0
,
0
);
Assert
.
AreEqual
(
0
,
cin
.
Position
);
// Field 1:
uint
tag
=
cin
.
ReadTag
();
Assert
.
AreEqual
(
1
,
tag
>>
3
);
Assert
.
AreEqual
(
1
,
cin
.
Position
);
Assert
.
AreEqual
(
500
,
cin
.
ReadInt32
());
Assert
.
AreEqual
(
3
,
cin
.
Position
);
//Field 2:
tag
=
cin
.
ReadTag
();
Assert
.
AreEqual
(
2
,
tag
>>
3
);
Assert
.
AreEqual
(
4
,
cin
.
Position
);
int
childlen
=
cin
.
ReadLength
();
Assert
.
AreEqual
(
120
,
childlen
);
Assert
.
AreEqual
(
5
,
cin
.
Position
);
int
oldlimit
=
cin
.
PushLimit
((
int
)
childlen
);
Assert
.
AreEqual
(
5
,
cin
.
Position
);
// Now we are reading child message
{
// Field 11: numeric value: 500
tag
=
cin
.
ReadTag
();
Assert
.
AreEqual
(
11
,
tag
>>
3
);
Assert
.
AreEqual
(
6
,
cin
.
Position
);
Assert
.
AreEqual
(
500
,
cin
.
ReadInt32
());
Assert
.
AreEqual
(
8
,
cin
.
Position
);
//Field 12: length delimited 120 bytes
tag
=
cin
.
ReadTag
();
Assert
.
AreEqual
(
12
,
tag
>>
3
);
Assert
.
AreEqual
(
9
,
cin
.
Position
);
ByteString
bstr
=
cin
.
ReadBytes
();
Assert
.
AreEqual
(
110
,
bstr
.
Length
);
Assert
.
AreEqual
((
byte
)
109
,
bstr
[
109
]);
Assert
.
AreEqual
(
120
,
cin
.
Position
);
// Field 13: fixed numeric value: 501
tag
=
cin
.
ReadTag
();
Assert
.
AreEqual
(
13
,
tag
>>
3
);
// ROK - Previously broken here, this returned 126 failing to account for bufferSizeAfterLimit
Assert
.
AreEqual
(
121
,
cin
.
Position
);
Assert
.
AreEqual
(
501
,
cin
.
ReadSFixed32
());
Assert
.
AreEqual
(
125
,
cin
.
Position
);
Assert
.
IsTrue
(
cin
.
IsAtEnd
);
}
cin
.
PopLimit
(
oldlimit
);
Assert
.
AreEqual
(
125
,
cin
.
Position
);
// Field 3: fixed numeric value: 501
tag
=
cin
.
ReadTag
();
Assert
.
AreEqual
(
3
,
tag
>>
3
);
Assert
.
AreEqual
(
126
,
cin
.
Position
);
Assert
.
AreEqual
(
501
,
cin
.
ReadSFixed32
());
Assert
.
AreEqual
(
130
,
cin
.
Position
);
Assert
.
IsTrue
(
cin
.
IsAtEnd
);
}
}
[
Test
]
public
void
Dispose_DisposesUnderlyingStream
()
{
var
memoryStream
=
new
MemoryStream
();
Assert
.
IsTrue
(
memoryStream
.
CanWrite
);
using
(
var
cos
=
new
CodedOutputStream
(
memoryStream
))
{
cos
.
WriteRawByte
(
0
);
Assert
.
AreEqual
(
0
,
memoryStream
.
Position
);
// Not flushed yet
}
Assert
.
AreEqual
(
1
,
memoryStream
.
ToArray
().
Length
);
// Flushed data from CodedOutputStream to MemoryStream
Assert
.
IsFalse
(
memoryStream
.
CanWrite
);
// Disposed
}
[
Test
]
public
void
Dispose_WithLeaveOpen
()
{
var
memoryStream
=
new
MemoryStream
();
Assert
.
IsTrue
(
memoryStream
.
CanWrite
);
using
(
var
cos
=
new
CodedOutputStream
(
memoryStream
,
true
))
{
cos
.
WriteRawByte
(
0
);
Assert
.
AreEqual
(
0
,
memoryStream
.
Position
);
// Not flushed yet
}
Assert
.
AreEqual
(
1
,
memoryStream
.
Position
);
// Flushed data from CodedOutputStream to MemoryStream
Assert
.
IsTrue
(
memoryStream
.
CanWrite
);
// We left the stream open
}
}
}
\ No newline at end of file
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Collections/MapFieldTest.cs
0 → 100644
View file @
3f6f73b7
#
region
Copyright
notice
and
license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
System
;
using
System.Collections.Generic
;
using
Google.Protobuf.TestProtos
;
using
NUnit.Framework
;
using
System.Collections
;
using
System.Linq
;
namespace
Google.Protobuf.Collections
{
/// <summary>
/// Tests for MapField which aren't reliant on the encoded format -
/// tests for serialization/deserialization are part of GeneratedMessageTest.
/// </summary>
public
class
MapFieldTest
{
[
Test
]
public
void
Clone_ClonesMessages
()
{
var
message
=
new
ForeignMessage
{
C
=
20
};
var
map
=
new
MapField
<
string
,
ForeignMessage
>
{
{
"x"
,
message
}
};
var
clone
=
map
.
Clone
();
map
[
"x"
].
C
=
30
;
Assert
.
AreEqual
(
20
,
clone
[
"x"
].
C
);
}
[
Test
]
public
void
NullValuesProhibited
()
{
TestNullValues
<
int
?>(
0
);
TestNullValues
(
""
);
TestNullValues
(
new
TestAllTypes
());
}
private
void
TestNullValues
<
T
>(
T
nonNullValue
)
{
var
map
=
new
MapField
<
int
,
T
>();
var
nullValue
=
(
T
)
(
object
)
null
;
Assert
.
Throws
<
ArgumentNullException
>(()
=>
map
.
Add
(
0
,
nullValue
));
Assert
.
Throws
<
ArgumentNullException
>(()
=>
map
[
0
]
=
nullValue
);
map
.
Add
(
1
,
nonNullValue
);
map
[
1
]
=
nonNullValue
;
}
[
Test
]
public
void
Add_ForbidsNullKeys
()
{
var
map
=
new
MapField
<
string
,
ForeignMessage
>();
Assert
.
Throws
<
ArgumentNullException
>(()
=>
map
.
Add
(
null
,
new
ForeignMessage
()));
}
[
Test
]
public
void
Indexer_ForbidsNullKeys
()
{
var
map
=
new
MapField
<
string
,
ForeignMessage
>();
Assert
.
Throws
<
ArgumentNullException
>(()
=>
map
[
null
]
=
new
ForeignMessage
());
}
[
Test
]
public
void
AddPreservesInsertionOrder
()
{
var
map
=
new
MapField
<
string
,
string
>();
map
.
Add
(
"a"
,
"v1"
);
map
.
Add
(
"b"
,
"v2"
);
map
.
Add
(
"c"
,
"v3"
);
map
.
Remove
(
"b"
);
map
.
Add
(
"d"
,
"v4"
);
CollectionAssert
.
AreEqual
(
new
[]
{
"a"
,
"c"
,
"d"
},
map
.
Keys
);
CollectionAssert
.
AreEqual
(
new
[]
{
"v1"
,
"v3"
,
"v4"
},
map
.
Values
);
}
[
Test
]
public
void
EqualityIsOrderInsensitive
()
{
var
map1
=
new
MapField
<
string
,
string
>();
map1
.
Add
(
"a"
,
"v1"
);
map1
.
Add
(
"b"
,
"v2"
);
var
map2
=
new
MapField
<
string
,
string
>();
map2
.
Add
(
"b"
,
"v2"
);
map2
.
Add
(
"a"
,
"v1"
);
EqualityTester
.
AssertEquality
(
map1
,
map2
);
}
[
Test
]
public
void
EqualityIsKeySensitive
()
{
var
map1
=
new
MapField
<
string
,
string
>();
map1
.
Add
(
"first key"
,
"v1"
);
map1
.
Add
(
"second key"
,
"v2"
);
var
map2
=
new
MapField
<
string
,
string
>();
map2
.
Add
(
"third key"
,
"v1"
);
map2
.
Add
(
"fourth key"
,
"v2"
);
EqualityTester
.
AssertInequality
(
map1
,
map2
);
}
[
Test
]
public
void
Equality_Simple
()
{
var
map
=
new
MapField
<
string
,
string
>();
EqualityTester
.
AssertEquality
(
map
,
map
);
EqualityTester
.
AssertInequality
(
map
,
null
);
Assert
.
IsFalse
(
map
.
Equals
(
new
object
()));
}
[
Test
]
public
void
EqualityIsValueSensitive
()
{
// Note: Without some care, it's a little easier than one might
// hope to see hash collisions, but only in some environments...
var
map1
=
new
MapField
<
string
,
string
>();
map1
.
Add
(
"a"
,
"first value"
);
map1
.
Add
(
"b"
,
"second value"
);
var
map2
=
new
MapField
<
string
,
string
>();
map2
.
Add
(
"a"
,
"third value"
);
map2
.
Add
(
"b"
,
"fourth value"
);
EqualityTester
.
AssertInequality
(
map1
,
map2
);
}
[
Test
]
public
void
Add_Dictionary
()
{
var
map1
=
new
MapField
<
string
,
string
>
{
{
"x"
,
"y"
},
{
"a"
,
"b"
}
};
var
map2
=
new
MapField
<
string
,
string
>
{
{
"before"
,
""
},
map1
,
{
"after"
,
""
}
};
var
expected
=
new
MapField
<
string
,
string
>
{
{
"before"
,
""
},
{
"x"
,
"y"
},
{
"a"
,
"b"
},
{
"after"
,
""
}
};
Assert
.
AreEqual
(
expected
,
map2
);
CollectionAssert
.
AreEqual
(
new
[]
{
"before"
,
"x"
,
"a"
,
"after"
},
map2
.
Keys
);
}
// General IDictionary<TKey, TValue> behavior tests
[
Test
]
public
void
Add_KeyAlreadyExists
()
{
var
map
=
new
MapField
<
string
,
string
>();
map
.
Add
(
"foo"
,
"bar"
);
Assert
.
Throws
<
ArgumentException
>(()
=>
map
.
Add
(
"foo"
,
"baz"
));
}
[
Test
]
public
void
Add_Pair
()
{
var
map
=
new
MapField
<
string
,
string
>();
ICollection
<
KeyValuePair
<
string
,
string
>>
collection
=
map
;
collection
.
Add
(
NewKeyValuePair
(
"x"
,
"y"
));
Assert
.
AreEqual
(
"y"
,
map
[
"x"
]);
Assert
.
Throws
<
ArgumentException
>(()
=>
collection
.
Add
(
NewKeyValuePair
(
"x"
,
"z"
)));
}
[
Test
]
public
void
Contains_Pair
()
{
var
map
=
new
MapField
<
string
,
string
>
{
{
"x"
,
"y"
}
};
ICollection
<
KeyValuePair
<
string
,
string
>>
collection
=
map
;
Assert
.
IsTrue
(
collection
.
Contains
(
NewKeyValuePair
(
"x"
,
"y"
)));
Assert
.
IsFalse
(
collection
.
Contains
(
NewKeyValuePair
(
"x"
,
"z"
)));
Assert
.
IsFalse
(
collection
.
Contains
(
NewKeyValuePair
(
"z"
,
"y"
)));
}
[
Test
]
public
void
Remove_Key
()
{
var
map
=
new
MapField
<
string
,
string
>();
map
.
Add
(
"foo"
,
"bar"
);
Assert
.
AreEqual
(
1
,
map
.
Count
);
Assert
.
IsFalse
(
map
.
Remove
(
"missing"
));
Assert
.
AreEqual
(
1
,
map
.
Count
);
Assert
.
IsTrue
(
map
.
Remove
(
"foo"
));
Assert
.
AreEqual
(
0
,
map
.
Count
);
Assert
.
Throws
<
ArgumentNullException
>(()
=>
map
.
Remove
(
null
));
}
[
Test
]
public
void
Remove_Pair
()
{
var
map
=
new
MapField
<
string
,
string
>();
map
.
Add
(
"foo"
,
"bar"
);
ICollection
<
KeyValuePair
<
string
,
string
>>
collection
=
map
;
Assert
.
AreEqual
(
1
,
map
.
Count
);
Assert
.
IsFalse
(
collection
.
Remove
(
NewKeyValuePair
(
"wrong key"
,
"bar"
)));
Assert
.
AreEqual
(
1
,
map
.
Count
);
Assert
.
IsFalse
(
collection
.
Remove
(
NewKeyValuePair
(
"foo"
,
"wrong value"
)));
Assert
.
AreEqual
(
1
,
map
.
Count
);
Assert
.
IsTrue
(
collection
.
Remove
(
NewKeyValuePair
(
"foo"
,
"bar"
)));
Assert
.
AreEqual
(
0
,
map
.
Count
);
Assert
.
Throws
<
ArgumentException
>(()
=>
collection
.
Remove
(
new
KeyValuePair
<
string
,
string
>(
null
,
""
)));
}
[
Test
]
public
void
CopyTo_Pair
()
{
var
map
=
new
MapField
<
string
,
string
>();
map
.
Add
(
"foo"
,
"bar"
);
ICollection
<
KeyValuePair
<
string
,
string
>>
collection
=
map
;
KeyValuePair
<
string
,
string
>[]
array
=
new
KeyValuePair
<
string
,
string
>[
3
];
collection
.
CopyTo
(
array
,
1
);
Assert
.
AreEqual
(
NewKeyValuePair
(
"foo"
,
"bar"
),
array
[
1
]);
}
[
Test
]
public
void
Clear
()
{
var
map
=
new
MapField
<
string
,
string
>
{
{
"x"
,
"y"
}
};
Assert
.
AreEqual
(
1
,
map
.
Count
);
map
.
Clear
();
Assert
.
AreEqual
(
0
,
map
.
Count
);
map
.
Add
(
"x"
,
"y"
);
Assert
.
AreEqual
(
1
,
map
.
Count
);
}
[
Test
]
public
void
Indexer_Get
()
{
var
map
=
new
MapField
<
string
,
string
>
{
{
"x"
,
"y"
}
};
Assert
.
AreEqual
(
"y"
,
map
[
"x"
]);
Assert
.
Throws
<
KeyNotFoundException
>(()
=>
{
var
ignored
=
map
[
"z"
];
});
}
[
Test
]
public
void
Indexer_Set
()
{
var
map
=
new
MapField
<
string
,
string
>();
map
[
"x"
]
=
"y"
;
Assert
.
AreEqual
(
"y"
,
map
[
"x"
]);
map
[
"x"
]
=
"z"
;
// This won't throw, unlike Add.
Assert
.
AreEqual
(
"z"
,
map
[
"x"
]);
}
[
Test
]
public
void
GetEnumerator_NonGeneric
()
{
IEnumerable
map
=
new
MapField
<
string
,
string
>
{
{
"x"
,
"y"
}
};
CollectionAssert
.
AreEqual
(
new
[]
{
new
KeyValuePair
<
string
,
string
>(
"x"
,
"y"
)
},
map
.
Cast
<
object
>().
ToList
());
}
// Test for the explicitly-implemented non-generic IDictionary interface
[
Test
]
public
void
IDictionary_GetEnumerator
()
{
IDictionary
map
=
new
MapField
<
string
,
string
>
{
{
"x"
,
"y"
}
};
var
enumerator
=
map
.
GetEnumerator
();
// Commented assertions show an ideal situation - it looks like
// the LinkedList enumerator doesn't throw when you ask for the current entry
// at an inappropriate time; fixing this would be more work than it's worth.
// Assert.Throws<InvalidOperationException>(() => enumerator.Current.GetHashCode());
Assert
.
IsTrue
(
enumerator
.
MoveNext
());
Assert
.
AreEqual
(
"x"
,
enumerator
.
Key
);
Assert
.
AreEqual
(
"y"
,
enumerator
.
Value
);
Assert
.
AreEqual
(
new
DictionaryEntry
(
"x"
,
"y"
),
enumerator
.
Current
);
Assert
.
AreEqual
(
new
DictionaryEntry
(
"x"
,
"y"
),
enumerator
.
Entry
);
Assert
.
IsFalse
(
enumerator
.
MoveNext
());
// Assert.Throws<InvalidOperationException>(() => enumerator.Current.GetHashCode());
enumerator
.
Reset
();
// Assert.Throws<InvalidOperationException>(() => enumerator.Current.GetHashCode());
Assert
.
IsTrue
(
enumerator
.
MoveNext
());
Assert
.
AreEqual
(
"x"
,
enumerator
.
Key
);
// Assume the rest are okay
}
[
Test
]
public
void
IDictionary_Add
()
{
var
map
=
new
MapField
<
string
,
string
>
{
{
"x"
,
"y"
}
};
IDictionary
dictionary
=
map
;
dictionary
.
Add
(
"a"
,
"b"
);
Assert
.
AreEqual
(
"b"
,
map
[
"a"
]);
Assert
.
Throws
<
ArgumentException
>(()
=>
dictionary
.
Add
(
"a"
,
"duplicate"
));
Assert
.
Throws
<
InvalidCastException
>(()
=>
dictionary
.
Add
(
new
object
(),
"key is bad"
));
Assert
.
Throws
<
InvalidCastException
>(()
=>
dictionary
.
Add
(
"value is bad"
,
new
object
()));
}
[
Test
]
public
void
IDictionary_Contains
()
{
var
map
=
new
MapField
<
string
,
string
>
{
{
"x"
,
"y"
}
};
IDictionary
dictionary
=
map
;
Assert
.
IsFalse
(
dictionary
.
Contains
(
"a"
));
Assert
.
IsFalse
(
dictionary
.
Contains
(
5
));
// Surprising, but IDictionary.Contains is only about keys.
Assert
.
IsFalse
(
dictionary
.
Contains
(
new
DictionaryEntry
(
"x"
,
"y"
)));
Assert
.
IsTrue
(
dictionary
.
Contains
(
"x"
));
}
[
Test
]
public
void
IDictionary_Remove
()
{
var
map
=
new
MapField
<
string
,
string
>
{
{
"x"
,
"y"
}
};
IDictionary
dictionary
=
map
;
dictionary
.
Remove
(
"a"
);
Assert
.
AreEqual
(
1
,
dictionary
.
Count
);
dictionary
.
Remove
(
5
);
Assert
.
AreEqual
(
1
,
dictionary
.
Count
);
dictionary
.
Remove
(
new
DictionaryEntry
(
"x"
,
"y"
));
Assert
.
AreEqual
(
1
,
dictionary
.
Count
);
dictionary
.
Remove
(
"x"
);
Assert
.
AreEqual
(
0
,
dictionary
.
Count
);
Assert
.
Throws
<
ArgumentNullException
>(()
=>
dictionary
.
Remove
(
null
));
}
[
Test
]
public
void
IDictionary_CopyTo
()
{
var
map
=
new
MapField
<
string
,
string
>
{
{
"x"
,
"y"
}
};
IDictionary
dictionary
=
map
;
var
array
=
new
DictionaryEntry
[
3
];
dictionary
.
CopyTo
(
array
,
1
);
CollectionAssert
.
AreEqual
(
new
[]
{
default
(
DictionaryEntry
),
new
DictionaryEntry
(
"x"
,
"y"
),
default
(
DictionaryEntry
)
},
array
);
var
objectArray
=
new
object
[
3
];
dictionary
.
CopyTo
(
objectArray
,
1
);
CollectionAssert
.
AreEqual
(
new
object
[]
{
null
,
new
DictionaryEntry
(
"x"
,
"y"
),
null
},
objectArray
);
}
[
Test
]
public
void
IDictionary_IsFixedSize
()
{
var
map
=
new
MapField
<
string
,
string
>
{
{
"x"
,
"y"
}
};
IDictionary
dictionary
=
map
;
Assert
.
IsFalse
(
dictionary
.
IsFixedSize
);
}
[
Test
]
public
void
IDictionary_Keys
()
{
IDictionary
dictionary
=
new
MapField
<
string
,
string
>
{
{
"x"
,
"y"
}
};
CollectionAssert
.
AreEqual
(
new
[]
{
"x"
},
dictionary
.
Keys
);
}
[
Test
]
public
void
IDictionary_Values
()
{
IDictionary
dictionary
=
new
MapField
<
string
,
string
>
{
{
"x"
,
"y"
}
};
CollectionAssert
.
AreEqual
(
new
[]
{
"y"
},
dictionary
.
Values
);
}
[
Test
]
public
void
IDictionary_IsSynchronized
()
{
IDictionary
dictionary
=
new
MapField
<
string
,
string
>
{
{
"x"
,
"y"
}
};
Assert
.
IsFalse
(
dictionary
.
IsSynchronized
);
}
[
Test
]
public
void
IDictionary_SyncRoot
()
{
IDictionary
dictionary
=
new
MapField
<
string
,
string
>
{
{
"x"
,
"y"
}
};
Assert
.
AreSame
(
dictionary
,
dictionary
.
SyncRoot
);
}
[
Test
]
public
void
IDictionary_Indexer_Get
()
{
IDictionary
dictionary
=
new
MapField
<
string
,
string
>
{
{
"x"
,
"y"
}
};
Assert
.
AreEqual
(
"y"
,
dictionary
[
"x"
]);
Assert
.
IsNull
(
dictionary
[
"a"
]);
Assert
.
IsNull
(
dictionary
[
5
]);
Assert
.
Throws
<
ArgumentNullException
>(()
=>
dictionary
[
null
].
GetHashCode
());
}
[
Test
]
public
void
IDictionary_Indexer_Set
()
{
var
map
=
new
MapField
<
string
,
string
>
{
{
"x"
,
"y"
}
};
IDictionary
dictionary
=
map
;
map
[
"a"
]
=
"b"
;
Assert
.
AreEqual
(
"b"
,
map
[
"a"
]);
map
[
"a"
]
=
"c"
;
Assert
.
AreEqual
(
"c"
,
map
[
"a"
]);
Assert
.
Throws
<
InvalidCastException
>(()
=>
dictionary
[
5
]
=
"x"
);
Assert
.
Throws
<
InvalidCastException
>(()
=>
dictionary
[
"x"
]
=
5
);
Assert
.
Throws
<
ArgumentNullException
>(()
=>
dictionary
[
null
]
=
"z"
);
Assert
.
Throws
<
ArgumentNullException
>(()
=>
dictionary
[
"x"
]
=
null
);
}
[
Test
]
public
void
KeysReturnsLiveView
()
{
var
map
=
new
MapField
<
string
,
string
>();
var
keys
=
map
.
Keys
;
CollectionAssert
.
AreEqual
(
new
string
[
0
],
keys
);
map
[
"foo"
]
=
"bar"
;
map
[
"x"
]
=
"y"
;
CollectionAssert
.
AreEqual
(
new
[]
{
"foo"
,
"x"
},
keys
);
}
[
Test
]
public
void
ValuesReturnsLiveView
()
{
var
map
=
new
MapField
<
string
,
string
>();
var
values
=
map
.
Values
;
CollectionAssert
.
AreEqual
(
new
string
[
0
],
values
);
map
[
"foo"
]
=
"bar"
;
map
[
"x"
]
=
"y"
;
CollectionAssert
.
AreEqual
(
new
[]
{
"bar"
,
"y"
},
values
);
}
// Just test keys - we know the implementation is the same for values
[
Test
]
public
void
ViewsAreReadOnly
()
{
var
map
=
new
MapField
<
string
,
string
>();
var
keys
=
map
.
Keys
;
Assert
.
IsTrue
(
keys
.
IsReadOnly
);
Assert
.
Throws
<
NotSupportedException
>(()
=>
keys
.
Clear
());
Assert
.
Throws
<
NotSupportedException
>(()
=>
keys
.
Remove
(
"a"
));
Assert
.
Throws
<
NotSupportedException
>(()
=>
keys
.
Add
(
"a"
));
}
// Just test keys - we know the implementation is the same for values
[
Test
]
public
void
ViewCopyTo
()
{
var
map
=
new
MapField
<
string
,
string
>
{
{
"foo"
,
"bar"
},
{
"x"
,
"y"
}
};
var
keys
=
map
.
Keys
;
var
array
=
new
string
[
4
];
Assert
.
Throws
<
ArgumentException
>(()
=>
keys
.
CopyTo
(
array
,
3
));
Assert
.
Throws
<
ArgumentOutOfRangeException
>(()
=>
keys
.
CopyTo
(
array
,
-
1
));
keys
.
CopyTo
(
array
,
1
);
CollectionAssert
.
AreEqual
(
new
[]
{
null
,
"foo"
,
"x"
,
null
},
array
);
}
// Just test keys - we know the implementation is the same for values
[
Test
]
public
void
NonGenericViewCopyTo
()
{
IDictionary
map
=
new
MapField
<
string
,
string
>
{
{
"foo"
,
"bar"
},
{
"x"
,
"y"
}
};
ICollection
keys
=
map
.
Keys
;
// Note the use of the Array type here rather than string[]
Array
array
=
new
string
[
4
];
Assert
.
Throws
<
ArgumentException
>(()
=>
keys
.
CopyTo
(
array
,
3
));
Assert
.
Throws
<
ArgumentOutOfRangeException
>(()
=>
keys
.
CopyTo
(
array
,
-
1
));
keys
.
CopyTo
(
array
,
1
);
CollectionAssert
.
AreEqual
(
new
[]
{
null
,
"foo"
,
"x"
,
null
},
array
);
}
[
Test
]
public
void
KeysContains
()
{
var
map
=
new
MapField
<
string
,
string
>
{
{
"foo"
,
"bar"
},
{
"x"
,
"y"
}
};
var
keys
=
map
.
Keys
;
Assert
.
IsTrue
(
keys
.
Contains
(
"foo"
));
Assert
.
IsFalse
(
keys
.
Contains
(
"bar"
));
// It's a value!
Assert
.
IsFalse
(
keys
.
Contains
(
"1"
));
// Keys can't be null, so we should prevent contains check
Assert
.
Throws
<
ArgumentNullException
>(()
=>
keys
.
Contains
(
null
));
}
[
Test
]
public
void
ValuesContains
()
{
var
map
=
new
MapField
<
string
,
string
>
{
{
"foo"
,
"bar"
},
{
"x"
,
"y"
}
};
var
values
=
map
.
Values
;
Assert
.
IsTrue
(
values
.
Contains
(
"bar"
));
Assert
.
IsFalse
(
values
.
Contains
(
"foo"
));
// It's a key!
Assert
.
IsFalse
(
values
.
Contains
(
"1"
));
// Values can be null, so this makes sense
Assert
.
IsFalse
(
values
.
Contains
(
null
));
}
[
Test
]
public
void
ToString_StringToString
()
{
var
map
=
new
MapField
<
string
,
string
>
{
{
"foo"
,
"bar"
},
{
"x"
,
"y"
}
};
Assert
.
AreEqual
(
"{ \"foo\": \"bar\", \"x\": \"y\" }"
,
map
.
ToString
());
}
[
Test
]
public
void
ToString_UnsupportedKeyType
()
{
var
map
=
new
MapField
<
byte
,
string
>
{
{
10
,
"foo"
}
};
Assert
.
Throws
<
ArgumentException
>(()
=>
map
.
ToString
());
}
private
static
KeyValuePair
<
TKey
,
TValue
>
NewKeyValuePair
<
TKey
,
TValue
>(
TKey
key
,
TValue
value
)
{
return
new
KeyValuePair
<
TKey
,
TValue
>(
key
,
value
);
}
}
}
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs
0 → 100644
View file @
3f6f73b7
#
region
Copyright
notice
and
license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
System
;
using
System.Collections
;
using
System.Collections.Generic
;
using
System.IO
;
using
System.Linq
;
using
System.Text
;
using
Google.Protobuf.TestProtos
;
using
Google.Protobuf.WellKnownTypes
;
using
NUnit.Framework
;
namespace
Google.Protobuf.Collections
{
public
class
RepeatedFieldTest
{
[
Test
]
public
void
NullValuesRejected
()
{
var
list
=
new
RepeatedField
<
string
>();
Assert
.
Throws
<
ArgumentNullException
>(()
=>
list
.
Add
((
string
)
null
));
Assert
.
Throws
<
ArgumentNullException
>(()
=>
list
.
Add
((
IEnumerable
<
string
>)
null
));
Assert
.
Throws
<
ArgumentNullException
>(()
=>
list
.
Add
((
RepeatedField
<
string
>)
null
));
Assert
.
Throws
<
ArgumentNullException
>(()
=>
list
.
Contains
(
null
));
Assert
.
Throws
<
ArgumentNullException
>(()
=>
list
.
IndexOf
(
null
));
}
[
Test
]
public
void
Add_SingleItem
()
{
var
list
=
new
RepeatedField
<
string
>();
list
.
Add
(
"foo"
);
Assert
.
AreEqual
(
1
,
list
.
Count
);
Assert
.
AreEqual
(
"foo"
,
list
[
0
]);
}
[
Test
]
public
void
Add_Sequence
()
{
var
list
=
new
RepeatedField
<
string
>();
list
.
Add
(
new
[]
{
"foo"
,
"bar"
});
Assert
.
AreEqual
(
2
,
list
.
Count
);
Assert
.
AreEqual
(
"foo"
,
list
[
0
]);
Assert
.
AreEqual
(
"bar"
,
list
[
1
]);
}
[
Test
]
public
void
AddRange_SlowPath
()
{
var
list
=
new
RepeatedField
<
string
>();
list
.
AddRange
(
new
[]
{
"foo"
,
"bar"
}.
Select
(
x
=>
x
));
Assert
.
AreEqual
(
2
,
list
.
Count
);
Assert
.
AreEqual
(
"foo"
,
list
[
0
]);
Assert
.
AreEqual
(
"bar"
,
list
[
1
]);
}
[
Test
]
public
void
AddRange_SlowPath_NullsProhibited_ReferenceType
()
{
var
list
=
new
RepeatedField
<
string
>();
// It's okay for this to throw ArgumentNullException if necessary.
// It's not ideal, but not awful.
Assert
.
Catch
<
ArgumentException
>(()
=>
list
.
AddRange
(
new
[]
{
"foo"
,
null
}.
Select
(
x
=>
x
)));
}
[
Test
]
public
void
AddRange_SlowPath_NullsProhibited_NullableValueType
()
{
var
list
=
new
RepeatedField
<
int
?>();
// It's okay for this to throw ArgumentNullException if necessary.
// It's not ideal, but not awful.
Assert
.
Catch
<
ArgumentException
>(()
=>
list
.
AddRange
(
new
[]
{
20
,
(
int
?)
null
}.
Select
(
x
=>
x
)));
}
[
Test
]
public
void
AddRange_Optimized_NonNullableValueType
()
{
var
list
=
new
RepeatedField
<
int
>();
list
.
AddRange
(
new
List
<
int
>
{
20
,
30
});
Assert
.
AreEqual
(
2
,
list
.
Count
);
Assert
.
AreEqual
(
20
,
list
[
0
]);
Assert
.
AreEqual
(
30
,
list
[
1
]);
}
[
Test
]
public
void
AddRange_Optimized_ReferenceType
()
{
var
list
=
new
RepeatedField
<
string
>();
list
.
AddRange
(
new
List
<
string
>
{
"foo"
,
"bar"
});
Assert
.
AreEqual
(
2
,
list
.
Count
);
Assert
.
AreEqual
(
"foo"
,
list
[
0
]);
Assert
.
AreEqual
(
"bar"
,
list
[
1
]);
}
[
Test
]
public
void
AddRange_Optimized_NullableValueType
()
{
var
list
=
new
RepeatedField
<
int
?>();
list
.
AddRange
(
new
List
<
int
?>
{
20
,
30
});
Assert
.
AreEqual
(
2
,
list
.
Count
);
Assert
.
AreEqual
((
int
?)
20
,
list
[
0
]);
Assert
.
AreEqual
((
int
?)
30
,
list
[
1
]);
}
[
Test
]
public
void
AddRange_Optimized_NullsProhibited_ReferenceType
()
{
// We don't just trust that a collection with a nullable element type doesn't contain nulls
var
list
=
new
RepeatedField
<
string
>();
// It's okay for this to throw ArgumentNullException if necessary.
// It's not ideal, but not awful.
Assert
.
Catch
<
ArgumentException
>(()
=>
list
.
AddRange
(
new
List
<
string
>
{
"foo"
,
null
}));
}
[
Test
]
public
void
AddRange_Optimized_NullsProhibited_NullableValueType
()
{
// We don't just trust that a collection with a nullable element type doesn't contain nulls
var
list
=
new
RepeatedField
<
int
?>();
// It's okay for this to throw ArgumentNullException if necessary.
// It's not ideal, but not awful.
Assert
.
Catch
<
ArgumentException
>(()
=>
list
.
AddRange
(
new
List
<
int
?>
{
20
,
null
}));
}
[
Test
]
public
void
AddRange_AlreadyNotEmpty
()
{
var
list
=
new
RepeatedField
<
int
>
{
1
,
2
,
3
};
list
.
AddRange
(
new
List
<
int
>
{
4
,
5
,
6
});
CollectionAssert
.
AreEqual
(
new
[]
{
1
,
2
,
3
,
4
,
5
,
6
},
list
);
}
[
Test
]
public
void
AddRange_RepeatedField
()
{
var
list
=
new
RepeatedField
<
string
>
{
"original"
};
list
.
AddRange
(
new
RepeatedField
<
string
>
{
"foo"
,
"bar"
});
Assert
.
AreEqual
(
3
,
list
.
Count
);
Assert
.
AreEqual
(
"original"
,
list
[
0
]);
Assert
.
AreEqual
(
"foo"
,
list
[
1
]);
Assert
.
AreEqual
(
"bar"
,
list
[
2
]);
}
[
Test
]
public
void
RemoveAt_Valid
()
{
var
list
=
new
RepeatedField
<
string
>
{
"first"
,
"second"
,
"third"
};
list
.
RemoveAt
(
1
);
CollectionAssert
.
AreEqual
(
new
[]
{
"first"
,
"third"
},
list
);
// Just check that these don't throw...
list
.
RemoveAt
(
list
.
Count
-
1
);
// Now the count will be 1...
list
.
RemoveAt
(
0
);
Assert
.
AreEqual
(
0
,
list
.
Count
);
}
[
Test
]
public
void
RemoveAt_Invalid
()
{
var
list
=
new
RepeatedField
<
string
>
{
"first"
,
"second"
,
"third"
};
Assert
.
Throws
<
ArgumentOutOfRangeException
>(()
=>
list
.
RemoveAt
(-
1
));
Assert
.
Throws
<
ArgumentOutOfRangeException
>(()
=>
list
.
RemoveAt
(
3
));
}
[
Test
]
public
void
Insert_Valid
()
{
var
list
=
new
RepeatedField
<
string
>
{
"first"
,
"second"
};
list
.
Insert
(
1
,
"middle"
);
CollectionAssert
.
AreEqual
(
new
[]
{
"first"
,
"middle"
,
"second"
},
list
);
list
.
Insert
(
3
,
"end"
);
CollectionAssert
.
AreEqual
(
new
[]
{
"first"
,
"middle"
,
"second"
,
"end"
},
list
);
list
.
Insert
(
0
,
"start"
);
CollectionAssert
.
AreEqual
(
new
[]
{
"start"
,
"first"
,
"middle"
,
"second"
,
"end"
},
list
);
}
[
Test
]
public
void
Insert_Invalid
()
{
var
list
=
new
RepeatedField
<
string
>
{
"first"
,
"second"
};
Assert
.
Throws
<
ArgumentOutOfRangeException
>(()
=>
list
.
Insert
(-
1
,
"foo"
));
Assert
.
Throws
<
ArgumentOutOfRangeException
>(()
=>
list
.
Insert
(
3
,
"foo"
));
Assert
.
Throws
<
ArgumentNullException
>(()
=>
list
.
Insert
(
0
,
null
));
}
[
Test
]
public
void
Equals_RepeatedField
()
{
var
list
=
new
RepeatedField
<
string
>
{
"first"
,
"second"
};
Assert
.
IsFalse
(
list
.
Equals
((
RepeatedField
<
string
>)
null
));
Assert
.
IsTrue
(
list
.
Equals
(
list
));
Assert
.
IsFalse
(
list
.
Equals
(
new
RepeatedField
<
string
>
{
"first"
,
"third"
}));
Assert
.
IsFalse
(
list
.
Equals
(
new
RepeatedField
<
string
>
{
"first"
}));
Assert
.
IsTrue
(
list
.
Equals
(
new
RepeatedField
<
string
>
{
"first"
,
"second"
}));
}
[
Test
]
public
void
Equals_Object
()
{
var
list
=
new
RepeatedField
<
string
>
{
"first"
,
"second"
};
Assert
.
IsFalse
(
list
.
Equals
((
object
)
null
));
Assert
.
IsTrue
(
list
.
Equals
((
object
)
list
));
Assert
.
IsFalse
(
list
.
Equals
((
object
)
new
RepeatedField
<
string
>
{
"first"
,
"third"
}));
Assert
.
IsFalse
(
list
.
Equals
((
object
)
new
RepeatedField
<
string
>
{
"first"
}));
Assert
.
IsTrue
(
list
.
Equals
((
object
)
new
RepeatedField
<
string
>
{
"first"
,
"second"
}));
Assert
.
IsFalse
(
list
.
Equals
(
new
object
()));
}
[
Test
]
public
void
GetEnumerator_GenericInterface
()
{
IEnumerable
<
string
>
list
=
new
RepeatedField
<
string
>
{
"first"
,
"second"
};
// Select gets rid of the optimizations in ToList...
CollectionAssert
.
AreEqual
(
new
[]
{
"first"
,
"second"
},
list
.
Select
(
x
=>
x
).
ToList
());
}
[
Test
]
public
void
GetEnumerator_NonGenericInterface
()
{
IEnumerable
list
=
new
RepeatedField
<
string
>
{
"first"
,
"second"
};
CollectionAssert
.
AreEqual
(
new
[]
{
"first"
,
"second"
},
list
.
Cast
<
object
>().
ToList
());
}
[
Test
]
public
void
CopyTo
()
{
var
list
=
new
RepeatedField
<
string
>
{
"first"
,
"second"
};
string
[]
stringArray
=
new
string
[
4
];
list
.
CopyTo
(
stringArray
,
1
);
CollectionAssert
.
AreEqual
(
new
[]
{
null
,
"first"
,
"second"
,
null
},
stringArray
);
}
[
Test
]
public
void
Indexer_Get
()
{
var
list
=
new
RepeatedField
<
string
>
{
"first"
,
"second"
};
Assert
.
AreEqual
(
"first"
,
list
[
0
]);
Assert
.
AreEqual
(
"second"
,
list
[
1
]);
Assert
.
Throws
<
ArgumentOutOfRangeException
>(()
=>
list
[-
1
].
GetHashCode
());
Assert
.
Throws
<
ArgumentOutOfRangeException
>(()
=>
list
[
2
].
GetHashCode
());
}
[
Test
]
public
void
Indexer_Set
()
{
var
list
=
new
RepeatedField
<
string
>
{
"first"
,
"second"
};
list
[
0
]
=
"changed"
;
Assert
.
AreEqual
(
"changed"
,
list
[
0
]);
Assert
.
Throws
<
ArgumentNullException
>(()
=>
list
[
0
]
=
null
);
Assert
.
Throws
<
ArgumentOutOfRangeException
>(()
=>
list
[-
1
]
=
"bad"
);
Assert
.
Throws
<
ArgumentOutOfRangeException
>(()
=>
list
[
2
]
=
"bad"
);
}
[
Test
]
public
void
Clone_ReturnsMutable
()
{
var
list
=
new
RepeatedField
<
int
>
{
0
};
var
clone
=
list
.
Clone
();
clone
[
0
]
=
1
;
}
[
Test
]
public
void
Enumerator
()
{
var
list
=
new
RepeatedField
<
string
>
{
"first"
,
"second"
};
using
(
var
enumerator
=
list
.
GetEnumerator
())
{
Assert
.
IsTrue
(
enumerator
.
MoveNext
());
Assert
.
AreEqual
(
"first"
,
enumerator
.
Current
);
Assert
.
IsTrue
(
enumerator
.
MoveNext
());
Assert
.
AreEqual
(
"second"
,
enumerator
.
Current
);
Assert
.
IsFalse
(
enumerator
.
MoveNext
());
Assert
.
IsFalse
(
enumerator
.
MoveNext
());
}
}
[
Test
]
public
void
AddEntriesFrom_PackedInt32
()
{
uint
packedTag
=
WireFormat
.
MakeTag
(
10
,
WireFormat
.
WireType
.
LengthDelimited
);
var
stream
=
new
MemoryStream
();
var
output
=
new
CodedOutputStream
(
stream
);
var
length
=
CodedOutputStream
.
ComputeInt32Size
(
10
)
+
CodedOutputStream
.
ComputeInt32Size
(
999
)
+
CodedOutputStream
.
ComputeInt32Size
(-
1000
);
output
.
WriteTag
(
packedTag
);
output
.
WriteRawVarint32
((
uint
)
length
);
output
.
WriteInt32
(
10
);
output
.
WriteInt32
(
999
);
output
.
WriteInt32
(-
1000
);
output
.
Flush
();
stream
.
Position
=
0
;
// Deliberately "expecting" a non-packed tag, but we detect that the data is
// actually packed.
uint
nonPackedTag
=
WireFormat
.
MakeTag
(
10
,
WireFormat
.
WireType
.
LengthDelimited
);
var
field
=
new
RepeatedField
<
int
>();
var
input
=
new
CodedInputStream
(
stream
);
input
.
AssertNextTag
(
packedTag
);
field
.
AddEntriesFrom
(
input
,
FieldCodec
.
ForInt32
(
nonPackedTag
));
CollectionAssert
.
AreEqual
(
new
[]
{
10
,
999
,
-
1000
},
field
);
Assert
.
IsTrue
(
input
.
IsAtEnd
);
}
[
Test
]
public
void
AddEntriesFrom_NonPackedInt32
()
{
uint
nonPackedTag
=
WireFormat
.
MakeTag
(
10
,
WireFormat
.
WireType
.
Varint
);
var
stream
=
new
MemoryStream
();
var
output
=
new
CodedOutputStream
(
stream
);
output
.
WriteTag
(
nonPackedTag
);
output
.
WriteInt32
(
10
);
output
.
WriteTag
(
nonPackedTag
);
output
.
WriteInt32
(
999
);
output
.
WriteTag
(
nonPackedTag
);
output
.
WriteInt32
(-
1000
);
// Just for variety...
output
.
Flush
();
stream
.
Position
=
0
;
// Deliberately "expecting" a packed tag, but we detect that the data is
// actually not packed.
uint
packedTag
=
WireFormat
.
MakeTag
(
10
,
WireFormat
.
WireType
.
LengthDelimited
);
var
field
=
new
RepeatedField
<
int
>();
var
input
=
new
CodedInputStream
(
stream
);
input
.
AssertNextTag
(
nonPackedTag
);
field
.
AddEntriesFrom
(
input
,
FieldCodec
.
ForInt32
(
packedTag
));
CollectionAssert
.
AreEqual
(
new
[]
{
10
,
999
,
-
1000
},
field
);
Assert
.
IsTrue
(
input
.
IsAtEnd
);
}
[
Test
]
public
void
AddEntriesFrom_String
()
{
uint
tag
=
WireFormat
.
MakeTag
(
10
,
WireFormat
.
WireType
.
LengthDelimited
);
var
stream
=
new
MemoryStream
();
var
output
=
new
CodedOutputStream
(
stream
);
output
.
WriteTag
(
tag
);
output
.
WriteString
(
"Foo"
);
output
.
WriteTag
(
tag
);
output
.
WriteString
(
""
);
output
.
WriteTag
(
tag
);
output
.
WriteString
(
"Bar"
);
output
.
Flush
();
stream
.
Position
=
0
;
var
field
=
new
RepeatedField
<
string
>();
var
input
=
new
CodedInputStream
(
stream
);
input
.
AssertNextTag
(
tag
);
field
.
AddEntriesFrom
(
input
,
FieldCodec
.
ForString
(
tag
));
CollectionAssert
.
AreEqual
(
new
[]
{
"Foo"
,
""
,
"Bar"
},
field
);
Assert
.
IsTrue
(
input
.
IsAtEnd
);
}
[
Test
]
public
void
AddEntriesFrom_Message
()
{
var
message1
=
new
ForeignMessage
{
C
=
2000
};
var
message2
=
new
ForeignMessage
{
C
=
-
250
};
uint
tag
=
WireFormat
.
MakeTag
(
10
,
WireFormat
.
WireType
.
LengthDelimited
);
var
stream
=
new
MemoryStream
();
var
output
=
new
CodedOutputStream
(
stream
);
output
.
WriteTag
(
tag
);
output
.
WriteMessage
(
message1
);
output
.
WriteTag
(
tag
);
output
.
WriteMessage
(
message2
);
output
.
Flush
();
stream
.
Position
=
0
;
var
field
=
new
RepeatedField
<
ForeignMessage
>();
var
input
=
new
CodedInputStream
(
stream
);
input
.
AssertNextTag
(
tag
);
field
.
AddEntriesFrom
(
input
,
FieldCodec
.
ForMessage
(
tag
,
ForeignMessage
.
Parser
));
CollectionAssert
.
AreEqual
(
new
[]
{
message1
,
message2
},
field
);
Assert
.
IsTrue
(
input
.
IsAtEnd
);
}
[
Test
]
public
void
WriteTo_PackedInt32
()
{
uint
tag
=
WireFormat
.
MakeTag
(
10
,
WireFormat
.
WireType
.
LengthDelimited
);
var
field
=
new
RepeatedField
<
int
>
{
10
,
1000
,
1000000
};
var
stream
=
new
MemoryStream
();
var
output
=
new
CodedOutputStream
(
stream
);
field
.
WriteTo
(
output
,
FieldCodec
.
ForInt32
(
tag
));
output
.
Flush
();
stream
.
Position
=
0
;
var
input
=
new
CodedInputStream
(
stream
);
input
.
AssertNextTag
(
tag
);
var
length
=
input
.
ReadLength
();
Assert
.
AreEqual
(
10
,
input
.
ReadInt32
());
Assert
.
AreEqual
(
1000
,
input
.
ReadInt32
());
Assert
.
AreEqual
(
1000000
,
input
.
ReadInt32
());
Assert
.
IsTrue
(
input
.
IsAtEnd
);
Assert
.
AreEqual
(
1
+
CodedOutputStream
.
ComputeLengthSize
(
length
)
+
length
,
stream
.
Length
);
}
[
Test
]
public
void
WriteTo_NonPackedInt32
()
{
uint
tag
=
WireFormat
.
MakeTag
(
10
,
WireFormat
.
WireType
.
Varint
);
var
field
=
new
RepeatedField
<
int
>
{
10
,
1000
,
1000000
};
var
stream
=
new
MemoryStream
();
var
output
=
new
CodedOutputStream
(
stream
);
field
.
WriteTo
(
output
,
FieldCodec
.
ForInt32
(
tag
));
output
.
Flush
();
stream
.
Position
=
0
;
var
input
=
new
CodedInputStream
(
stream
);
input
.
AssertNextTag
(
tag
);
Assert
.
AreEqual
(
10
,
input
.
ReadInt32
());
input
.
AssertNextTag
(
tag
);
Assert
.
AreEqual
(
1000
,
input
.
ReadInt32
());
input
.
AssertNextTag
(
tag
);
Assert
.
AreEqual
(
1000000
,
input
.
ReadInt32
());
Assert
.
IsTrue
(
input
.
IsAtEnd
);
}
[
Test
]
public
void
WriteTo_String
()
{
uint
tag
=
WireFormat
.
MakeTag
(
10
,
WireFormat
.
WireType
.
LengthDelimited
);
var
field
=
new
RepeatedField
<
string
>
{
"Foo"
,
""
,
"Bar"
};
var
stream
=
new
MemoryStream
();
var
output
=
new
CodedOutputStream
(
stream
);
field
.
WriteTo
(
output
,
FieldCodec
.
ForString
(
tag
));
output
.
Flush
();
stream
.
Position
=
0
;
var
input
=
new
CodedInputStream
(
stream
);
input
.
AssertNextTag
(
tag
);
Assert
.
AreEqual
(
"Foo"
,
input
.
ReadString
());
input
.
AssertNextTag
(
tag
);
Assert
.
AreEqual
(
""
,
input
.
ReadString
());
input
.
AssertNextTag
(
tag
);
Assert
.
AreEqual
(
"Bar"
,
input
.
ReadString
());
Assert
.
IsTrue
(
input
.
IsAtEnd
);
}
[
Test
]
public
void
WriteTo_Message
()
{
var
message1
=
new
ForeignMessage
{
C
=
20
};
var
message2
=
new
ForeignMessage
{
C
=
25
};
uint
tag
=
WireFormat
.
MakeTag
(
10
,
WireFormat
.
WireType
.
LengthDelimited
);
var
field
=
new
RepeatedField
<
ForeignMessage
>
{
message1
,
message2
};
var
stream
=
new
MemoryStream
();
var
output
=
new
CodedOutputStream
(
stream
);
field
.
WriteTo
(
output
,
FieldCodec
.
ForMessage
(
tag
,
ForeignMessage
.
Parser
));
output
.
Flush
();
stream
.
Position
=
0
;
var
input
=
new
CodedInputStream
(
stream
);
input
.
AssertNextTag
(
tag
);
Assert
.
AreEqual
(
message1
,
input
.
ReadMessage
(
ForeignMessage
.
Parser
));
input
.
AssertNextTag
(
tag
);
Assert
.
AreEqual
(
message2
,
input
.
ReadMessage
(
ForeignMessage
.
Parser
));
Assert
.
IsTrue
(
input
.
IsAtEnd
);
}
[
Test
]
public
void
CalculateSize_VariableSizeNonPacked
()
{
var
list
=
new
RepeatedField
<
int
>
{
1
,
500
,
1
};
var
tag
=
WireFormat
.
MakeTag
(
1
,
WireFormat
.
WireType
.
Varint
);
// 2 bytes for the first entry, 3 bytes for the second, 2 bytes for the third
Assert
.
AreEqual
(
7
,
list
.
CalculateSize
(
FieldCodec
.
ForInt32
(
tag
)));
}
[
Test
]
public
void
CalculateSize_FixedSizeNonPacked
()
{
var
list
=
new
RepeatedField
<
int
>
{
1
,
500
,
1
};
var
tag
=
WireFormat
.
MakeTag
(
1
,
WireFormat
.
WireType
.
Fixed32
);
// 5 bytes for the each entry
Assert
.
AreEqual
(
15
,
list
.
CalculateSize
(
FieldCodec
.
ForSFixed32
(
tag
)));
}
[
Test
]
public
void
CalculateSize_VariableSizePacked
()
{
var
list
=
new
RepeatedField
<
int
>
{
1
,
500
,
1
};
var
tag
=
WireFormat
.
MakeTag
(
1
,
WireFormat
.
WireType
.
LengthDelimited
);
// 1 byte for the tag, 1 byte for the length,
// 1 byte for the first entry, 2 bytes for the second, 1 byte for the third
Assert
.
AreEqual
(
6
,
list
.
CalculateSize
(
FieldCodec
.
ForInt32
(
tag
)));
}
[
Test
]
public
void
CalculateSize_FixedSizePacked
()
{
var
list
=
new
RepeatedField
<
int
>
{
1
,
500
,
1
};
var
tag
=
WireFormat
.
MakeTag
(
1
,
WireFormat
.
WireType
.
LengthDelimited
);
// 1 byte for the tag, 1 byte for the length, 4 bytes per entry
Assert
.
AreEqual
(
14
,
list
.
CalculateSize
(
FieldCodec
.
ForSFixed32
(
tag
)));
}
[
Test
]
public
void
TestNegativeEnumArray
()
{
int
arraySize
=
1
+
1
+
(
11
*
5
);
int
msgSize
=
arraySize
;
byte
[]
bytes
=
new
byte
[
msgSize
];
CodedOutputStream
output
=
new
CodedOutputStream
(
bytes
);
uint
tag
=
WireFormat
.
MakeTag
(
8
,
WireFormat
.
WireType
.
Varint
);
for
(
int
i
=
0
;
i
>=
-
5
;
i
--)
{
output
.
WriteTag
(
tag
);
output
.
WriteEnum
(
i
);
}
Assert
.
AreEqual
(
0
,
output
.
SpaceLeft
);
CodedInputStream
input
=
new
CodedInputStream
(
bytes
);
tag
=
input
.
ReadTag
();
RepeatedField
<
SampleEnum
>
values
=
new
RepeatedField
<
SampleEnum
>();
values
.
AddEntriesFrom
(
input
,
FieldCodec
.
ForEnum
(
tag
,
x
=>
(
int
)
x
,
x
=>
(
SampleEnum
)
x
));
Assert
.
AreEqual
(
6
,
values
.
Count
);
Assert
.
AreEqual
(
SampleEnum
.
None
,
values
[
0
]);
Assert
.
AreEqual
(((
SampleEnum
)(-
1
)),
values
[
1
]);
Assert
.
AreEqual
(
SampleEnum
.
NegativeValue
,
values
[
2
]);
Assert
.
AreEqual
(((
SampleEnum
)(-
3
)),
values
[
3
]);
Assert
.
AreEqual
(((
SampleEnum
)(-
4
)),
values
[
4
]);
Assert
.
AreEqual
(((
SampleEnum
)(-
5
)),
values
[
5
]);
}
[
Test
]
public
void
TestNegativeEnumPackedArray
()
{
int
arraySize
=
1
+
(
10
*
5
);
int
msgSize
=
1
+
1
+
arraySize
;
byte
[]
bytes
=
new
byte
[
msgSize
];
CodedOutputStream
output
=
new
CodedOutputStream
(
bytes
);
// Length-delimited to show we want the packed representation
uint
tag
=
WireFormat
.
MakeTag
(
8
,
WireFormat
.
WireType
.
LengthDelimited
);
output
.
WriteTag
(
tag
);
int
size
=
0
;
for
(
int
i
=
0
;
i
>=
-
5
;
i
--)
{
size
+=
CodedOutputStream
.
ComputeEnumSize
(
i
);
}
output
.
WriteRawVarint32
((
uint
)
size
);
for
(
int
i
=
0
;
i
>=
-
5
;
i
--)
{
output
.
WriteEnum
(
i
);
}
Assert
.
AreEqual
(
0
,
output
.
SpaceLeft
);
CodedInputStream
input
=
new
CodedInputStream
(
bytes
);
tag
=
input
.
ReadTag
();
RepeatedField
<
SampleEnum
>
values
=
new
RepeatedField
<
SampleEnum
>();
values
.
AddEntriesFrom
(
input
,
FieldCodec
.
ForEnum
(
tag
,
x
=>
(
int
)
x
,
x
=>
(
SampleEnum
)
x
));
Assert
.
AreEqual
(
6
,
values
.
Count
);
Assert
.
AreEqual
(
SampleEnum
.
None
,
values
[
0
]);
Assert
.
AreEqual
(((
SampleEnum
)(-
1
)),
values
[
1
]);
Assert
.
AreEqual
(
SampleEnum
.
NegativeValue
,
values
[
2
]);
Assert
.
AreEqual
(((
SampleEnum
)(-
3
)),
values
[
3
]);
Assert
.
AreEqual
(((
SampleEnum
)(-
4
)),
values
[
4
]);
Assert
.
AreEqual
(((
SampleEnum
)(-
5
)),
values
[
5
]);
}
// Fairly perfunctory tests for the non-generic IList implementation
[
Test
]
public
void
IList_Indexer
()
{
var
field
=
new
RepeatedField
<
string
>
{
"first"
,
"second"
};
IList
list
=
field
;
Assert
.
AreEqual
(
"first"
,
list
[
0
]);
list
[
1
]
=
"changed"
;
Assert
.
AreEqual
(
"changed"
,
field
[
1
]);
}
[
Test
]
public
void
IList_Contains
()
{
IList
list
=
new
RepeatedField
<
string
>
{
"first"
,
"second"
};
Assert
.
IsTrue
(
list
.
Contains
(
"second"
));
Assert
.
IsFalse
(
list
.
Contains
(
"third"
));
Assert
.
IsFalse
(
list
.
Contains
(
new
object
()));
}
[
Test
]
public
void
IList_Add
()
{
IList
list
=
new
RepeatedField
<
string
>
{
"first"
,
"second"
};
list
.
Add
(
"third"
);
CollectionAssert
.
AreEqual
(
new
[]
{
"first"
,
"second"
,
"third"
},
list
);
}
[
Test
]
public
void
IList_Remove
()
{
IList
list
=
new
RepeatedField
<
string
>
{
"first"
,
"second"
};
list
.
Remove
(
"third"
);
// No-op, no exception
list
.
Remove
(
new
object
());
// No-op, no exception
list
.
Remove
(
"first"
);
CollectionAssert
.
AreEqual
(
new
[]
{
"second"
},
list
);
}
[
Test
]
public
void
IList_IsFixedSize
()
{
var
field
=
new
RepeatedField
<
string
>
{
"first"
,
"second"
};
IList
list
=
field
;
Assert
.
IsFalse
(
list
.
IsFixedSize
);
}
[
Test
]
public
void
IList_IndexOf
()
{
IList
list
=
new
RepeatedField
<
string
>
{
"first"
,
"second"
};
Assert
.
AreEqual
(
1
,
list
.
IndexOf
(
"second"
));
Assert
.
AreEqual
(-
1
,
list
.
IndexOf
(
"third"
));
Assert
.
AreEqual
(-
1
,
list
.
IndexOf
(
new
object
()));
}
[
Test
]
public
void
IList_SyncRoot
()
{
IList
list
=
new
RepeatedField
<
string
>
{
"first"
,
"second"
};
Assert
.
AreSame
(
list
,
list
.
SyncRoot
);
}
[
Test
]
public
void
IList_CopyTo
()
{
IList
list
=
new
RepeatedField
<
string
>
{
"first"
,
"second"
};
string
[]
stringArray
=
new
string
[
4
];
list
.
CopyTo
(
stringArray
,
1
);
CollectionAssert
.
AreEqual
(
new
[]
{
null
,
"first"
,
"second"
,
null
},
stringArray
);
object
[]
objectArray
=
new
object
[
4
];
list
.
CopyTo
(
objectArray
,
1
);
CollectionAssert
.
AreEqual
(
new
[]
{
null
,
"first"
,
"second"
,
null
},
objectArray
);
Assert
.
Throws
<
ArrayTypeMismatchException
>(()
=>
list
.
CopyTo
(
new
StringBuilder
[
4
],
1
));
Assert
.
Throws
<
ArrayTypeMismatchException
>(()
=>
list
.
CopyTo
(
new
int
[
4
],
1
));
}
[
Test
]
public
void
IList_IsSynchronized
()
{
IList
list
=
new
RepeatedField
<
string
>
{
"first"
,
"second"
};
Assert
.
IsFalse
(
list
.
IsSynchronized
);
}
[
Test
]
public
void
IList_Insert
()
{
IList
list
=
new
RepeatedField
<
string
>
{
"first"
,
"second"
};
list
.
Insert
(
1
,
"middle"
);
CollectionAssert
.
AreEqual
(
new
[]
{
"first"
,
"middle"
,
"second"
},
list
);
}
[
Test
]
public
void
ToString_Integers
()
{
var
list
=
new
RepeatedField
<
int
>
{
5
,
10
,
20
};
var
text
=
list
.
ToString
();
Assert
.
AreEqual
(
"[ 5, 10, 20 ]"
,
text
);
}
[
Test
]
public
void
ToString_Strings
()
{
var
list
=
new
RepeatedField
<
string
>
{
"x"
,
"y"
,
"z"
};
var
text
=
list
.
ToString
();
Assert
.
AreEqual
(
"[ \"x\", \"y\", \"z\" ]"
,
text
);
}
[
Test
]
public
void
ToString_Messages
()
{
var
list
=
new
RepeatedField
<
TestAllTypes
>
{
new
TestAllTypes
{
SingleDouble
=
1.5
},
new
TestAllTypes
{
SingleInt32
=
10
}
};
var
text
=
list
.
ToString
();
Assert
.
AreEqual
(
"[ { \"singleDouble\": 1.5 }, { \"singleInt32\": 10 } ]"
,
text
);
}
[
Test
]
public
void
ToString_Empty
()
{
var
list
=
new
RepeatedField
<
TestAllTypes
>
{
};
var
text
=
list
.
ToString
();
Assert
.
AreEqual
(
"[ ]"
,
text
);
}
[
Test
]
public
void
ToString_InvalidElementType
()
{
var
list
=
new
RepeatedField
<
decimal
>
{
15
m
};
Assert
.
Throws
<
ArgumentException
>(()
=>
list
.
ToString
());
}
[
Test
]
public
void
ToString_Timestamp
()
{
var
list
=
new
RepeatedField
<
Timestamp
>
{
Timestamp
.
FromDateTime
(
new
DateTime
(
2015
,
10
,
1
,
12
,
34
,
56
,
DateTimeKind
.
Utc
))
};
var
text
=
list
.
ToString
();
Assert
.
AreEqual
(
"[ \"2015-10-01T12:34:56Z\" ]"
,
text
);
}
[
Test
]
public
void
ToString_Struct
()
{
var
message
=
new
Struct
{
Fields
=
{
{
"foo"
,
new
Value
{
NumberValue
=
20
}
}
}
};
var
list
=
new
RepeatedField
<
Struct
>
{
message
};
var
text
=
list
.
ToString
();
Assert
.
AreEqual
(
text
,
"[ { \"foo\": 20 } ]"
,
message
.
ToString
());
}
}
}
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Compatibility/PropertyInfoExtensionsTest.cs
0 → 100644
View file @
3f6f73b7
#
region
Copyright
notice
and
license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
NUnit.Framework
;
using
System.Reflection
;
namespace
Google.Protobuf.Compatibility
{
public
class
PropertyInfoExtensionsTest
{
public
string
PublicReadWrite
{
get
;
set
;
}
private
string
PrivateReadWrite
{
get
;
set
;
}
public
string
PublicReadPrivateWrite
{
get
;
private
set
;
}
public
string
PrivateReadPublicWrite
{
private
get
;
set
;
}
public
string
PublicReadOnly
{
get
{
return
null
;
}
}
private
string
PrivateReadOnly
{
get
{
return
null
;
}
}
public
string
PublicWriteOnly
{
set
{
}
}
private
string
PrivateWriteOnly
{
set
{
}
}
[
Test
]
[
TestCase
(
"PublicReadWrite"
)]
[
TestCase
(
"PublicReadPrivateWrite"
)]
[
TestCase
(
"PublicReadOnly"
)]
public
void
GetGetMethod_Success
(
string
name
)
{
var
propertyInfo
=
typeof
(
PropertyInfoExtensionsTest
)
.
GetProperty
(
name
,
BindingFlags
.
Instance
|
BindingFlags
.
NonPublic
|
BindingFlags
.
Public
);
Assert
.
IsNotNull
(
PropertyInfoExtensions
.
GetGetMethod
(
propertyInfo
));
}
[
Test
]
[
TestCase
(
"PrivateReadWrite"
)]
[
TestCase
(
"PrivateReadPublicWrite"
)]
[
TestCase
(
"PrivateReadOnly"
)]
[
TestCase
(
"PublicWriteOnly"
)]
[
TestCase
(
"PrivateWriteOnly"
)]
public
void
GetGetMethod_NoAccessibleGetter
(
string
name
)
{
var
propertyInfo
=
typeof
(
PropertyInfoExtensionsTest
)
.
GetProperty
(
name
,
BindingFlags
.
Instance
|
BindingFlags
.
NonPublic
|
BindingFlags
.
Public
);
Assert
.
IsNull
(
PropertyInfoExtensions
.
GetGetMethod
(
propertyInfo
));
}
[
Test
]
[
TestCase
(
"PublicReadWrite"
)]
[
TestCase
(
"PrivateReadPublicWrite"
)]
[
TestCase
(
"PublicWriteOnly"
)]
public
void
GetSetMethod_Success
(
string
name
)
{
var
propertyInfo
=
typeof
(
PropertyInfoExtensionsTest
)
.
GetProperty
(
name
,
BindingFlags
.
Instance
|
BindingFlags
.
NonPublic
|
BindingFlags
.
Public
);
Assert
.
IsNotNull
(
PropertyInfoExtensions
.
GetSetMethod
(
propertyInfo
));
}
[
Test
]
[
TestCase
(
"PublicReadPrivateWrite"
)]
[
TestCase
(
"PrivateReadWrite"
)]
[
TestCase
(
"PrivateReadOnly"
)]
[
TestCase
(
"PublicReadOnly"
)]
[
TestCase
(
"PrivateWriteOnly"
)]
public
void
GetSetMethod_NoAccessibleGetter
(
string
name
)
{
var
propertyInfo
=
typeof
(
PropertyInfoExtensionsTest
)
.
GetProperty
(
name
,
BindingFlags
.
Instance
|
BindingFlags
.
NonPublic
|
BindingFlags
.
Public
);
Assert
.
IsNull
(
PropertyInfoExtensions
.
GetSetMethod
(
propertyInfo
));
}
}
}
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs
0 → 100644
View file @
3f6f73b7
#
region
Copyright
notice
and
license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
NUnit.Framework
;
using
System
;
using
System.Collections.Generic
;
using
System.Reflection
;
#if !DOTNET35
namespace
Google.Protobuf.Compatibility
{
public
class
TypeExtensionsTest
{
public
class
DerivedList
:
List
<
string
>
{
}
public
string
PublicProperty
{
get
;
set
;
}
private
string
PrivateProperty
{
get
;
set
;
}
public
void
PublicMethod
()
{
}
private
void
PrivateMethod
()
{
}
[
Test
]
[
TestCase
(
typeof
(
object
),
typeof
(
string
),
true
)]
[
TestCase
(
typeof
(
object
),
typeof
(
int
),
true
)]
[
TestCase
(
typeof
(
string
),
typeof
(
string
),
true
)]
[
TestCase
(
typeof
(
string
),
typeof
(
object
),
false
)]
[
TestCase
(
typeof
(
string
),
typeof
(
int
),
false
)]
[
TestCase
(
typeof
(
int
),
typeof
(
int
),
true
)]
[
TestCase
(
typeof
(
ValueType
),
typeof
(
int
),
true
)]
[
TestCase
(
typeof
(
long
),
typeof
(
int
),
false
)]
//
public
void
IsAssignableFrom
(
Type
target
,
Type
argument
,
bool
expected
)
{
Assert
.
AreEqual
(
expected
,
TypeExtensions
.
IsAssignableFrom
(
target
,
argument
));
}
[
Test
]
[
TestCase
(
typeof
(
DerivedList
),
"Count"
)]
// Go up the type hierarchy
[
TestCase
(
typeof
(
List
<
string
>),
"Count"
)]
[
TestCase
(
typeof
(
List
<>),
"Count"
)]
[
TestCase
(
typeof
(
TypeExtensionsTest
),
"PublicProperty"
)]
public
void
GetProperty_Success
(
Type
type
,
string
name
)
{
var
property
=
TypeExtensions
.
GetProperty
(
type
,
name
);
Assert
.
IsNotNull
(
property
);
Assert
.
AreEqual
(
name
,
property
.
Name
);
}
[
Test
]
[
TestCase
(
typeof
(
TypeExtensionsTest
),
"PrivateProperty"
)]
[
TestCase
(
typeof
(
TypeExtensionsTest
),
"Garbage"
)]
public
void
GetProperty_NoSuchProperty
(
Type
type
,
string
name
)
{
var
property
=
TypeExtensions
.
GetProperty
(
type
,
name
);
Assert
.
IsNull
(
property
);
}
[
Test
]
[
TestCase
(
typeof
(
DerivedList
),
"RemoveAt"
)]
// Go up the type hierarchy
[
TestCase
(
typeof
(
List
<>),
"RemoveAt"
)]
[
TestCase
(
typeof
(
TypeExtensionsTest
),
"PublicMethod"
)]
public
void
GetMethod_Success
(
Type
type
,
string
name
)
{
var
method
=
TypeExtensions
.
GetMethod
(
type
,
name
);
Assert
.
IsNotNull
(
method
);
Assert
.
AreEqual
(
name
,
method
.
Name
);
}
[
Test
]
[
TestCase
(
typeof
(
TypeExtensionsTest
),
"PrivateMethod"
)]
[
TestCase
(
typeof
(
TypeExtensionsTest
),
"GarbageMethod"
)]
public
void
GetMethod_NoSuchMethod
(
Type
type
,
string
name
)
{
var
method
=
TypeExtensions
.
GetMethod
(
type
,
name
);
Assert
.
IsNull
(
method
);
}
[
Test
]
[
TestCase
(
typeof
(
List
<
string
>),
"IndexOf"
)]
public
void
GetMethod_Ambiguous
(
Type
type
,
string
name
)
{
Assert
.
Throws
<
AmbiguousMatchException
>(()
=>
TypeExtensions
.
GetMethod
(
type
,
name
));
}
}
}
#endif
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/DeprecatedMemberTest.cs
0 → 100644
View file @
3f6f73b7
#
region
Copyright
notice
and
license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
System
;
using
System.Reflection
;
using
Google.Protobuf.TestProtos
;
using
NUnit.Framework
;
namespace
Google.Protobuf
{
public
class
DeprecatedMemberTest
{
private
static
void
AssertIsDeprecated
(
MemberInfo
member
)
{
Assert
.
NotNull
(
member
);
Assert
.
IsTrue
(
member
.
IsDefined
(
typeof
(
ObsoleteAttribute
),
false
),
"Member not obsolete: "
+
member
);
}
[
Test
]
public
void
TestDepreatedPrimitiveValue
()
{
AssertIsDeprecated
(
typeof
(
TestDeprecatedFields
).
GetProperty
(
"DeprecatedInt32"
));
}
}
}
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/EqualityTester.cs
0 → 100644
View file @
3f6f73b7
#
region
Copyright
notice
and
license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
System
;
using
NUnit.Framework
;
namespace
Google.Protobuf
{
/// <summary>
/// Helper methods when testing equality. NUnit's Assert.AreEqual and
/// Assert.AreNotEqual methods try to be clever with collections, which can
/// be annoying...
/// </summary>
internal
static
class
EqualityTester
{
public
static
void
AssertEquality
<
T
>(
T
first
,
T
second
)
where
T
:
IEquatable
<
T
>
{
Assert
.
IsTrue
(
first
.
Equals
(
second
));
Assert
.
IsTrue
(
first
.
Equals
((
object
)
second
));
Assert
.
AreEqual
(
first
.
GetHashCode
(),
second
.
GetHashCode
());
}
public
static
void
AssertInequality
<
T
>(
T
first
,
T
second
)
where
T
:
IEquatable
<
T
>
{
Assert
.
IsFalse
(
first
.
Equals
(
second
));
Assert
.
IsFalse
(
first
.
Equals
((
object
)
second
));
// While this isn't a requirement, the chances of this test failing due to
// coincidence rather than a bug are very small.
if
(
first
!=
null
&&
second
!=
null
)
{
Assert
.
AreNotEqual
(
first
.
GetHashCode
(),
second
.
GetHashCode
());
}
}
}
}
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/FieldCodecTest.cs
0 → 100644
View file @
3f6f73b7
#
region
Copyright
notice
and
license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
System.Collections.Generic
;
using
System.IO
;
using
System.Reflection
;
using
Google.Protobuf.TestProtos
;
using
NUnit.Framework
;
namespace
Google.Protobuf
{
public
class
FieldCodecTest
{
#pragma warning disable 0414 // Used by tests via reflection - do not remove!
private
static
readonly
List
<
ICodecTestData
>
Codecs
=
new
List
<
ICodecTestData
>
{
new
FieldCodecTestData
<
bool
>(
FieldCodec
.
ForBool
(
100
),
true
,
"Bool"
),
new
FieldCodecTestData
<
string
>(
FieldCodec
.
ForString
(
100
),
"sample"
,
"String"
),
new
FieldCodecTestData
<
ByteString
>(
FieldCodec
.
ForBytes
(
100
),
ByteString
.
CopyFrom
(
1
,
2
,
3
),
"Bytes"
),
new
FieldCodecTestData
<
int
>(
FieldCodec
.
ForInt32
(
100
),
-
1000
,
"Int32"
),
new
FieldCodecTestData
<
int
>(
FieldCodec
.
ForSInt32
(
100
),
-
1000
,
"SInt32"
),
new
FieldCodecTestData
<
int
>(
FieldCodec
.
ForSFixed32
(
100
),
-
1000
,
"SFixed32"
),
new
FieldCodecTestData
<
uint
>(
FieldCodec
.
ForUInt32
(
100
),
1234
,
"UInt32"
),
new
FieldCodecTestData
<
uint
>(
FieldCodec
.
ForFixed32
(
100
),
1234
,
"Fixed32"
),
new
FieldCodecTestData
<
long
>(
FieldCodec
.
ForInt64
(
100
),
-
1000
,
"Int64"
),
new
FieldCodecTestData
<
long
>(
FieldCodec
.
ForSInt64
(
100
),
-
1000
,
"SInt64"
),
new
FieldCodecTestData
<
long
>(
FieldCodec
.
ForSFixed64
(
100
),
-
1000
,
"SFixed64"
),
new
FieldCodecTestData
<
ulong
>(
FieldCodec
.
ForUInt64
(
100
),
1234
,
"UInt64"
),
new
FieldCodecTestData
<
ulong
>(
FieldCodec
.
ForFixed64
(
100
),
1234
,
"Fixed64"
),
new
FieldCodecTestData
<
float
>(
FieldCodec
.
ForFloat
(
100
),
1234.5f
,
"Float"
),
new
FieldCodecTestData
<
double
>(
FieldCodec
.
ForDouble
(
100
),
1234567890.5d
,
"Double"
),
new
FieldCodecTestData
<
ForeignEnum
>(
FieldCodec
.
ForEnum
(
100
,
t
=>
(
int
)
t
,
t
=>
(
ForeignEnum
)
t
),
ForeignEnum
.
ForeignBaz
,
"Enum"
),
new
FieldCodecTestData
<
ForeignMessage
>(
FieldCodec
.
ForMessage
(
100
,
ForeignMessage
.
Parser
),
new
ForeignMessage
{
C
=
10
},
"Message"
),
};
#pragma warning restore 0414
[
Test
,
TestCaseSource
(
"Codecs"
)]
public
void
RoundTripWithTag
(
ICodecTestData
codec
)
{
codec
.
TestRoundTripWithTag
();
}
[
Test
,
TestCaseSource
(
"Codecs"
)]
public
void
RoundTripRaw
(
ICodecTestData
codec
)
{
codec
.
TestRoundTripRaw
();
}
[
Test
,
TestCaseSource
(
"Codecs"
)]
public
void
CalculateSize
(
ICodecTestData
codec
)
{
codec
.
TestCalculateSizeWithTag
();
}
[
Test
,
TestCaseSource
(
"Codecs"
)]
public
void
DefaultValue
(
ICodecTestData
codec
)
{
codec
.
TestDefaultValue
();
}
[
Test
,
TestCaseSource
(
"Codecs"
)]
public
void
FixedSize
(
ICodecTestData
codec
)
{
codec
.
TestFixedSize
();
}
// This is ugly, but it means we can have a non-generic interface.
// It feels like NUnit should support this better, but I don't know
// of any better ways right now.
public
interface
ICodecTestData
{
void
TestRoundTripRaw
();
void
TestRoundTripWithTag
();
void
TestCalculateSizeWithTag
();
void
TestDefaultValue
();
void
TestFixedSize
();
}
public
class
FieldCodecTestData
<
T
>
:
ICodecTestData
{
private
readonly
FieldCodec
<
T
>
codec
;
private
readonly
T
sampleValue
;
private
readonly
string
name
;
public
FieldCodecTestData
(
FieldCodec
<
T
>
codec
,
T
sampleValue
,
string
name
)
{
this
.
codec
=
codec
;
this
.
sampleValue
=
sampleValue
;
this
.
name
=
name
;
}
public
void
TestRoundTripRaw
()
{
var
stream
=
new
MemoryStream
();
var
codedOutput
=
new
CodedOutputStream
(
stream
);
codec
.
ValueWriter
(
codedOutput
,
sampleValue
);
codedOutput
.
Flush
();
stream
.
Position
=
0
;
var
codedInput
=
new
CodedInputStream
(
stream
);
Assert
.
AreEqual
(
sampleValue
,
codec
.
ValueReader
(
codedInput
));
Assert
.
IsTrue
(
codedInput
.
IsAtEnd
);
}
public
void
TestRoundTripWithTag
()
{
var
stream
=
new
MemoryStream
();
var
codedOutput
=
new
CodedOutputStream
(
stream
);
codec
.
WriteTagAndValue
(
codedOutput
,
sampleValue
);
codedOutput
.
Flush
();
stream
.
Position
=
0
;
var
codedInput
=
new
CodedInputStream
(
stream
);
codedInput
.
AssertNextTag
(
codec
.
Tag
);
Assert
.
AreEqual
(
sampleValue
,
codec
.
Read
(
codedInput
));
Assert
.
IsTrue
(
codedInput
.
IsAtEnd
);
}
public
void
TestCalculateSizeWithTag
()
{
var
stream
=
new
MemoryStream
();
var
codedOutput
=
new
CodedOutputStream
(
stream
);
codec
.
WriteTagAndValue
(
codedOutput
,
sampleValue
);
codedOutput
.
Flush
();
Assert
.
AreEqual
(
stream
.
Position
,
codec
.
CalculateSizeWithTag
(
sampleValue
));
}
public
void
TestDefaultValue
()
{
// WriteTagAndValue ignores default values
var
stream
=
new
MemoryStream
();
var
codedOutput
=
new
CodedOutputStream
(
stream
);
codec
.
WriteTagAndValue
(
codedOutput
,
codec
.
DefaultValue
);
codedOutput
.
Flush
();
Assert
.
AreEqual
(
0
,
stream
.
Position
);
Assert
.
AreEqual
(
0
,
codec
.
CalculateSizeWithTag
(
codec
.
DefaultValue
));
if
(
typeof
(
T
).
GetTypeInfo
().
IsValueType
)
{
Assert
.
AreEqual
(
default
(
T
),
codec
.
DefaultValue
);
}
// The plain ValueWriter/ValueReader delegates don't.
if
(
codec
.
DefaultValue
!=
null
)
// This part isn't appropriate for message types.
{
codedOutput
=
new
CodedOutputStream
(
stream
);
codec
.
ValueWriter
(
codedOutput
,
codec
.
DefaultValue
);
codedOutput
.
Flush
();
Assert
.
AreNotEqual
(
0
,
stream
.
Position
);
Assert
.
AreEqual
(
stream
.
Position
,
codec
.
ValueSizeCalculator
(
codec
.
DefaultValue
));
stream
.
Position
=
0
;
var
codedInput
=
new
CodedInputStream
(
stream
);
Assert
.
AreEqual
(
codec
.
DefaultValue
,
codec
.
ValueReader
(
codedInput
));
}
}
public
void
TestFixedSize
()
{
Assert
.
AreEqual
(
name
.
Contains
(
"Fixed"
),
codec
.
FixedSize
!=
0
);
}
public
override
string
ToString
()
{
return
name
;
}
}
}
}
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/GeneratedMessageTest.cs
0 → 100644
View file @
3f6f73b7
#
region
Copyright
notice
and
license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
System
;
using
System.IO
;
using
Google.Protobuf.TestProtos
;
using
NUnit.Framework
;
using
System.Collections
;
using
System.Collections.Generic
;
using
System.Linq
;
using
Google.Protobuf.WellKnownTypes
;
namespace
Google.Protobuf
{
/// <summary>
/// Tests around the generated TestAllTypes message.
/// </summary>
public
class
GeneratedMessageTest
{
[
Test
]
public
void
EmptyMessageFieldDistinctFromMissingMessageField
()
{
// This demonstrates what we're really interested in...
var
message1
=
new
TestAllTypes
{
SingleForeignMessage
=
new
ForeignMessage
()
};
var
message2
=
new
TestAllTypes
();
// SingleForeignMessage is null
EqualityTester
.
AssertInequality
(
message1
,
message2
);
}
[
Test
]
public
void
DefaultValues
()
{
// Single fields
var
message
=
new
TestAllTypes
();
Assert
.
AreEqual
(
false
,
message
.
SingleBool
);
Assert
.
AreEqual
(
ByteString
.
Empty
,
message
.
SingleBytes
);
Assert
.
AreEqual
(
0.0
,
message
.
SingleDouble
);
Assert
.
AreEqual
(
0
,
message
.
SingleFixed32
);
Assert
.
AreEqual
(
0L
,
message
.
SingleFixed64
);
Assert
.
AreEqual
(
0.0f
,
message
.
SingleFloat
);
Assert
.
AreEqual
(
ForeignEnum
.
ForeignUnspecified
,
message
.
SingleForeignEnum
);
Assert
.
IsNull
(
message
.
SingleForeignMessage
);
Assert
.
AreEqual
(
ImportEnum
.
Unspecified
,
message
.
SingleImportEnum
);
Assert
.
IsNull
(
message
.
SingleImportMessage
);
Assert
.
AreEqual
(
0
,
message
.
SingleInt32
);
Assert
.
AreEqual
(
0L
,
message
.
SingleInt64
);
Assert
.
AreEqual
(
TestAllTypes
.
Types
.
NestedEnum
.
Unspecified
,
message
.
SingleNestedEnum
);
Assert
.
IsNull
(
message
.
SingleNestedMessage
);
Assert
.
IsNull
(
message
.
SinglePublicImportMessage
);
Assert
.
AreEqual
(
0
,
message
.
SingleSfixed32
);
Assert
.
AreEqual
(
0L
,
message
.
SingleSfixed64
);
Assert
.
AreEqual
(
0
,
message
.
SingleSint32
);
Assert
.
AreEqual
(
0L
,
message
.
SingleSint64
);
Assert
.
AreEqual
(
""
,
message
.
SingleString
);
Assert
.
AreEqual
(
0U
,
message
.
SingleUint32
);
Assert
.
AreEqual
(
0U
L
,
message
.
SingleUint64
);
// Repeated fields
Assert
.
AreEqual
(
0
,
message
.
RepeatedBool
.
Count
);
Assert
.
AreEqual
(
0
,
message
.
RepeatedBytes
.
Count
);
Assert
.
AreEqual
(
0
,
message
.
RepeatedDouble
.
Count
);
Assert
.
AreEqual
(
0
,
message
.
RepeatedFixed32
.
Count
);
Assert
.
AreEqual
(
0
,
message
.
RepeatedFixed64
.
Count
);
Assert
.
AreEqual
(
0
,
message
.
RepeatedFloat
.
Count
);
Assert
.
AreEqual
(
0
,
message
.
RepeatedForeignEnum
.
Count
);
Assert
.
AreEqual
(
0
,
message
.
RepeatedForeignMessage
.
Count
);
Assert
.
AreEqual
(
0
,
message
.
RepeatedImportEnum
.
Count
);
Assert
.
AreEqual
(
0
,
message
.
RepeatedImportMessage
.
Count
);
Assert
.
AreEqual
(
0
,
message
.
RepeatedNestedEnum
.
Count
);
Assert
.
AreEqual
(
0
,
message
.
RepeatedNestedMessage
.
Count
);
Assert
.
AreEqual
(
0
,
message
.
RepeatedPublicImportMessage
.
Count
);
Assert
.
AreEqual
(
0
,
message
.
RepeatedSfixed32
.
Count
);
Assert
.
AreEqual
(
0
,
message
.
RepeatedSfixed64
.
Count
);
Assert
.
AreEqual
(
0
,
message
.
RepeatedSint32
.
Count
);
Assert
.
AreEqual
(
0
,
message
.
RepeatedSint64
.
Count
);
Assert
.
AreEqual
(
0
,
message
.
RepeatedString
.
Count
);
Assert
.
AreEqual
(
0
,
message
.
RepeatedUint32
.
Count
);
Assert
.
AreEqual
(
0
,
message
.
RepeatedUint64
.
Count
);
// Oneof fields
Assert
.
AreEqual
(
TestAllTypes
.
OneofFieldOneofCase
.
None
,
message
.
OneofFieldCase
);
Assert
.
AreEqual
(
0
,
message
.
OneofUint32
);
Assert
.
AreEqual
(
""
,
message
.
OneofString
);
Assert
.
AreEqual
(
ByteString
.
Empty
,
message
.
OneofBytes
);
Assert
.
IsNull
(
message
.
OneofNestedMessage
);
}
[
Test
]
public
void
NullStringAndBytesRejected
()
{
var
message
=
new
TestAllTypes
();
Assert
.
Throws
<
ArgumentNullException
>(()
=>
message
.
SingleString
=
null
);
Assert
.
Throws
<
ArgumentNullException
>(()
=>
message
.
OneofString
=
null
);
Assert
.
Throws
<
ArgumentNullException
>(()
=>
message
.
SingleBytes
=
null
);
Assert
.
Throws
<
ArgumentNullException
>(()
=>
message
.
OneofBytes
=
null
);
}
[
Test
]
public
void
RoundTrip_Empty
()
{
var
message
=
new
TestAllTypes
();
// Without setting any values, there's nothing to write.
byte
[]
bytes
=
message
.
ToByteArray
();
Assert
.
AreEqual
(
0
,
bytes
.
Length
);
TestAllTypes
parsed
=
TestAllTypes
.
Parser
.
ParseFrom
(
bytes
);
Assert
.
AreEqual
(
message
,
parsed
);
}
[
Test
]
public
void
RoundTrip_SingleValues
()
{
var
message
=
new
TestAllTypes
{
SingleBool
=
true
,
SingleBytes
=
ByteString
.
CopyFrom
(
1
,
2
,
3
,
4
),
SingleDouble
=
23.5
,
SingleFixed32
=
23
,
SingleFixed64
=
1234567890123
,
SingleFloat
=
12.25f
,
SingleForeignEnum
=
ForeignEnum
.
ForeignBar
,
SingleForeignMessage
=
new
ForeignMessage
{
C
=
10
},
SingleImportEnum
=
ImportEnum
.
ImportBaz
,
SingleImportMessage
=
new
ImportMessage
{
D
=
20
},
SingleInt32
=
100
,
SingleInt64
=
3210987654321
,
SingleNestedEnum
=
TestAllTypes
.
Types
.
NestedEnum
.
Foo
,
SingleNestedMessage
=
new
TestAllTypes
.
Types
.
NestedMessage
{
Bb
=
35
},
SinglePublicImportMessage
=
new
PublicImportMessage
{
E
=
54
},
SingleSfixed32
=
-
123
,
SingleSfixed64
=
-
12345678901234
,
SingleSint32
=
-
456
,
SingleSint64
=
-
12345678901235
,
SingleString
=
"test"
,
SingleUint32
=
uint
.
MaxValue
,
SingleUint64
=
ulong
.
MaxValue
};
byte
[]
bytes
=
message
.
ToByteArray
();
TestAllTypes
parsed
=
TestAllTypes
.
Parser
.
ParseFrom
(
bytes
);
Assert
.
AreEqual
(
message
,
parsed
);
}
[
Test
]
public
void
RoundTrip_RepeatedValues
()
{
var
message
=
new
TestAllTypes
{
RepeatedBool
=
{
true
,
false
},
RepeatedBytes
=
{
ByteString
.
CopyFrom
(
1
,
2
,
3
,
4
),
ByteString
.
CopyFrom
(
5
,
6
)
},
RepeatedDouble
=
{
-
12.25
,
23.5
},
RepeatedFixed32
=
{
uint
.
MaxValue
,
23
},
RepeatedFixed64
=
{
ulong
.
MaxValue
,
1234567890123
},
RepeatedFloat
=
{
100f
,
12.25f
},
RepeatedForeignEnum
=
{
ForeignEnum
.
ForeignFoo
,
ForeignEnum
.
ForeignBar
},
RepeatedForeignMessage
=
{
new
ForeignMessage
(),
new
ForeignMessage
{
C
=
10
}
},
RepeatedImportEnum
=
{
ImportEnum
.
ImportBaz
,
ImportEnum
.
Unspecified
},
RepeatedImportMessage
=
{
new
ImportMessage
{
D
=
20
},
new
ImportMessage
{
D
=
25
}
},
RepeatedInt32
=
{
100
,
200
},
RepeatedInt64
=
{
3210987654321
,
long
.
MaxValue
},
RepeatedNestedEnum
=
{
TestAllTypes
.
Types
.
NestedEnum
.
Foo
,
TestAllTypes
.
Types
.
NestedEnum
.
Neg
},
RepeatedNestedMessage
=
{
new
TestAllTypes
.
Types
.
NestedMessage
{
Bb
=
35
},
new
TestAllTypes
.
Types
.
NestedMessage
{
Bb
=
10
}
},
RepeatedPublicImportMessage
=
{
new
PublicImportMessage
{
E
=
54
},
new
PublicImportMessage
{
E
=
-
1
}
},
RepeatedSfixed32
=
{
-
123
,
123
},
RepeatedSfixed64
=
{
-
12345678901234
,
12345678901234
},
RepeatedSint32
=
{
-
456
,
100
},
RepeatedSint64
=
{
-
12345678901235
,
123
},
RepeatedString
=
{
"foo"
,
"bar"
},
RepeatedUint32
=
{
uint
.
MaxValue
,
uint
.
MinValue
},
RepeatedUint64
=
{
ulong
.
MaxValue
,
uint
.
MinValue
}
};
byte
[]
bytes
=
message
.
ToByteArray
();
TestAllTypes
parsed
=
TestAllTypes
.
Parser
.
ParseFrom
(
bytes
);
Assert
.
AreEqual
(
message
,
parsed
);
}
// Note that not every map within map_unittest_proto3 is used. They all go through very
// similar code paths. The fact that all maps are present is validation that we have codecs
// for every type.
[
Test
]
public
void
RoundTrip_Maps
()
{
var
message
=
new
TestMap
{
MapBoolBool
=
{
{
false
,
true
},
{
true
,
false
}
},
MapInt32Bytes
=
{
{
5
,
ByteString
.
CopyFrom
(
6
,
7
,
8
)
},
{
25
,
ByteString
.
CopyFrom
(
1
,
2
,
3
,
4
,
5
)
},
{
10
,
ByteString
.
Empty
}
},
MapInt32ForeignMessage
=
{
{
0
,
new
ForeignMessage
{
C
=
10
}
},
{
5
,
new
ForeignMessage
()
},
},
MapInt32Enum
=
{
{
1
,
MapEnum
.
Bar
},
{
2000
,
MapEnum
.
Foo
}
}
};
byte
[]
bytes
=
message
.
ToByteArray
();
TestMap
parsed
=
TestMap
.
Parser
.
ParseFrom
(
bytes
);
Assert
.
AreEqual
(
message
,
parsed
);
}
[
Test
]
public
void
MapWithEmptyEntry
()
{
var
message
=
new
TestMap
{
MapInt32Bytes
=
{
{
0
,
ByteString
.
Empty
}
}
};
byte
[]
bytes
=
message
.
ToByteArray
();
Assert
.
AreEqual
(
2
,
bytes
.
Length
);
// Tag for field entry (1 byte), length of entry (0; 1 byte)
var
parsed
=
TestMap
.
Parser
.
ParseFrom
(
bytes
);
Assert
.
AreEqual
(
1
,
parsed
.
MapInt32Bytes
.
Count
);
Assert
.
AreEqual
(
ByteString
.
Empty
,
parsed
.
MapInt32Bytes
[
0
]);
}
[
Test
]
public
void
MapWithOnlyValue
()
{
// Hand-craft the stream to contain a single entry with just a value.
var
memoryStream
=
new
MemoryStream
();
var
output
=
new
CodedOutputStream
(
memoryStream
);
output
.
WriteTag
(
TestMap
.
MapInt32ForeignMessageFieldNumber
,
WireFormat
.
WireType
.
LengthDelimited
);
var
nestedMessage
=
new
ForeignMessage
{
C
=
20
};
// Size of the entry (tag, size written by WriteMessage, data written by WriteMessage)
output
.
WriteLength
(
2
+
nestedMessage
.
CalculateSize
());
output
.
WriteTag
(
2
,
WireFormat
.
WireType
.
LengthDelimited
);
output
.
WriteMessage
(
nestedMessage
);
output
.
Flush
();
var
parsed
=
TestMap
.
Parser
.
ParseFrom
(
memoryStream
.
ToArray
());
Assert
.
AreEqual
(
nestedMessage
,
parsed
.
MapInt32ForeignMessage
[
0
]);
}
[
Test
]
public
void
MapWithOnlyKey_PrimitiveValue
()
{
// Hand-craft the stream to contain a single entry with just a key.
var
memoryStream
=
new
MemoryStream
();
var
output
=
new
CodedOutputStream
(
memoryStream
);
output
.
WriteTag
(
TestMap
.
MapInt32DoubleFieldNumber
,
WireFormat
.
WireType
.
LengthDelimited
);
int
key
=
10
;
output
.
WriteLength
(
1
+
CodedOutputStream
.
ComputeInt32Size
(
key
));
output
.
WriteTag
(
1
,
WireFormat
.
WireType
.
Varint
);
output
.
WriteInt32
(
key
);
output
.
Flush
();
var
parsed
=
TestMap
.
Parser
.
ParseFrom
(
memoryStream
.
ToArray
());
Assert
.
AreEqual
(
0.0
,
parsed
.
MapInt32Double
[
key
]);
}
[
Test
]
public
void
MapWithOnlyKey_MessageValue
()
{
// Hand-craft the stream to contain a single entry with just a key.
var
memoryStream
=
new
MemoryStream
();
var
output
=
new
CodedOutputStream
(
memoryStream
);
output
.
WriteTag
(
TestMap
.
MapInt32ForeignMessageFieldNumber
,
WireFormat
.
WireType
.
LengthDelimited
);
int
key
=
10
;
output
.
WriteLength
(
1
+
CodedOutputStream
.
ComputeInt32Size
(
key
));
output
.
WriteTag
(
1
,
WireFormat
.
WireType
.
Varint
);
output
.
WriteInt32
(
key
);
output
.
Flush
();
var
parsed
=
TestMap
.
Parser
.
ParseFrom
(
memoryStream
.
ToArray
());
Assert
.
AreEqual
(
new
ForeignMessage
(),
parsed
.
MapInt32ForeignMessage
[
key
]);
}
[
Test
]
public
void
MapIgnoresExtraFieldsWithinEntryMessages
()
{
// Hand-craft the stream to contain a single entry with three fields
var
memoryStream
=
new
MemoryStream
();
var
output
=
new
CodedOutputStream
(
memoryStream
);
output
.
WriteTag
(
TestMap
.
MapInt32Int32FieldNumber
,
WireFormat
.
WireType
.
LengthDelimited
);
var
key
=
10
;
// Field 1
var
value
=
20
;
// Field 2
var
extra
=
30
;
// Field 3
// Each field can be represented in a single byte, with a single byte tag.
// Total message size: 6 bytes.
output
.
WriteLength
(
6
);
output
.
WriteTag
(
1
,
WireFormat
.
WireType
.
Varint
);
output
.
WriteInt32
(
key
);
output
.
WriteTag
(
2
,
WireFormat
.
WireType
.
Varint
);
output
.
WriteInt32
(
value
);
output
.
WriteTag
(
3
,
WireFormat
.
WireType
.
Varint
);
output
.
WriteInt32
(
extra
);
output
.
Flush
();
var
parsed
=
TestMap
.
Parser
.
ParseFrom
(
memoryStream
.
ToArray
());
Assert
.
AreEqual
(
value
,
parsed
.
MapInt32Int32
[
key
]);
}
[
Test
]
public
void
MapFieldOrderIsIrrelevant
()
{
var
memoryStream
=
new
MemoryStream
();
var
output
=
new
CodedOutputStream
(
memoryStream
);
output
.
WriteTag
(
TestMap
.
MapInt32Int32FieldNumber
,
WireFormat
.
WireType
.
LengthDelimited
);
var
key
=
10
;
var
value
=
20
;
// Each field can be represented in a single byte, with a single byte tag.
// Total message size: 4 bytes.
output
.
WriteLength
(
4
);
output
.
WriteTag
(
2
,
WireFormat
.
WireType
.
Varint
);
output
.
WriteInt32
(
value
);
output
.
WriteTag
(
1
,
WireFormat
.
WireType
.
Varint
);
output
.
WriteInt32
(
key
);
output
.
Flush
();
var
parsed
=
TestMap
.
Parser
.
ParseFrom
(
memoryStream
.
ToArray
());
Assert
.
AreEqual
(
value
,
parsed
.
MapInt32Int32
[
key
]);
}
[
Test
]
public
void
MapNonContiguousEntries
()
{
var
memoryStream
=
new
MemoryStream
();
var
output
=
new
CodedOutputStream
(
memoryStream
);
// Message structure:
// Entry for MapInt32Int32
// Entry for MapStringString
// Entry for MapInt32Int32
// First entry
var
key1
=
10
;
var
value1
=
20
;
output
.
WriteTag
(
TestMap
.
MapInt32Int32FieldNumber
,
WireFormat
.
WireType
.
LengthDelimited
);
output
.
WriteLength
(
4
);
output
.
WriteTag
(
1
,
WireFormat
.
WireType
.
Varint
);
output
.
WriteInt32
(
key1
);
output
.
WriteTag
(
2
,
WireFormat
.
WireType
.
Varint
);
output
.
WriteInt32
(
value1
);
// Second entry
var
key2
=
"a"
;
var
value2
=
"b"
;
output
.
WriteTag
(
TestMap
.
MapStringStringFieldNumber
,
WireFormat
.
WireType
.
LengthDelimited
);
output
.
WriteLength
(
6
);
// 3 bytes per entry: tag, size, character
output
.
WriteTag
(
1
,
WireFormat
.
WireType
.
LengthDelimited
);
output
.
WriteString
(
key2
);
output
.
WriteTag
(
2
,
WireFormat
.
WireType
.
LengthDelimited
);
output
.
WriteString
(
value2
);
// Third entry
var
key3
=
15
;
var
value3
=
25
;
output
.
WriteTag
(
TestMap
.
MapInt32Int32FieldNumber
,
WireFormat
.
WireType
.
LengthDelimited
);
output
.
WriteLength
(
4
);
output
.
WriteTag
(
1
,
WireFormat
.
WireType
.
Varint
);
output
.
WriteInt32
(
key3
);
output
.
WriteTag
(
2
,
WireFormat
.
WireType
.
Varint
);
output
.
WriteInt32
(
value3
);
output
.
Flush
();
var
parsed
=
TestMap
.
Parser
.
ParseFrom
(
memoryStream
.
ToArray
());
var
expected
=
new
TestMap
{
MapInt32Int32
=
{
{
key1
,
value1
},
{
key3
,
value3
}
},
MapStringString
=
{
{
key2
,
value2
}
}
};
Assert
.
AreEqual
(
expected
,
parsed
);
}
[
Test
]
public
void
DuplicateKeys_LastEntryWins
()
{
var
memoryStream
=
new
MemoryStream
();
var
output
=
new
CodedOutputStream
(
memoryStream
);
var
key
=
10
;
var
value1
=
20
;
var
value2
=
30
;
// First entry
output
.
WriteTag
(
TestMap
.
MapInt32Int32FieldNumber
,
WireFormat
.
WireType
.
LengthDelimited
);
output
.
WriteLength
(
4
);
output
.
WriteTag
(
1
,
WireFormat
.
WireType
.
Varint
);
output
.
WriteInt32
(
key
);
output
.
WriteTag
(
2
,
WireFormat
.
WireType
.
Varint
);
output
.
WriteInt32
(
value1
);
// Second entry - same key, different value
output
.
WriteTag
(
TestMap
.
MapInt32Int32FieldNumber
,
WireFormat
.
WireType
.
LengthDelimited
);
output
.
WriteLength
(
4
);
output
.
WriteTag
(
1
,
WireFormat
.
WireType
.
Varint
);
output
.
WriteInt32
(
key
);
output
.
WriteTag
(
2
,
WireFormat
.
WireType
.
Varint
);
output
.
WriteInt32
(
value2
);
output
.
Flush
();
var
parsed
=
TestMap
.
Parser
.
ParseFrom
(
memoryStream
.
ToArray
());
Assert
.
AreEqual
(
value2
,
parsed
.
MapInt32Int32
[
key
]);
}
[
Test
]
public
void
CloneSingleNonMessageValues
()
{
var
original
=
new
TestAllTypes
{
SingleBool
=
true
,
SingleBytes
=
ByteString
.
CopyFrom
(
1
,
2
,
3
,
4
),
SingleDouble
=
23.5
,
SingleFixed32
=
23
,
SingleFixed64
=
1234567890123
,
SingleFloat
=
12.25f
,
SingleInt32
=
100
,
SingleInt64
=
3210987654321
,
SingleNestedEnum
=
TestAllTypes
.
Types
.
NestedEnum
.
Foo
,
SingleSfixed32
=
-
123
,
SingleSfixed64
=
-
12345678901234
,
SingleSint32
=
-
456
,
SingleSint64
=
-
12345678901235
,
SingleString
=
"test"
,
SingleUint32
=
uint
.
MaxValue
,
SingleUint64
=
ulong
.
MaxValue
};
var
clone
=
original
.
Clone
();
Assert
.
AreNotSame
(
original
,
clone
);
Assert
.
AreEqual
(
original
,
clone
);
// Just as a single example
clone
.
SingleInt32
=
150
;
Assert
.
AreNotEqual
(
original
,
clone
);
}
[
Test
]
public
void
CloneRepeatedNonMessageValues
()
{
var
original
=
new
TestAllTypes
{
RepeatedBool
=
{
true
,
false
},
RepeatedBytes
=
{
ByteString
.
CopyFrom
(
1
,
2
,
3
,
4
),
ByteString
.
CopyFrom
(
5
,
6
)
},
RepeatedDouble
=
{
-
12.25
,
23.5
},
RepeatedFixed32
=
{
uint
.
MaxValue
,
23
},
RepeatedFixed64
=
{
ulong
.
MaxValue
,
1234567890123
},
RepeatedFloat
=
{
100f
,
12.25f
},
RepeatedInt32
=
{
100
,
200
},
RepeatedInt64
=
{
3210987654321
,
long
.
MaxValue
},
RepeatedNestedEnum
=
{
TestAllTypes
.
Types
.
NestedEnum
.
Foo
,
TestAllTypes
.
Types
.
NestedEnum
.
Neg
},
RepeatedSfixed32
=
{
-
123
,
123
},
RepeatedSfixed64
=
{
-
12345678901234
,
12345678901234
},
RepeatedSint32
=
{
-
456
,
100
},
RepeatedSint64
=
{
-
12345678901235
,
123
},
RepeatedString
=
{
"foo"
,
"bar"
},
RepeatedUint32
=
{
uint
.
MaxValue
,
uint
.
MinValue
},
RepeatedUint64
=
{
ulong
.
MaxValue
,
uint
.
MinValue
}
};
var
clone
=
original
.
Clone
();
Assert
.
AreNotSame
(
original
,
clone
);
Assert
.
AreEqual
(
original
,
clone
);
// Just as a single example
clone
.
RepeatedDouble
.
Add
(
25.5
);
Assert
.
AreNotEqual
(
original
,
clone
);
}
[
Test
]
public
void
CloneSingleMessageField
()
{
var
original
=
new
TestAllTypes
{
SingleNestedMessage
=
new
TestAllTypes
.
Types
.
NestedMessage
{
Bb
=
20
}
};
var
clone
=
original
.
Clone
();
Assert
.
AreNotSame
(
original
,
clone
);
Assert
.
AreNotSame
(
original
.
SingleNestedMessage
,
clone
.
SingleNestedMessage
);
Assert
.
AreEqual
(
original
,
clone
);
clone
.
SingleNestedMessage
.
Bb
=
30
;
Assert
.
AreNotEqual
(
original
,
clone
);
}
[
Test
]
public
void
CloneRepeatedMessageField
()
{
var
original
=
new
TestAllTypes
{
RepeatedNestedMessage
=
{
new
TestAllTypes
.
Types
.
NestedMessage
{
Bb
=
20
}
}
};
var
clone
=
original
.
Clone
();
Assert
.
AreNotSame
(
original
,
clone
);
Assert
.
AreNotSame
(
original
.
RepeatedNestedMessage
,
clone
.
RepeatedNestedMessage
);
Assert
.
AreNotSame
(
original
.
RepeatedNestedMessage
[
0
],
clone
.
RepeatedNestedMessage
[
0
]);
Assert
.
AreEqual
(
original
,
clone
);
clone
.
RepeatedNestedMessage
[
0
].
Bb
=
30
;
Assert
.
AreNotEqual
(
original
,
clone
);
}
[
Test
]
public
void
CloneOneofField
()
{
var
original
=
new
TestAllTypes
{
OneofNestedMessage
=
new
TestAllTypes
.
Types
.
NestedMessage
{
Bb
=
20
}
};
var
clone
=
original
.
Clone
();
Assert
.
AreNotSame
(
original
,
clone
);
Assert
.
AreEqual
(
original
,
clone
);
// We should have cloned the message
original
.
OneofNestedMessage
.
Bb
=
30
;
Assert
.
AreNotEqual
(
original
,
clone
);
}
[
Test
]
public
void
OneofProperties
()
{
// Switch the oneof case between each of the different options, and check everything behaves
// as expected in each case.
var
message
=
new
TestAllTypes
();
Assert
.
AreEqual
(
""
,
message
.
OneofString
);
Assert
.
AreEqual
(
0
,
message
.
OneofUint32
);
Assert
.
AreEqual
(
ByteString
.
Empty
,
message
.
OneofBytes
);
Assert
.
IsNull
(
message
.
OneofNestedMessage
);
Assert
.
AreEqual
(
TestAllTypes
.
OneofFieldOneofCase
.
None
,
message
.
OneofFieldCase
);
message
.
OneofString
=
"sample"
;
Assert
.
AreEqual
(
"sample"
,
message
.
OneofString
);
Assert
.
AreEqual
(
0
,
message
.
OneofUint32
);
Assert
.
AreEqual
(
ByteString
.
Empty
,
message
.
OneofBytes
);
Assert
.
IsNull
(
message
.
OneofNestedMessage
);
Assert
.
AreEqual
(
TestAllTypes
.
OneofFieldOneofCase
.
OneofString
,
message
.
OneofFieldCase
);
var
bytes
=
ByteString
.
CopyFrom
(
1
,
2
,
3
);
message
.
OneofBytes
=
bytes
;
Assert
.
AreEqual
(
""
,
message
.
OneofString
);
Assert
.
AreEqual
(
0
,
message
.
OneofUint32
);
Assert
.
AreEqual
(
bytes
,
message
.
OneofBytes
);
Assert
.
IsNull
(
message
.
OneofNestedMessage
);
Assert
.
AreEqual
(
TestAllTypes
.
OneofFieldOneofCase
.
OneofBytes
,
message
.
OneofFieldCase
);
message
.
OneofUint32
=
20
;
Assert
.
AreEqual
(
""
,
message
.
OneofString
);
Assert
.
AreEqual
(
20
,
message
.
OneofUint32
);
Assert
.
AreEqual
(
ByteString
.
Empty
,
message
.
OneofBytes
);
Assert
.
IsNull
(
message
.
OneofNestedMessage
);
Assert
.
AreEqual
(
TestAllTypes
.
OneofFieldOneofCase
.
OneofUint32
,
message
.
OneofFieldCase
);
var
nestedMessage
=
new
TestAllTypes
.
Types
.
NestedMessage
{
Bb
=
25
};
message
.
OneofNestedMessage
=
nestedMessage
;
Assert
.
AreEqual
(
""
,
message
.
OneofString
);
Assert
.
AreEqual
(
0
,
message
.
OneofUint32
);
Assert
.
AreEqual
(
ByteString
.
Empty
,
message
.
OneofBytes
);
Assert
.
AreEqual
(
nestedMessage
,
message
.
OneofNestedMessage
);
Assert
.
AreEqual
(
TestAllTypes
.
OneofFieldOneofCase
.
OneofNestedMessage
,
message
.
OneofFieldCase
);
message
.
ClearOneofField
();
Assert
.
AreEqual
(
""
,
message
.
OneofString
);
Assert
.
AreEqual
(
0
,
message
.
OneofUint32
);
Assert
.
AreEqual
(
ByteString
.
Empty
,
message
.
OneofBytes
);
Assert
.
IsNull
(
message
.
OneofNestedMessage
);
Assert
.
AreEqual
(
TestAllTypes
.
OneofFieldOneofCase
.
None
,
message
.
OneofFieldCase
);
}
[
Test
]
public
void
Oneof_DefaultValuesNotEqual
()
{
var
message1
=
new
TestAllTypes
{
OneofString
=
""
};
var
message2
=
new
TestAllTypes
{
OneofUint32
=
0
};
Assert
.
AreEqual
(
TestAllTypes
.
OneofFieldOneofCase
.
OneofString
,
message1
.
OneofFieldCase
);
Assert
.
AreEqual
(
TestAllTypes
.
OneofFieldOneofCase
.
OneofUint32
,
message2
.
OneofFieldCase
);
Assert
.
AreNotEqual
(
message1
,
message2
);
}
[
Test
]
public
void
OneofSerialization_NonDefaultValue
()
{
var
message
=
new
TestAllTypes
();
message
.
OneofString
=
"this would take a bit of space"
;
message
.
OneofUint32
=
10
;
var
bytes
=
message
.
ToByteArray
();
Assert
.
AreEqual
(
3
,
bytes
.
Length
);
// 2 bytes for the tag + 1 for the value - no string!
var
message2
=
TestAllTypes
.
Parser
.
ParseFrom
(
bytes
);
Assert
.
AreEqual
(
message
,
message2
);
Assert
.
AreEqual
(
TestAllTypes
.
OneofFieldOneofCase
.
OneofUint32
,
message2
.
OneofFieldCase
);
}
[
Test
]
public
void
OneofSerialization_DefaultValue
()
{
var
message
=
new
TestAllTypes
();
message
.
OneofString
=
"this would take a bit of space"
;
message
.
OneofUint32
=
0
;
// This is the default value for UInt32; normally wouldn't be serialized
var
bytes
=
message
.
ToByteArray
();
Assert
.
AreEqual
(
3
,
bytes
.
Length
);
// 2 bytes for the tag + 1 for the value - it's still serialized
var
message2
=
TestAllTypes
.
Parser
.
ParseFrom
(
bytes
);
Assert
.
AreEqual
(
message
,
message2
);
Assert
.
AreEqual
(
TestAllTypes
.
OneofFieldOneofCase
.
OneofUint32
,
message2
.
OneofFieldCase
);
}
[
Test
]
public
void
IgnoreUnknownFields_RealDataStillRead
()
{
var
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
stream
=
new
MemoryStream
();
var
output
=
new
CodedOutputStream
(
stream
);
var
unusedFieldNumber
=
23456
;
Assert
.
IsFalse
(
TestAllTypes
.
Descriptor
.
Fields
.
InDeclarationOrder
().
Select
(
x
=>
x
.
FieldNumber
).
Contains
(
unusedFieldNumber
));
output
.
WriteTag
(
unusedFieldNumber
,
WireFormat
.
WireType
.
LengthDelimited
);
output
.
WriteString
(
"ignore me"
);
message
.
WriteTo
(
output
);
output
.
Flush
();
stream
.
Position
=
0
;
var
parsed
=
TestAllTypes
.
Parser
.
ParseFrom
(
stream
);
Assert
.
AreEqual
(
message
,
parsed
);
}
[
Test
]
public
void
IgnoreUnknownFields_AllTypes
()
{
// Simple way of ensuring we can skip all kinds of fields.
var
data
=
SampleMessages
.
CreateFullTestAllTypes
().
ToByteArray
();
var
empty
=
Empty
.
Parser
.
ParseFrom
(
data
);
Assert
.
AreEqual
(
new
Empty
(),
empty
);
}
// This was originally seen as a conformance test failure.
[
Test
]
public
void
TruncatedMessageFieldThrows
()
{
// 130, 3 is the message tag
// 1 is the data length - but there's no data.
var
data
=
new
byte
[]
{
130
,
3
,
1
};
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
TestAllTypes
.
Parser
.
ParseFrom
(
data
));
}
/// <summary>
/// Demonstrates current behaviour with an extraneous end group tag - see issue 688
/// for details; we may want to change this.
/// </summary>
[
Test
]
public
void
ExtraEndGroupThrows
()
{
var
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
stream
=
new
MemoryStream
();
var
output
=
new
CodedOutputStream
(
stream
);
output
.
WriteTag
(
TestAllTypes
.
SingleFixed32FieldNumber
,
WireFormat
.
WireType
.
Fixed32
);
output
.
WriteFixed32
(
123
);
output
.
WriteTag
(
100
,
WireFormat
.
WireType
.
EndGroup
);
output
.
Flush
();
stream
.
Position
=
0
;
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
TestAllTypes
.
Parser
.
ParseFrom
(
stream
));
}
[
Test
]
public
void
CustomDiagnosticMessage_DirectToStringCall
()
{
var
message
=
new
ForeignMessage
{
C
=
31
};
Assert
.
AreEqual
(
"{ \"c\": 31, \"@cInHex\": \"1f\" }"
,
message
.
ToString
());
Assert
.
AreEqual
(
"{ \"c\": 31 }"
,
JsonFormatter
.
Default
.
Format
(
message
));
}
[
Test
]
public
void
CustomDiagnosticMessage_Nested
()
{
var
message
=
new
TestAllTypes
{
SingleForeignMessage
=
new
ForeignMessage
{
C
=
16
}
};
Assert
.
AreEqual
(
"{ \"singleForeignMessage\": { \"c\": 16, \"@cInHex\": \"10\" } }"
,
message
.
ToString
());
Assert
.
AreEqual
(
"{ \"singleForeignMessage\": { \"c\": 16 } }"
,
JsonFormatter
.
Default
.
Format
(
message
));
}
[
Test
]
public
void
CustomDiagnosticMessage_DirectToTextWriterCall
()
{
var
message
=
new
ForeignMessage
{
C
=
31
};
var
writer
=
new
StringWriter
();
JsonFormatter
.
Default
.
Format
(
message
,
writer
);
Assert
.
AreEqual
(
"{ \"c\": 31 }"
,
writer
.
ToString
());
}
}
}
\ No newline at end of file
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Google.Protobuf.Test.xproj
0 → 100644
View file @
3f6f73b7
<?xml version="1.0" encoding="utf-8"?>
<Project
ToolsVersion=
"14.0"
DefaultTargets=
"Build"
xmlns=
"http://schemas.microsoft.com/developer/msbuild/2003"
>
<PropertyGroup>
<VisualStudioVersion
Condition=
"'$(VisualStudioVersion)' == ''"
>
14.0
</VisualStudioVersion>
<VSToolsPath
Condition=
"'$(VSToolsPath)' == ''"
>
$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
</VSToolsPath>
</PropertyGroup>
<Import
Project=
"$(VSToolsPath)\DotNet\Microsoft.DotNet.Props"
Condition=
"'$(VSToolsPath)' != ''"
/>
<PropertyGroup
Label=
"Globals"
>
<ProjectGuid>
580eb013-d3c7-4578-b845-015f4a3b0591
</ProjectGuid>
<RootNamespace>
Google.Protobuf.Test
</RootNamespace>
<BaseIntermediateOutputPath
Condition=
"'$(BaseIntermediateOutputPath)'=='' "
>
.\obj
</BaseIntermediateOutputPath>
<OutputPath
Condition=
"'$(OutputPath)'=='' "
>
.\bin\
</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>
2.0
</SchemaVersion>
</PropertyGroup>
<Import
Project=
"$(VSToolsPath)\DotNet\Microsoft.DotNet.targets"
Condition=
"'$(VSToolsPath)' != ''"
/>
</Project>
\ No newline at end of file
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/IssuesTest.cs
0 → 100644
View file @
3f6f73b7
#
region
Copyright
notice
and
license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
Google.Protobuf.Reflection
;
using
UnitTest.Issues.TestProtos
;
using
NUnit.Framework
;
namespace
Google.Protobuf
{
/// <summary>
/// Tests for issues which aren't easily compartmentalized into other unit tests.
/// </summary>
public
class
IssuesTest
{
// Issue 45
[
Test
]
public
void
FieldCalledItem
()
{
ItemField
message
=
new
ItemField
{
Item
=
3
};
FieldDescriptor
field
=
ItemField
.
Descriptor
.
FindFieldByName
(
"item"
);
Assert
.
NotNull
(
field
);
Assert
.
AreEqual
(
3
,
(
int
)
field
.
Accessor
.
GetValue
(
message
));
}
[
Test
]
public
void
ReservedNames
()
{
var
message
=
new
ReservedNames
{
Types_
=
10
,
Descriptor_
=
20
};
// Underscores aren't reflected in the JSON.
Assert
.
AreEqual
(
"{ \"types\": 10, \"descriptor\": 20 }"
,
message
.
ToString
());
}
[
Test
]
public
void
JsonNameParseTest
()
{
var
settings
=
new
JsonParser
.
Settings
(
10
,
TypeRegistry
.
FromFiles
(
UnittestIssuesReflection
.
Descriptor
));
var
parser
=
new
JsonParser
(
settings
);
// It is safe to use either original field name or explicitly specified json_name
Assert
.
AreEqual
(
new
TestJsonName
{
Name
=
"test"
,
Description
=
"test2"
,
Guid
=
"test3"
},
parser
.
Parse
<
TestJsonName
>(
"{ \"name\": \"test\", \"desc\": \"test2\", \"guid\": \"test3\" }"
));
}
[
Test
]
public
void
JsonNameFormatTest
()
{
var
message
=
new
TestJsonName
{
Name
=
"test"
,
Description
=
"test2"
,
Guid
=
"test3"
};
Assert
.
AreEqual
(
"{ \"name\": \"test\", \"desc\": \"test2\", \"exid\": \"test3\" }"
,
JsonFormatter
.
Default
.
Format
(
message
));
}
}
}
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/JsonParserTest.cs
0 → 100644
View file @
3f6f73b7
#
region
Copyright
notice
and
license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
Google.Protobuf.Reflection
;
using
Google.Protobuf.TestProtos
;
using
Google.Protobuf.WellKnownTypes
;
using
NUnit.Framework
;
using
System
;
namespace
Google.Protobuf
{
/// <summary>
/// Unit tests for JSON parsing.
/// </summary>
public
class
JsonParserTest
{
// Sanity smoke test
[
Test
]
public
void
AllTypesRoundtrip
()
{
AssertRoundtrip
(
SampleMessages
.
CreateFullTestAllTypes
());
}
[
Test
]
public
void
Maps
()
{
AssertRoundtrip
(
new
TestMap
{
MapStringString
=
{
{
"with spaces"
,
"bar"
},
{
"a"
,
"b"
}
}
});
AssertRoundtrip
(
new
TestMap
{
MapInt32Int32
=
{
{
0
,
1
},
{
2
,
3
}
}
});
AssertRoundtrip
(
new
TestMap
{
MapBoolBool
=
{
{
false
,
true
},
{
true
,
false
}
}
});
}
[
Test
]
[
TestCase
(
" 1 "
)]
[
TestCase
(
"+1"
)]
[
TestCase
(
"1,000"
)]
[
TestCase
(
"1.5"
)]
public
void
IntegerMapKeysAreStrict
(
string
keyText
)
{
// Test that integer parsing is strict. We assume that if this is correct for int32,
// it's correct for other numeric key types.
var
json
=
"{ \"mapInt32Int32\": { \""
+
keyText
+
"\" : \"1\" } }"
;
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
JsonParser
.
Default
.
Parse
<
TestMap
>(
json
));
}
[
Test
]
public
void
OriginalFieldNameAccepted
()
{
var
json
=
"{ \"single_int32\": 10 }"
;
var
expected
=
new
TestAllTypes
{
SingleInt32
=
10
};
Assert
.
AreEqual
(
expected
,
TestAllTypes
.
Parser
.
ParseJson
(
json
));
}
[
Test
]
public
void
SourceContextRoundtrip
()
{
AssertRoundtrip
(
new
SourceContext
{
FileName
=
"foo.proto"
});
}
[
Test
]
public
void
SingularWrappers_DefaultNonNullValues
()
{
var
message
=
new
TestWellKnownTypes
{
StringField
=
""
,
BytesField
=
ByteString
.
Empty
,
BoolField
=
false
,
FloatField
=
0f
,
DoubleField
=
0d
,
Int32Field
=
0
,
Int64Field
=
0
,
Uint32Field
=
0
,
Uint64Field
=
0
};
AssertRoundtrip
(
message
);
}
[
Test
]
public
void
SingularWrappers_NonDefaultValues
()
{
var
message
=
new
TestWellKnownTypes
{
StringField
=
"x"
,
BytesField
=
ByteString
.
CopyFrom
(
1
,
2
,
3
),
BoolField
=
true
,
FloatField
=
12.5f
,
DoubleField
=
12.25d
,
Int32Field
=
1
,
Int64Field
=
2
,
Uint32Field
=
3
,
Uint64Field
=
4
};
AssertRoundtrip
(
message
);
}
[
Test
]
public
void
SingularWrappers_ExplicitNulls
()
{
// When we parse the "valueField": null part, we remember it... basically, it's one case
// where explicit default values don't fully roundtrip.
var
message
=
new
TestWellKnownTypes
{
ValueField
=
Value
.
ForNull
()
};
var
json
=
new
JsonFormatter
(
new
JsonFormatter
.
Settings
(
true
)).
Format
(
message
);
var
parsed
=
JsonParser
.
Default
.
Parse
<
TestWellKnownTypes
>(
json
);
Assert
.
AreEqual
(
message
,
parsed
);
}
[
Test
]
[
TestCase
(
typeof
(
BoolValue
),
"true"
,
true
)]
[
TestCase
(
typeof
(
Int32Value
),
"32"
,
32
)]
[
TestCase
(
typeof
(
Int64Value
),
"32"
,
32L
)]
[
TestCase
(
typeof
(
Int64Value
),
"\"32\""
,
32L
)]
[
TestCase
(
typeof
(
UInt32Value
),
"32"
,
32U
)]
[
TestCase
(
typeof
(
UInt64Value
),
"\"32\""
,
32U
L
)]
[
TestCase
(
typeof
(
UInt64Value
),
"32"
,
32U
L
)]
[
TestCase
(
typeof
(
StringValue
),
"\"foo\""
,
"foo"
)]
[
TestCase
(
typeof
(
FloatValue
),
"1.5"
,
1.5f
)]
[
TestCase
(
typeof
(
DoubleValue
),
"1.5"
,
1.5d
)]
public
void
Wrappers_Standalone
(
System
.
Type
wrapperType
,
string
json
,
object
expectedValue
)
{
IMessage
parsed
=
(
IMessage
)
Activator
.
CreateInstance
(
wrapperType
);
IMessage
expected
=
(
IMessage
)
Activator
.
CreateInstance
(
wrapperType
);
JsonParser
.
Default
.
Merge
(
parsed
,
"null"
);
Assert
.
AreEqual
(
expected
,
parsed
);
JsonParser
.
Default
.
Merge
(
parsed
,
json
);
expected
.
Descriptor
.
Fields
[
WrappersReflection
.
WrapperValueFieldNumber
].
Accessor
.
SetValue
(
expected
,
expectedValue
);
Assert
.
AreEqual
(
expected
,
parsed
);
}
[
Test
]
public
void
ExplicitNullValue
()
{
string
json
=
"{\"valueField\": null}"
;
var
message
=
JsonParser
.
Default
.
Parse
<
TestWellKnownTypes
>(
json
);
Assert
.
AreEqual
(
new
TestWellKnownTypes
{
ValueField
=
Value
.
ForNull
()
},
message
);
}
[
Test
]
public
void
BytesWrapper_Standalone
()
{
ByteString
data
=
ByteString
.
CopyFrom
(
1
,
2
,
3
);
// Can't do this with attributes...
var
parsed
=
JsonParser
.
Default
.
Parse
<
BytesValue
>(
WrapInQuotes
(
data
.
ToBase64
()));
var
expected
=
new
BytesValue
{
Value
=
data
};
Assert
.
AreEqual
(
expected
,
parsed
);
}
[
Test
]
public
void
RepeatedWrappers
()
{
var
message
=
new
RepeatedWellKnownTypes
{
BoolField
=
{
true
,
false
},
BytesField
=
{
ByteString
.
CopyFrom
(
1
,
2
,
3
),
ByteString
.
CopyFrom
(
4
,
5
,
6
),
ByteString
.
Empty
},
DoubleField
=
{
12.5
,
-
1.5
,
0d
},
FloatField
=
{
123.25f
,
-
20f
,
0f
},
Int32Field
=
{
int
.
MaxValue
,
int
.
MinValue
,
0
},
Int64Field
=
{
long
.
MaxValue
,
long
.
MinValue
,
0L
},
StringField
=
{
"First"
,
"Second"
,
""
},
Uint32Field
=
{
uint
.
MaxValue
,
uint
.
MinValue
,
0U
},
Uint64Field
=
{
ulong
.
MaxValue
,
ulong
.
MinValue
,
0U
L
},
};
AssertRoundtrip
(
message
);
}
[
Test
]
public
void
RepeatedField_NullElementProhibited
()
{
string
json
=
"{ \"repeated_foreign_message\": [null] }"
;
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
TestAllTypes
.
Parser
.
ParseJson
(
json
));
}
[
Test
]
public
void
RepeatedField_NullOverallValueAllowed
()
{
string
json
=
"{ \"repeated_foreign_message\": null }"
;
Assert
.
AreEqual
(
new
TestAllTypes
(),
TestAllTypes
.
Parser
.
ParseJson
(
json
));
}
[
Test
]
[
TestCase
(
"{ \"mapInt32Int32\": { \"10\": null }"
)]
[
TestCase
(
"{ \"mapStringString\": { \"abc\": null }"
)]
[
TestCase
(
"{ \"mapInt32ForeignMessage\": { \"10\": null }"
)]
public
void
MapField_NullValueProhibited
(
string
json
)
{
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
TestMap
.
Parser
.
ParseJson
(
json
));
}
[
Test
]
public
void
MapField_NullOverallValueAllowed
()
{
string
json
=
"{ \"mapInt32Int32\": null }"
;
Assert
.
AreEqual
(
new
TestMap
(),
TestMap
.
Parser
.
ParseJson
(
json
));
}
[
Test
]
public
void
IndividualWrapperTypes
()
{
Assert
.
AreEqual
(
new
StringValue
{
Value
=
"foo"
},
StringValue
.
Parser
.
ParseJson
(
"\"foo\""
));
Assert
.
AreEqual
(
new
Int32Value
{
Value
=
1
},
Int32Value
.
Parser
.
ParseJson
(
"1"
));
// Can parse strings directly too
Assert
.
AreEqual
(
new
Int32Value
{
Value
=
1
},
Int32Value
.
Parser
.
ParseJson
(
"\"1\""
));
}
private
static
void
AssertRoundtrip
<
T
>(
T
message
)
where
T
:
IMessage
<
T
>,
new
()
{
var
clone
=
message
.
Clone
();
var
json
=
JsonFormatter
.
Default
.
Format
(
message
);
var
parsed
=
JsonParser
.
Default
.
Parse
<
T
>(
json
);
Assert
.
AreEqual
(
clone
,
parsed
);
}
[
Test
]
[
TestCase
(
"0"
,
0
)]
[
TestCase
(
"-0"
,
0
)]
// Not entirely clear whether we intend to allow this...
[
TestCase
(
"1"
,
1
)]
[
TestCase
(
"-1"
,
-
1
)]
[
TestCase
(
"2147483647"
,
2147483647
)]
[
TestCase
(
"-2147483648"
,
-
2147483648
)]
public
void
StringToInt32_Valid
(
string
jsonValue
,
int
expectedParsedValue
)
{
string
json
=
"{ \"singleInt32\": \""
+
jsonValue
+
"\"}"
;
var
parsed
=
TestAllTypes
.
Parser
.
ParseJson
(
json
);
Assert
.
AreEqual
(
expectedParsedValue
,
parsed
.
SingleInt32
);
}
[
Test
]
[
TestCase
(
"+0"
)]
[
TestCase
(
" 1"
)]
[
TestCase
(
"1 "
)]
[
TestCase
(
"00"
)]
[
TestCase
(
"-00"
)]
[
TestCase
(
"--1"
)]
[
TestCase
(
"+1"
)]
[
TestCase
(
"1.5"
)]
[
TestCase
(
"1e10"
)]
[
TestCase
(
"2147483648"
)]
[
TestCase
(
"-2147483649"
)]
public
void
StringToInt32_Invalid
(
string
jsonValue
)
{
string
json
=
"{ \"singleInt32\": \""
+
jsonValue
+
"\"}"
;
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
TestAllTypes
.
Parser
.
ParseJson
(
json
));
}
[
Test
]
[
TestCase
(
"0"
,
0U
)]
[
TestCase
(
"1"
,
1U
)]
[
TestCase
(
"4294967295"
,
4294967295U
)]
public
void
StringToUInt32_Valid
(
string
jsonValue
,
uint
expectedParsedValue
)
{
string
json
=
"{ \"singleUint32\": \""
+
jsonValue
+
"\"}"
;
var
parsed
=
TestAllTypes
.
Parser
.
ParseJson
(
json
);
Assert
.
AreEqual
(
expectedParsedValue
,
parsed
.
SingleUint32
);
}
// Assume that anything non-bounds-related is covered in the Int32 case
[
Test
]
[
TestCase
(
"-1"
)]
[
TestCase
(
"4294967296"
)]
public
void
StringToUInt32_Invalid
(
string
jsonValue
)
{
string
json
=
"{ \"singleUint32\": \""
+
jsonValue
+
"\"}"
;
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
TestAllTypes
.
Parser
.
ParseJson
(
json
));
}
[
Test
]
[
TestCase
(
"0"
,
0L
)]
[
TestCase
(
"1"
,
1L
)]
[
TestCase
(
"-1"
,
-
1L
)]
[
TestCase
(
"9223372036854775807"
,
9223372036854775807
)]
[
TestCase
(
"-9223372036854775808"
,
-
9223372036854775808
)]
public
void
StringToInt64_Valid
(
string
jsonValue
,
long
expectedParsedValue
)
{
string
json
=
"{ \"singleInt64\": \""
+
jsonValue
+
"\"}"
;
var
parsed
=
TestAllTypes
.
Parser
.
ParseJson
(
json
);
Assert
.
AreEqual
(
expectedParsedValue
,
parsed
.
SingleInt64
);
}
// Assume that anything non-bounds-related is covered in the Int32 case
[
Test
]
[
TestCase
(
"-9223372036854775809"
)]
[
TestCase
(
"9223372036854775808"
)]
public
void
StringToInt64_Invalid
(
string
jsonValue
)
{
string
json
=
"{ \"singleInt64\": \""
+
jsonValue
+
"\"}"
;
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
TestAllTypes
.
Parser
.
ParseJson
(
json
));
}
[
Test
]
[
TestCase
(
"0"
,
0U
L
)]
[
TestCase
(
"1"
,
1U
L
)]
[
TestCase
(
"18446744073709551615"
,
18446744073709551615
)]
public
void
StringToUInt64_Valid
(
string
jsonValue
,
ulong
expectedParsedValue
)
{
string
json
=
"{ \"singleUint64\": \""
+
jsonValue
+
"\"}"
;
var
parsed
=
TestAllTypes
.
Parser
.
ParseJson
(
json
);
Assert
.
AreEqual
(
expectedParsedValue
,
parsed
.
SingleUint64
);
}
// Assume that anything non-bounds-related is covered in the Int32 case
[
Test
]
[
TestCase
(
"-1"
)]
[
TestCase
(
"18446744073709551616"
)]
public
void
StringToUInt64_Invalid
(
string
jsonValue
)
{
string
json
=
"{ \"singleUint64\": \""
+
jsonValue
+
"\"}"
;
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
TestAllTypes
.
Parser
.
ParseJson
(
json
));
}
[
Test
]
[
TestCase
(
"0"
,
0d
)]
[
TestCase
(
"1"
,
1d
)]
[
TestCase
(
"1.000000"
,
1d
)]
[
TestCase
(
"1.0000000000000000000000001"
,
1d
)]
// We don't notice that we haven't preserved the exact value
[
TestCase
(
"-1"
,
-
1d
)]
[
TestCase
(
"1e1"
,
10d
)]
[
TestCase
(
"1e01"
,
10d
)]
// Leading decimals are allowed in exponents
[
TestCase
(
"1E1"
,
10d
)]
// Either case is fine
[
TestCase
(
"-1e1"
,
-
10d
)]
[
TestCase
(
"1.5e1"
,
15d
)]
[
TestCase
(
"-1.5e1"
,
-
15d
)]
[
TestCase
(
"15e-1"
,
1.5d
)]
[
TestCase
(
"-15e-1"
,
-
1.5d
)]
[
TestCase
(
"1.79769e308"
,
1.79769
e308
)]
[
TestCase
(
"-1.79769e308"
,
-
1.79769
e308
)]
[
TestCase
(
"Infinity"
,
double
.
PositiveInfinity
)]
[
TestCase
(
"-Infinity"
,
double
.
NegativeInfinity
)]
[
TestCase
(
"NaN"
,
double
.
NaN
)]
public
void
StringToDouble_Valid
(
string
jsonValue
,
double
expectedParsedValue
)
{
string
json
=
"{ \"singleDouble\": \""
+
jsonValue
+
"\"}"
;
var
parsed
=
TestAllTypes
.
Parser
.
ParseJson
(
json
);
Assert
.
AreEqual
(
expectedParsedValue
,
parsed
.
SingleDouble
);
}
[
Test
]
[
TestCase
(
"1.7977e308"
)]
[
TestCase
(
"-1.7977e308"
)]
[
TestCase
(
"1e309"
)]
[
TestCase
(
"1,0"
)]
[
TestCase
(
"1.0.0"
)]
[
TestCase
(
"+1"
)]
[
TestCase
(
"00"
)]
[
TestCase
(
"01"
)]
[
TestCase
(
"-00"
)]
[
TestCase
(
"-01"
)]
[
TestCase
(
"--1"
)]
[
TestCase
(
" Infinity"
)]
[
TestCase
(
" -Infinity"
)]
[
TestCase
(
"NaN "
)]
[
TestCase
(
"Infinity "
)]
[
TestCase
(
"-Infinity "
)]
[
TestCase
(
" NaN"
)]
[
TestCase
(
"INFINITY"
)]
[
TestCase
(
"nan"
)]
[
TestCase
(
"\u00BD"
)]
// 1/2 as a single Unicode character. Just sanity checking...
public
void
StringToDouble_Invalid
(
string
jsonValue
)
{
string
json
=
"{ \"singleDouble\": \""
+
jsonValue
+
"\"}"
;
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
TestAllTypes
.
Parser
.
ParseJson
(
json
));
}
[
Test
]
[
TestCase
(
"0"
,
0f
)]
[
TestCase
(
"1"
,
1f
)]
[
TestCase
(
"1.000000"
,
1f
)]
[
TestCase
(
"-1"
,
-
1f
)]
[
TestCase
(
"3.402823e38"
,
3.402823
e38f
)]
[
TestCase
(
"-3.402823e38"
,
-
3.402823
e38f
)]
[
TestCase
(
"1.5e1"
,
15f
)]
[
TestCase
(
"15e-1"
,
1.5f
)]
public
void
StringToFloat_Valid
(
string
jsonValue
,
float
expectedParsedValue
)
{
string
json
=
"{ \"singleFloat\": \""
+
jsonValue
+
"\"}"
;
var
parsed
=
TestAllTypes
.
Parser
.
ParseJson
(
json
);
Assert
.
AreEqual
(
expectedParsedValue
,
parsed
.
SingleFloat
);
}
[
Test
]
[
TestCase
(
"3.402824e38"
)]
[
TestCase
(
"-3.402824e38"
)]
[
TestCase
(
"1,0"
)]
[
TestCase
(
"1.0.0"
)]
[
TestCase
(
"+1"
)]
[
TestCase
(
"00"
)]
[
TestCase
(
"--1"
)]
public
void
StringToFloat_Invalid
(
string
jsonValue
)
{
string
json
=
"{ \"singleFloat\": \""
+
jsonValue
+
"\"}"
;
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
TestAllTypes
.
Parser
.
ParseJson
(
json
));
}
[
Test
]
[
TestCase
(
"0"
,
0
)]
[
TestCase
(
"-0"
,
0
)]
// Not entirely clear whether we intend to allow this...
[
TestCase
(
"1"
,
1
)]
[
TestCase
(
"-1"
,
-
1
)]
[
TestCase
(
"2147483647"
,
2147483647
)]
[
TestCase
(
"-2147483648"
,
-
2147483648
)]
[
TestCase
(
"1e1"
,
10
)]
[
TestCase
(
"-1e1"
,
-
10
)]
[
TestCase
(
"10.00"
,
10
)]
[
TestCase
(
"-10.00"
,
-
10
)]
public
void
NumberToInt32_Valid
(
string
jsonValue
,
int
expectedParsedValue
)
{
string
json
=
"{ \"singleInt32\": "
+
jsonValue
+
"}"
;
var
parsed
=
TestAllTypes
.
Parser
.
ParseJson
(
json
);
Assert
.
AreEqual
(
expectedParsedValue
,
parsed
.
SingleInt32
);
}
[
Test
]
[
TestCase
(
"+0"
,
typeof
(
InvalidJsonException
))]
[
TestCase
(
"00"
,
typeof
(
InvalidJsonException
))]
[
TestCase
(
"-00"
,
typeof
(
InvalidJsonException
))]
[
TestCase
(
"--1"
,
typeof
(
InvalidJsonException
))]
[
TestCase
(
"+1"
,
typeof
(
InvalidJsonException
))]
[
TestCase
(
"1.5"
,
typeof
(
InvalidProtocolBufferException
))]
// Value is out of range
[
TestCase
(
"1e10"
,
typeof
(
InvalidProtocolBufferException
))]
[
TestCase
(
"2147483648"
,
typeof
(
InvalidProtocolBufferException
))]
[
TestCase
(
"-2147483649"
,
typeof
(
InvalidProtocolBufferException
))]
public
void
NumberToInt32_Invalid
(
string
jsonValue
,
System
.
Type
expectedExceptionType
)
{
string
json
=
"{ \"singleInt32\": "
+
jsonValue
+
"}"
;
Assert
.
Throws
(
expectedExceptionType
,
()
=>
TestAllTypes
.
Parser
.
ParseJson
(
json
));
}
[
Test
]
[
TestCase
(
"0"
,
0U
)]
[
TestCase
(
"1"
,
1U
)]
[
TestCase
(
"4294967295"
,
4294967295U
)]
public
void
NumberToUInt32_Valid
(
string
jsonValue
,
uint
expectedParsedValue
)
{
string
json
=
"{ \"singleUint32\": "
+
jsonValue
+
"}"
;
var
parsed
=
TestAllTypes
.
Parser
.
ParseJson
(
json
);
Assert
.
AreEqual
(
expectedParsedValue
,
parsed
.
SingleUint32
);
}
// Assume that anything non-bounds-related is covered in the Int32 case
[
Test
]
[
TestCase
(
"-1"
)]
[
TestCase
(
"4294967296"
)]
public
void
NumberToUInt32_Invalid
(
string
jsonValue
)
{
string
json
=
"{ \"singleUint32\": "
+
jsonValue
+
"}"
;
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
TestAllTypes
.
Parser
.
ParseJson
(
json
));
}
[
Test
]
[
TestCase
(
"0"
,
0L
)]
[
TestCase
(
"1"
,
1L
)]
[
TestCase
(
"-1"
,
-
1L
)]
// long.MaxValue isn't actually representable as a double. This string value is the highest
// representable value which isn't greater than long.MaxValue.
[
TestCase
(
"9223372036854774784"
,
9223372036854774784
)]
[
TestCase
(
"-9223372036854775808"
,
-
9223372036854775808
)]
public
void
NumberToInt64_Valid
(
string
jsonValue
,
long
expectedParsedValue
)
{
string
json
=
"{ \"singleInt64\": "
+
jsonValue
+
"}"
;
var
parsed
=
TestAllTypes
.
Parser
.
ParseJson
(
json
);
Assert
.
AreEqual
(
expectedParsedValue
,
parsed
.
SingleInt64
);
}
// Assume that anything non-bounds-related is covered in the Int32 case
[
Test
]
[
TestCase
(
"9223372036854775808"
)]
// Theoretical bound would be -9223372036854775809, but when that is parsed to a double
// we end up with the exact value of long.MinValue due to lack of precision. The value here
// is the "next double down".
[
TestCase
(
"-9223372036854780000"
)]
public
void
NumberToInt64_Invalid
(
string
jsonValue
)
{
string
json
=
"{ \"singleInt64\": "
+
jsonValue
+
"}"
;
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
TestAllTypes
.
Parser
.
ParseJson
(
json
));
}
[
Test
]
[
TestCase
(
"0"
,
0U
L
)]
[
TestCase
(
"1"
,
1U
L
)]
// ulong.MaxValue isn't representable as a double. This value is the largest double within
// the range of ulong.
[
TestCase
(
"18446744073709549568"
,
18446744073709549568U
L
)]
public
void
NumberToUInt64_Valid
(
string
jsonValue
,
ulong
expectedParsedValue
)
{
string
json
=
"{ \"singleUint64\": "
+
jsonValue
+
"}"
;
var
parsed
=
TestAllTypes
.
Parser
.
ParseJson
(
json
);
Assert
.
AreEqual
(
expectedParsedValue
,
parsed
.
SingleUint64
);
}
// Assume that anything non-bounds-related is covered in the Int32 case
[
Test
]
[
TestCase
(
"-1"
)]
[
TestCase
(
"18446744073709551616"
)]
public
void
NumberToUInt64_Invalid
(
string
jsonValue
)
{
string
json
=
"{ \"singleUint64\": "
+
jsonValue
+
"}"
;
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
TestAllTypes
.
Parser
.
ParseJson
(
json
));
}
[
Test
]
[
TestCase
(
"0"
,
0d
)]
[
TestCase
(
"1"
,
1d
)]
[
TestCase
(
"1.000000"
,
1d
)]
[
TestCase
(
"1.0000000000000000000000001"
,
1d
)]
// We don't notice that we haven't preserved the exact value
[
TestCase
(
"-1"
,
-
1d
)]
[
TestCase
(
"1e1"
,
10d
)]
[
TestCase
(
"1e01"
,
10d
)]
// Leading decimals are allowed in exponents
[
TestCase
(
"1E1"
,
10d
)]
// Either case is fine
[
TestCase
(
"-1e1"
,
-
10d
)]
[
TestCase
(
"1.5e1"
,
15d
)]
[
TestCase
(
"-1.5e1"
,
-
15d
)]
[
TestCase
(
"15e-1"
,
1.5d
)]
[
TestCase
(
"-15e-1"
,
-
1.5d
)]
[
TestCase
(
"1.79769e308"
,
1.79769
e308
)]
[
TestCase
(
"-1.79769e308"
,
-
1.79769
e308
)]
public
void
NumberToDouble_Valid
(
string
jsonValue
,
double
expectedParsedValue
)
{
string
json
=
"{ \"singleDouble\": "
+
jsonValue
+
"}"
;
var
parsed
=
TestAllTypes
.
Parser
.
ParseJson
(
json
);
Assert
.
AreEqual
(
expectedParsedValue
,
parsed
.
SingleDouble
);
}
[
Test
]
[
TestCase
(
"1.7977e308"
)]
[
TestCase
(
"-1.7977e308"
)]
[
TestCase
(
"1e309"
)]
[
TestCase
(
"1,0"
)]
[
TestCase
(
"1.0.0"
)]
[
TestCase
(
"+1"
)]
[
TestCase
(
"00"
)]
[
TestCase
(
"--1"
)]
[
TestCase
(
"\u00BD"
)]
// 1/2 as a single Unicode character. Just sanity checking...
public
void
NumberToDouble_Invalid
(
string
jsonValue
)
{
string
json
=
"{ \"singleDouble\": "
+
jsonValue
+
"}"
;
Assert
.
Throws
<
InvalidJsonException
>(()
=>
TestAllTypes
.
Parser
.
ParseJson
(
json
));
}
[
Test
]
[
TestCase
(
"0"
,
0f
)]
[
TestCase
(
"1"
,
1f
)]
[
TestCase
(
"1.000000"
,
1f
)]
[
TestCase
(
"-1"
,
-
1f
)]
[
TestCase
(
"3.402823e38"
,
3.402823
e38f
)]
[
TestCase
(
"-3.402823e38"
,
-
3.402823
e38f
)]
[
TestCase
(
"1.5e1"
,
15f
)]
[
TestCase
(
"15e-1"
,
1.5f
)]
public
void
NumberToFloat_Valid
(
string
jsonValue
,
float
expectedParsedValue
)
{
string
json
=
"{ \"singleFloat\": "
+
jsonValue
+
"}"
;
var
parsed
=
TestAllTypes
.
Parser
.
ParseJson
(
json
);
Assert
.
AreEqual
(
expectedParsedValue
,
parsed
.
SingleFloat
);
}
[
Test
]
[
TestCase
(
"3.402824e38"
,
typeof
(
InvalidProtocolBufferException
))]
[
TestCase
(
"-3.402824e38"
,
typeof
(
InvalidProtocolBufferException
))]
[
TestCase
(
"1,0"
,
typeof
(
InvalidJsonException
))]
[
TestCase
(
"1.0.0"
,
typeof
(
InvalidJsonException
))]
[
TestCase
(
"+1"
,
typeof
(
InvalidJsonException
))]
[
TestCase
(
"00"
,
typeof
(
InvalidJsonException
))]
[
TestCase
(
"--1"
,
typeof
(
InvalidJsonException
))]
public
void
NumberToFloat_Invalid
(
string
jsonValue
,
System
.
Type
expectedExceptionType
)
{
string
json
=
"{ \"singleFloat\": "
+
jsonValue
+
"}"
;
Assert
.
Throws
(
expectedExceptionType
,
()
=>
TestAllTypes
.
Parser
.
ParseJson
(
json
));
}
// The simplest way of testing that the value has parsed correctly is to reformat it,
// as we trust the formatting. In many cases that will give the same result as the input,
// so in those cases we accept an expectedFormatted value of null. Sometimes the results
// will be different though, due to a different number of digits being provided.
[
Test
]
// Z offset
[
TestCase
(
"2015-10-09T14:46:23.123456789Z"
,
null
)]
[
TestCase
(
"2015-10-09T14:46:23.123456Z"
,
null
)]
[
TestCase
(
"2015-10-09T14:46:23.123Z"
,
null
)]
[
TestCase
(
"2015-10-09T14:46:23Z"
,
null
)]
[
TestCase
(
"2015-10-09T14:46:23.123456000Z"
,
"2015-10-09T14:46:23.123456Z"
)]
[
TestCase
(
"2015-10-09T14:46:23.1234560Z"
,
"2015-10-09T14:46:23.123456Z"
)]
[
TestCase
(
"2015-10-09T14:46:23.123000000Z"
,
"2015-10-09T14:46:23.123Z"
)]
[
TestCase
(
"2015-10-09T14:46:23.1230Z"
,
"2015-10-09T14:46:23.123Z"
)]
[
TestCase
(
"2015-10-09T14:46:23.00Z"
,
"2015-10-09T14:46:23Z"
)]
// +00:00 offset
[
TestCase
(
"2015-10-09T14:46:23.123456789+00:00"
,
"2015-10-09T14:46:23.123456789Z"
)]
[
TestCase
(
"2015-10-09T14:46:23.123456+00:00"
,
"2015-10-09T14:46:23.123456Z"
)]
[
TestCase
(
"2015-10-09T14:46:23.123+00:00"
,
"2015-10-09T14:46:23.123Z"
)]
[
TestCase
(
"2015-10-09T14:46:23+00:00"
,
"2015-10-09T14:46:23Z"
)]
[
TestCase
(
"2015-10-09T14:46:23.123456000+00:00"
,
"2015-10-09T14:46:23.123456Z"
)]
[
TestCase
(
"2015-10-09T14:46:23.1234560+00:00"
,
"2015-10-09T14:46:23.123456Z"
)]
[
TestCase
(
"2015-10-09T14:46:23.123000000+00:00"
,
"2015-10-09T14:46:23.123Z"
)]
[
TestCase
(
"2015-10-09T14:46:23.1230+00:00"
,
"2015-10-09T14:46:23.123Z"
)]
[
TestCase
(
"2015-10-09T14:46:23.00+00:00"
,
"2015-10-09T14:46:23Z"
)]
// Other offsets (assume by now that the subsecond handling is okay)
[
TestCase
(
"2015-10-09T15:46:23.123456789+01:00"
,
"2015-10-09T14:46:23.123456789Z"
)]
[
TestCase
(
"2015-10-09T13:46:23.123456789-01:00"
,
"2015-10-09T14:46:23.123456789Z"
)]
[
TestCase
(
"2015-10-09T15:16:23.123456789+00:30"
,
"2015-10-09T14:46:23.123456789Z"
)]
[
TestCase
(
"2015-10-09T14:16:23.123456789-00:30"
,
"2015-10-09T14:46:23.123456789Z"
)]
[
TestCase
(
"2015-10-09T16:31:23.123456789+01:45"
,
"2015-10-09T14:46:23.123456789Z"
)]
[
TestCase
(
"2015-10-09T13:01:23.123456789-01:45"
,
"2015-10-09T14:46:23.123456789Z"
)]
[
TestCase
(
"2015-10-10T08:46:23.123456789+18:00"
,
"2015-10-09T14:46:23.123456789Z"
)]
[
TestCase
(
"2015-10-08T20:46:23.123456789-18:00"
,
"2015-10-09T14:46:23.123456789Z"
)]
// Leap years and min/max
[
TestCase
(
"2016-02-29T14:46:23.123456789Z"
,
null
)]
[
TestCase
(
"2000-02-29T14:46:23.123456789Z"
,
null
)]
[
TestCase
(
"0001-01-01T00:00:00Z"
,
null
)]
[
TestCase
(
"9999-12-31T23:59:59.999999999Z"
,
null
)]
public
void
Timestamp_Valid
(
string
jsonValue
,
string
expectedFormatted
)
{
expectedFormatted
=
expectedFormatted
??
jsonValue
;
string
json
=
WrapInQuotes
(
jsonValue
);
var
parsed
=
Timestamp
.
Parser
.
ParseJson
(
json
);
Assert
.
AreEqual
(
WrapInQuotes
(
expectedFormatted
),
parsed
.
ToString
());
}
[
Test
]
[
TestCase
(
"2015-10-09 14:46:23.123456789Z"
,
Description
=
"No T between date and time"
)]
[
TestCase
(
"2015/10/09T14:46:23.123456789Z"
,
Description
=
"Wrong date separators"
)]
[
TestCase
(
"2015-10-09T14.46.23.123456789Z"
,
Description
=
"Wrong time separators"
)]
[
TestCase
(
"2015-10-09T14:46:23,123456789Z"
,
Description
=
"Wrong fractional second separators (valid ISO-8601 though)"
)]
[
TestCase
(
" 2015-10-09T14:46:23.123456789Z"
,
Description
=
"Whitespace at start"
)]
[
TestCase
(
"2015-10-09T14:46:23.123456789Z "
,
Description
=
"Whitespace at end"
)]
[
TestCase
(
"2015-10-09T14:46:23.1234567890"
,
Description
=
"Too many digits"
)]
[
TestCase
(
"2015-10-09T14:46:23.123456789"
,
Description
=
"No offset"
)]
[
TestCase
(
"2015-13-09T14:46:23.123456789Z"
,
Description
=
"Invalid month"
)]
[
TestCase
(
"2015-10-32T14:46:23.123456789Z"
,
Description
=
"Invalid day"
)]
[
TestCase
(
"2015-10-09T24:00:00.000000000Z"
,
Description
=
"Invalid hour (valid ISO-8601 though)"
)]
[
TestCase
(
"2015-10-09T14:60:23.123456789Z"
,
Description
=
"Invalid minutes"
)]
[
TestCase
(
"2015-10-09T14:46:60.123456789Z"
,
Description
=
"Invalid seconds"
)]
[
TestCase
(
"2015-10-09T14:46:23.123456789+18:01"
,
Description
=
"Offset too large (positive)"
)]
[
TestCase
(
"2015-10-09T14:46:23.123456789-18:01"
,
Description
=
"Offset too large (negative)"
)]
[
TestCase
(
"2015-10-09T14:46:23.123456789-00:00"
,
Description
=
"Local offset (-00:00) makes no sense here"
)]
[
TestCase
(
"0001-01-01T00:00:00+00:01"
,
Description
=
"Value before earliest when offset applied"
)]
[
TestCase
(
"9999-12-31T23:59:59.999999999-00:01"
,
Description
=
"Value after latest when offset applied"
)]
[
TestCase
(
"2100-02-29T14:46:23.123456789Z"
,
Description
=
"Feb 29th on a non-leap-year"
)]
public
void
Timestamp_Invalid
(
string
jsonValue
)
{
string
json
=
WrapInQuotes
(
jsonValue
);
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
Timestamp
.
Parser
.
ParseJson
(
json
));
}
[
Test
]
public
void
StructValue_Null
()
{
Assert
.
AreEqual
(
new
Value
{
NullValue
=
0
},
Value
.
Parser
.
ParseJson
(
"null"
));
}
[
Test
]
public
void
StructValue_String
()
{
Assert
.
AreEqual
(
new
Value
{
StringValue
=
"hi"
},
Value
.
Parser
.
ParseJson
(
"\"hi\""
));
}
[
Test
]
public
void
StructValue_Bool
()
{
Assert
.
AreEqual
(
new
Value
{
BoolValue
=
true
},
Value
.
Parser
.
ParseJson
(
"true"
));
Assert
.
AreEqual
(
new
Value
{
BoolValue
=
false
},
Value
.
Parser
.
ParseJson
(
"false"
));
}
[
Test
]
public
void
StructValue_List
()
{
Assert
.
AreEqual
(
Value
.
ForList
(
Value
.
ForNumber
(
1
),
Value
.
ForString
(
"x"
)),
Value
.
Parser
.
ParseJson
(
"[1, \"x\"]"
));
}
[
Test
]
public
void
ParseListValue
()
{
Assert
.
AreEqual
(
new
ListValue
{
Values
=
{
Value
.
ForNumber
(
1
),
Value
.
ForString
(
"x"
)
}
},
ListValue
.
Parser
.
ParseJson
(
"[1, \"x\"]"
));
}
[
Test
]
public
void
StructValue_Struct
()
{
Assert
.
AreEqual
(
Value
.
ForStruct
(
new
Struct
{
Fields
=
{
{
"x"
,
Value
.
ForNumber
(
1
)
},
{
"y"
,
Value
.
ForString
(
"z"
)
}
}
}),
Value
.
Parser
.
ParseJson
(
"{ \"x\": 1, \"y\": \"z\" }"
));
}
[
Test
]
public
void
ParseStruct
()
{
Assert
.
AreEqual
(
new
Struct
{
Fields
=
{
{
"x"
,
Value
.
ForNumber
(
1
)
},
{
"y"
,
Value
.
ForString
(
"z"
)
}
}
},
Struct
.
Parser
.
ParseJson
(
"{ \"x\": 1, \"y\": \"z\" }"
));
}
// TODO for duration parsing: upper and lower bounds.
// +/- 315576000000 seconds
[
Test
]
[
TestCase
(
"1.123456789s"
,
null
)]
[
TestCase
(
"1.123456s"
,
null
)]
[
TestCase
(
"1.123s"
,
null
)]
[
TestCase
(
"1.12300s"
,
"1.123s"
)]
[
TestCase
(
"1.12345s"
,
"1.123450s"
)]
[
TestCase
(
"1s"
,
null
)]
[
TestCase
(
"-1.123456789s"
,
null
)]
[
TestCase
(
"-1.123456s"
,
null
)]
[
TestCase
(
"-1.123s"
,
null
)]
[
TestCase
(
"-1s"
,
null
)]
[
TestCase
(
"0.123s"
,
null
)]
[
TestCase
(
"-0.123s"
,
null
)]
[
TestCase
(
"123456.123s"
,
null
)]
[
TestCase
(
"-123456.123s"
,
null
)]
// Upper and lower bounds
[
TestCase
(
"315576000000s"
,
null
)]
[
TestCase
(
"-315576000000s"
,
null
)]
public
void
Duration_Valid
(
string
jsonValue
,
string
expectedFormatted
)
{
expectedFormatted
=
expectedFormatted
??
jsonValue
;
string
json
=
WrapInQuotes
(
jsonValue
);
var
parsed
=
Duration
.
Parser
.
ParseJson
(
json
);
Assert
.
AreEqual
(
WrapInQuotes
(
expectedFormatted
),
parsed
.
ToString
());
}
// The simplest way of testing that the value has parsed correctly is to reformat it,
// as we trust the formatting. In many cases that will give the same result as the input,
// so in those cases we accept an expectedFormatted value of null. Sometimes the results
// will be different though, due to a different number of digits being provided.
[
Test
]
[
TestCase
(
"1.1234567890s"
,
Description
=
"Too many digits"
)]
[
TestCase
(
"1.123456789"
,
Description
=
"No suffix"
)]
[
TestCase
(
"1.123456789ss"
,
Description
=
"Too much suffix"
)]
[
TestCase
(
"1.123456789S"
,
Description
=
"Upper case suffix"
)]
[
TestCase
(
"+1.123456789s"
,
Description
=
"Leading +"
)]
[
TestCase
(
".123456789s"
,
Description
=
"No integer before the fraction"
)]
[
TestCase
(
"1,123456789s"
,
Description
=
"Comma as decimal separator"
)]
[
TestCase
(
"1x1.123456789s"
,
Description
=
"Non-digit in integer part"
)]
[
TestCase
(
"1.1x3456789s"
,
Description
=
"Non-digit in fractional part"
)]
[
TestCase
(
" 1.123456789s"
,
Description
=
"Whitespace before fraction"
)]
[
TestCase
(
"1.123456789s "
,
Description
=
"Whitespace after value"
)]
[
TestCase
(
"01.123456789s"
,
Description
=
"Leading zero (positive)"
)]
[
TestCase
(
"-01.123456789s"
,
Description
=
"Leading zero (negative)"
)]
[
TestCase
(
"--0.123456789s"
,
Description
=
"Double minus sign"
)]
// Violate upper/lower bounds in various ways
[
TestCase
(
"315576000001s"
,
Description
=
"Integer part too large"
)]
[
TestCase
(
"3155760000000s"
,
Description
=
"Integer part too long (positive)"
)]
[
TestCase
(
"-3155760000000s"
,
Description
=
"Integer part too long (negative)"
)]
public
void
Duration_Invalid
(
string
jsonValue
)
{
string
json
=
WrapInQuotes
(
jsonValue
);
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
Duration
.
Parser
.
ParseJson
(
json
));
}
// Not as many tests for field masks as I'd like; more to be added when we have more
// detailed specifications.
[
Test
]
[
TestCase
(
""
)]
[
TestCase
(
"foo"
,
"foo"
)]
[
TestCase
(
"foo,bar"
,
"foo"
,
"bar"
)]
[
TestCase
(
"foo.bar"
,
"foo.bar"
)]
[
TestCase
(
"fooBar"
,
"foo_bar"
)]
[
TestCase
(
"fooBar.bazQux"
,
"foo_bar.baz_qux"
)]
public
void
FieldMask_Valid
(
string
jsonValue
,
params
string
[]
expectedPaths
)
{
string
json
=
WrapInQuotes
(
jsonValue
);
var
parsed
=
FieldMask
.
Parser
.
ParseJson
(
json
);
CollectionAssert
.
AreEqual
(
expectedPaths
,
parsed
.
Paths
);
}
[
Test
]
[
TestCase
(
"foo_bar"
)]
public
void
FieldMask_Invalid
(
string
jsonValue
)
{
string
json
=
WrapInQuotes
(
jsonValue
);
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
FieldMask
.
Parser
.
ParseJson
(
json
));
}
[
Test
]
public
void
Any_RegularMessage
()
{
var
registry
=
TypeRegistry
.
FromMessages
(
TestAllTypes
.
Descriptor
);
var
formatter
=
new
JsonFormatter
(
new
JsonFormatter
.
Settings
(
false
,
TypeRegistry
.
FromMessages
(
TestAllTypes
.
Descriptor
)));
var
message
=
new
TestAllTypes
{
SingleInt32
=
10
,
SingleNestedMessage
=
new
TestAllTypes
.
Types
.
NestedMessage
{
Bb
=
20
}
};
var
original
=
Any
.
Pack
(
message
);
var
json
=
formatter
.
Format
(
original
);
// This is tested in JsonFormatterTest
var
parser
=
new
JsonParser
(
new
JsonParser
.
Settings
(
10
,
registry
));
Assert
.
AreEqual
(
original
,
parser
.
Parse
<
Any
>(
json
));
string
valueFirstJson
=
"{ \"singleInt32\": 10, \"singleNestedMessage\": { \"bb\": 20 }, \"@type\": \"type.googleapis.com/protobuf_unittest.TestAllTypes\" }"
;
Assert
.
AreEqual
(
original
,
parser
.
Parse
<
Any
>(
valueFirstJson
));
}
[
Test
]
public
void
Any_CustomPrefix
()
{
var
registry
=
TypeRegistry
.
FromMessages
(
TestAllTypes
.
Descriptor
);
var
message
=
new
TestAllTypes
{
SingleInt32
=
10
};
var
original
=
Any
.
Pack
(
message
,
"custom.prefix/middle-part"
);
var
parser
=
new
JsonParser
(
new
JsonParser
.
Settings
(
10
,
registry
));
string
json
=
"{ \"@type\": \"custom.prefix/middle-part/protobuf_unittest.TestAllTypes\", \"singleInt32\": 10 }"
;
Assert
.
AreEqual
(
original
,
parser
.
Parse
<
Any
>(
json
));
}
[
Test
]
public
void
Any_UnknownType
()
{
string
json
=
"{ \"@type\": \"type.googleapis.com/bogus\" }"
;
Assert
.
Throws
<
InvalidOperationException
>(()
=>
Any
.
Parser
.
ParseJson
(
json
));
}
[
Test
]
public
void
Any_NoTypeUrl
()
{
string
json
=
"{ \"foo\": \"bar\" }"
;
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
Any
.
Parser
.
ParseJson
(
json
));
}
[
Test
]
public
void
Any_WellKnownType
()
{
var
registry
=
TypeRegistry
.
FromMessages
(
Timestamp
.
Descriptor
);
var
formatter
=
new
JsonFormatter
(
new
JsonFormatter
.
Settings
(
false
,
registry
));
var
timestamp
=
new
DateTime
(
1673
,
6
,
19
,
12
,
34
,
56
,
DateTimeKind
.
Utc
).
ToTimestamp
();
var
original
=
Any
.
Pack
(
timestamp
);
var
json
=
formatter
.
Format
(
original
);
// This is tested in JsonFormatterTest
var
parser
=
new
JsonParser
(
new
JsonParser
.
Settings
(
10
,
registry
));
Assert
.
AreEqual
(
original
,
parser
.
Parse
<
Any
>(
json
));
string
valueFirstJson
=
"{ \"value\": \"1673-06-19T12:34:56Z\", \"@type\": \"type.googleapis.com/google.protobuf.Timestamp\" }"
;
Assert
.
AreEqual
(
original
,
parser
.
Parse
<
Any
>(
valueFirstJson
));
}
[
Test
]
public
void
Any_Nested
()
{
var
registry
=
TypeRegistry
.
FromMessages
(
TestWellKnownTypes
.
Descriptor
,
TestAllTypes
.
Descriptor
);
var
formatter
=
new
JsonFormatter
(
new
JsonFormatter
.
Settings
(
false
,
registry
));
var
parser
=
new
JsonParser
(
new
JsonParser
.
Settings
(
10
,
registry
));
var
doubleNestedMessage
=
new
TestAllTypes
{
SingleInt32
=
20
};
var
nestedMessage
=
Any
.
Pack
(
doubleNestedMessage
);
var
message
=
new
TestWellKnownTypes
{
AnyField
=
Any
.
Pack
(
nestedMessage
)
};
var
json
=
formatter
.
Format
(
message
);
// Use the descriptor-based parser just for a change.
Assert
.
AreEqual
(
message
,
parser
.
Parse
(
json
,
TestWellKnownTypes
.
Descriptor
));
}
[
Test
]
public
void
DataAfterObject
()
{
string
json
=
"{} 10"
;
Assert
.
Throws
<
InvalidJsonException
>(()
=>
TestAllTypes
.
Parser
.
ParseJson
(
json
));
}
/// <summary>
/// JSON equivalent to <see cref="CodedInputStreamTest.MaliciousRecursion"/>
/// </summary>
[
Test
]
public
void
MaliciousRecursion
()
{
string
data64
=
CodedInputStreamTest
.
MakeRecursiveMessage
(
64
).
ToString
();
string
data65
=
CodedInputStreamTest
.
MakeRecursiveMessage
(
65
).
ToString
();
var
parser64
=
new
JsonParser
(
new
JsonParser
.
Settings
(
64
));
CodedInputStreamTest
.
AssertMessageDepth
(
parser64
.
Parse
<
TestRecursiveMessage
>(
data64
),
64
);
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
parser64
.
Parse
<
TestRecursiveMessage
>(
data65
));
var
parser63
=
new
JsonParser
(
new
JsonParser
.
Settings
(
63
));
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
parser63
.
Parse
<
TestRecursiveMessage
>(
data64
));
}
[
Test
]
[
TestCase
(
"AQI"
)]
[
TestCase
(
"_-=="
)]
public
void
Bytes_InvalidBase64
(
string
badBase64
)
{
string
json
=
"{ \"singleBytes\": \""
+
badBase64
+
"\" }"
;
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
TestAllTypes
.
Parser
.
ParseJson
(
json
));
}
[
Test
]
[
TestCase
(
"\"FOREIGN_BAR\""
,
ForeignEnum
.
ForeignBar
)]
[
TestCase
(
"5"
,
ForeignEnum
.
ForeignBar
)]
[
TestCase
(
"100"
,
(
ForeignEnum
)
100
)]
public
void
EnumValid
(
string
value
,
ForeignEnum
expectedValue
)
{
string
json
=
"{ \"singleForeignEnum\": "
+
value
+
" }"
;
var
parsed
=
TestAllTypes
.
Parser
.
ParseJson
(
json
);
Assert
.
AreEqual
(
new
TestAllTypes
{
SingleForeignEnum
=
expectedValue
},
parsed
);
}
[
Test
]
[
TestCase
(
"\"NOT_A_VALID_VALUE\""
)]
[
TestCase
(
"5.5"
)]
public
void
Enum_Invalid
(
string
value
)
{
string
json
=
"{ \"singleForeignEnum\": "
+
value
+
" }"
;
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
TestAllTypes
.
Parser
.
ParseJson
(
json
));
}
[
Test
]
public
void
OneofDuplicate_Invalid
()
{
string
json
=
"{ \"oneofString\": \"x\", \"oneofUint32\": 10 }"
;
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
TestAllTypes
.
Parser
.
ParseJson
(
json
));
}
/// <summary>
/// Various tests use strings which have quotes round them for parsing or as the result
/// of formatting, but without those quotes being specified in the tests (for the sake of readability).
/// This method simply returns the input, wrapped in double quotes.
/// </summary>
internal
static
string
WrapInQuotes
(
string
text
)
{
return
'"'
+
text
+
'"'
;
}
}
}
\ No newline at end of file
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/JsonTokenizerTest.cs
0 → 100644
View file @
3f6f73b7
#
region
Copyright
notice
and
license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
NUnit.Framework
;
using
System
;
using
System.IO
;
namespace
Google.Protobuf
{
public
class
JsonTokenizerTest
{
[
Test
]
public
void
EmptyObjectValue
()
{
AssertTokens
(
"{}"
,
JsonToken
.
StartObject
,
JsonToken
.
EndObject
);
}
[
Test
]
public
void
EmptyArrayValue
()
{
AssertTokens
(
"[]"
,
JsonToken
.
StartArray
,
JsonToken
.
EndArray
);
}
[
Test
]
[
TestCase
(
"foo"
,
"foo"
)]
[
TestCase
(
"tab\\t"
,
"tab\t"
)]
[
TestCase
(
"line\\nfeed"
,
"line\nfeed"
)]
[
TestCase
(
"carriage\\rreturn"
,
"carriage\rreturn"
)]
[
TestCase
(
"back\\bspace"
,
"back\bspace"
)]
[
TestCase
(
"form\\ffeed"
,
"form\ffeed"
)]
[
TestCase
(
"escaped\\/slash"
,
"escaped/slash"
)]
[
TestCase
(
"escaped\\\\backslash"
,
"escaped\\backslash"
)]
[
TestCase
(
"escaped\\\"quote"
,
"escaped\"quote"
)]
[
TestCase
(
"foo {}[] bar"
,
"foo {}[] bar"
)]
[
TestCase
(
"foo\\u09aFbar"
,
"foo\u09afbar"
)]
// Digits, upper hex, lower hex
[
TestCase
(
"ab\ud800\udc00cd"
,
"ab\ud800\udc00cd"
)]
[
TestCase
(
"ab\\ud800\\udc00cd"
,
"ab\ud800\udc00cd"
)]
public
void
StringValue
(
string
json
,
string
expectedValue
)
{
AssertTokensNoReplacement
(
"\""
+
json
+
"\""
,
JsonToken
.
Value
(
expectedValue
));
}
// Valid surrogate pairs, with mixed escaping. These test cases can't be expressed
// using TestCase as they have no valid UTF-8 representation.
// It's unclear exactly how we should handle a mixture of escaped or not: that can't
// come from UTF-8 text, but could come from a .NET string. For the moment,
// treat it as valid in the obvious way.
[
Test
]
public
void
MixedSurrogatePairs
()
{
string
expected
=
"\ud800\udc00"
;
AssertTokens
(
"'\\ud800\udc00'"
,
JsonToken
.
Value
(
expected
));
AssertTokens
(
"'\ud800\\udc00'"
,
JsonToken
.
Value
(
expected
));
}
[
Test
]
public
void
ObjectDepth
()
{
string
json
=
"{ \"foo\": { \"x\": 1, \"y\": [ 0 ] } }"
;
var
tokenizer
=
JsonTokenizer
.
FromTextReader
(
new
StringReader
(
json
));
// If we had more tests like this, I'd introduce a helper method... but for one test, it's not worth it.
Assert
.
AreEqual
(
0
,
tokenizer
.
ObjectDepth
);
Assert
.
AreEqual
(
JsonToken
.
StartObject
,
tokenizer
.
Next
());
Assert
.
AreEqual
(
1
,
tokenizer
.
ObjectDepth
);
Assert
.
AreEqual
(
JsonToken
.
Name
(
"foo"
),
tokenizer
.
Next
());
Assert
.
AreEqual
(
1
,
tokenizer
.
ObjectDepth
);
Assert
.
AreEqual
(
JsonToken
.
StartObject
,
tokenizer
.
Next
());
Assert
.
AreEqual
(
2
,
tokenizer
.
ObjectDepth
);
Assert
.
AreEqual
(
JsonToken
.
Name
(
"x"
),
tokenizer
.
Next
());
Assert
.
AreEqual
(
2
,
tokenizer
.
ObjectDepth
);
Assert
.
AreEqual
(
JsonToken
.
Value
(
1
),
tokenizer
.
Next
());
Assert
.
AreEqual
(
2
,
tokenizer
.
ObjectDepth
);
Assert
.
AreEqual
(
JsonToken
.
Name
(
"y"
),
tokenizer
.
Next
());
Assert
.
AreEqual
(
2
,
tokenizer
.
ObjectDepth
);
Assert
.
AreEqual
(
JsonToken
.
StartArray
,
tokenizer
.
Next
());
Assert
.
AreEqual
(
2
,
tokenizer
.
ObjectDepth
);
// Depth hasn't changed in array
Assert
.
AreEqual
(
JsonToken
.
Value
(
0
),
tokenizer
.
Next
());
Assert
.
AreEqual
(
2
,
tokenizer
.
ObjectDepth
);
Assert
.
AreEqual
(
JsonToken
.
EndArray
,
tokenizer
.
Next
());
Assert
.
AreEqual
(
2
,
tokenizer
.
ObjectDepth
);
Assert
.
AreEqual
(
JsonToken
.
EndObject
,
tokenizer
.
Next
());
Assert
.
AreEqual
(
1
,
tokenizer
.
ObjectDepth
);
Assert
.
AreEqual
(
JsonToken
.
EndObject
,
tokenizer
.
Next
());
Assert
.
AreEqual
(
0
,
tokenizer
.
ObjectDepth
);
Assert
.
AreEqual
(
JsonToken
.
EndDocument
,
tokenizer
.
Next
());
Assert
.
AreEqual
(
0
,
tokenizer
.
ObjectDepth
);
}
[
Test
]
public
void
ObjectDepth_WithPushBack
()
{
string
json
=
"{}"
;
var
tokenizer
=
JsonTokenizer
.
FromTextReader
(
new
StringReader
(
json
));
Assert
.
AreEqual
(
0
,
tokenizer
.
ObjectDepth
);
var
token
=
tokenizer
.
Next
();
Assert
.
AreEqual
(
1
,
tokenizer
.
ObjectDepth
);
// When we push back a "start object", we should effectively be back to the previous depth.
tokenizer
.
PushBack
(
token
);
Assert
.
AreEqual
(
0
,
tokenizer
.
ObjectDepth
);
// Read the same token again, and get back to depth 1
token
=
tokenizer
.
Next
();
Assert
.
AreEqual
(
1
,
tokenizer
.
ObjectDepth
);
// Now the same in reverse, with EndObject
token
=
tokenizer
.
Next
();
Assert
.
AreEqual
(
0
,
tokenizer
.
ObjectDepth
);
tokenizer
.
PushBack
(
token
);
Assert
.
AreEqual
(
1
,
tokenizer
.
ObjectDepth
);
tokenizer
.
Next
();
Assert
.
AreEqual
(
0
,
tokenizer
.
ObjectDepth
);
}
[
Test
]
[
TestCase
(
"embedded tab\t"
)]
[
TestCase
(
"embedded CR\r"
)]
[
TestCase
(
"embedded LF\n"
)]
[
TestCase
(
"embedded bell\u0007"
)]
[
TestCase
(
"bad escape\\a"
)]
[
TestCase
(
"incomplete escape\\"
)]
[
TestCase
(
"incomplete Unicode escape\\u000"
)]
[
TestCase
(
"invalid Unicode escape\\u000H"
)]
// Surrogate pair handling, both in raw .NET strings and escaped. We only need
// to detect this in strings, as non-ASCII characters anywhere other than in strings
// will already lead to parsing errors.
[
TestCase
(
"\\ud800"
)]
[
TestCase
(
"\\udc00"
)]
[
TestCase
(
"\\ud800x"
)]
[
TestCase
(
"\\udc00x"
)]
[
TestCase
(
"\\udc00\\ud800y"
)]
public
void
InvalidStringValue
(
string
json
)
{
AssertThrowsAfter
(
"\""
+
json
+
"\""
);
}
// Tests for invalid strings that can't be expressed in attributes,
// as the constants can't be expressed as UTF-8 strings.
[
Test
]
public
void
InvalidSurrogatePairs
()
{
AssertThrowsAfter
(
"\"\ud800x\""
);
AssertThrowsAfter
(
"\"\udc00y\""
);
AssertThrowsAfter
(
"\"\udc00\ud800y\""
);
}
[
Test
]
[
TestCase
(
"0"
,
0
)]
[
TestCase
(
"-0"
,
0
)]
// We don't distinguish between positive and negative 0
[
TestCase
(
"1"
,
1
)]
[
TestCase
(
"-1"
,
-
1
)]
// From here on, assume leading sign is okay...
[
TestCase
(
"1.125"
,
1.125
)]
[
TestCase
(
"1.0"
,
1
)]
[
TestCase
(
"1e5"
,
100000
)]
[
TestCase
(
"1e000000"
,
1
)]
// Weird, but not prohibited by the spec
[
TestCase
(
"1E5"
,
100000
)]
[
TestCase
(
"1e+5"
,
100000
)]
[
TestCase
(
"1E-5"
,
0.00001
)]
[
TestCase
(
"123E-2"
,
1.23
)]
[
TestCase
(
"123.45E3"
,
123450
)]
[
TestCase
(
" 1 "
,
1
)]
public
void
NumberValue
(
string
json
,
double
expectedValue
)
{
AssertTokens
(
json
,
JsonToken
.
Value
(
expectedValue
));
}
[
Test
]
[
TestCase
(
"00"
)]
[
TestCase
(
".5"
)]
[
TestCase
(
"1."
)]
[
TestCase
(
"1e"
)]
[
TestCase
(
"1e-"
)]
[
TestCase
(
"--"
)]
[
TestCase
(
"--1"
)]
[
TestCase
(
"-1.7977e308"
)]
[
TestCase
(
"1.7977e308"
)]
public
void
InvalidNumberValue
(
string
json
)
{
AssertThrowsAfter
(
json
);
}
[
Test
]
[
TestCase
(
"nul"
)]
[
TestCase
(
"nothing"
)]
[
TestCase
(
"truth"
)]
[
TestCase
(
"fALSEhood"
)]
public
void
InvalidLiterals
(
string
json
)
{
AssertThrowsAfter
(
json
);
}
[
Test
]
public
void
NullValue
()
{
AssertTokens
(
"null"
,
JsonToken
.
Null
);
}
[
Test
]
public
void
TrueValue
()
{
AssertTokens
(
"true"
,
JsonToken
.
True
);
}
[
Test
]
public
void
FalseValue
()
{
AssertTokens
(
"false"
,
JsonToken
.
False
);
}
[
Test
]
public
void
SimpleObject
()
{
AssertTokens
(
"{'x': 'y'}"
,
JsonToken
.
StartObject
,
JsonToken
.
Name
(
"x"
),
JsonToken
.
Value
(
"y"
),
JsonToken
.
EndObject
);
}
[
Test
]
[
TestCase
(
"[10, 20"
,
3
)]
[
TestCase
(
"[10,"
,
2
)]
[
TestCase
(
"[10:20]"
,
2
)]
[
TestCase
(
"["
,
1
)]
[
TestCase
(
"[,"
,
1
)]
[
TestCase
(
"{"
,
1
)]
[
TestCase
(
"{,"
,
1
)]
[
TestCase
(
"{["
,
1
)]
[
TestCase
(
"{{"
,
1
)]
[
TestCase
(
"{0"
,
1
)]
[
TestCase
(
"{null"
,
1
)]
[
TestCase
(
"{false"
,
1
)]
[
TestCase
(
"{true"
,
1
)]
[
TestCase
(
"}"
,
0
)]
[
TestCase
(
"]"
,
0
)]
[
TestCase
(
","
,
0
)]
[
TestCase
(
"'foo' 'bar'"
,
1
)]
[
TestCase
(
":"
,
0
)]
[
TestCase
(
"'foo"
,
0
)]
// Incomplete string
[
TestCase
(
"{ 'foo' }"
,
2
)]
[
TestCase
(
"{ x:1"
,
1
)]
// Property names must be quoted
[
TestCase
(
"{]"
,
1
)]
[
TestCase
(
"[}"
,
1
)]
[
TestCase
(
"[1,"
,
2
)]
[
TestCase
(
"{'x':0]"
,
3
)]
[
TestCase
(
"{ 'foo': }"
,
2
)]
[
TestCase
(
"{ 'foo':'bar', }"
,
3
)]
public
void
InvalidStructure
(
string
json
,
int
expectedValidTokens
)
{
// Note: we don't test that the earlier tokens are exactly as expected,
// partly because that's hard to parameterize.
var
reader
=
new
StringReader
(
json
.
Replace
(
'\''
,
'"'
));
var
tokenizer
=
JsonTokenizer
.
FromTextReader
(
reader
);
for
(
int
i
=
0
;
i
<
expectedValidTokens
;
i
++)
{
Assert
.
IsNotNull
(
tokenizer
.
Next
());
}
Assert
.
Throws
<
InvalidJsonException
>(()
=>
tokenizer
.
Next
());
}
[
Test
]
public
void
ArrayMixedType
()
{
AssertTokens
(
"[1, 'foo', null, false, true, [2], {'x':'y' }]"
,
JsonToken
.
StartArray
,
JsonToken
.
Value
(
1
),
JsonToken
.
Value
(
"foo"
),
JsonToken
.
Null
,
JsonToken
.
False
,
JsonToken
.
True
,
JsonToken
.
StartArray
,
JsonToken
.
Value
(
2
),
JsonToken
.
EndArray
,
JsonToken
.
StartObject
,
JsonToken
.
Name
(
"x"
),
JsonToken
.
Value
(
"y"
),
JsonToken
.
EndObject
,
JsonToken
.
EndArray
);
}
[
Test
]
public
void
ObjectMixedType
()
{
AssertTokens
(
@"{'a': 1, 'b': 'bar', 'c': null, 'd': false, 'e': true,
'f': [2], 'g': {'x':'y' }}"
,
JsonToken
.
StartObject
,
JsonToken
.
Name
(
"a"
),
JsonToken
.
Value
(
1
),
JsonToken
.
Name
(
"b"
),
JsonToken
.
Value
(
"bar"
),
JsonToken
.
Name
(
"c"
),
JsonToken
.
Null
,
JsonToken
.
Name
(
"d"
),
JsonToken
.
False
,
JsonToken
.
Name
(
"e"
),
JsonToken
.
True
,
JsonToken
.
Name
(
"f"
),
JsonToken
.
StartArray
,
JsonToken
.
Value
(
2
),
JsonToken
.
EndArray
,
JsonToken
.
Name
(
"g"
),
JsonToken
.
StartObject
,
JsonToken
.
Name
(
"x"
),
JsonToken
.
Value
(
"y"
),
JsonToken
.
EndObject
,
JsonToken
.
EndObject
);
}
[
Test
]
public
void
NextAfterEndDocumentThrows
()
{
var
tokenizer
=
JsonTokenizer
.
FromTextReader
(
new
StringReader
(
"null"
));
Assert
.
AreEqual
(
JsonToken
.
Null
,
tokenizer
.
Next
());
Assert
.
AreEqual
(
JsonToken
.
EndDocument
,
tokenizer
.
Next
());
Assert
.
Throws
<
InvalidOperationException
>(()
=>
tokenizer
.
Next
());
}
[
Test
]
public
void
CanPushBackEndDocument
()
{
var
tokenizer
=
JsonTokenizer
.
FromTextReader
(
new
StringReader
(
"null"
));
Assert
.
AreEqual
(
JsonToken
.
Null
,
tokenizer
.
Next
());
Assert
.
AreEqual
(
JsonToken
.
EndDocument
,
tokenizer
.
Next
());
tokenizer
.
PushBack
(
JsonToken
.
EndDocument
);
Assert
.
AreEqual
(
JsonToken
.
EndDocument
,
tokenizer
.
Next
());
Assert
.
Throws
<
InvalidOperationException
>(()
=>
tokenizer
.
Next
());
}
/// <summary>
/// Asserts that the specified JSON is tokenized into the given sequence of tokens.
/// All apostrophes are first converted to double quotes, allowing any tests
/// that don't need to check actual apostrophe handling to use apostrophes in the JSON, avoiding
/// messy string literal escaping. The "end document" token is not specified in the list of
/// expected tokens, but is implicit.
/// </summary>
private
static
void
AssertTokens
(
string
json
,
params
JsonToken
[]
expectedTokens
)
{
AssertTokensNoReplacement
(
json
.
Replace
(
'\''
,
'"'
),
expectedTokens
);
}
/// <summary>
/// Asserts that the specified JSON is tokenized into the given sequence of tokens.
/// Unlike <see cref="AssertTokens(string, JsonToken[])"/>, this does not perform any character
/// replacement on the specified JSON, and should be used when the text contains apostrophes which
/// are expected to be used *as* apostrophes. The "end document" token is not specified in the list of
/// expected tokens, but is implicit.
/// </summary>
private
static
void
AssertTokensNoReplacement
(
string
json
,
params
JsonToken
[]
expectedTokens
)
{
var
reader
=
new
StringReader
(
json
);
var
tokenizer
=
JsonTokenizer
.
FromTextReader
(
reader
);
for
(
int
i
=
0
;
i
<
expectedTokens
.
Length
;
i
++)
{
var
actualToken
=
tokenizer
.
Next
();
if
(
actualToken
==
JsonToken
.
EndDocument
)
{
Assert
.
Fail
(
"Expected {0} but reached end of token stream"
,
expectedTokens
[
i
]);
}
Assert
.
AreEqual
(
expectedTokens
[
i
],
actualToken
);
}
var
finalToken
=
tokenizer
.
Next
();
if
(
finalToken
!=
JsonToken
.
EndDocument
)
{
Assert
.
Fail
(
"Expected token stream to be exhausted; received {0}"
,
finalToken
);
}
}
private
static
void
AssertThrowsAfter
(
string
json
,
params
JsonToken
[]
expectedTokens
)
{
var
reader
=
new
StringReader
(
json
);
var
tokenizer
=
JsonTokenizer
.
FromTextReader
(
reader
);
for
(
int
i
=
0
;
i
<
expectedTokens
.
Length
;
i
++)
{
var
actualToken
=
tokenizer
.
Next
();
if
(
actualToken
==
JsonToken
.
EndDocument
)
{
Assert
.
Fail
(
"Expected {0} but reached end of document"
,
expectedTokens
[
i
]);
}
Assert
.
AreEqual
(
expectedTokens
[
i
],
actualToken
);
}
Assert
.
Throws
<
InvalidJsonException
>(()
=>
tokenizer
.
Next
());
}
}
}
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs
0 → 100644
View file @
3f6f73b7
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
System.Linq
;
using
Google.Protobuf.TestProtos
;
using
NUnit.Framework
;
using
UnitTest.Issues.TestProtos
;
namespace
Google.Protobuf.Reflection
{
/// <summary>
/// Tests for descriptors. (Not in its own namespace or broken up into individual classes as the
/// size doesn't warrant it. On the other hand, this makes me feel a bit dirty...)
/// </summary>
public
class
DescriptorsTest
{
[
Test
]
public
void
FileDescriptor
()
{
FileDescriptor
file
=
UnittestProto3Reflection
.
Descriptor
;
Assert
.
AreEqual
(
"google/protobuf/unittest_proto3.proto"
,
file
.
Name
);
Assert
.
AreEqual
(
"protobuf_unittest"
,
file
.
Package
);
Assert
.
AreEqual
(
"UnittestProto"
,
file
.
Proto
.
Options
.
JavaOuterClassname
);
Assert
.
AreEqual
(
"google/protobuf/unittest_proto3.proto"
,
file
.
Proto
.
Name
);
// unittest.proto doesn't have any public imports, but unittest_import.proto does.
Assert
.
AreEqual
(
0
,
file
.
PublicDependencies
.
Count
);
Assert
.
AreEqual
(
1
,
UnittestImportProto3Reflection
.
Descriptor
.
PublicDependencies
.
Count
);
Assert
.
AreEqual
(
UnittestImportPublicProto3Reflection
.
Descriptor
,
UnittestImportProto3Reflection
.
Descriptor
.
PublicDependencies
[
0
]);
Assert
.
AreEqual
(
1
,
file
.
Dependencies
.
Count
);
Assert
.
AreEqual
(
UnittestImportProto3Reflection
.
Descriptor
,
file
.
Dependencies
[
0
]);
MessageDescriptor
messageType
=
TestAllTypes
.
Descriptor
;
Assert
.
AreSame
(
typeof
(
TestAllTypes
),
messageType
.
ClrType
);
Assert
.
AreSame
(
TestAllTypes
.
Parser
,
messageType
.
Parser
);
Assert
.
AreEqual
(
messageType
,
file
.
MessageTypes
[
0
]);
Assert
.
AreEqual
(
messageType
,
file
.
FindTypeByName
<
MessageDescriptor
>(
"TestAllTypes"
));
Assert
.
Null
(
file
.
FindTypeByName
<
MessageDescriptor
>(
"NoSuchType"
));
Assert
.
Null
(
file
.
FindTypeByName
<
MessageDescriptor
>(
"protobuf_unittest.TestAllTypes"
));
for
(
int
i
=
0
;
i
<
file
.
MessageTypes
.
Count
;
i
++)
{
Assert
.
AreEqual
(
i
,
file
.
MessageTypes
[
i
].
Index
);
}
Assert
.
AreEqual
(
file
.
EnumTypes
[
0
],
file
.
FindTypeByName
<
EnumDescriptor
>(
"ForeignEnum"
));
Assert
.
Null
(
file
.
FindTypeByName
<
EnumDescriptor
>(
"NoSuchType"
));
Assert
.
Null
(
file
.
FindTypeByName
<
EnumDescriptor
>(
"protobuf_unittest.ForeignEnum"
));
Assert
.
AreEqual
(
1
,
UnittestImportProto3Reflection
.
Descriptor
.
EnumTypes
.
Count
);
Assert
.
AreEqual
(
"ImportEnum"
,
UnittestImportProto3Reflection
.
Descriptor
.
EnumTypes
[
0
].
Name
);
for
(
int
i
=
0
;
i
<
file
.
EnumTypes
.
Count
;
i
++)
{
Assert
.
AreEqual
(
i
,
file
.
EnumTypes
[
i
].
Index
);
}
Assert
.
AreEqual
(
10
,
file
.
SerializedData
[
0
]);
}
[
Test
]
public
void
MessageDescriptor
()
{
MessageDescriptor
messageType
=
TestAllTypes
.
Descriptor
;
MessageDescriptor
nestedType
=
TestAllTypes
.
Types
.
NestedMessage
.
Descriptor
;
Assert
.
AreEqual
(
"TestAllTypes"
,
messageType
.
Name
);
Assert
.
AreEqual
(
"protobuf_unittest.TestAllTypes"
,
messageType
.
FullName
);
Assert
.
AreEqual
(
UnittestProto3Reflection
.
Descriptor
,
messageType
.
File
);
Assert
.
IsNull
(
messageType
.
ContainingType
);
Assert
.
IsNull
(
messageType
.
Proto
.
Options
);
Assert
.
AreEqual
(
"TestAllTypes"
,
messageType
.
Name
);
Assert
.
AreEqual
(
"NestedMessage"
,
nestedType
.
Name
);
Assert
.
AreEqual
(
"protobuf_unittest.TestAllTypes.NestedMessage"
,
nestedType
.
FullName
);
Assert
.
AreEqual
(
UnittestProto3Reflection
.
Descriptor
,
nestedType
.
File
);
Assert
.
AreEqual
(
messageType
,
nestedType
.
ContainingType
);
FieldDescriptor
field
=
messageType
.
Fields
.
InDeclarationOrder
()[
0
];
Assert
.
AreEqual
(
"single_int32"
,
field
.
Name
);
Assert
.
AreEqual
(
field
,
messageType
.
FindDescriptor
<
FieldDescriptor
>(
"single_int32"
));
Assert
.
Null
(
messageType
.
FindDescriptor
<
FieldDescriptor
>(
"no_such_field"
));
Assert
.
AreEqual
(
field
,
messageType
.
FindFieldByNumber
(
1
));
Assert
.
Null
(
messageType
.
FindFieldByNumber
(
571283
));
var
fieldsInDeclarationOrder
=
messageType
.
Fields
.
InDeclarationOrder
();
for
(
int
i
=
0
;
i
<
fieldsInDeclarationOrder
.
Count
;
i
++)
{
Assert
.
AreEqual
(
i
,
fieldsInDeclarationOrder
[
i
].
Index
);
}
Assert
.
AreEqual
(
nestedType
,
messageType
.
NestedTypes
[
0
]);
Assert
.
AreEqual
(
nestedType
,
messageType
.
FindDescriptor
<
MessageDescriptor
>(
"NestedMessage"
));
Assert
.
Null
(
messageType
.
FindDescriptor
<
MessageDescriptor
>(
"NoSuchType"
));
for
(
int
i
=
0
;
i
<
messageType
.
NestedTypes
.
Count
;
i
++)
{
Assert
.
AreEqual
(
i
,
messageType
.
NestedTypes
[
i
].
Index
);
}
Assert
.
AreEqual
(
messageType
.
EnumTypes
[
0
],
messageType
.
FindDescriptor
<
EnumDescriptor
>(
"NestedEnum"
));
Assert
.
Null
(
messageType
.
FindDescriptor
<
EnumDescriptor
>(
"NoSuchType"
));
for
(
int
i
=
0
;
i
<
messageType
.
EnumTypes
.
Count
;
i
++)
{
Assert
.
AreEqual
(
i
,
messageType
.
EnumTypes
[
i
].
Index
);
}
}
[
Test
]
public
void
FieldDescriptor
()
{
MessageDescriptor
messageType
=
TestAllTypes
.
Descriptor
;
FieldDescriptor
primitiveField
=
messageType
.
FindDescriptor
<
FieldDescriptor
>(
"single_int32"
);
FieldDescriptor
enumField
=
messageType
.
FindDescriptor
<
FieldDescriptor
>(
"single_nested_enum"
);
FieldDescriptor
messageField
=
messageType
.
FindDescriptor
<
FieldDescriptor
>(
"single_foreign_message"
);
Assert
.
AreEqual
(
"single_int32"
,
primitiveField
.
Name
);
Assert
.
AreEqual
(
"protobuf_unittest.TestAllTypes.single_int32"
,
primitiveField
.
FullName
);
Assert
.
AreEqual
(
1
,
primitiveField
.
FieldNumber
);
Assert
.
AreEqual
(
messageType
,
primitiveField
.
ContainingType
);
Assert
.
AreEqual
(
UnittestProto3Reflection
.
Descriptor
,
primitiveField
.
File
);
Assert
.
AreEqual
(
FieldType
.
Int32
,
primitiveField
.
FieldType
);
Assert
.
IsNull
(
primitiveField
.
Proto
.
Options
);
Assert
.
AreEqual
(
"single_nested_enum"
,
enumField
.
Name
);
Assert
.
AreEqual
(
FieldType
.
Enum
,
enumField
.
FieldType
);
// Assert.AreEqual(TestAllTypes.Types.NestedEnum.DescriptorProtoFile, enumField.EnumType);
Assert
.
AreEqual
(
"single_foreign_message"
,
messageField
.
Name
);
Assert
.
AreEqual
(
FieldType
.
Message
,
messageField
.
FieldType
);
Assert
.
AreEqual
(
ForeignMessage
.
Descriptor
,
messageField
.
MessageType
);
}
[
Test
]
public
void
FieldDescriptorLabel
()
{
FieldDescriptor
singleField
=
TestAllTypes
.
Descriptor
.
FindDescriptor
<
FieldDescriptor
>(
"single_int32"
);
FieldDescriptor
repeatedField
=
TestAllTypes
.
Descriptor
.
FindDescriptor
<
FieldDescriptor
>(
"repeated_int32"
);
Assert
.
IsFalse
(
singleField
.
IsRepeated
);
Assert
.
IsTrue
(
repeatedField
.
IsRepeated
);
}
[
Test
]
public
void
EnumDescriptor
()
{
// Note: this test is a bit different to the Java version because there's no static way of getting to the descriptor
EnumDescriptor
enumType
=
UnittestProto3Reflection
.
Descriptor
.
FindTypeByName
<
EnumDescriptor
>(
"ForeignEnum"
);
EnumDescriptor
nestedType
=
TestAllTypes
.
Descriptor
.
FindDescriptor
<
EnumDescriptor
>(
"NestedEnum"
);
Assert
.
AreEqual
(
"ForeignEnum"
,
enumType
.
Name
);
Assert
.
AreEqual
(
"protobuf_unittest.ForeignEnum"
,
enumType
.
FullName
);
Assert
.
AreEqual
(
UnittestProto3Reflection
.
Descriptor
,
enumType
.
File
);
Assert
.
Null
(
enumType
.
ContainingType
);
Assert
.
Null
(
enumType
.
Proto
.
Options
);
Assert
.
AreEqual
(
"NestedEnum"
,
nestedType
.
Name
);
Assert
.
AreEqual
(
"protobuf_unittest.TestAllTypes.NestedEnum"
,
nestedType
.
FullName
);
Assert
.
AreEqual
(
UnittestProto3Reflection
.
Descriptor
,
nestedType
.
File
);
Assert
.
AreEqual
(
TestAllTypes
.
Descriptor
,
nestedType
.
ContainingType
);
EnumValueDescriptor
value
=
enumType
.
FindValueByName
(
"FOREIGN_FOO"
);
Assert
.
AreEqual
(
value
,
enumType
.
Values
[
1
]);
Assert
.
AreEqual
(
"FOREIGN_FOO"
,
value
.
Name
);
Assert
.
AreEqual
(
4
,
value
.
Number
);
Assert
.
AreEqual
((
int
)
ForeignEnum
.
ForeignFoo
,
value
.
Number
);
Assert
.
AreEqual
(
value
,
enumType
.
FindValueByNumber
(
4
));
Assert
.
Null
(
enumType
.
FindValueByName
(
"NO_SUCH_VALUE"
));
for
(
int
i
=
0
;
i
<
enumType
.
Values
.
Count
;
i
++)
{
Assert
.
AreEqual
(
i
,
enumType
.
Values
[
i
].
Index
);
}
}
[
Test
]
public
void
OneofDescriptor
()
{
OneofDescriptor
descriptor
=
TestAllTypes
.
Descriptor
.
FindDescriptor
<
OneofDescriptor
>(
"oneof_field"
);
Assert
.
AreEqual
(
"oneof_field"
,
descriptor
.
Name
);
Assert
.
AreEqual
(
"protobuf_unittest.TestAllTypes.oneof_field"
,
descriptor
.
FullName
);
var
expectedFields
=
new
[]
{
TestAllTypes
.
OneofBytesFieldNumber
,
TestAllTypes
.
OneofNestedMessageFieldNumber
,
TestAllTypes
.
OneofStringFieldNumber
,
TestAllTypes
.
OneofUint32FieldNumber
}
.
Select
(
fieldNumber
=>
TestAllTypes
.
Descriptor
.
FindFieldByNumber
(
fieldNumber
))
.
ToList
();
foreach
(
var
field
in
expectedFields
)
{
Assert
.
AreSame
(
descriptor
,
field
.
ContainingOneof
);
}
CollectionAssert
.
AreEquivalent
(
expectedFields
,
descriptor
.
Fields
);
}
[
Test
]
public
void
MapEntryMessageDescriptor
()
{
var
descriptor
=
MapWellKnownTypes
.
Descriptor
.
NestedTypes
[
0
];
Assert
.
IsNull
(
descriptor
.
Parser
);
Assert
.
IsNull
(
descriptor
.
ClrType
);
Assert
.
IsNull
(
descriptor
.
Fields
[
1
].
Accessor
);
}
// From TestFieldOrdering:
// string my_string = 11;
// int64 my_int = 1;
// float my_float = 101;
// NestedMessage single_nested_message = 200;
[
Test
]
public
void
FieldListOrderings
()
{
var
fields
=
TestFieldOrderings
.
Descriptor
.
Fields
;
Assert
.
AreEqual
(
new
[]
{
11
,
1
,
101
,
200
},
fields
.
InDeclarationOrder
().
Select
(
x
=>
x
.
FieldNumber
));
Assert
.
AreEqual
(
new
[]
{
1
,
11
,
101
,
200
},
fields
.
InFieldNumberOrder
().
Select
(
x
=>
x
.
FieldNumber
));
}
[
Test
]
public
void
DescriptorProtoFileDescriptor
()
{
var
descriptor
=
Google
.
Protobuf
.
Reflection
.
FileDescriptor
.
DescriptorProtoFileDescriptor
;
Assert
.
AreEqual
(
"google/protobuf/descriptor.proto"
,
descriptor
.
Name
);
}
}
}
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs
0 → 100644
View file @
3f6f73b7
#
region
Copyright
notice
and
license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
Google.Protobuf.TestProtos
;
using
NUnit.Framework
;
using
System
;
using
System.Collections
;
using
System.Collections.Generic
;
namespace
Google.Protobuf.Reflection
{
public
class
FieldAccessTest
{
[
Test
]
public
void
GetValue
()
{
var
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
fields
=
TestAllTypes
.
Descriptor
.
Fields
;
Assert
.
AreEqual
(
message
.
SingleBool
,
fields
[
TestAllTypes
.
SingleBoolFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleBytes
,
fields
[
TestAllTypes
.
SingleBytesFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleDouble
,
fields
[
TestAllTypes
.
SingleDoubleFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleFixed32
,
fields
[
TestAllTypes
.
SingleFixed32FieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleFixed64
,
fields
[
TestAllTypes
.
SingleFixed64FieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleFloat
,
fields
[
TestAllTypes
.
SingleFloatFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleForeignEnum
,
fields
[
TestAllTypes
.
SingleForeignEnumFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleForeignMessage
,
fields
[
TestAllTypes
.
SingleForeignMessageFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleImportEnum
,
fields
[
TestAllTypes
.
SingleImportEnumFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleImportMessage
,
fields
[
TestAllTypes
.
SingleImportMessageFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleInt32
,
fields
[
TestAllTypes
.
SingleInt32FieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleInt64
,
fields
[
TestAllTypes
.
SingleInt64FieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleNestedEnum
,
fields
[
TestAllTypes
.
SingleNestedEnumFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleNestedMessage
,
fields
[
TestAllTypes
.
SingleNestedMessageFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SinglePublicImportMessage
,
fields
[
TestAllTypes
.
SinglePublicImportMessageFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleSint32
,
fields
[
TestAllTypes
.
SingleSint32FieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleSint64
,
fields
[
TestAllTypes
.
SingleSint64FieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleString
,
fields
[
TestAllTypes
.
SingleStringFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleSfixed32
,
fields
[
TestAllTypes
.
SingleSfixed32FieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleSfixed64
,
fields
[
TestAllTypes
.
SingleSfixed64FieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleUint32
,
fields
[
TestAllTypes
.
SingleUint32FieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleUint64
,
fields
[
TestAllTypes
.
SingleUint64FieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
OneofBytes
,
fields
[
TestAllTypes
.
OneofBytesFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
OneofString
,
fields
[
TestAllTypes
.
OneofStringFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
OneofNestedMessage
,
fields
[
TestAllTypes
.
OneofNestedMessageFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
OneofUint32
,
fields
[
TestAllTypes
.
OneofUint32FieldNumber
].
Accessor
.
GetValue
(
message
));
// Just one example for repeated fields - they're all just returning the list
var
list
=
(
IList
)
fields
[
TestAllTypes
.
RepeatedInt32FieldNumber
].
Accessor
.
GetValue
(
message
);
Assert
.
AreEqual
(
message
.
RepeatedInt32
,
list
);
Assert
.
AreEqual
(
message
.
RepeatedInt32
[
0
],
list
[
0
]);
// Just in case there was any doubt...
// Just a single map field, for the same reason
var
mapMessage
=
new
TestMap
{
MapStringString
=
{
{
"key1"
,
"value1"
},
{
"key2"
,
"value2"
}
}
};
fields
=
TestMap
.
Descriptor
.
Fields
;
var
dictionary
=
(
IDictionary
)
fields
[
TestMap
.
MapStringStringFieldNumber
].
Accessor
.
GetValue
(
mapMessage
);
Assert
.
AreEqual
(
mapMessage
.
MapStringString
,
dictionary
);
Assert
.
AreEqual
(
"value1"
,
dictionary
[
"key1"
]);
}
[
Test
]
public
void
Clear
()
{
var
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
fields
=
TestAllTypes
.
Descriptor
.
Fields
;
fields
[
TestAllTypes
.
SingleBoolFieldNumber
].
Accessor
.
Clear
(
message
);
fields
[
TestAllTypes
.
SingleInt32FieldNumber
].
Accessor
.
Clear
(
message
);
fields
[
TestAllTypes
.
SingleStringFieldNumber
].
Accessor
.
Clear
(
message
);
fields
[
TestAllTypes
.
SingleBytesFieldNumber
].
Accessor
.
Clear
(
message
);
fields
[
TestAllTypes
.
SingleForeignEnumFieldNumber
].
Accessor
.
Clear
(
message
);
fields
[
TestAllTypes
.
SingleForeignMessageFieldNumber
].
Accessor
.
Clear
(
message
);
fields
[
TestAllTypes
.
RepeatedDoubleFieldNumber
].
Accessor
.
Clear
(
message
);
var
expected
=
new
TestAllTypes
(
SampleMessages
.
CreateFullTestAllTypes
())
{
SingleBool
=
false
,
SingleInt32
=
0
,
SingleString
=
""
,
SingleBytes
=
ByteString
.
Empty
,
SingleForeignEnum
=
0
,
SingleForeignMessage
=
null
,
};
expected
.
RepeatedDouble
.
Clear
();
Assert
.
AreEqual
(
expected
,
message
);
// Separately, maps.
var
mapMessage
=
new
TestMap
{
MapStringString
=
{
{
"key1"
,
"value1"
},
{
"key2"
,
"value2"
}
}
};
fields
=
TestMap
.
Descriptor
.
Fields
;
fields
[
TestMap
.
MapStringStringFieldNumber
].
Accessor
.
Clear
(
mapMessage
);
Assert
.
AreEqual
(
0
,
mapMessage
.
MapStringString
.
Count
);
}
[
Test
]
public
void
SetValue_SingleFields
()
{
// Just a sample (primitives, messages, enums, strings, byte strings)
var
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
fields
=
TestAllTypes
.
Descriptor
.
Fields
;
fields
[
TestAllTypes
.
SingleBoolFieldNumber
].
Accessor
.
SetValue
(
message
,
false
);
fields
[
TestAllTypes
.
SingleInt32FieldNumber
].
Accessor
.
SetValue
(
message
,
500
);
fields
[
TestAllTypes
.
SingleStringFieldNumber
].
Accessor
.
SetValue
(
message
,
"It's a string"
);
fields
[
TestAllTypes
.
SingleBytesFieldNumber
].
Accessor
.
SetValue
(
message
,
ByteString
.
CopyFrom
(
99
,
98
,
97
));
fields
[
TestAllTypes
.
SingleForeignEnumFieldNumber
].
Accessor
.
SetValue
(
message
,
ForeignEnum
.
ForeignFoo
);
fields
[
TestAllTypes
.
SingleForeignMessageFieldNumber
].
Accessor
.
SetValue
(
message
,
new
ForeignMessage
{
C
=
12345
});
fields
[
TestAllTypes
.
SingleDoubleFieldNumber
].
Accessor
.
SetValue
(
message
,
20150701.5
);
var
expected
=
new
TestAllTypes
(
SampleMessages
.
CreateFullTestAllTypes
())
{
SingleBool
=
false
,
SingleInt32
=
500
,
SingleString
=
"It's a string"
,
SingleBytes
=
ByteString
.
CopyFrom
(
99
,
98
,
97
),
SingleForeignEnum
=
ForeignEnum
.
ForeignFoo
,
SingleForeignMessage
=
new
ForeignMessage
{
C
=
12345
},
SingleDouble
=
20150701.5
};
Assert
.
AreEqual
(
expected
,
message
);
}
[
Test
]
public
void
SetValue_SingleFields_WrongType
()
{
IMessage
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
fields
=
message
.
Descriptor
.
Fields
;
Assert
.
Throws
<
InvalidCastException
>(()
=>
fields
[
TestAllTypes
.
SingleBoolFieldNumber
].
Accessor
.
SetValue
(
message
,
"This isn't a bool"
));
}
[
Test
]
public
void
SetValue_MapFields
()
{
IMessage
message
=
new
TestMap
();
var
fields
=
message
.
Descriptor
.
Fields
;
Assert
.
Throws
<
InvalidOperationException
>(()
=>
fields
[
TestMap
.
MapStringStringFieldNumber
].
Accessor
.
SetValue
(
message
,
new
Dictionary
<
string
,
string
>()));
}
[
Test
]
public
void
SetValue_RepeatedFields
()
{
IMessage
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
fields
=
message
.
Descriptor
.
Fields
;
Assert
.
Throws
<
InvalidOperationException
>(()
=>
fields
[
TestAllTypes
.
RepeatedDoubleFieldNumber
].
Accessor
.
SetValue
(
message
,
new
double
[
10
]));
}
[
Test
]
public
void
GetValue_IncorrectType
()
{
IMessage
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
fields
=
message
.
Descriptor
.
Fields
;
Assert
.
Throws
<
InvalidCastException
>(()
=>
fields
[
TestAllTypes
.
SingleBoolFieldNumber
].
Accessor
.
GetValue
(
new
TestMap
()));
}
[
Test
]
public
void
Oneof
()
{
var
message
=
new
TestAllTypes
();
var
descriptor
=
TestAllTypes
.
Descriptor
;
Assert
.
AreEqual
(
1
,
descriptor
.
Oneofs
.
Count
);
var
oneof
=
descriptor
.
Oneofs
[
0
];
Assert
.
AreEqual
(
"oneof_field"
,
oneof
.
Name
);
Assert
.
IsNull
(
oneof
.
Accessor
.
GetCaseFieldDescriptor
(
message
));
message
.
OneofString
=
"foo"
;
Assert
.
AreSame
(
descriptor
.
Fields
[
TestAllTypes
.
OneofStringFieldNumber
],
oneof
.
Accessor
.
GetCaseFieldDescriptor
(
message
));
message
.
OneofUint32
=
10
;
Assert
.
AreSame
(
descriptor
.
Fields
[
TestAllTypes
.
OneofUint32FieldNumber
],
oneof
.
Accessor
.
GetCaseFieldDescriptor
(
message
));
oneof
.
Accessor
.
Clear
(
message
);
Assert
.
AreEqual
(
TestAllTypes
.
OneofFieldOneofCase
.
None
,
message
.
OneofFieldCase
);
}
[
Test
]
public
void
FieldDescriptor_ByName
()
{
var
descriptor
=
TestAllTypes
.
Descriptor
;
Assert
.
AreSame
(
descriptor
.
Fields
[
TestAllTypes
.
SingleBoolFieldNumber
],
descriptor
.
Fields
[
"single_bool"
]);
}
[
Test
]
public
void
FieldDescriptor_NotFound
()
{
var
descriptor
=
TestAllTypes
.
Descriptor
;
Assert
.
Throws
<
KeyNotFoundException
>(()
=>
descriptor
.
Fields
[
999999
].
ToString
());
Assert
.
Throws
<
KeyNotFoundException
>(()
=>
descriptor
.
Fields
[
"not found"
].
ToString
());
}
}
}
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Reflection/TypeRegistryTest.cs
0 → 100644
View file @
3f6f73b7
#
region
Copyright
notice
and
license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
Google.Protobuf.TestProtos
;
using
Google.Protobuf.WellKnownTypes
;
using
NUnit.Framework
;
namespace
Google.Protobuf.Reflection
{
public
class
TypeRegistryTest
{
// Most of our tests use messages. Simple test that we really can use files...
[
Test
]
public
void
CreateWithFileDescriptor
()
{
var
registry
=
TypeRegistry
.
FromFiles
(
DurationReflection
.
Descriptor
,
StructReflection
.
Descriptor
);
AssertDescriptorPresent
(
registry
,
Duration
.
Descriptor
);
AssertDescriptorPresent
(
registry
,
ListValue
.
Descriptor
);
AssertDescriptorAbsent
(
registry
,
Timestamp
.
Descriptor
);
}
[
Test
]
public
void
TypesFromSameFile
()
{
// Just for kicks, let's start with a nested type
var
registry
=
TypeRegistry
.
FromMessages
(
TestAllTypes
.
Types
.
NestedMessage
.
Descriptor
);
// Top-level...
AssertDescriptorPresent
(
registry
,
TestFieldOrderings
.
Descriptor
);
// ... and nested (not the same as the original NestedMessage!)
AssertDescriptorPresent
(
registry
,
TestFieldOrderings
.
Types
.
NestedMessage
.
Descriptor
);
}
[
Test
]
public
void
DependenciesAreIncluded
()
{
var
registry
=
TypeRegistry
.
FromMessages
(
TestAllTypes
.
Descriptor
);
// Direct dependencies
AssertDescriptorPresent
(
registry
,
ImportMessage
.
Descriptor
);
// Public dependencies
AssertDescriptorPresent
(
registry
,
PublicImportMessage
.
Descriptor
);
}
[
Test
]
public
void
DuplicateFiles
()
{
// Duplicates via dependencies and simply via repetition
var
registry
=
TypeRegistry
.
FromFiles
(
UnittestProto3Reflection
.
Descriptor
,
UnittestImportProto3Reflection
.
Descriptor
,
TimestampReflection
.
Descriptor
,
TimestampReflection
.
Descriptor
);
AssertDescriptorPresent
(
registry
,
TestAllTypes
.
Descriptor
);
AssertDescriptorPresent
(
registry
,
ImportMessage
.
Descriptor
);
AssertDescriptorPresent
(
registry
,
Timestamp
.
Descriptor
);
}
private
static
void
AssertDescriptorPresent
(
TypeRegistry
registry
,
MessageDescriptor
descriptor
)
{
Assert
.
AreSame
(
descriptor
,
registry
.
Find
(
descriptor
.
FullName
));
}
private
static
void
AssertDescriptorAbsent
(
TypeRegistry
registry
,
MessageDescriptor
descriptor
)
{
Assert
.
IsNull
(
registry
.
Find
(
descriptor
.
FullName
));
}
}
}
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/SampleEnum.cs
0 → 100644
View file @
3f6f73b7
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
namespace
Google.Protobuf
{
// Just a sample enum with positive and negative values to be used in tests.
internal
enum
SampleEnum
{
NegativeValue
=
-
2
,
None
=
0
,
PositiveValue
=
3
}
}
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/SampleMessages.cs
0 → 100644
View file @
3f6f73b7
#
region
Copyright
notice
and
license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
System
;
using
Google.Protobuf.TestProtos
;
namespace
Google.Protobuf
{
/// <summary>
/// Helper methods to create sample instances of types generated from unit test messages.
/// </summary>
public
class
SampleMessages
{
/// <summary>
/// Creates a new sample TestAllTypes message with all fields populated.
/// The "oneof" field is populated with the string property (OneofString).
/// </summary>
public
static
TestAllTypes
CreateFullTestAllTypes
()
{
return
new
TestAllTypes
{
SingleBool
=
true
,
SingleBytes
=
ByteString
.
CopyFrom
(
1
,
2
,
3
,
4
),
SingleDouble
=
23.5
,
SingleFixed32
=
23
,
SingleFixed64
=
1234567890123
,
SingleFloat
=
12.25f
,
SingleForeignEnum
=
ForeignEnum
.
ForeignBar
,
SingleForeignMessage
=
new
ForeignMessage
{
C
=
10
},
SingleImportEnum
=
ImportEnum
.
ImportBaz
,
SingleImportMessage
=
new
ImportMessage
{
D
=
20
},
SingleInt32
=
100
,
SingleInt64
=
3210987654321
,
SingleNestedEnum
=
TestAllTypes
.
Types
.
NestedEnum
.
Foo
,
SingleNestedMessage
=
new
TestAllTypes
.
Types
.
NestedMessage
{
Bb
=
35
},
SinglePublicImportMessage
=
new
PublicImportMessage
{
E
=
54
},
SingleSfixed32
=
-
123
,
SingleSfixed64
=
-
12345678901234
,
SingleSint32
=
-
456
,
SingleSint64
=
-
12345678901235
,
SingleString
=
"test"
,
SingleUint32
=
UInt32
.
MaxValue
,
SingleUint64
=
UInt64
.
MaxValue
,
RepeatedBool
=
{
true
,
false
},
RepeatedBytes
=
{
ByteString
.
CopyFrom
(
1
,
2
,
3
,
4
),
ByteString
.
CopyFrom
(
5
,
6
),
ByteString
.
CopyFrom
(
new
byte
[
1000
])
},
RepeatedDouble
=
{
-
12.25
,
23.5
},
RepeatedFixed32
=
{
UInt32
.
MaxValue
,
23
},
RepeatedFixed64
=
{
UInt64
.
MaxValue
,
1234567890123
},
RepeatedFloat
=
{
100f
,
12.25f
},
RepeatedForeignEnum
=
{
ForeignEnum
.
ForeignFoo
,
ForeignEnum
.
ForeignBar
},
RepeatedForeignMessage
=
{
new
ForeignMessage
(),
new
ForeignMessage
{
C
=
10
}
},
RepeatedImportEnum
=
{
ImportEnum
.
ImportBaz
,
ImportEnum
.
Unspecified
},
RepeatedImportMessage
=
{
new
ImportMessage
{
D
=
20
},
new
ImportMessage
{
D
=
25
}
},
RepeatedInt32
=
{
100
,
200
},
RepeatedInt64
=
{
3210987654321
,
Int64
.
MaxValue
},
RepeatedNestedEnum
=
{
TestAllTypes
.
Types
.
NestedEnum
.
Foo
,
TestAllTypes
.
Types
.
NestedEnum
.
Neg
},
RepeatedNestedMessage
=
{
new
TestAllTypes
.
Types
.
NestedMessage
{
Bb
=
35
},
new
TestAllTypes
.
Types
.
NestedMessage
{
Bb
=
10
}
},
RepeatedPublicImportMessage
=
{
new
PublicImportMessage
{
E
=
54
},
new
PublicImportMessage
{
E
=
-
1
}
},
RepeatedSfixed32
=
{
-
123
,
123
},
RepeatedSfixed64
=
{
-
12345678901234
,
12345678901234
},
RepeatedSint32
=
{
-
456
,
100
},
RepeatedSint64
=
{
-
12345678901235
,
123
},
RepeatedString
=
{
"foo"
,
"bar"
},
RepeatedUint32
=
{
UInt32
.
MaxValue
,
UInt32
.
MinValue
},
RepeatedUint64
=
{
UInt64
.
MaxValue
,
UInt32
.
MinValue
},
OneofString
=
"Oneof string"
};
}
}
}
\ No newline at end of file
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/TestCornerCases.cs
0 → 100644
View file @
3f6f73b7
#
region
Copyright
notice
and
license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
UnitTest.Issues.TestProtos
;
using
NUnit.Framework
;
namespace
Google.Protobuf
{
public
class
TestCornerCases
{
[
Test
]
public
void
TestRoundTripNegativeEnums
()
{
NegativeEnumMessage
msg
=
new
NegativeEnumMessage
{
Value
=
NegativeEnum
.
MinusOne
,
Values
=
{
NegativeEnum
.
Zero
,
NegativeEnum
.
MinusOne
,
NegativeEnum
.
FiveBelow
},
PackedValues
=
{
NegativeEnum
.
Zero
,
NegativeEnum
.
MinusOne
,
NegativeEnum
.
FiveBelow
}
};
Assert
.
AreEqual
(
58
,
msg
.
CalculateSize
());
byte
[]
bytes
=
new
byte
[
58
];
CodedOutputStream
output
=
new
CodedOutputStream
(
bytes
);
msg
.
WriteTo
(
output
);
Assert
.
AreEqual
(
0
,
output
.
SpaceLeft
);
NegativeEnumMessage
copy
=
NegativeEnumMessage
.
Parser
.
ParseFrom
(
bytes
);
Assert
.
AreEqual
(
msg
,
copy
);
}
}
}
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/TestProtos/ForeignMessagePartial.cs
0 → 100644
View file @
3f6f73b7
#
region
Copyright
notice
and
license
// Protocol Buffers - Google's data interchange format
// Copyright 2016 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
namespace
Google.Protobuf.TestProtos
{
/// <summary>
/// A message with custom diagnostics (to test that they work).
/// </summary>
public
partial
class
ForeignMessage
:
ICustomDiagnosticMessage
{
public
string
ToDiagnosticString
()
{
return
$"
{{
\
"c\": {C}, \"@cInHex\": \"{C:x}\" }}"
;
}
}
}
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs
0 → 100644
View file @
3f6f73b7
#
region
Copyright
notice
and
license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
Google.Protobuf.TestProtos
;
using
NUnit.Framework
;
namespace
Google.Protobuf.WellKnownTypes
{
public
class
AnyTest
{
[
Test
]
public
void
Pack
()
{
var
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
any
=
Any
.
Pack
(
message
);
Assert
.
AreEqual
(
"type.googleapis.com/protobuf_unittest.TestAllTypes"
,
any
.
TypeUrl
);
Assert
.
AreEqual
(
message
.
CalculateSize
(),
any
.
Value
.
Length
);
}
[
Test
]
public
void
Pack_WithCustomPrefix
()
{
var
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
any
=
Any
.
Pack
(
message
,
"foo.bar/baz"
);
Assert
.
AreEqual
(
"foo.bar/baz/protobuf_unittest.TestAllTypes"
,
any
.
TypeUrl
);
Assert
.
AreEqual
(
message
.
CalculateSize
(),
any
.
Value
.
Length
);
}
[
Test
]
public
void
Pack_WithCustomPrefixTrailingSlash
()
{
var
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
any
=
Any
.
Pack
(
message
,
"foo.bar/baz/"
);
Assert
.
AreEqual
(
"foo.bar/baz/protobuf_unittest.TestAllTypes"
,
any
.
TypeUrl
);
Assert
.
AreEqual
(
message
.
CalculateSize
(),
any
.
Value
.
Length
);
}
[
Test
]
public
void
Unpack_WrongType
()
{
var
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
any
=
Any
.
Pack
(
message
);
Assert
.
Throws
<
InvalidProtocolBufferException
>(()
=>
any
.
Unpack
<
TestOneof
>());
}
[
Test
]
public
void
Unpack_Success
()
{
var
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
any
=
Any
.
Pack
(
message
);
var
unpacked
=
any
.
Unpack
<
TestAllTypes
>();
Assert
.
AreEqual
(
message
,
unpacked
);
}
[
Test
]
public
void
Unpack_CustomPrefix_Success
()
{
var
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
any
=
Any
.
Pack
(
message
,
"foo.bar/baz"
);
var
unpacked
=
any
.
Unpack
<
TestAllTypes
>();
Assert
.
AreEqual
(
message
,
unpacked
);
}
[
Test
]
public
void
ToString_WithValues
()
{
var
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
any
=
Any
.
Pack
(
message
);
var
text
=
any
.
ToString
();
Assert
.
That
(
text
,
Does
.
Contain
(
"\"@value\": \""
+
message
.
ToByteString
().
ToBase64
()
+
"\""
));
}
[
Test
]
public
void
ToString_Empty
()
{
var
any
=
new
Any
();
Assert
.
AreEqual
(
"{ \"@type\": \"\", \"@value\": \"\" }"
,
any
.
ToString
());
}
[
Test
]
public
void
ToString_MessageContainingAny
()
{
var
message
=
new
TestWellKnownTypes
{
AnyField
=
new
Any
()
};
Assert
.
AreEqual
(
"{ \"anyField\": { \"@type\": \"\", \"@value\": \"\" } }"
,
message
.
ToString
());
}
}
}
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/WellKnownTypes/DurationTest.cs
0 → 100644
View file @
3f6f73b7
#
region
Copyright
notice
and
license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
NUnit.Framework
;
using
System
;
namespace
Google.Protobuf.WellKnownTypes
{
public
class
DurationTest
{
[
Test
]
public
void
ToTimeSpan
()
{
Assert
.
AreEqual
(
TimeSpan
.
FromSeconds
(
1
),
new
Duration
{
Seconds
=
1
}.
ToTimeSpan
());
Assert
.
AreEqual
(
TimeSpan
.
FromSeconds
(-
1
),
new
Duration
{
Seconds
=
-
1
}.
ToTimeSpan
());
Assert
.
AreEqual
(
TimeSpan
.
FromMilliseconds
(
1
),
new
Duration
{
Nanos
=
1000000
}.
ToTimeSpan
());
Assert
.
AreEqual
(
TimeSpan
.
FromMilliseconds
(-
1
),
new
Duration
{
Nanos
=
-
1000000
}.
ToTimeSpan
());
Assert
.
AreEqual
(
TimeSpan
.
FromTicks
(
1
),
new
Duration
{
Nanos
=
100
}.
ToTimeSpan
());
Assert
.
AreEqual
(
TimeSpan
.
FromTicks
(-
1
),
new
Duration
{
Nanos
=
-
100
}.
ToTimeSpan
());
// Rounding is towards 0
Assert
.
AreEqual
(
TimeSpan
.
FromTicks
(
2
),
new
Duration
{
Nanos
=
250
}.
ToTimeSpan
());
Assert
.
AreEqual
(
TimeSpan
.
FromTicks
(-
2
),
new
Duration
{
Nanos
=
-
250
}.
ToTimeSpan
());
}
[
Test
]
public
void
Addition
()
{
Assert
.
AreEqual
(
new
Duration
{
Seconds
=
2
,
Nanos
=
100000000
},
new
Duration
{
Seconds
=
1
,
Nanos
=
600000000
}
+
new
Duration
{
Nanos
=
500000000
});
Assert
.
AreEqual
(
new
Duration
{
Seconds
=
-
2
,
Nanos
=
-
100000000
},
new
Duration
{
Seconds
=
-
1
,
Nanos
=
-
600000000
}
+
new
Duration
{
Nanos
=
-
500000000
});
Assert
.
AreEqual
(
new
Duration
{
Seconds
=
1
,
Nanos
=
100000000
},
new
Duration
{
Seconds
=
1
,
Nanos
=
600000000
}
+
new
Duration
{
Nanos
=
-
500000000
});
// Non-normalized durations, or non-normalized intermediate results
Assert
.
AreEqual
(
new
Duration
{
Seconds
=
1
},
new
Duration
{
Seconds
=
1
,
Nanos
=
-
500000000
}
+
new
Duration
{
Nanos
=
500000000
});
Assert
.
AreEqual
(
new
Duration
{
Nanos
=
-
900000000
},
new
Duration
{
Seconds
=
-
1
,
Nanos
=
-
100000000
}
+
new
Duration
{
Nanos
=
200000000
});
Assert
.
AreEqual
(
new
Duration
{
Nanos
=
900000000
},
new
Duration
{
Seconds
=
1
,
Nanos
=
100000000
}
+
new
Duration
{
Nanos
=
-
200000000
});
}
[
Test
]
public
void
Subtraction
()
{
Assert
.
AreEqual
(
new
Duration
{
Seconds
=
1
,
Nanos
=
100000000
},
new
Duration
{
Seconds
=
1
,
Nanos
=
600000000
}
-
new
Duration
{
Nanos
=
500000000
});
Assert
.
AreEqual
(
new
Duration
{
Seconds
=
-
1
,
Nanos
=
-
100000000
},
new
Duration
{
Seconds
=
-
1
,
Nanos
=
-
600000000
}
-
new
Duration
{
Nanos
=
-
500000000
});
Assert
.
AreEqual
(
new
Duration
{
Seconds
=
2
,
Nanos
=
100000000
},
new
Duration
{
Seconds
=
1
,
Nanos
=
600000000
}
-
new
Duration
{
Nanos
=
-
500000000
});
// Non-normalized durations
Assert
.
AreEqual
(
new
Duration
(),
new
Duration
{
Seconds
=
1
,
Nanos
=
-
500000000
}
-
new
Duration
{
Nanos
=
500000000
});
Assert
.
AreEqual
(
new
Duration
{
Seconds
=
1
},
new
Duration
{
Nanos
=
2000000000
}
-
new
Duration
{
Nanos
=
1000000000
});
}
[
Test
]
public
void
FromTimeSpan
()
{
Assert
.
AreEqual
(
new
Duration
{
Seconds
=
1
},
Duration
.
FromTimeSpan
(
TimeSpan
.
FromSeconds
(
1
)));
Assert
.
AreEqual
(
new
Duration
{
Nanos
=
Duration
.
NanosecondsPerTick
},
Duration
.
FromTimeSpan
(
TimeSpan
.
FromTicks
(
1
)));
}
[
Test
]
[
TestCase
(
0
,
Duration
.
MaxNanoseconds
+
1
)]
[
TestCase
(
0
,
Duration
.
MinNanoseconds
-
1
)]
[
TestCase
(
Duration
.
MinSeconds
-
1
,
0
)]
[
TestCase
(
Duration
.
MaxSeconds
+
1
,
0
)]
[
TestCase
(
1
,
-
1
)]
[
TestCase
(-
1
,
1
)]
public
void
ToTimeSpan_Invalid
(
long
seconds
,
int
nanoseconds
)
{
var
duration
=
new
Duration
{
Seconds
=
seconds
,
Nanos
=
nanoseconds
};
Assert
.
Throws
<
InvalidOperationException
>(()
=>
duration
.
ToTimeSpan
());
}
[
Test
]
[
TestCase
(
0
,
Duration
.
MaxNanoseconds
)]
[
TestCase
(
0
,
Duration
.
MinNanoseconds
)]
[
TestCase
(
Duration
.
MinSeconds
,
Duration
.
MinNanoseconds
)]
[
TestCase
(
Duration
.
MaxSeconds
,
Duration
.
MaxNanoseconds
)]
public
void
ToTimeSpan_Valid
(
long
seconds
,
int
nanoseconds
)
{
// Only testing that these values don't throw, unlike their similar tests in ToTimeSpan_Invalid
var
duration
=
new
Duration
{
Seconds
=
seconds
,
Nanos
=
nanoseconds
};
duration
.
ToTimeSpan
();
}
[
Test
]
public
void
ToString_NonNormalized
()
{
// Just a single example should be sufficient...
var
duration
=
new
Duration
{
Seconds
=
1
,
Nanos
=
-
1
};
Assert
.
AreEqual
(
"{ \"@warning\": \"Invalid Duration\", \"seconds\": \"1\", \"nanos\": -1 }"
,
duration
.
ToString
());
}
}
}
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/WellKnownTypes/FieldMaskTest.cs
0 → 100644
View file @
3f6f73b7
#
region
Copyright
notice
and
license
// Protocol Buffers - Google's data interchange format
// Copyright 2016 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
NUnit.Framework
;
namespace
Google.Protobuf.WellKnownTypes
{
public
class
FieldMaskTest
{
[
Test
]
[
TestCase
(
"foo__bar"
)]
[
TestCase
(
"foo_3_ar"
)]
[
TestCase
(
"fooBar"
)]
public
void
ToString_Invalid
(
string
input
)
{
var
mask
=
new
FieldMask
{
Paths
=
{
input
}
};
var
text
=
mask
.
ToString
();
// More specific test below
Assert
.
That
(
text
,
Does
.
Contain
(
"@warning"
));
Assert
.
That
(
text
,
Does
.
Contain
(
input
));
}
[
Test
]
public
void
ToString_Invalid_Precise
()
{
var
mask
=
new
FieldMask
{
Paths
=
{
"x"
,
"foo__bar"
,
@"x\y"
}
};
Assert
.
AreEqual
(
"{ \"@warning\": \"Invalid FieldMask\", \"paths\": [ \"x\", \"foo__bar\", \"x\\\\y\" ] }"
,
mask
.
ToString
());
}
}
}
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs
0 → 100644
View file @
3f6f73b7
#
region
Copyright
notice
and
license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
NUnit.Framework
;
using
System
;
namespace
Google.Protobuf.WellKnownTypes
{
public
class
TimestampTest
{
[
Test
]
public
void
FromAndToDateTime
()
{
DateTime
utcMin
=
DateTime
.
SpecifyKind
(
DateTime
.
MinValue
,
DateTimeKind
.
Utc
);
DateTime
utcMax
=
DateTime
.
SpecifyKind
(
DateTime
.
MaxValue
,
DateTimeKind
.
Utc
);
AssertRoundtrip
(
new
Timestamp
{
Seconds
=
-
62135596800
},
utcMin
);
AssertRoundtrip
(
new
Timestamp
{
Seconds
=
253402300799
,
Nanos
=
999999900
},
utcMax
);
AssertRoundtrip
(
new
Timestamp
(),
new
DateTime
(
1970
,
1
,
1
,
0
,
0
,
0
,
DateTimeKind
.
Utc
));
AssertRoundtrip
(
new
Timestamp
{
Nanos
=
1000000
},
new
DateTime
(
1970
,
1
,
1
,
0
,
0
,
0
,
1
,
DateTimeKind
.
Utc
));
AssertRoundtrip
(
new
Timestamp
{
Seconds
=
-
1
,
Nanos
=
999000000
},
new
DateTime
(
1969
,
12
,
31
,
23
,
59
,
59
,
999
,
DateTimeKind
.
Utc
));
AssertRoundtrip
(
new
Timestamp
{
Seconds
=
3600
},
new
DateTime
(
1970
,
1
,
1
,
1
,
0
,
0
,
DateTimeKind
.
Utc
));
AssertRoundtrip
(
new
Timestamp
{
Seconds
=
-
3600
},
new
DateTime
(
1969
,
12
,
31
,
23
,
0
,
0
,
DateTimeKind
.
Utc
));
}
[
Test
]
public
void
ToDateTimeTruncation
()
{
var
t1
=
new
Timestamp
{
Seconds
=
1
,
Nanos
=
1000000
+
Duration
.
NanosecondsPerTick
-
1
};
Assert
.
AreEqual
(
new
DateTime
(
1970
,
1
,
1
,
0
,
0
,
1
,
DateTimeKind
.
Utc
).
AddMilliseconds
(
1
),
t1
.
ToDateTime
());
var
t2
=
new
Timestamp
{
Seconds
=
-
1
,
Nanos
=
1000000
+
Duration
.
NanosecondsPerTick
-
1
};
Assert
.
AreEqual
(
new
DateTime
(
1969
,
12
,
31
,
23
,
59
,
59
).
AddMilliseconds
(
1
),
t2
.
ToDateTime
());
}
[
Test
]
[
TestCase
(
Timestamp
.
UnixSecondsAtBclMinValue
-
1
,
Timestamp
.
MaxNanos
)]
[
TestCase
(
Timestamp
.
UnixSecondsAtBclMaxValue
+
1
,
0
)]
[
TestCase
(
0
,
-
1
)]
[
TestCase
(
0
,
Timestamp
.
MaxNanos
+
1
)]
public
void
ToDateTime_OutOfRange
(
long
seconds
,
int
nanoseconds
)
{
var
value
=
new
Timestamp
{
Seconds
=
seconds
,
Nanos
=
nanoseconds
};
Assert
.
Throws
<
InvalidOperationException
>(()
=>
value
.
ToDateTime
());
}
// 1ns larger or smaller than the above values
[
Test
]
[
TestCase
(
Timestamp
.
UnixSecondsAtBclMinValue
,
0
)]
[
TestCase
(
Timestamp
.
UnixSecondsAtBclMaxValue
,
Timestamp
.
MaxNanos
)]
[
TestCase
(
0
,
0
)]
[
TestCase
(
0
,
Timestamp
.
MaxNanos
)]
public
void
ToDateTime_ValidBoundaries
(
long
seconds
,
int
nanoseconds
)
{
var
value
=
new
Timestamp
{
Seconds
=
seconds
,
Nanos
=
nanoseconds
};
value
.
ToDateTime
();
}
private
static
void
AssertRoundtrip
(
Timestamp
timestamp
,
DateTime
dateTime
)
{
Assert
.
AreEqual
(
timestamp
,
Timestamp
.
FromDateTime
(
dateTime
));
Assert
.
AreEqual
(
dateTime
,
timestamp
.
ToDateTime
());
Assert
.
AreEqual
(
DateTimeKind
.
Utc
,
timestamp
.
ToDateTime
().
Kind
);
}
[
Test
]
public
void
Arithmetic
()
{
Timestamp
t1
=
new
Timestamp
{
Seconds
=
10000
,
Nanos
=
5000
};
Timestamp
t2
=
new
Timestamp
{
Seconds
=
8000
,
Nanos
=
10000
};
Duration
difference
=
new
Duration
{
Seconds
=
1999
,
Nanos
=
Duration
.
NanosecondsPerSecond
-
5000
};
Assert
.
AreEqual
(
difference
,
t1
-
t2
);
Assert
.
AreEqual
(-
difference
,
t2
-
t1
);
Assert
.
AreEqual
(
t1
,
t2
+
difference
);
Assert
.
AreEqual
(
t2
,
t1
-
difference
);
}
[
Test
]
public
void
ToString_NonNormalized
()
{
// Just a single example should be sufficient...
var
duration
=
new
Timestamp
{
Seconds
=
1
,
Nanos
=
-
1
};
Assert
.
AreEqual
(
"{ \"@warning\": \"Invalid Timestamp\", \"seconds\": \"1\", \"nanos\": -1 }"
,
duration
.
ToString
());
}
}
}
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
0 → 100644
View file @
3f6f73b7
#
region
Copyright
notice
and
license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using
System
;
using
Google.Protobuf.TestProtos
;
using
NUnit.Framework
;
using
System.Collections
;
using
System.IO
;
namespace
Google.Protobuf.WellKnownTypes
{
public
class
WrappersTest
{
[
Test
]
public
void
NullIsDefault
()
{
var
message
=
new
TestWellKnownTypes
();
Assert
.
IsNull
(
message
.
StringField
);
Assert
.
IsNull
(
message
.
BytesField
);
Assert
.
IsNull
(
message
.
BoolField
);
Assert
.
IsNull
(
message
.
FloatField
);
Assert
.
IsNull
(
message
.
DoubleField
);
Assert
.
IsNull
(
message
.
Int32Field
);
Assert
.
IsNull
(
message
.
Int64Field
);
Assert
.
IsNull
(
message
.
Uint32Field
);
Assert
.
IsNull
(
message
.
Uint64Field
);
}
[
Test
]
public
void
NonDefaultSingleValues
()
{
var
message
=
new
TestWellKnownTypes
{
StringField
=
"x"
,
BytesField
=
ByteString
.
CopyFrom
(
1
,
2
,
3
),
BoolField
=
true
,
FloatField
=
12.5f
,
DoubleField
=
12.25d
,
Int32Field
=
1
,
Int64Field
=
2
,
Uint32Field
=
3
,
Uint64Field
=
4
};
var
bytes
=
message
.
ToByteArray
();
var
parsed
=
TestWellKnownTypes
.
Parser
.
ParseFrom
(
bytes
);
Assert
.
AreEqual
(
"x"
,
parsed
.
StringField
);
Assert
.
AreEqual
(
ByteString
.
CopyFrom
(
1
,
2
,
3
),
parsed
.
BytesField
);
Assert
.
AreEqual
(
true
,
parsed
.
BoolField
);
Assert
.
AreEqual
(
12.5f
,
parsed
.
FloatField
);
Assert
.
AreEqual
(
12.25d
,
parsed
.
DoubleField
);
Assert
.
AreEqual
(
1
,
parsed
.
Int32Field
);
Assert
.
AreEqual
(
2L
,
parsed
.
Int64Field
);
Assert
.
AreEqual
(
3U
,
parsed
.
Uint32Field
);
Assert
.
AreEqual
(
4U
L
,
parsed
.
Uint64Field
);
}
[
Test
]
public
void
NonNullDefaultIsPreservedThroughSerialization
()
{
var
message
=
new
TestWellKnownTypes
{
StringField
=
""
,
BytesField
=
ByteString
.
Empty
,
BoolField
=
false
,
FloatField
=
0f
,
DoubleField
=
0d
,
Int32Field
=
0
,
Int64Field
=
0
,
Uint32Field
=
0
,
Uint64Field
=
0
};
var
bytes
=
message
.
ToByteArray
();
var
parsed
=
TestWellKnownTypes
.
Parser
.
ParseFrom
(
bytes
);
Assert
.
AreEqual
(
""
,
parsed
.
StringField
);
Assert
.
AreEqual
(
ByteString
.
Empty
,
parsed
.
BytesField
);
Assert
.
AreEqual
(
false
,
parsed
.
BoolField
);
Assert
.
AreEqual
(
0f
,
parsed
.
FloatField
);
Assert
.
AreEqual
(
0d
,
parsed
.
DoubleField
);
Assert
.
AreEqual
(
0
,
parsed
.
Int32Field
);
Assert
.
AreEqual
(
0L
,
parsed
.
Int64Field
);
Assert
.
AreEqual
(
0U
,
parsed
.
Uint32Field
);
Assert
.
AreEqual
(
0U
L
,
parsed
.
Uint64Field
);
}
[
Test
]
public
void
RepeatedWrappersProhibitNullItems
()
{
var
message
=
new
RepeatedWellKnownTypes
();
Assert
.
Throws
<
ArgumentNullException
>(()
=>
message
.
BoolField
.
Add
((
bool
?)
null
));
Assert
.
Throws
<
ArgumentNullException
>(()
=>
message
.
Int32Field
.
Add
((
int
?)
null
));
Assert
.
Throws
<
ArgumentNullException
>(()
=>
message
.
StringField
.
Add
((
string
)
null
));
Assert
.
Throws
<
ArgumentNullException
>(()
=>
message
.
BytesField
.
Add
((
ByteString
)
null
));
}
[
Test
]
public
void
RepeatedWrappersSerializeDeserialize
()
{
var
message
=
new
RepeatedWellKnownTypes
{
BoolField
=
{
true
,
false
},
BytesField
=
{
ByteString
.
CopyFrom
(
1
,
2
,
3
),
ByteString
.
CopyFrom
(
4
,
5
,
6
),
ByteString
.
Empty
},
DoubleField
=
{
12.5
,
-
1.5
,
0d
},
FloatField
=
{
123.25f
,
-
20f
,
0f
},
Int32Field
=
{
int
.
MaxValue
,
int
.
MinValue
,
0
},
Int64Field
=
{
long
.
MaxValue
,
long
.
MinValue
,
0L
},
StringField
=
{
"First"
,
"Second"
,
""
},
Uint32Field
=
{
uint
.
MaxValue
,
uint
.
MinValue
,
0U
},
Uint64Field
=
{
ulong
.
MaxValue
,
ulong
.
MinValue
,
0U
L
},
};
var
bytes
=
message
.
ToByteArray
();
var
parsed
=
RepeatedWellKnownTypes
.
Parser
.
ParseFrom
(
bytes
);
Assert
.
AreEqual
(
message
,
parsed
);
// Just to test a single value for sanity...
Assert
.
AreEqual
(
"Second"
,
message
.
StringField
[
1
]);
}
[
Test
]
public
void
RepeatedWrappersBinaryFormat
()
{
// At one point we accidentally used a packed format for repeated wrappers, which is wrong (and weird).
// This test is just to prove that we use the right format.
var
rawOutput
=
new
MemoryStream
();
var
output
=
new
CodedOutputStream
(
rawOutput
);
// Write a value of 5
output
.
WriteTag
(
RepeatedWellKnownTypes
.
Int32FieldFieldNumber
,
WireFormat
.
WireType
.
LengthDelimited
);
output
.
WriteLength
(
2
);
output
.
WriteTag
(
WrappersReflection
.
WrapperValueFieldNumber
,
WireFormat
.
WireType
.
Varint
);
output
.
WriteInt32
(
5
);
// Write a value of 0 (empty message)
output
.
WriteTag
(
RepeatedWellKnownTypes
.
Int32FieldFieldNumber
,
WireFormat
.
WireType
.
LengthDelimited
);
output
.
WriteLength
(
0
);
output
.
Flush
();
var
expectedBytes
=
rawOutput
.
ToArray
();
var
message
=
new
RepeatedWellKnownTypes
{
Int32Field
=
{
5
,
0
}
};
var
actualBytes
=
message
.
ToByteArray
();
Assert
.
AreEqual
(
expectedBytes
,
actualBytes
);
}
[
Test
]
public
void
MapWrappersSerializeDeserialize
()
{
// Note: no null values here, as they are prohibited in map fields
// (despite being representable).
var
message
=
new
MapWellKnownTypes
{
BoolField
=
{
{
10
,
false
},
{
20
,
true
}
},
BytesField
=
{
{
-
1
,
ByteString
.
CopyFrom
(
1
,
2
,
3
)
},
{
10
,
ByteString
.
CopyFrom
(
4
,
5
,
6
)
},
{
1000
,
ByteString
.
Empty
},
},
DoubleField
=
{
{
1
,
12.5
},
{
10
,
-
1.5
},
{
20
,
0d
}
},
FloatField
=
{
{
2
,
123.25f
},
{
3
,
-
20f
},
{
4
,
0f
}
},
Int32Field
=
{
{
5
,
int
.
MaxValue
},
{
6
,
int
.
MinValue
},
{
7
,
0
}
},
Int64Field
=
{
{
8
,
long
.
MaxValue
},
{
9
,
long
.
MinValue
},
{
10
,
0L
}
},
StringField
=
{
{
11
,
"First"
},
{
12
,
"Second"
},
{
13
,
""
}
},
Uint32Field
=
{
{
15
,
uint
.
MaxValue
},
{
16
,
uint
.
MinValue
},
{
17
,
0U
}
},
Uint64Field
=
{
{
18
,
ulong
.
MaxValue
},
{
19
,
ulong
.
MinValue
},
{
20
,
0U
L
}
},
};
var
bytes
=
message
.
ToByteArray
();
var
parsed
=
MapWellKnownTypes
.
Parser
.
ParseFrom
(
bytes
);
Assert
.
AreEqual
(
message
,
parsed
);
// Just to test a single value for sanity...
Assert
.
AreEqual
(
"Second"
,
message
.
StringField
[
12
]);
}
[
Test
]
public
void
Reflection_SingleValues
()
{
var
message
=
new
TestWellKnownTypes
{
StringField
=
"x"
,
BytesField
=
ByteString
.
CopyFrom
(
1
,
2
,
3
),
BoolField
=
true
,
FloatField
=
12.5f
,
DoubleField
=
12.25d
,
Int32Field
=
1
,
Int64Field
=
2
,
Uint32Field
=
3
,
Uint64Field
=
4
};
var
fields
=
TestWellKnownTypes
.
Descriptor
.
Fields
;
Assert
.
AreEqual
(
"x"
,
fields
[
TestWellKnownTypes
.
StringFieldFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
ByteString
.
CopyFrom
(
1
,
2
,
3
),
fields
[
TestWellKnownTypes
.
BytesFieldFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
true
,
fields
[
TestWellKnownTypes
.
BoolFieldFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
12.5f
,
fields
[
TestWellKnownTypes
.
FloatFieldFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
12.25d
,
fields
[
TestWellKnownTypes
.
DoubleFieldFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
1
,
fields
[
TestWellKnownTypes
.
Int32FieldFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
2L
,
fields
[
TestWellKnownTypes
.
Int64FieldFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
3U
,
fields
[
TestWellKnownTypes
.
Uint32FieldFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
4U
L
,
fields
[
TestWellKnownTypes
.
Uint64FieldFieldNumber
].
Accessor
.
GetValue
(
message
));
// And a couple of null fields...
message
.
StringField
=
null
;
message
.
FloatField
=
null
;
Assert
.
IsNull
(
fields
[
TestWellKnownTypes
.
StringFieldFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
IsNull
(
fields
[
TestWellKnownTypes
.
FloatFieldFieldNumber
].
Accessor
.
GetValue
(
message
));
}
[
Test
]
public
void
Reflection_RepeatedFields
()
{
// Just a single example... note that we can't have a null value here
var
message
=
new
RepeatedWellKnownTypes
{
Int32Field
=
{
1
,
2
}
};
var
fields
=
RepeatedWellKnownTypes
.
Descriptor
.
Fields
;
var
list
=
(
IList
)
fields
[
RepeatedWellKnownTypes
.
Int32FieldFieldNumber
].
Accessor
.
GetValue
(
message
);
CollectionAssert
.
AreEqual
(
new
[]
{
1
,
2
},
list
);
}
[
Test
]
public
void
Reflection_MapFields
()
{
// Just a single example... note that we can't have a null value here despite the value type being int?
var
message
=
new
MapWellKnownTypes
{
Int32Field
=
{
{
1
,
2
}
}
};
var
fields
=
MapWellKnownTypes
.
Descriptor
.
Fields
;
var
dictionary
=
(
IDictionary
)
fields
[
MapWellKnownTypes
.
Int32FieldFieldNumber
].
Accessor
.
GetValue
(
message
);
Assert
.
AreEqual
(
2
,
dictionary
[
1
]);
}
[
Test
]
public
void
Oneof
()
{
var
message
=
new
OneofWellKnownTypes
{
EmptyField
=
new
Empty
()
};
// Start off with a non-wrapper
Assert
.
AreEqual
(
OneofWellKnownTypes
.
OneofFieldOneofCase
.
EmptyField
,
message
.
OneofFieldCase
);
AssertOneofRoundTrip
(
message
);
message
.
StringField
=
"foo"
;
Assert
.
AreEqual
(
OneofWellKnownTypes
.
OneofFieldOneofCase
.
StringField
,
message
.
OneofFieldCase
);
AssertOneofRoundTrip
(
message
);
message
.
StringField
=
"foo"
;
Assert
.
AreEqual
(
OneofWellKnownTypes
.
OneofFieldOneofCase
.
StringField
,
message
.
OneofFieldCase
);
AssertOneofRoundTrip
(
message
);
message
.
DoubleField
=
0.0f
;
Assert
.
AreEqual
(
OneofWellKnownTypes
.
OneofFieldOneofCase
.
DoubleField
,
message
.
OneofFieldCase
);
AssertOneofRoundTrip
(
message
);
message
.
DoubleField
=
1.0f
;
Assert
.
AreEqual
(
OneofWellKnownTypes
.
OneofFieldOneofCase
.
DoubleField
,
message
.
OneofFieldCase
);
AssertOneofRoundTrip
(
message
);
message
.
ClearOneofField
();
Assert
.
AreEqual
(
OneofWellKnownTypes
.
OneofFieldOneofCase
.
None
,
message
.
OneofFieldCase
);
AssertOneofRoundTrip
(
message
);
}
private
void
AssertOneofRoundTrip
(
OneofWellKnownTypes
message
)
{
// Normal roundtrip, but explicitly checking the case...
var
bytes
=
message
.
ToByteArray
();
var
parsed
=
OneofWellKnownTypes
.
Parser
.
ParseFrom
(
bytes
);
Assert
.
AreEqual
(
message
,
parsed
);
Assert
.
AreEqual
(
message
.
OneofFieldCase
,
parsed
.
OneofFieldCase
);
}
[
Test
]
[
TestCase
(
"x"
,
"y"
,
"y"
)]
[
TestCase
(
"x"
,
""
,
"x"
)]
[
TestCase
(
"x"
,
null
,
"x"
)]
[
TestCase
(
""
,
"y"
,
"y"
)]
[
TestCase
(
""
,
""
,
""
)]
[
TestCase
(
""
,
null
,
""
)]
[
TestCase
(
null
,
"y"
,
"y"
)]
[
TestCase
(
null
,
""
,
""
)]
[
TestCase
(
null
,
null
,
null
)]
public
void
Merging
(
string
original
,
string
merged
,
string
expected
)
{
var
originalMessage
=
new
TestWellKnownTypes
{
StringField
=
original
};
var
mergingMessage
=
new
TestWellKnownTypes
{
StringField
=
merged
};
originalMessage
.
MergeFrom
(
mergingMessage
);
Assert
.
AreEqual
(
expected
,
originalMessage
.
StringField
);
// Try it using MergeFrom(CodedInputStream) too...
originalMessage
=
new
TestWellKnownTypes
{
StringField
=
original
};
originalMessage
.
MergeFrom
(
mergingMessage
.
ToByteArray
());
Assert
.
AreEqual
(
expected
,
originalMessage
.
StringField
);
}
// Merging is odd with wrapper types, due to the way that default values aren't emitted in
// the binary stream. In fact we cheat a little bit - a message with an explicitly present default
// value will have that default value ignored. See issue 615. Fixing this would require significant upheaval to
// the FieldCodec side of things.
[
Test
]
public
void
MergingStreamExplicitValue
()
{
var
message
=
new
TestWellKnownTypes
{
Int32Field
=
5
};
// Create a byte array which has the data of an Int32Value explicitly containing a value of 0.
// This wouldn't normally happen.
byte
[]
bytes
;
var
wrapperTag
=
WireFormat
.
MakeTag
(
TestWellKnownTypes
.
Int32FieldFieldNumber
,
WireFormat
.
WireType
.
LengthDelimited
);
var
valueTag
=
WireFormat
.
MakeTag
(
Int32Value
.
ValueFieldNumber
,
WireFormat
.
WireType
.
Varint
);
using
(
var
stream
=
new
MemoryStream
())
{
var
coded
=
new
CodedOutputStream
(
stream
);
coded
.
WriteTag
(
wrapperTag
);
coded
.
WriteLength
(
2
);
// valueTag + a value 0, each one byte
coded
.
WriteTag
(
valueTag
);
coded
.
WriteInt32
(
0
);
coded
.
Flush
();
bytes
=
stream
.
ToArray
();
}
message
.
MergeFrom
(
bytes
);
// A normal implementation would have 0 now, as the explicit default would have been overwritten the 5.
// With the FieldCodec for Nullable<int>, we can't tell the difference between an implicit 0 and an explicit 0.
Assert
.
AreEqual
(
5
,
message
.
Int32Field
);
}
[
Test
]
public
void
MergingStreamNoValue
()
{
var
message
=
new
TestWellKnownTypes
{
Int32Field
=
5
};
// Create a byte array which an Int32 field, but with no value.
var
bytes
=
new
TestWellKnownTypes
{
Int32Field
=
0
}.
ToByteArray
();
Assert
.
AreEqual
(
2
,
bytes
.
Length
);
// The tag for Int32Field is a single byte, then a byte indicating a 0-length message.
message
.
MergeFrom
(
bytes
);
// The "implicit" 0 did *not* overwrite the value.
// (This is the correct behaviour.)
Assert
.
AreEqual
(
5
,
message
.
Int32Field
);
}
// All permutations of origin/merging value being null, zero (default) or non-default.
// As this is the in-memory version, we don't need to worry about the difference between implicit and explicit 0.
[
Test
]
[
TestCase
(
null
,
null
,
null
)]
[
TestCase
(
null
,
0
,
0
)]
[
TestCase
(
null
,
5
,
5
)]
[
TestCase
(
0
,
null
,
0
)]
[
TestCase
(
0
,
0
,
0
)]
[
TestCase
(
0
,
5
,
5
)]
[
TestCase
(
5
,
null
,
5
)]
[
TestCase
(
5
,
0
,
5
)]
[
TestCase
(
5
,
10
,
10
)]
public
void
MergingMessageWithZero
(
int
?
originValue
,
int
?
mergingValue
,
int
?
expectedResult
)
{
// This differs from the MergingStreamCornerCase because when we merge message *objects*,
// we ignore default values from the "source".
var
message1
=
new
TestWellKnownTypes
{
Int32Field
=
originValue
};
var
message2
=
new
TestWellKnownTypes
{
Int32Field
=
mergingValue
};
message1
.
MergeFrom
(
message2
);
Assert
.
AreEqual
(
expectedResult
,
message1
.
Int32Field
);
}
[
Test
]
public
void
UnknownFieldInWrapper
()
{
var
stream
=
new
MemoryStream
();
var
output
=
new
CodedOutputStream
(
stream
);
var
wrapperTag
=
WireFormat
.
MakeTag
(
TestWellKnownTypes
.
Int32FieldFieldNumber
,
WireFormat
.
WireType
.
LengthDelimited
);
var
unknownTag
=
WireFormat
.
MakeTag
(
15
,
WireFormat
.
WireType
.
Varint
);
var
valueTag
=
WireFormat
.
MakeTag
(
Int32Value
.
ValueFieldNumber
,
WireFormat
.
WireType
.
Varint
);
output
.
WriteTag
(
wrapperTag
);
output
.
WriteLength
(
4
);
// unknownTag + value 5 + valueType + value 6, each 1 byte
output
.
WriteTag
(
unknownTag
);
output
.
WriteInt32
((
int
)
valueTag
);
// Sneakily "pretend" it's a tag when it's really a value
output
.
WriteTag
(
valueTag
);
output
.
WriteInt32
(
6
);
output
.
Flush
();
stream
.
Position
=
0
;
var
message
=
TestWellKnownTypes
.
Parser
.
ParseFrom
(
stream
);
Assert
.
AreEqual
(
6
,
message
.
Int32Field
);
}
[
Test
]
public
void
ClearWithReflection
()
{
// String and Bytes are the tricky ones here, as the CLR type of the property
// is the same between the wrapper and non-wrapper types.
var
message
=
new
TestWellKnownTypes
{
StringField
=
"foo"
};
TestWellKnownTypes
.
Descriptor
.
Fields
[
TestWellKnownTypes
.
StringFieldFieldNumber
].
Accessor
.
Clear
(
message
);
Assert
.
IsNull
(
message
.
StringField
);
}
}
}
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/project.json
0 → 100644
View file @
3f6f73b7
{
"buildOptions"
:
{
"debugType"
:
"portable"
,
"keyFile"
:
"../../keys/Google.Protobuf.snk"
},
"configurations"
:
{
"Debug"
:
{
"buildOptions"
:
{
"define"
:
[
"DEBUG"
,
"TRACE"
]
}
},
"Release"
:
{
"buildOptions"
:
{
"define"
:
[
"RELEASE"
,
"TRACE"
],
"optimize"
:
true
}
}
},
"dependencies"
:
{
"Google.Protobuf"
:
{
"target"
:
"project"
},
"NUnit"
:
"3.4.0"
,
"dotnet-test-nunit"
:
"3.4.0-alpha-2"
,
},
"testRunner"
:
"nunit"
,
"frameworks"
:
{
"netcoreapp1.0"
:
{
"imports"
:
[
"dnxcore50"
,
"netcoreapp1.0"
,
"portable-net45+win8"
],
"buildOptions"
:
{
"define"
:
[
"PCL"
]
},
"dependencies"
:
{
"Microsoft.NETCore.App"
:
{
"version"
:
"1.0.0"
,
"type"
:
"platform"
},
"System.Console"
:
"4.0.0"
}
}
}
}
\ No newline at end of file
csharp/compatibility_tests/v3.0.0/test.sh
0 → 100755
View file @
3f6f73b7
#!/bin/bash
function
run_test
()
{
# Generate test proto files.
./protoc_1
-Iprotos
/src
-I
../../../src/
--csharp_out
=
src/Google.Protobuf.Test
\
--csharp_opt
=
base_namespace
=
Google.Protobuf
\
protos/src/google/protobuf/unittest_import_proto3.proto
\
protos/src/google/protobuf/unittest_import_public_proto3.proto
\
protos/src/google/protobuf/unittest_well_known_types.proto
./protoc_1
-Iprotos
/csharp
--csharp_out
=
src/Google.Protobuf.Test
\
--csharp_opt
=
base_namespace
=
UnitTest.Issues
\
protos/csharp/protos/unittest_issues.proto
./protoc_2
-Iprotos
/src
--csharp_out
=
src/Google.Protobuf.Test
\
--csharp_opt
=
base_namespace
=
Google.Protobuf
\
protos/src/google/protobuf/unittest_proto3.proto
\
protos/src/google/protobuf/map_unittest_proto3.proto
# Build and test.
dotnet build
-c
release src/Google.Protobuf src/Google.Protobuf.Test
dotnet
test
-c
release
-f
netcoreapp1.0 src/Google.Protobuf.Test
}
set
-ex
# Change to the script's directory.
cd
$(
dirname
$0
)
# Version of the tests (i.e., the version of protobuf from where we extracted
# these tests).
TEST_VERSION
=
3.0.0
# The old version of protobuf that we are testing compatibility against. This
# is usually the same as TEST_VERSION (i.e., we use the tests extracted from
# that version to test compatibility of the newest runtime against it), but it
# is also possible to use this same test set to test the compatibiilty of the
# latest version against other versions.
case
"
$1
"
in
""
|
3.0.0
)
OLD_VERSION
=
3.0.0
OLD_VERSION_PROTOC
=
http://repo1.maven.org/maven2/com/google/protobuf/protoc/3.0.0/protoc-3.0.0-linux-x86_64.exe
;;
3.0.2
)
OLD_VERSION
=
3.0.2
OLD_VERSION_PROTOC
=
http://repo1.maven.org/maven2/com/google/protobuf/protoc/3.0.2/protoc-3.0.2-linux-x86_64.exe
;;
3.1.0
)
OLD_VERSION
=
3.1.0
OLD_VERSION_PROTOC
=
http://repo1.maven.org/maven2/com/google/protobuf/protoc/3.1.0/protoc-3.1.0-linux-x86_64.exe
;;
*
)
echo
"[ERROR]: Unknown version number:
$1
"
exit
1
;;
esac
echo
"Running compatibility tests with
$OLD_VERSION
"
# Check protoc
[
-f
../../../src/protoc
]
||
{
echo
"[ERROR]: Please build protoc first."
exit
1
}
# Download old version protoc compiler (for linux).
wget
$OLD_VERSION_PROTOC
-O
old_protoc
chmod
+x old_protoc
# Test source compatibility. In these tests we recompile everything against
# the new runtime (including old version generated code).
# Copy the new runtime and keys.
cp
../../src/Google.Protobuf src/Google.Protobuf
-r
cp
../../keys
.
-r
dotnet restore
# Test A.1:
# proto set 1: use old version
# proto set 2 which may import protos in set 1: use old version
cp
old_protoc protoc_1
cp
old_protoc protoc_2
run_test
# Test A.2:
# proto set 1: use new version
# proto set 2 which may import protos in set 1: use old version
cp
../../../src/protoc protoc_1
cp
old_protoc protoc_2
run_test
# Test A.3:
# proto set 1: use old version
# proto set 2 which may import protos in set 1: use new version
cp
old_protoc protoc_1
cp
../../../src/protoc protoc_2
run_test
rm
protoc_1
rm
protoc_2
rm
old_protoc
rm
keys
-r
rm
src/Google.Protobuf
-r
tests.sh
View file @
3f6f73b7
...
...
@@ -63,7 +63,7 @@ build_cpp_distcheck() {
# List all files that should be included in the distribution package.
git ls-files |
grep
"^
\(
java
\|
python
\|
objectivec
\|
csharp
\|
js
\|
ruby
\|
php
\|
cmake
\|
examples
\)
"
|
\
grep
-v
".gitignore"
|
grep
-v
"java/compatibility_tests"
|
\
grep
-v
"python/compatibility_tests"
>
dist.lst
grep
-v
"python/compatibility_tests"
|
grep
-v
"csharp/compatibility_tests"
>
dist.lst
# Unzip the dist tar file.
DIST
=
`
ls
*
.tar.gz
`
tar
-xf
$DIST
...
...
@@ -119,6 +119,9 @@ build_csharp() {
(
cd
csharp/src
;
dotnet restore
)
csharp/buildall.sh
cd
conformance
&&
make test_csharp
&&
cd
..
# Run csharp compatibility test between 3.0.0 and the current version.
csharp/compatibility_tests/v3.0.0/test.sh 3.0.0
}
build_golang
()
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment