blob: a14040d1ac6c90b5eee333302de10ef0f163ec32 [file] [log] [blame]
Jon Skeet286edc02015-06-26 20:11:34 +01001#region Copyright notice and license
2// Protocol Buffers - Google's data interchange format
3// Copyright 2015 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
33using System.Collections.Generic;
34using System.IO;
35using Google.Protobuf.TestProtos;
36using NUnit.Framework;
37
38namespace Google.Protobuf
39{
40 public class FieldCodecTest
41 {
42 private static readonly List<ICodecTestData> Codecs = new List<ICodecTestData>
43 {
44 new FieldCodecTestData<bool>(FieldCodec.ForBool(100), true, "Bool"),
45 new FieldCodecTestData<string>(FieldCodec.ForString(100), "sample", "String"),
46 new FieldCodecTestData<ByteString>(FieldCodec.ForBytes(100), ByteString.CopyFrom(1, 2, 3), "Bytes"),
47 new FieldCodecTestData<int>(FieldCodec.ForInt32(100), -1000, "Int32"),
48 new FieldCodecTestData<int>(FieldCodec.ForSInt32(100), -1000, "SInt32"),
49 new FieldCodecTestData<int>(FieldCodec.ForSFixed32(100), -1000, "SFixed32"),
50 new FieldCodecTestData<uint>(FieldCodec.ForUInt32(100), 1234, "UInt32"),
51 new FieldCodecTestData<uint>(FieldCodec.ForFixed32(100), 1234, "Fixed32"),
52 new FieldCodecTestData<long>(FieldCodec.ForInt64(100), -1000, "Int64"),
53 new FieldCodecTestData<long>(FieldCodec.ForSInt64(100), -1000, "SInt64"),
54 new FieldCodecTestData<long>(FieldCodec.ForSFixed64(100), -1000, "SFixed64"),
55 new FieldCodecTestData<ulong>(FieldCodec.ForUInt64(100), 1234, "UInt64"),
56 new FieldCodecTestData<ulong>(FieldCodec.ForFixed64(100), 1234, "Fixed64"),
57 new FieldCodecTestData<float>(FieldCodec.ForFloat(100), 1234.5f, "Float"),
58 new FieldCodecTestData<double>(FieldCodec.ForDouble(100), 1234567890.5d, "Double"),
59 new FieldCodecTestData<ForeignEnum>(
60 FieldCodec.ForEnum(100, t => (int) t, t => (ForeignEnum) t), ForeignEnum.FOREIGN_BAZ, "Enum"),
61 new FieldCodecTestData<ForeignMessage>(
62 FieldCodec.ForMessage(100, ForeignMessage.Parser), new ForeignMessage { C = 10 }, "Message"),
63 };
64
65 [Test, TestCaseSource("Codecs")]
Jon Skeetf34d37a2015-06-30 13:16:20 +010066 public void RoundTripWithTag(ICodecTestData codec)
Jon Skeet286edc02015-06-26 20:11:34 +010067 {
Jon Skeetf34d37a2015-06-30 13:16:20 +010068 codec.TestRoundTripWithTag();
69 }
70
71 [Test, TestCaseSource("Codecs")]
72 public void RoundTripRaw(ICodecTestData codec)
73 {
74 codec.TestRoundTripRaw();
Jon Skeet286edc02015-06-26 20:11:34 +010075 }
76
77 [Test, TestCaseSource("Codecs")]
78 public void CalculateSize(ICodecTestData codec)
79 {
Jon Skeetf34d37a2015-06-30 13:16:20 +010080 codec.TestCalculateSizeWithTag();
Jon Skeet286edc02015-06-26 20:11:34 +010081 }
82
83 [Test, TestCaseSource("Codecs")]
84 public void DefaultValue(ICodecTestData codec)
85 {
86 codec.TestDefaultValue();
87 }
88
89 public interface ICodecTestData
90 {
Jon Skeetf34d37a2015-06-30 13:16:20 +010091 void TestRoundTripRaw();
92 void TestRoundTripWithTag();
93 void TestCalculateSizeWithTag();
Jon Skeet286edc02015-06-26 20:11:34 +010094 void TestDefaultValue();
95 }
96
97 public class FieldCodecTestData<T> : ICodecTestData
98 {
99 private readonly FieldCodec<T> codec;
100 private readonly T sampleValue;
101 private readonly string name;
102
103 public FieldCodecTestData(FieldCodec<T> codec, T sampleValue, string name)
104 {
105 this.codec = codec;
106 this.sampleValue = sampleValue;
107 this.name = name;
108 }
109
Jon Skeetf34d37a2015-06-30 13:16:20 +0100110 public void TestRoundTripRaw()
111 {
112 var stream = new MemoryStream();
113 var codedOutput = CodedOutputStream.CreateInstance(stream);
114 codec.ValueWriter(codedOutput, sampleValue);
115 codedOutput.Flush();
116 stream.Position = 0;
117 var codedInput = CodedInputStream.CreateInstance(stream);
118 Assert.AreEqual(sampleValue, codec.ValueReader(codedInput));
119 Assert.IsTrue(codedInput.IsAtEnd);
120 }
121
122 public void TestRoundTripWithTag()
Jon Skeet286edc02015-06-26 20:11:34 +0100123 {
124 var stream = new MemoryStream();
125 var codedOutput = CodedOutputStream.CreateInstance(stream);
Jon Skeetb9d1d382015-06-29 10:30:09 +0100126 codec.WriteTagAndValue(codedOutput, sampleValue);
Jon Skeet286edc02015-06-26 20:11:34 +0100127 codedOutput.Flush();
128 stream.Position = 0;
129 var codedInput = CodedInputStream.CreateInstance(stream);
Jon Skeetf34d37a2015-06-30 13:16:20 +0100130 codedInput.AssertNextTag(codec.Tag);
Jon Skeet286edc02015-06-26 20:11:34 +0100131 Assert.AreEqual(sampleValue, codec.Read(codedInput));
132 Assert.IsTrue(codedInput.IsAtEnd);
133 }
134
Jon Skeetf34d37a2015-06-30 13:16:20 +0100135 public void TestCalculateSizeWithTag()
Jon Skeet286edc02015-06-26 20:11:34 +0100136 {
137 var stream = new MemoryStream();
138 var codedOutput = CodedOutputStream.CreateInstance(stream);
Jon Skeetb9d1d382015-06-29 10:30:09 +0100139 codec.WriteTagAndValue(codedOutput, sampleValue);
Jon Skeet286edc02015-06-26 20:11:34 +0100140 codedOutput.Flush();
Jon Skeetb9d1d382015-06-29 10:30:09 +0100141 Assert.AreEqual(stream.Position, codec.CalculateSizeWithTag(sampleValue));
Jon Skeet286edc02015-06-26 20:11:34 +0100142 }
143
144 public void TestDefaultValue()
145 {
Jon Skeetf34d37a2015-06-30 13:16:20 +0100146 // WriteTagAndValue ignores default values
Jon Skeet286edc02015-06-26 20:11:34 +0100147 var stream = new MemoryStream();
148 var codedOutput = CodedOutputStream.CreateInstance(stream);
Jon Skeetb9d1d382015-06-29 10:30:09 +0100149 codec.WriteTagAndValue(codedOutput, codec.DefaultValue);
Jon Skeet286edc02015-06-26 20:11:34 +0100150 codedOutput.Flush();
151 Assert.AreEqual(0, stream.Position);
Jon Skeetb9d1d382015-06-29 10:30:09 +0100152 Assert.AreEqual(0, codec.CalculateSizeWithTag(codec.DefaultValue));
Jon Skeet286edc02015-06-26 20:11:34 +0100153 if (typeof(T).IsValueType)
154 {
155 Assert.AreEqual(default(T), codec.DefaultValue);
156 }
Jon Skeet286edc02015-06-26 20:11:34 +0100157
Jon Skeetf34d37a2015-06-30 13:16:20 +0100158 // The plain ValueWriter/ValueReader delegates don't.
159 if (codec.DefaultValue != null) // This part isn't appropriate for message types.
160 {
161 codedOutput = CodedOutputStream.CreateInstance(stream);
162 codec.ValueWriter(codedOutput, codec.DefaultValue);
163 codedOutput.Flush();
164 Assert.AreNotEqual(0, stream.Position);
165 Assert.AreEqual(stream.Position, codec.ValueSizeCalculator(codec.DefaultValue));
166 stream.Position = 0;
167 var codedInput = CodedInputStream.CreateInstance(stream);
168 Assert.AreEqual(codec.DefaultValue, codec.ValueReader(codedInput));
169 }
170 }
Jon Skeet286edc02015-06-26 20:11:34 +0100171
172 public override string ToString()
173 {
174 return name;
175 }
176 }
177 }
178}