1#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 NUnit.Framework; 34using System; 35 36namespace Google.Protobuf.WellKnownTypes 37{ 38 public class DurationTest 39 { 40 [Test] 41 public void ToTimeSpan() 42 { 43 Assert.AreEqual(TimeSpan.FromSeconds(1), new Duration { Seconds = 1 }.ToTimeSpan()); 44 Assert.AreEqual(TimeSpan.FromSeconds(-1), new Duration { Seconds = -1 }.ToTimeSpan()); 45 Assert.AreEqual(TimeSpan.FromMilliseconds(1), new Duration { Nanos = 1000000 }.ToTimeSpan()); 46 Assert.AreEqual(TimeSpan.FromMilliseconds(-1), new Duration { Nanos = -1000000 }.ToTimeSpan()); 47 Assert.AreEqual(TimeSpan.FromTicks(1), new Duration { Nanos = 100 }.ToTimeSpan()); 48 Assert.AreEqual(TimeSpan.FromTicks(-1), new Duration { Nanos = -100 }.ToTimeSpan()); 49 50 // Rounding is towards 0 51 Assert.AreEqual(TimeSpan.FromTicks(2), new Duration { Nanos = 250 }.ToTimeSpan()); 52 Assert.AreEqual(TimeSpan.FromTicks(-2), new Duration { Nanos = -250 }.ToTimeSpan()); 53 } 54 55 [Test] 56 public void Addition() 57 { 58 Assert.AreEqual(new Duration { Seconds = 2, Nanos = 100000000 }, 59 new Duration { Seconds = 1, Nanos = 600000000 } + new Duration { Nanos = 500000000 }); 60 Assert.AreEqual(new Duration { Seconds = -2, Nanos = -100000000 }, 61 new Duration { Seconds = -1, Nanos = -600000000 } + new Duration { Nanos = -500000000 }); 62 Assert.AreEqual(new Duration { Seconds = 1, Nanos = 100000000 }, 63 new Duration { Seconds = 1, Nanos = 600000000 } + new Duration { Nanos = -500000000 }); 64 65 // Non-normalized durations, or non-normalized intermediate results 66 Assert.AreEqual(new Duration { Seconds = 1 }, 67 new Duration { Seconds = 1, Nanos = -500000000 } + new Duration { Nanos = 500000000 }); 68 69 Assert.AreEqual(new Duration { Nanos = -900000000 }, 70 new Duration { Seconds = -1, Nanos = -100000000 } + new Duration { Nanos = 200000000 }); 71 Assert.AreEqual(new Duration { Nanos = 900000000 }, 72 new Duration { Seconds = 1, Nanos = 100000000 } + new Duration { Nanos = -200000000 }); 73 } 74 75 [Test] 76 public void Subtraction() 77 { 78 Assert.AreEqual(new Duration { Seconds = 1, Nanos = 100000000 }, 79 new Duration { Seconds = 1, Nanos = 600000000 } - new Duration { Nanos = 500000000 }); 80 Assert.AreEqual(new Duration { Seconds = -1, Nanos = -100000000 }, 81 new Duration { Seconds = -1, Nanos = -600000000 } - new Duration { Nanos = -500000000 }); 82 Assert.AreEqual(new Duration { Seconds = 2, Nanos = 100000000 }, 83 new Duration { Seconds = 1, Nanos = 600000000 } - new Duration { Nanos = -500000000 }); 84 85 // Non-normalized durations 86 Assert.AreEqual(new Duration(), 87 new Duration { Seconds = 1, Nanos = -500000000 } - new Duration { Nanos = 500000000 }); 88 Assert.AreEqual(new Duration { Seconds = 1 }, 89 new Duration { Nanos = 2000000000 } - new Duration { Nanos = 1000000000 }); 90 } 91 92 [Test] 93 public void FromTimeSpan() 94 { 95 Assert.AreEqual(new Duration { Seconds = 1 }, Duration.FromTimeSpan(TimeSpan.FromSeconds(1))); 96 Assert.AreEqual(new Duration { Nanos = Duration.NanosecondsPerTick }, Duration.FromTimeSpan(TimeSpan.FromTicks(1))); 97 } 98 99 [Test] 100 [TestCase(0, Duration.MaxNanoseconds + 1)] 101 [TestCase(0, Duration.MinNanoseconds - 1)] 102 [TestCase(Duration.MinSeconds - 1, 0)] 103 [TestCase(Duration.MaxSeconds + 1, 0)] 104 [TestCase(1, -1)] 105 [TestCase(-1, 1)] 106 public void ToTimeSpan_Invalid(long seconds, int nanoseconds) 107 { 108 var duration = new Duration { Seconds = seconds, Nanos = nanoseconds }; 109 Assert.Throws<InvalidOperationException>(() => duration.ToTimeSpan()); 110 } 111 112 [Test] 113 [TestCase(0, Duration.MaxNanoseconds)] 114 [TestCase(0, Duration.MinNanoseconds)] 115 [TestCase(Duration.MinSeconds, Duration.MinNanoseconds)] 116 [TestCase(Duration.MaxSeconds, Duration.MaxNanoseconds)] 117 public void ToTimeSpan_Valid(long seconds, int nanoseconds) 118 { 119 // Only testing that these values don't throw, unlike their similar tests in ToTimeSpan_Invalid 120 var duration = new Duration { Seconds = seconds, Nanos = nanoseconds }; 121 duration.ToTimeSpan(); 122 } 123 124 [Test] 125 public void ToString_NonNormalized() 126 { 127 // Just a single example should be sufficient... 128 var duration = new Duration { Seconds = 1, Nanos = -1 }; 129 Assert.AreEqual("{ \"@warning\": \"Invalid Duration\", \"seconds\": \"1\", \"nanos\": -1 }", duration.ToString()); 130 } 131 } 132} 133