5 // Chris Bacon (chrisbacon76@gmail.com)
7 // Copyright (C) 2010 Chris Bacon
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 #define CONTRACTS_FULL
32 using System.Collections.Generic;
35 using NUnit.Framework;
36 using System.Diagnostics.Contracts;
37 using System.Linq.Expressions;
39 namespace MonoTests.Mono.CodeContracts {
42 public class TestCCRewrite {
44 private RewriteAndLoad ral = null;
47 public void FixtureSetup ()
49 this.ral = new RewriteAndLoad ();
54 public void FixtureTearDown ()
56 if (this.ral != null) {
63 private static void TestEqualsByte (byte value)
65 Contract.Requires (value == 0);
68 private static void TestEqualsSByte (sbyte value)
70 Contract.Requires (value == 0);
73 private static void TestEqualsUShort (ushort value)
75 Contract.Requires (value == 0);
78 private static void TestEqualsShort (short value)
80 Contract.Requires (value == 0);
83 private static void TestEqualsUInt (uint value)
85 Contract.Requires (value == 0);
88 private static void TestEqualsInt (int value)
90 Contract.Requires (value == 0);
93 private static void TestEqualsULong (ulong value)
95 Contract.Requires (value == 0);
98 private static void TestEqualsLong (long value)
100 Contract.Requires (value == 0);
103 private static void TestEqualsFloat (float value)
105 Contract.Requires (value == 0);
108 private static void TestEqualsDouble (double value)
110 Contract.Requires (value == 0);
115 private static void TestNotEqualsByte (byte value)
117 Contract.Requires (value != 0);
120 private static void TestNotEqualsSByte (sbyte value)
122 Contract.Requires (value != 0);
125 private static void TestNotEqualsUShort (ushort value)
127 Contract.Requires (value != 0);
130 private static void TestNotEqualsShort (short value)
132 Contract.Requires (value != 0);
135 private static void TestNotEqualsUInt (uint value)
137 Contract.Requires (value != 0);
140 private static void TestNotEqualsInt (int value)
142 Contract.Requires (value != 0);
145 private static void TestNotEqualsULong (ulong value)
147 Contract.Requires (value != 0);
150 private static void TestNotEqualsLong (long value)
152 Contract.Requires (value != 0);
155 private static void TestNotEqualsFloat (float value)
157 Contract.Requires (value != 0);
160 private static void TestNotEqualsDouble (double value)
162 Contract.Requires (value != 0);
167 private static void TestLessThanInt (int value)
169 Contract.Requires (value < 10);
172 private static void TestLessThanUInt (uint value)
174 Contract.Requires (value < 10);
177 private static void TestLessThanLong (long value)
179 Contract.Requires (value < 10);
182 private static void TestLessThanULong (ulong value)
184 Contract.Requires (value < 10);
187 private static void TestLessThanFloat (float value)
189 Contract.Requires (value < 10);
192 private static void TestLessThanDouble (double value)
194 Contract.Requires (value < 10);
199 private static void TestLessThanOrEqualInt (int value)
201 Contract.Requires (value <= 10);
204 private static void TestLessThanOrEqualUInt (uint value)
206 Contract.Requires (value <= 10);
209 private static void TestLessThanOrEqualLong (long value)
211 Contract.Requires (value <= 10);
214 private static void TestLessThanOrEqualULong (ulong value)
216 Contract.Requires (value <= 10);
219 private static void TestLessThanOrEqualFloat (float value)
221 Contract.Requires (value <= 10);
224 private static void TestLessThanOrEqualDouble (double value)
226 Contract.Requires (value <= 10);
231 private static void TestGreaterThanInt (int value)
233 Contract.Requires (value > 10);
236 private static void TestGreaterThanUInt (uint value)
238 Contract.Requires (value > 10);
241 private static void TestGreaterThanLong (long value)
243 Contract.Requires (value > 10);
246 private static void TestGreaterThanULong (ulong value)
248 Contract.Requires (value > 10);
251 private static void TestGreaterThanFloat (float value)
253 Contract.Requires (value > 10);
256 private static void TestGreaterThanDouble (double value)
258 Contract.Requires (value > 10);
263 private static void TestGreaterThanOrEqualInt (int value)
265 Contract.Requires (value >= 10);
268 private static void TestGreaterThanOrEqualUInt (uint value)
270 Contract.Requires (value >= 10);
273 private static void TestGreaterThanOrEqualLong (long value)
275 Contract.Requires (value >= 10);
278 private static void TestGreaterThanOrEqualULong (ulong value)
280 Contract.Requires (value >= 10);
283 private static void TestGreaterThanOrEqualFloat (float value)
285 Contract.Requires (value >= 10);
288 private static void TestGreaterThanOrEqualDouble (double value)
290 Contract.Requires (value >= 10);
295 private static void TestObjectEquals (object value)
297 Contract.Requires (value == null);
302 private static void TestObjectNotEquals (object value)
304 Contract.Requires (value != null);
309 private void CheckException (Expression<Action> fnExpr, params string [] messageContains)
312 this.ral.Call (fnExpr);
313 } catch (Exception e) {
314 string m = e.Message.Split ('\n', '\r') [0].Trim ();
315 foreach (var contains in messageContains) {
316 StringAssert.Contains (contains, m);
320 Assert.Fail ("Contract should have thrown an exception");
323 private void CheckTwice (Expression<Action> fnGood, Expression<Action> fnBad, string condition)
325 const string PreFail = "Precondition failed";
326 this.ral.Call (fnGood);
327 this.CheckException (fnBad, PreFail, condition);
331 public void TestTrivial_Equals ()
333 const string CondEquals = "value == 0";
335 this.CheckTwice (() => TestEqualsByte (0), () => TestEqualsByte (1), CondEquals);
336 this.CheckTwice (() => TestEqualsSByte (0), () => TestEqualsSByte (1), CondEquals);
337 this.CheckTwice (() => TestEqualsUShort (0), () => TestEqualsUShort (1), CondEquals);
338 this.CheckTwice (() => TestEqualsShort (0), () => TestEqualsShort (1), CondEquals);
339 this.CheckTwice (() => TestEqualsUInt (0), () => TestEqualsUInt (1), CondEquals);
340 this.CheckTwice (() => TestEqualsInt (0), () => TestEqualsInt (1), CondEquals);
341 this.CheckTwice (() => TestEqualsULong (0), () => TestEqualsULong (1), CondEquals);
342 this.CheckTwice (() => TestEqualsLong (0), () => TestEqualsLong (1), CondEquals);
343 this.CheckTwice (() => TestEqualsDouble (0), () => TestEqualsDouble (1), CondEquals);
344 this.CheckTwice (() => TestEqualsFloat (0), () => TestEqualsFloat (1), CondEquals);
348 public void TestTrivial_NotEquals()
350 const string CondNotEquals = "value != 0";
352 this.CheckTwice (() => TestNotEqualsByte (1), () => TestNotEqualsByte (0), CondNotEquals);
353 this.CheckTwice (() => TestNotEqualsSByte (1), () => TestNotEqualsSByte (0), CondNotEquals);
354 this.CheckTwice (() => TestNotEqualsUShort (1), () => TestNotEqualsUShort (0), CondNotEquals);
355 this.CheckTwice (() => TestNotEqualsShort (1), () => TestNotEqualsShort (0), CondNotEquals);
356 this.CheckTwice (() => TestNotEqualsUInt (1), () => TestNotEqualsUInt (0), CondNotEquals);
357 this.CheckTwice (() => TestNotEqualsInt (1), () => TestNotEqualsInt (0), CondNotEquals);
358 this.CheckTwice (() => TestNotEqualsULong (1), () => TestNotEqualsULong (0), CondNotEquals);
359 this.CheckTwice (() => TestNotEqualsLong (1), () => TestNotEqualsLong (0), CondNotEquals);
360 this.CheckTwice (() => TestNotEqualsDouble (1), () => TestNotEqualsDouble (0), CondNotEquals);
361 this.CheckTwice (() => TestNotEqualsFloat (1), () => TestNotEqualsFloat (0), CondNotEquals);
365 public void TestTrivial_LessThan()
367 const string CondLessThan = "value < 10";
369 this.CheckTwice (() => TestLessThanInt (9), () => TestLessThanInt (10), CondLessThan);
370 this.CheckTwice (() => TestLessThanUInt (9), () => TestLessThanUInt (10), CondLessThan);
371 this.CheckTwice (() => TestLessThanLong (9), () => TestLessThanLong (10), CondLessThan);
372 this.CheckTwice (() => TestLessThanULong (9), () => TestLessThanULong (10), CondLessThan);
373 this.CheckTwice (() => TestLessThanFloat (9.9f), () => TestLessThanFloat (10), CondLessThan);
374 this.CheckTwice (() => TestLessThanDouble (9.9), () => TestLessThanDouble (10), CondLessThan);
378 public void TestTrivial_LessThanOrEqual()
380 const string CondLessThanOrEqual = "value <= 10";
382 this.CheckTwice (() => TestLessThanOrEqualInt (10), () => TestLessThanOrEqualInt (11), CondLessThanOrEqual);
383 this.CheckTwice (() => TestLessThanOrEqualUInt (10), () => TestLessThanOrEqualUInt (11), CondLessThanOrEqual);
384 this.CheckTwice (() => TestLessThanOrEqualLong (10), () => TestLessThanOrEqualLong (11), CondLessThanOrEqual);
385 this.CheckTwice (() => TestLessThanOrEqualULong (10), () => TestLessThanOrEqualULong (11), CondLessThanOrEqual);
386 this.CheckTwice (() => TestLessThanOrEqualFloat (10.0f), () => TestLessThanOrEqualFloat (10.1f), CondLessThanOrEqual);
387 this.CheckTwice (() => TestLessThanOrEqualDouble (10.0), () => TestLessThanOrEqualDouble (10.1), CondLessThanOrEqual);
391 public void TestTrivial_GreaterThan()
393 const string CondGreaterThan = "value > 10";
395 this.CheckTwice (() => TestGreaterThanInt (11), () => TestGreaterThanInt (10), CondGreaterThan);
396 this.CheckTwice (() => TestGreaterThanUInt (11), () => TestGreaterThanUInt (10), CondGreaterThan);
397 this.CheckTwice (() => TestGreaterThanLong (11), () => TestGreaterThanLong (10), CondGreaterThan);
398 this.CheckTwice (() => TestGreaterThanULong (11), () => TestGreaterThanULong (10), CondGreaterThan);
399 this.CheckTwice (() => TestGreaterThanFloat (10.1f), () => TestGreaterThanFloat (10), CondGreaterThan);
400 this.CheckTwice (() => TestGreaterThanDouble (10.1), () => TestGreaterThanDouble (10), CondGreaterThan);
404 public void TestTrivial_GreaterThanOrEqual()
406 const string CondGreaterThanOrEqual = "value >= 10";
408 this.CheckTwice (() => TestGreaterThanOrEqualInt (10), () => TestGreaterThanOrEqualInt (9), CondGreaterThanOrEqual);
409 this.CheckTwice (() => TestGreaterThanOrEqualUInt (10), () => TestGreaterThanOrEqualUInt (9), CondGreaterThanOrEqual);
410 this.CheckTwice (() => TestGreaterThanOrEqualLong (10), () => TestGreaterThanOrEqualLong (9), CondGreaterThanOrEqual);
411 this.CheckTwice (() => TestGreaterThanOrEqualULong (10), () => TestGreaterThanOrEqualULong (9), CondGreaterThanOrEqual);
412 this.CheckTwice (() => TestGreaterThanOrEqualFloat (10.0f), () => TestGreaterThanOrEqualFloat (9.9f), CondGreaterThanOrEqual);
413 this.CheckTwice (() => TestGreaterThanOrEqualDouble (10.0), () => TestGreaterThanOrEqualDouble (9.9), CondGreaterThanOrEqual);
417 public void TestTrivial_ObjectEquality()
419 object o = new object ();
420 this.CheckTwice (() => TestObjectEquals (null), () => TestObjectEquals (o), "value == null");
421 this.CheckTwice (() => TestObjectNotEquals (o), () => TestObjectNotEquals (null), "value != null");