context: // ConstraintCollection.cs - NUnit Test Cases for testing the ConstraintCollection 
  //	class.
  //	
  // Authors:
  //   Franklin Wise (gracenote@earthlink.net)
  //   Martin Willemoes Hansen (mwh@sysrq.dk)
  //   Roopa Wilson (rowilson@novell.com)	
  //
  // (C) Franklin Wise
  // (C) 2003 Martin Willemoes Hansen
  
  //
  // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
  //
  // Permission is hereby granted, free of charge, to any person obtaining
  // a copy of this software and associated documentation files (the
  // "Software"), to deal in the Software without restriction, including
  // without limitation the rights to use, copy, modify, merge, publish,
  // distribute, sublicense, and/or sell copies of the Software, and to
  // permit persons to whom the Software is furnished to do so, subject to
  // the following conditions:
  // 
  // The above copyright notice and this permission notice shall be
  // included in all copies or substantial portions of the Software.
  // 
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  //
  using NUnit.Framework;
  using System;
  using System.Data;
  #if !MOBILE
  using NUnit.Framework.SyntaxHelpers;
  #endif
  
  namespace MonoTests.System.Data
  {
  	[TestFixture]
  	public class ConstraintCollectionTest
  	{
  		private DataTable _table;
  		private DataTable _table2;
  		private Constraint _constraint1;
  		private Constraint _constraint2;
  
  		[SetUp]
  		public void GetReady ()
  		{
  			//Setup DataTable
  			_table = new DataTable ("TestTable");
  			_table.Columns.Add ("Col1", typeof(int));
  			_table.Columns.Add ("Col2", typeof(int));
  			_table.Columns.Add ("Col3", typeof(int));
  
  			_table2 = new DataTable ("TestTable");
  			_table2.Columns.Add ("Col1", typeof(int));
  			_table2.Columns.Add ("Col2", typeof(int));
  
  			//Use UniqueConstraint to test Constraint Base Class
  			_constraint1 = new UniqueConstraint (_table.Columns [0], false); 
  			_constraint2 = new UniqueConstraint (_table.Columns [1], false); 
  
  			// not sure why this is needed since a new _table was just created
  			// for us, but this Clear() keeps the tests from throwing
  			// an exception when the Add() is called.
  			_table.Constraints.Clear ();
  		}
  
  		[Test]
  		public void Add ()
  		{
  			ConstraintCollection col = _table.Constraints;
  			col.Add (_constraint1);
  			col.Add (_constraint2);
  
  			Assert.That (col.Count, Is.EqualTo (2), "Count doesn't equal added.");
  		}
  
  		[Test]
  		public void AddExceptions ()
  		{
  			ConstraintCollection col = _table.Constraints;
  			
  			//null
  			try {
  				col.Add (null);
  				Assert.Fail ("B1: Failed to throw ArgumentNullException.");
  			} catch (ArgumentNullException) {
  			} catch (AssertionException exc) {
  				throw exc;
  			} catch {
  				Assert.Fail ("A1: Wrong exception type");
  			}
  
  			//duplicate name
  			try {
  				_constraint1.ConstraintName = "Dog";
  				_constraint2.ConstraintName = "dog"; //case insensitive
  				col.Add (_constraint1);
  				col.Add (_constraint2);
  				col.Remove (_constraint2); // only for !1.0
  				col.Remove (_constraint1);
  			}
  			catch (AssertionException exc) {
  				throw exc;
  			}
  /* Don't use such catch. They cover our eyes from the exact exception location.
  			catch (Exception exc)
  			{
  				Assert.Fail("A2: Wrong exception type. " + exc.ToString());
  			}
  */
  			//Constraint Already exists
  			try {
  				col.Add (_constraint1);
  				col.Remove (_constraint1);
  			} catch (ArgumentException) {
  			} catch (AssertionException exc) {
  				throw exc;
  			} catch {
  				Assert.Fail ("A3: Wrong exception type");
  			}
  		}
  
  		[Test]
  		public void Indexer ()
  		{
  			Constraint c1 = new UniqueConstraint (_table.Columns [0]);
  			Constraint c2 = new UniqueConstraint (_table.Columns [1]);
  
  			c1.ConstraintName = "first";
  			c2.ConstraintName = "second";
  
  
  			_table.Constraints.Add (c1);
  			_table.Constraints.Add (c2);
  
  			Assert.AreSame (c1, _table.Constraints [0], "A1"); 
  			Assert.AreSame (c2, _table.Constraints [1], "A2");
  
  			Assert.AreSame (c1, _table.Constraints ["first"], "A3");
  			Assert.AreSame (c2, _table.Constraints ["sEcond"], "A4"); //case insensitive
  
  		}
  
  		[Test]
  		public void IndexOf ()
  		{
  			Constraint c1 = new UniqueConstraint (_table.Columns [0]);
  			Constraint c2 = new UniqueConstraint (_table.Columns [1]);
  
  			c1.ConstraintName = "first";
  			c2.ConstraintName = "second";
  
  			_table.Constraints.Add (c1);
  			_table.Constraints.Add (c2);
  
  			Assert.AreEqual (0, _table.Constraints.IndexOf (c1), "A1");
  			Assert.AreEqual (1, _table.Constraints.IndexOf (c2), "A2");
  			Assert.AreEqual (0, _table.Constraints.IndexOf ("first"), "A3");
  			Assert.AreEqual (1, _table.Constraints.IndexOf ("second"), "A4");
  		}
  
  		[Test]
  		public void Contains ()
  		{
  			Constraint c1 = new UniqueConstraint (_table.Columns [0]);
  			Constraint c2 = new UniqueConstraint (_table.Columns [1]);
  
  			c1.ConstraintName = "first";
  			c2.ConstraintName = "second";
  
  			_table.Constraints.Add (c1);
  
  			Assert.That (_table.Constraints.Contains (c1.ConstraintName), Is.True);
  			Assert.That (_table.Constraints.Contains (c2.ConstraintName), Is.False);
  		}
  
  		[Test]
  		public void IndexerFailures ()
  		{
  			_table.Constraints.Add (new UniqueConstraint (_table.Columns [0]));
  
  			//This doesn't throw
  			Assert.That (_table.Constraints ["notInCollection"], Is.Null);
  			
  			//Index too high
  			try {
  				Constraint c = _table.Constraints [_table.Constraints.Count];
  				Assert.Fail ("B1: Failed to throw IndexOutOfRangeException.");
  			} catch (IndexOutOfRangeException) {
  			} catch (AssertionException exc) {
  				throw exc;
  			} catch {
  				Assert.Fail ("A1: Wrong exception type");
  			}
  
  			//Index too low
  			try {
  				Constraint c = _table.Constraints [-1];
  				Assert.Fail ("B2: Failed to throw IndexOutOfRangeException.");
  			} catch (IndexOutOfRangeException) {
  			} catch (AssertionException exc) {
  				throw exc;
  			} catch {
  				Assert.Fail ("A2: Wrong exception type");
  			}	
  		}
  
  		[Test]
  		public void AddFkException1 ()
  		{
  			DataSet ds = new DataSet ();
  			ds.Tables.Add (_table);
  			_table2.TableName = "TestTable2";
  			ds.Tables.Add (_table2);
  
  			_table.Rows.Add (new object [] {1});
  			_table.Rows.Add (new object [] {1});
  
  			//FKC: can't create unique constraint because duplicate values already exist
  			try {
  				ForeignKeyConstraint fkc = new ForeignKeyConstraint (_table.Columns [0],
  											_table2.Columns [0]);
  				
  				_table2.Constraints.Add (fkc);	//should throw			
  				Assert.Fail ("B1: Failed to throw ArgumentException.");
  			} catch (ArgumentException) {
  			} catch (AssertionException exc) {
  				throw exc;
  			} catch (Exception exc) {
  				Assert.Fail ("A1: Wrong Exception type. " + exc.ToString ());
  			}
  		}
  
  		[Test]
  		public void AddFkException2 ()
  		{
  			//Foreign key rules only work when the tables
  			//are apart of the dataset
  			DataSet ds = new DataSet ();
  			ds.Tables.Add (_table);
  			_table2.TableName = "TestTable2";
  			ds.Tables.Add (_table2);
  
  			_table.Rows.Add (new object [] {1});
  			
  			// will need a matching parent value in 
  			// _table
  			_table2.Rows.Add (new object [] {3}); 
  								
  
  			//FKC: no matching parent value
  			try {
  				ForeignKeyConstraint fkc = new ForeignKeyConstraint (_table.Columns [0],
  					_table2.Columns [0]);
  				
  				_table2.Constraints.Add (fkc);	//should throw			
  				Assert.Fail ("B1: Failed to throw ArgumentException.");
  			} catch (ArgumentException) {
  			} catch (AssertionException exc) {
  				throw exc;
  			} catch (Exception exc) {
  				Assert.Fail ("A1: Wrong Exception type. " + exc.ToString ());
  			}
  		}
  
  		[Test]
  		public void AddUniqueExceptions ()
  		{
  			
  
  			//UC: can't create unique constraint because duplicate values already exist
  			try {
  
gt: 				_table.Rows.Add (new object [] {1});