1 // ***********************************************************************
2 // Copyright (c) 2009 Charlie Poole
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 // ***********************************************************************
25 #define NUNIT_FRAMEWORK
30 using System.Collections;
31 using System.Collections.Generic;
32 using System.Reflection;
33 using NUnit.Compatibility;
35 namespace NUnit.Framework.Constraints
38 /// ComparisonAdapter class centralizes all comparisons of
39 /// _values in NUnit, adapting to the use of any provided
40 /// <see cref="IComparer"/>, <see cref="IComparer{T}"/>
41 /// or <see cref="Comparison{T}"/>.
43 public abstract class ComparisonAdapter
46 /// Gets the default ComparisonAdapter, which wraps an
47 /// NUnitComparer object.
49 public static ComparisonAdapter Default
51 get { return new DefaultComparisonAdapter(); }
55 /// Returns a ComparisonAdapter that wraps an <see cref="IComparer"/>
57 public static ComparisonAdapter For(IComparer comparer)
59 return new ComparerAdapter(comparer);
63 /// Returns a ComparisonAdapter that wraps an <see cref="IComparer{T}"/>
65 public static ComparisonAdapter For<T>(IComparer<T> comparer)
67 return new ComparerAdapter<T>(comparer);
71 /// Returns a ComparisonAdapter that wraps a <see cref="Comparison{T}"/>
73 public static ComparisonAdapter For<T>(Comparison<T> comparer)
75 return new ComparisonAdapterForComparison<T>(comparer);
79 /// Compares two objects
81 public abstract int Compare(object expected, object actual);
83 class DefaultComparisonAdapter : ComparerAdapter
86 /// Construct a default ComparisonAdapter
88 public DefaultComparisonAdapter() : base( NUnitComparer.Default ) { }
91 class ComparerAdapter : ComparisonAdapter
93 private readonly IComparer comparer;
96 /// Construct a ComparisonAdapter for an <see cref="IComparer"/>
98 public ComparerAdapter(IComparer comparer)
100 this.comparer = comparer;
104 /// Compares two objects
106 /// <param name="expected"></param>
107 /// <param name="actual"></param>
108 /// <returns></returns>
109 public override int Compare(object expected, object actual)
111 return comparer.Compare(expected, actual);
116 /// ComparerAdapter extends <see cref="ComparisonAdapter"/> and
117 /// allows use of an <see cref="IComparer{T}"/> or <see cref="Comparison{T}"/>
118 /// to actually perform the comparison.
120 class ComparerAdapter<T> : ComparisonAdapter
122 private readonly IComparer<T> comparer;
125 /// Construct a ComparisonAdapter for an <see cref="IComparer{T}"/>
127 public ComparerAdapter(IComparer<T> comparer)
129 this.comparer = comparer;
133 /// Compare a Type T to an object
135 public override int Compare(object expected, object actual)
137 if (!typeof(T).GetTypeInfo().IsAssignableFrom(expected.GetType().GetTypeInfo()))
138 throw new ArgumentException("Cannot compare " + expected.ToString());
140 if (!typeof(T).GetTypeInfo().IsAssignableFrom(actual.GetType().GetTypeInfo()))
141 throw new ArgumentException("Cannot compare to " + actual.ToString());
143 return comparer.Compare((T)expected, (T)actual);
147 class ComparisonAdapterForComparison<T> : ComparisonAdapter
149 private readonly Comparison<T> comparison;
152 /// Construct a ComparisonAdapter for a <see cref="Comparison{T}"/>
154 public ComparisonAdapterForComparison(Comparison<T> comparer)
156 this.comparison = comparer;
160 /// Compare a Type T to an object
162 public override int Compare(object expected, object actual)
164 if (!typeof(T).GetTypeInfo().IsAssignableFrom(expected.GetType().GetTypeInfo()))
165 throw new ArgumentException("Cannot compare " + expected.ToString());
167 if (!typeof(T).GetTypeInfo().IsAssignableFrom(actual.GetType().GetTypeInfo()))
168 throw new ArgumentException("Cannot compare to " + actual.ToString());
170 return comparison.Invoke((T)expected, (T)actual);