[NUI] Rebase develnui (DevelNUI only patches --> master) (#3910)
[platform/core/csapi/tizenfx.git] / test / Tizen.NUI.Devel.Tests.Ubuntu / nunit.framework / Constraints / EqualityAdapter.cs
1 // ***********************************************************************
2 // Copyright (c) 2009 Charlie Poole
3 //
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:
11 // 
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 // 
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 // ***********************************************************************
23 #define PORTABLE
24 #define TIZEN
25 #define NUNIT_FRAMEWORK
26 #define NUNITLITE
27 #define NET_4_5
28 #define PARALLEL
29 using System;
30 using System.Collections;
31 using System.Collections.Generic;
32 using NUnit.Compatibility;
33 using System.Reflection;
34
35 namespace NUnit.Framework.Constraints
36 {
37
38     /// <summary>
39     /// EqualityAdapter class handles all equality comparisons
40     /// that use an <see cref="IEqualityComparer"/>, <see cref="IEqualityComparer{T}"/>
41     /// or a <see cref="ComparisonAdapter"/>.
42     /// </summary>
43     public abstract class EqualityAdapter
44     {
45         /// <summary>
46         /// Compares two objects, returning true if they are equal
47         /// </summary>
48         public abstract bool AreEqual(object x, object y);
49
50         /// <summary>
51         /// Returns true if the two objects can be compared by this adapter.
52         /// The base adapter cannot handle IEnumerables except for strings.
53         /// </summary>
54         public virtual bool CanCompare(object x, object y)
55         {
56             if (x is string && y is string)
57                 return true;
58
59             if (x is IEnumerable || y is IEnumerable)
60                 return false;
61
62             return true;
63         }
64
65         #region Nested IComparer Adapter
66
67         /// <summary>
68         /// Returns an <see cref="EqualityAdapter"/> that wraps an <see cref="IComparer"/>.
69         /// </summary>
70         public static EqualityAdapter For(IComparer comparer)
71         {
72             return new ComparerAdapter(comparer);
73         }
74
75         /// <summary>
76         /// <see cref="EqualityAdapter"/> that wraps an <see cref="IComparer"/>.
77         /// </summary>
78         class ComparerAdapter : EqualityAdapter
79         {
80             private IComparer comparer;
81
82             public ComparerAdapter(IComparer comparer)
83             {
84                 this.comparer = comparer;
85             }
86
87             public override bool AreEqual(object x, object y)
88             {
89                 return comparer.Compare(x, y) == 0;
90             }
91         }
92
93         #endregion
94
95         #region Nested IEqualityComparer Adapter
96
97         /// <summary>
98         /// Returns an <see cref="EqualityAdapter"/> that wraps an <see cref="IEqualityComparer"/>.
99         /// </summary>
100         public static EqualityAdapter For(IEqualityComparer comparer)
101         {
102             return new EqualityComparerAdapter(comparer);
103         }
104
105         class EqualityComparerAdapter : EqualityAdapter
106         {
107             private IEqualityComparer comparer;
108
109             public EqualityComparerAdapter(IEqualityComparer comparer)
110             {
111                 this.comparer = comparer;
112             }
113
114             public override bool AreEqual(object x, object y)
115             {
116                 return comparer.Equals(x, y);
117             }
118         }
119
120         /// <summary>
121         /// Returns an EqualityAdapter that uses a predicate function for items comparison.
122         /// </summary>
123         /// <typeparam name="TExpected"></typeparam>
124         /// <typeparam name="TActual"></typeparam>
125         /// <param name="comparison"></param>
126         /// <returns></returns>
127         public static EqualityAdapter For<TExpected, TActual>(Func<TExpected, TActual, bool> comparison)
128         {
129             return new PredicateEqualityAdapter<TExpected, TActual>(comparison);
130         }
131
132         internal class PredicateEqualityAdapter<TActual, TExpected> : EqualityAdapter
133         {
134             private readonly Func<TActual, TExpected, bool> _comparison;
135
136             /// <summary>
137             /// Returns true if the two objects can be compared by this adapter.
138             /// The base adapter cannot handle IEnumerables except for strings.
139             /// </summary>
140             public override bool CanCompare(object x, object y)
141             {
142                 return true;
143             }
144
145             /// <summary>
146             /// Compares two objects, returning true if they are equal
147             /// </summary>
148             public override bool AreEqual(object x, object y)
149             {
150                 return _comparison.Invoke((TActual)y, (TExpected)x);
151             }
152
153             public PredicateEqualityAdapter(Func<TActual, TExpected, bool> comparison)
154             {
155                 _comparison = comparison;
156             }
157         }
158
159         #endregion
160
161         #region Nested GenericEqualityAdapter<T>
162
163         abstract class GenericEqualityAdapter<T> : EqualityAdapter
164         {
165             /// <summary>
166             /// Returns true if the two objects can be compared by this adapter.
167             /// Generic adapter requires objects of the specified type.
168             /// </summary>
169             public override bool CanCompare(object x, object y)
170             {
171                 return typeof(T).GetTypeInfo().IsAssignableFrom(x.GetType().GetTypeInfo())
172                     && typeof(T).GetTypeInfo().IsAssignableFrom(y.GetType().GetTypeInfo());
173             }
174
175             protected void ThrowIfNotCompatible(object x, object y)
176             {
177                 if (!typeof(T).GetTypeInfo().IsAssignableFrom(x.GetType().GetTypeInfo()))
178                     throw new ArgumentException("Cannot compare " + x.ToString());
179
180                 if (!typeof(T).GetTypeInfo().IsAssignableFrom(y.GetType().GetTypeInfo()))
181                     throw new ArgumentException("Cannot compare " + y.ToString());
182             }
183         }
184
185         #endregion
186
187         #region Nested IEqualityComparer<T> Adapter
188
189         /// <summary>
190         /// Returns an <see cref="EqualityAdapter"/> that wraps an <see cref="IEqualityComparer{T}"/>.
191         /// </summary>
192         public static EqualityAdapter For<T>(IEqualityComparer<T> comparer)
193         {
194             return new EqualityComparerAdapter<T>(comparer);
195         }
196
197         class EqualityComparerAdapter<T> : GenericEqualityAdapter<T>
198         {
199             private IEqualityComparer<T> comparer;
200
201             public EqualityComparerAdapter(IEqualityComparer<T> comparer)
202             {
203                 this.comparer = comparer;
204             }
205
206             public override bool AreEqual(object x, object y)
207             {
208                 ThrowIfNotCompatible(x, y);
209                 return comparer.Equals((T)x, (T)y);
210             }
211         }
212
213         #endregion
214
215         #region Nested IComparer<T> Adapter
216
217         /// <summary>
218         /// Returns an <see cref="EqualityAdapter"/> that wraps an <see cref="IComparer{T}"/>.
219         /// </summary>
220         public static EqualityAdapter For<T>(IComparer<T> comparer)
221         {
222             return new ComparerAdapter<T>(comparer);
223         }
224
225         /// <summary>
226         /// <see cref="EqualityAdapter"/> that wraps an <see cref="IComparer"/>.
227         /// </summary>
228         class ComparerAdapter<T> : GenericEqualityAdapter<T>
229         {
230             private IComparer<T> comparer;
231
232             public ComparerAdapter(IComparer<T> comparer)
233             {
234                 this.comparer = comparer;
235             }
236
237             public override bool AreEqual(object x, object y)
238             {
239                 ThrowIfNotCompatible(x, y);
240                 return comparer.Compare((T)x, (T)y) == 0;
241             }
242         }
243
244         #endregion
245
246         #region Nested Comparison<T> Adapter
247
248         /// <summary>
249         /// Returns an <see cref="EqualityAdapter"/> that wraps a <see cref="Comparison{T}"/>.
250         /// </summary>
251         public static EqualityAdapter For<T>(Comparison<T> comparer)
252         {
253             return new ComparisonAdapter<T>(comparer);
254         }
255
256         class ComparisonAdapter<T> : GenericEqualityAdapter<T>
257         {
258             private Comparison<T> comparer;
259
260             public ComparisonAdapter(Comparison<T> comparer)
261             {
262                 this.comparer = comparer;
263             }
264
265             public override bool AreEqual(object x, object y)
266             {
267                 ThrowIfNotCompatible(x, y);
268                 return comparer.Invoke((T)x, (T)y) == 0;
269             }
270         }
271
272 #endregion
273     }
274 }