• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #region Copyright notice and license
2 // Protocol Buffers - Google's data interchange format
3 // Copyright 2018 Google Inc.  All rights reserved.
4 // https://developers.google.com/protocol-buffers/
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are
8 // met:
9 //
10 //     * Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 //     * Redistributions in binary form must reproduce the above
13 // copyright notice, this list of conditions and the following disclaimer
14 // in the documentation and/or other materials provided with the
15 // distribution.
16 //     * Neither the name of Google Inc. nor the names of its
17 // contributors may be used to endorse or promote products derived from
18 // this software without specific prior written permission.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #endregion
32 
33 using Google.Protobuf.Reflection;
34 using NUnit.Framework;
35 using System.Linq;
36 using System.Reflection;
37 
38 namespace Google.Protobuf.Test.Reflection
39 {
40     // In reality this isn't a test for DescriptorDeclaration so much as the way they're loaded.
41     public class DescriptorDeclarationTest
42     {
43         static readonly FileDescriptor unitTestProto3Descriptor = LoadProtos();
44 
45         // Note: we don't expose a declaration for FileDescriptor as it doesn't have comments
46         // at the moment and the locations aren't terribly useful.
47 
48         // The tests for most elements are quite basic: we don't test every aspect of every element.
49         // The code within the library falls into two categories:
50         // - Exposing the properties for *any* declaration
51         // - Finding the right declaration for an element from the descriptor data
52         // We have a per-element check to make sure we *are* finding the right declaration, and we
53         // check every property of declarations in at least one test, but we don't have a cross-product.
54         // That would effectively be testing protoc, which seems redundant here.
55 
56         [Test]
ServiceComments()57         public void ServiceComments()
58         {
59             var service = unitTestProto3Descriptor.FindTypeByName<ServiceDescriptor>("TestService");
60             Assert.NotNull(service.Declaration);
61             Assert.AreEqual(" This is a test service\n", service.Declaration.LeadingComments);
62         }
63 
64         [Test]
MethodComments()65         public void MethodComments()
66         {
67             var service = unitTestProto3Descriptor.FindTypeByName<ServiceDescriptor>("TestService");
68             var method = service.FindMethodByName("Foo");
69             Assert.NotNull(method.Declaration);
70             Assert.AreEqual(" This is a test method\n", method.Declaration.LeadingComments);
71         }
72 
73         [Test]
MessageComments()74         public void MessageComments()
75         {
76             var message = unitTestProto3Descriptor.FindTypeByName<MessageDescriptor>("CommentMessage");
77             Assert.NotNull(message.Declaration);
78             Assert.AreEqual(" This is a leading comment\n", message.Declaration.LeadingComments);
79             Assert.AreEqual(new[] { " This is leading detached comment 1\n", " This is leading detached comment 2\n" },
80                 message.Declaration.LeadingDetachedComments);
81         }
82 
83         // Note: this test is somewhat brittle; a change earlier in the proto will break it.
84         [Test]
MessageLocations()85         public void MessageLocations()
86         {
87             var message = unitTestProto3Descriptor.FindTypeByName<MessageDescriptor>("CommentMessage");
88             Assert.NotNull(message.Declaration);
89             Assert.AreEqual(389, message.Declaration.StartLine);
90             Assert.AreEqual(1, message.Declaration.StartColumn);
91 
92             Assert.AreEqual(404, message.Declaration.EndLine);
93             Assert.AreEqual(2, message.Declaration.EndColumn);
94         }
95 
96         [Test]
EnumComments()97         public void EnumComments()
98         {
99             var descriptor = unitTestProto3Descriptor.FindTypeByName<EnumDescriptor>("CommentEnum");
100             Assert.NotNull(descriptor.Declaration);
101             Assert.AreEqual(" Leading enum comment\n", descriptor.Declaration.LeadingComments);
102         }
103 
104         [Test]
NestedMessageComments()105         public void NestedMessageComments()
106         {
107             var outer = unitTestProto3Descriptor.FindTypeByName<MessageDescriptor>("CommentMessage");
108             var nested = outer.FindDescriptor<MessageDescriptor>("NestedCommentMessage");
109             Assert.NotNull(nested.Declaration);
110             Assert.AreEqual(" Leading nested message comment\n", nested.Declaration.LeadingComments);
111         }
112 
113         [Test]
NestedEnumComments()114         public void NestedEnumComments()
115         {
116             var outer = unitTestProto3Descriptor.FindTypeByName<MessageDescriptor>("CommentMessage");
117             var nested = outer.FindDescriptor<EnumDescriptor>("NestedCommentEnum");
118             Assert.NotNull(nested.Declaration);
119             Assert.AreEqual(" Leading nested enum comment\n", nested.Declaration.LeadingComments);
120         }
121 
122         [Test]
FieldComments()123         public void FieldComments()
124         {
125             var message = unitTestProto3Descriptor.FindTypeByName<MessageDescriptor>("CommentMessage");
126             var field = message.FindFieldByName("text");
127             Assert.NotNull(field.Declaration);
128             Assert.AreEqual(" Leading field comment\n", field.Declaration.LeadingComments);
129             Assert.AreEqual(" Trailing field comment\n", field.Declaration.TrailingComments);
130         }
131 
132         [Test]
NestedMessageFieldComments()133         public void NestedMessageFieldComments()
134         {
135             var outer = unitTestProto3Descriptor.FindTypeByName<MessageDescriptor>("CommentMessage");
136             var nested = outer.FindDescriptor<MessageDescriptor>("NestedCommentMessage");
137             var field = nested.FindFieldByName("nested_text");
138             Assert.NotNull(field.Declaration);
139             Assert.AreEqual(" Leading nested message field comment\n", field.Declaration.LeadingComments);
140         }
141 
142         [Test]
EnumValueComments()143         public void EnumValueComments()
144         {
145             var enumDescriptor = unitTestProto3Descriptor.FindTypeByName<EnumDescriptor>("CommentEnum");
146             var value = enumDescriptor.FindValueByName("ZERO_VALUE");
147             Assert.NotNull(value.Declaration);
148             Assert.AreEqual(" Zero value comment\n", value.Declaration.LeadingComments);
149         }
150 
151         [Test]
NestedEnumValueComments()152         public void NestedEnumValueComments()
153         {
154             var outer = unitTestProto3Descriptor.FindTypeByName<MessageDescriptor>("CommentMessage");
155             var nested = outer.FindDescriptor<EnumDescriptor>("NestedCommentEnum");
156             var value = nested.FindValueByName("ZERO_VALUE");
157             Assert.NotNull(value.Declaration);
158             Assert.AreEqual(" Zero value comment\n", value.Declaration.LeadingComments);
159         }
160 
LoadProtos()161         private static FileDescriptor LoadProtos()
162         {
163             var type = typeof(DescriptorDeclarationTest);
164             // TODO: Make this simpler :)
165             FileDescriptorSet descriptorSet;
166             using (var stream = type.GetTypeInfo().Assembly.GetManifestResourceStream($"Google.Protobuf.Test.testprotos.pb"))
167             {
168                 descriptorSet = FileDescriptorSet.Parser.ParseFrom(stream);
169             }
170             var byteStrings = descriptorSet.File.Select(f => f.ToByteString()).ToList();
171             var descriptors = FileDescriptor.BuildFromByteStrings(byteStrings);
172             return descriptors.Single(d => d.Name == "unittest_proto3.proto");
173         }
174     }
175 }
176