aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Data/Tests/PropertyCompareConstraint.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Data/Tests/PropertyCompareConstraint.cs')
-rw-r--r--OpenSim/Data/Tests/PropertyCompareConstraint.cs229
1 files changed, 172 insertions, 57 deletions
diff --git a/OpenSim/Data/Tests/PropertyCompareConstraint.cs b/OpenSim/Data/Tests/PropertyCompareConstraint.cs
index 678501e..06ca53e 100644
--- a/OpenSim/Data/Tests/PropertyCompareConstraint.cs
+++ b/OpenSim/Data/Tests/PropertyCompareConstraint.cs
@@ -1,3 +1,30 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
1using System; 28using System;
2using System.Collections; 29using System.Collections;
3using System.Collections.Generic; 30using System.Collections.Generic;
@@ -42,6 +69,28 @@ namespace OpenSim.Data.Tests
42 69
43 private bool ObjectCompare(object expected, object actual, Stack<string> propertyNames) 70 private bool ObjectCompare(object expected, object actual, Stack<string> propertyNames)
44 { 71 {
72 //If they are both null, they are equal
73 if (actual == null && expected == null)
74 return true;
75
76 //If only one is null, then they aren't
77 if (actual == null || expected == null)
78 {
79 failingPropertyName = string.Join(".", propertyNames.Reverse().ToArray());
80 failingActual = actual;
81 failingExpected = expected;
82 return false;
83 }
84
85 //prevent loops...
86 if (propertyNames.Count > 50)
87 {
88 failingPropertyName = string.Join(".", propertyNames.Reverse().ToArray());
89 failingActual = actual;
90 failingExpected = expected;
91 return false;
92 }
93
45 if (actual.GetType() != expected.GetType()) 94 if (actual.GetType() != expected.GetType())
46 { 95 {
47 propertyNames.Push("GetType()"); 96 propertyNames.Push("GetType()");
@@ -52,7 +101,7 @@ namespace OpenSim.Data.Tests
52 return false; 101 return false;
53 } 102 }
54 103
55 if(actual.GetType() == typeof(Color)) 104 if (actual.GetType() == typeof(Color))
56 { 105 {
57 Color actualColor = (Color) actual; 106 Color actualColor = (Color) actual;
58 Color expectedColor = (Color) expected; 107 Color expectedColor = (Color) expected;
@@ -95,65 +144,69 @@ namespace OpenSim.Data.Tests
95 return true; 144 return true;
96 } 145 }
97 146
98 //Skip static properties. I had a nasty problem comparing colors because of all of the public static colors. 147 IComparable comp = actual as IComparable;
99 PropertyInfo[] properties = expected.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); 148 if (comp != null)
100 foreach (var property in properties)
101 { 149 {
102 if (ignores.Contains(property.Name)) 150 if (comp.CompareTo(expected) != 0)
103 continue; 151 {
104 152 failingPropertyName = string.Join(".", propertyNames.Reverse().ToArray());
105 object actualValue = property.GetValue(actual, null); 153 failingActual = actual;
106 object expectedValue = property.GetValue(expected, null); 154 failingExpected = expected;
155 return false;
156 }
157 return true;
158 }
107 159
108 //If they are both null, they are equal 160 //Now try the much more annoying IComparable<T>
109 if (actualValue == null && expectedValue == null) 161 Type icomparableInterface = actual.GetType().GetInterface("IComparable`1");
110 continue; 162 if (icomparableInterface != null)
163 {
164 int result = (int)icomparableInterface.GetMethod("CompareTo").Invoke(actual, new[] { expected });
165 if (result != 0)
166 {
167 failingPropertyName = string.Join(".", propertyNames.Reverse().ToArray());
168 failingActual = actual;
169 failingExpected = expected;
170 return false;
171 }
172 return true;
173 }
111 174
112 //If only one is null, then they aren't 175 IEnumerable arr = actual as IEnumerable;
113 if (actualValue == null || expectedValue == null) 176 if (arr != null)
177 {
178 List<object> actualList = arr.Cast<object>().ToList();
179 List<object> expectedList = ((IEnumerable)expected).Cast<object>().ToList();
180 if (actualList.Count != expectedList.Count)
114 { 181 {
115 propertyNames.Push(property.Name); 182 propertyNames.Push("Count");
116 failingPropertyName = string.Join(".", propertyNames.Reverse().ToArray()); 183 failingPropertyName = string.Join(".", propertyNames.Reverse().ToArray());
184 failingActual = actualList.Count;
185 failingExpected = expectedList.Count;
117 propertyNames.Pop(); 186 propertyNames.Pop();
118 failingActual = actualValue;
119 failingExpected = expectedValue;
120 return false; 187 return false;
121 } 188 }
122 189 //actualList and expectedList should be the same size.
123 IComparable comp = actualValue as IComparable; 190 for (int i = 0; i < actualList.Count; i++)
124 if (comp != null)
125 { 191 {
126 if (comp.CompareTo(expectedValue) != 0) 192 propertyNames.Push("[" + i + "]");
127 { 193 if (!ObjectCompare(expectedList[i], actualList[i], propertyNames))
128 propertyNames.Push(property.Name);
129 failingPropertyName = string.Join(".", propertyNames.Reverse().ToArray());
130 propertyNames.Pop();
131 failingActual = actualValue;
132 failingExpected = expectedValue;
133 return false; 194 return false;
134 } 195 propertyNames.Pop();
135 continue;
136 } 196 }
197 //Everything seems okay...
198 return true;
199 }
137 200
138 IEnumerable arr = actualValue as IEnumerable; 201 //Skip static properties. I had a nasty problem comparing colors because of all of the public static colors.
139 if (arr != null) 202 PropertyInfo[] properties = expected.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
140 { 203 foreach (var property in properties)
141 List<object> actualList = arr.Cast<object>().ToList(); 204 {
142 List<object> expectedList = ((IEnumerable)expectedValue).Cast<object>().ToList(); 205 if (ignores.Contains(property.Name))
143 if (actualList.Count != expectedList.Count)
144 {
145 propertyNames.Push(property.Name);
146 propertyNames.Push("Count");
147 failingPropertyName = string.Join(".", propertyNames.Reverse().ToArray());
148 failingActual = actualList.Count;
149 failingExpected = expectedList.Count;
150 propertyNames.Pop();
151 propertyNames.Pop();
152 }
153 //Todo: A value-wise comparison of all of the values.
154 //Everything seems okay...
155 continue; 206 continue;
156 } 207
208 object actualValue = property.GetValue(actual, null);
209 object expectedValue = property.GetValue(expected, null);
157 210
158 propertyNames.Push(property.Name); 211 propertyNames.Push(property.Name);
159 if (!ObjectCompare(expectedValue, actualValue, propertyNames)) 212 if (!ObjectCompare(expectedValue, actualValue, propertyNames))
@@ -196,15 +249,7 @@ namespace OpenSim.Data.Tests
196 { 249 {
197 //If the inside of the lambda is the access to x, we've hit the end of the chain. 250 //If the inside of the lambda is the access to x, we've hit the end of the chain.
198 // We should track by the fully scoped parameter name, but this is the first rev of doing this. 251 // We should track by the fully scoped parameter name, but this is the first rev of doing this.
199 if (((MemberExpression)express).Expression is ParameterExpression) 252 ignores.Add(((MemberExpression)express).Member.Name);
200 {
201 ignores.Add(((MemberExpression)express).Member.Name);
202 }
203 else
204 {
205 //Otherwise there could be more parameters inside...
206 PullApartExpression(((MemberExpression)express).Expression);
207 }
208 } 253 }
209 } 254 }
210 } 255 }
@@ -243,7 +288,7 @@ namespace OpenSim.Data.Tests
243 { 288 {
244 HasInt actual = new HasInt { TheValue = 5 }; 289 HasInt actual = new HasInt { TheValue = 5 };
245 HasInt expected = new HasInt { TheValue = 4 }; 290 HasInt expected = new HasInt { TheValue = 4 };
246 var constraint = Constraints.PropertyCompareConstraint(expected).IgnoreProperty(x=>x.TheValue); 291 var constraint = Constraints.PropertyCompareConstraint(expected).IgnoreProperty(x => x.TheValue);
247 292
248 Assert.That(constraint.Matches(actual), Is.True); 293 Assert.That(constraint.Matches(actual), Is.True);
249 } 294 }
@@ -285,6 +330,28 @@ namespace OpenSim.Data.Tests
285 } 330 }
286 331
287 [Test] 332 [Test]
333 public void UUIDShouldMatch()
334 {
335 UUID uuid1 = UUID.Random();
336 UUID uuid2 = UUID.Parse(uuid1.ToString());
337
338 var constraint = Constraints.PropertyCompareConstraint(uuid1);
339
340 Assert.That(constraint.Matches(uuid2), Is.True);
341 }
342
343 [Test]
344 public void UUIDShouldNotMatch()
345 {
346 UUID uuid1 = UUID.Random();
347 UUID uuid2 = UUID.Random();
348
349 var constraint = Constraints.PropertyCompareConstraint(uuid1);
350
351 Assert.That(constraint.Matches(uuid2), Is.False);
352 }
353
354 [Test]
288 public void TestColors() 355 public void TestColors()
289 { 356 {
290 Color actual = Color.Red; 357 Color actual = Color.Red;
@@ -294,5 +361,53 @@ namespace OpenSim.Data.Tests
294 361
295 Assert.That(constraint.Matches(actual), Is.True); 362 Assert.That(constraint.Matches(actual), Is.True);
296 } 363 }
364
365 [Test]
366 public void ShouldCompareLists()
367 {
368 List<int> expected = new List<int> { 1, 2, 3 };
369 List<int> actual = new List<int> { 1, 2, 3 };
370
371 var constraint = Constraints.PropertyCompareConstraint(expected);
372 Assert.That(constraint.Matches(actual), Is.True);
373 }
374
375
376 [Test]
377 public void ShouldFailToCompareListsThatAreDifferent()
378 {
379 List<int> expected = new List<int> { 1, 2, 3 };
380 List<int> actual = new List<int> { 1, 2, 4 };
381
382 var constraint = Constraints.PropertyCompareConstraint(expected);
383 Assert.That(constraint.Matches(actual), Is.False);
384 }
385
386 [Test]
387 public void ShouldFailToCompareListsThatAreDifferentLengths()
388 {
389 List<int> expected = new List<int> { 1, 2, 3 };
390 List<int> actual = new List<int> { 1, 2 };
391
392 var constraint = Constraints.PropertyCompareConstraint(expected);
393 Assert.That(constraint.Matches(actual), Is.False);
394 }
395
396 public class Recursive
397 {
398 public Recursive Other { get; set; }
399 }
400
401 [Test]
402 public void ErrorsOutOnRecursive()
403 {
404 Recursive parent = new Recursive();
405 Recursive child = new Recursive();
406 parent.Other = child;
407 child.Other = parent;
408
409 var constraint = Constraints.PropertyCompareConstraint(child);
410 Assert.That(constraint.Matches(child), Is.False);
411 }
297 } 412 }
298} \ No newline at end of file 413} \ No newline at end of file