From 424c67c8bb23671e97befb4c685773d95425ae53 Mon Sep 17 00:00:00 2001 From: Rodrigo Moya Date: Tue, 13 Aug 2002 15:42:01 +0000 Subject: [PATCH] 2002-08-12 Franklin Wise * System.Data/Constraint.cs: Implemented * System.Data/UniqueConstraint.cs: GetHashCode() & special case Ctor. Still need to be implemented. LAMESPEC tags added. * System.Data/ConstraintCollection.cs: Clear() & AddRange() need to be finished. Several LAMESPEC tags. * Allow Constraint collection to be created in DataTable. * System.Data/ForeignKeyConstraint: Added a couple of helper functions. * System.Data/DataColumnCollection New/Added DataColumns now have Table property set. svn path=/trunk/mcs/; revision=6611 --- mcs/class/System.Data/ChangeLog | 19 ++ .../System.Data/System.Data/Constraint.cs | 72 +++-- .../System.Data/ConstraintCollection.cs | 294 ++++++++++++++---- .../System.Data/System.Data/DataColumn.cs | 11 +- .../System.Data/DataColumnCollection.cs | 7 + .../System.Data/System.Data/DataTable.cs | 2 +- .../System.Data/ForeignKeyConstraint.cs | 2 + .../System.Data/UniqueConstraint.cs | 25 +- mcs/class/System.Data/Test/ChangeLog | 12 + .../System.Data/Test/System.Data/AllTests.cs | 3 + .../System.Data/ConstraintCollectionTest.cs | 111 +++++++ .../Test/System.Data/ConstraintTest.cs | 132 ++++++++ .../Test/System.Data/DataColumnTest.cs | 2 + .../Test/System.Data/UniqueConstraintTest.cs | 171 ++++++++++ 14 files changed, 776 insertions(+), 87 deletions(-) create mode 100644 mcs/class/System.Data/Test/System.Data/ConstraintCollectionTest.cs create mode 100644 mcs/class/System.Data/Test/System.Data/ConstraintTest.cs create mode 100644 mcs/class/System.Data/Test/System.Data/UniqueConstraintTest.cs diff --git a/mcs/class/System.Data/ChangeLog b/mcs/class/System.Data/ChangeLog index a36a3f37afa..35697ba33a4 100644 --- a/mcs/class/System.Data/ChangeLog +++ b/mcs/class/System.Data/ChangeLog @@ -1,3 +1,22 @@ +2002-08-12 Franklin Wise + + * System.Data/Constraint.cs: Implemented + + * System.Data/UniqueConstraint.cs: GetHashCode() & + special case Ctor. Still need to be implemented. LAMESPEC tags + added. + + * System.Data/ConstraintCollection.cs: Clear() & + AddRange() need to be finished. Several LAMESPEC tags. + + * Allow Constraint collection to be created in DataTable. + + * System.Data/ForeignKeyConstraint: Added a couple of + helper functions. + + * System.Data/DataColumnCollection New/Added DataColumns now have + Table property set. + 2002-08-11 Rodrigo Moya * System.Data.OleDb/libgda.cs: added some GdaValue functions. diff --git a/mcs/class/System.Data/System.Data/Constraint.cs b/mcs/class/System.Data/System.Data/Constraint.cs index d6ce3b24307..51229e4d6b6 100644 --- a/mcs/class/System.Data/System.Data/Constraint.cs +++ b/mcs/class/System.Data/System.Data/Constraint.cs @@ -2,7 +2,9 @@ // System.Data.Constraint.cs // // Author: -// Daniel Morgan +// Franklin Wise +// Daniel Morgan +// // // (C) Ximian, Inc. 2002 // @@ -16,32 +18,44 @@ using System.Runtime.Serialization; namespace System.Data { [Serializable] - public abstract class Constraint { + internal delegate void DelegateConstraintNameChange(object sender, + string newName); + + [Serializable] + public abstract class Constraint + { + internal event DelegateConstraintNameChange + BeforeConstraintNameChange; + + private string _name = null; + private PropertyCollection _properties = null; - protected string name = null; - protected PropertyCollection properties = null; + //Used for membership checking + private ConstraintCollection _constraintCollection; - [MonoTODO] - protected Constraint() { - properties = new PropertyCollection(); + protected Constraint() + { + _properties = new PropertyCollection(); } public virtual string ConstraintName { - [MonoTODO] get{ - return name; + return "" + _name; } - [MonoTODO] set{ - name = value; + //This should only throw an exception when it + //is a member of a ConstraintCollection which + //means we should let the ConstraintCollection + //handle exceptions when this value changes + _onConstraintNameChange(value); + _name = value; } } public PropertyCollection ExtendedProperties { - [MonoTODO] get { - return properties; + return _properties; } } @@ -49,14 +63,32 @@ namespace System.Data get; } - [MonoTODO] - public override string ToString() { - return name; + /// + /// Gets the ConstraintName, if there is one, as a string. + /// + public override string ToString() + { + return "" + _name; + } + + internal ConstraintCollection ConstraintCollection { + get{ + return _constraintCollection; + } + set{ + _constraintCollection = value; + } + } + + + + private void _onConstraintNameChange(string newName) + { + if (null != BeforeConstraintNameChange) + { + BeforeConstraintNameChange(this, newName); + } } - //[MonoTODO] - //[ClassInterface(ClassInterfaceType.AutoDual)] - //~Constraint() { - //} } } diff --git a/mcs/class/System.Data/System.Data/ConstraintCollection.cs b/mcs/class/System.Data/System.Data/ConstraintCollection.cs index 7e9385e7e6b..5b953081bc2 100644 --- a/mcs/class/System.Data/System.Data/ConstraintCollection.cs +++ b/mcs/class/System.Data/System.Data/ConstraintCollection.cs @@ -2,9 +2,11 @@ // System.Data.ConstraintCollection.cs // // Author: +// Franklin Wise // Daniel Morgan -// +// // (C) Ximian, Inc. 2002 +// (C) 2002 Franklin Wise // (C) 2002 Daniel Morgan // @@ -14,63 +16,166 @@ using System.ComponentModel; namespace System.Data { + [Serializable] + internal delegate void DelegateValidateRemoveConstraint(ConstraintCollection sender, + Constraint constraintToRemove, ref bool cancel); + /// /// hold collection of constraints for data table /// - public class ConstraintCollection : InternalDataCollectionBase { + [Serializable] + public class ConstraintCollection : InternalDataCollectionBase + { + private bool beginInit = false; + + public event CollectionChangeEventHandler CollectionChanged; + internal event DelegateValidateRemoveConstraint ValidateRemoveConstraint; + + //Don't allow public instantiation + //Will be instantianted from DataTable + internal ConstraintCollection(){} public virtual Constraint this[string name] { - [MonoTODO] get { - throw new NotImplementedException (); + int index = IndexOf(name); + if (-1 == index) return null; + return this[index]; } } public virtual Constraint this[int index] { - [MonoTODO] get { - throw new NotImplementedException (); + return (Constraint)List[index]; + } + } + + private void _handleBeforeConstraintNameChange(object sender, string newName) + { + //null or empty + if (newName == null || newName == "") + throw new ArgumentException("ConstraintName cannot be set to null or empty " + + " after it has been added to a ConstraintCollection."); + + if (_isDuplicateConstraintName(newName,(Constraint)sender)) + throw new DuplicateNameException("Constraint name already exists."); + } + + private bool _isDuplicateConstraintName(string constraintName, Constraint excludeFromComparison) + { + string cmpr = constraintName.ToUpper(); + foreach (Constraint cst in List) + { + //Case insensitive comparision + if ( cmpr.CompareTo(cst.ConstraintName.ToUpper()) == 0 && + cst != excludeFromComparison) + { + return true; + } } + + return false; } + + //finds an open name slot of ConstraintXX + //where XX is a number + private string _createNewConstraintName() + { + bool loopAgain = false; + int index = 1; + do + { + loopAgain = false; + foreach (Constraint cst in List) + { + //Case insensitive + if (cst.ConstraintName.ToUpper().CompareTo("CONSTRAINT" + + index.ToString()) == 0 ) + { + loopAgain = true; + index++; + } + } + } while (loopAgain); + + return "Constraint" + index.ToString(); + + } + + // Overloaded Add method (5 of them) // to add Constraint object to the collection - [MonoTODO] - public void Add(Constraint constraint) { + public void Add(Constraint constraint) + { + //not null + if (null == constraint) throw new ArgumentNullException("Can not add null."); - throw new NotImplementedException (); + //check constraint membership + //can't already exist in this collection or any other + if (this == constraint.ConstraintCollection) + throw new ArgumentException("Constraint already belongs to this collection."); + if (null != constraint.ConstraintCollection) + throw new ArgumentException("Constraint already belongs to another collection."); + + //check for duplicate + if (_isDuplicateConstraintName(constraint.ConstraintName,null) ) + throw new DuplicateNameException("Constraint name already exists."); + + //if name is null or empty give it a name + if (constraint.ConstraintName == null || + constraint.ConstraintName == "" ) + { + constraint.ConstraintName = _createNewConstraintName(); + } + + //Add event handler for ConstraintName change + constraint.BeforeConstraintNameChange += new DelegateConstraintNameChange( + _handleBeforeConstraintNameChange); + + constraint.ConstraintCollection = this; + List.Add(constraint); + + OnCollectionChanged( new CollectionChangeEventArgs( CollectionChangeAction.Add, this) ); } - [MonoTODO] - public virtual Constraint Add(string name, - DataColumn column, bool primaryKey) { + - throw new NotImplementedException (); + public virtual Constraint Add(string name, DataColumn column, bool primaryKey) + { + UniqueConstraint uc = new UniqueConstraint(name, column, primaryKey); + Add(uc); + + return uc; } - [MonoTODO] - public virtual Constraint Add(string name, - DataColumn primaryKeyColumn, - DataColumn foreignKeyColumn) { + public virtual Constraint Add(string name, DataColumn primaryKeyColumn, + DataColumn foreignKeyColumn) + { + ForeignKeyConstraint fc = new ForeignKeyConstraint(name, primaryKeyColumn, + foreignKeyColumn); + Add(fc); - throw new NotImplementedException (); + return fc; } - [MonoTODO] - public virtual Constraint Add(string name, - DataColumn[] columns, bool primaryKey) { + public virtual Constraint Add(string name, DataColumn[] columns, bool primaryKey) + { + UniqueConstraint uc = new UniqueConstraint(name, columns, primaryKey); + Add(uc); - throw new NotImplementedException (); + return uc; } - [MonoTODO] - public virtual Constraint Add(string name, - DataColumn[] primaryKeyColumns, - DataColumn[] foreignKeyColumns) { + public virtual Constraint Add(string name, DataColumn[] primaryKeyColumns, + DataColumn[] foreignKeyColumns) + { + ForeignKeyConstraint fc = new ForeignKeyConstraint(name, primaryKeyColumns, + foreignKeyColumns); + Add(fc); - throw new NotImplementedException (); + return fc; } [MonoTODO] @@ -79,63 +184,138 @@ namespace System.Data throw new NotImplementedException (); } - [MonoTODO] - public bool CanRemove(Constraint constraint) { + public bool CanRemove(Constraint constraint) + { - throw new NotImplementedException (); + //Rule A UniqueConstraint can't be removed if there is + //a foreign key relationship to that column + + //not null + //LAMESPEC: MSFT implementation throws and exception here + //spec says nothing about this + if (null == constraint) throw new ArgumentNullException("Constraint can't be null."); + + //if we are not a unique constraint then it's ok to remove + UniqueConstraint uc = constraint as UniqueConstraint; + if (null == uc) return true; + + //LAMESPEC: spec says return false (which makes sense) and throw exception for False case (?). + //discover if there is a related ForeignKey + return _canRemoveConstraint(constraint); + } [MonoTODO] - public void Clear() { + public void Clear() + { - throw new NotImplementedException (); + //CanRemove? See Lamespec below. + + //the Constraints have a reference to us + //and we listen to name change events + //we should remove these before clearing + foreach (Constraint con in List) + { + con.ConstraintCollection = null; + con.BeforeConstraintNameChange -= new DelegateConstraintNameChange( + _handleBeforeConstraintNameChange); + } + + //LAMESPEC: MSFT implementation allows this + //even when a ForeignKeyConstraint exist for a UniqueConstraint + //thus violating the CanRemove logic + List.Clear(); //Will violate CanRemove rule + OnCollectionChanged( new CollectionChangeEventArgs(CollectionChangeAction.Refresh, this) ); } - [MonoTODO] - public bool Contains(string name) { - throw new NotImplementedException (); + public bool Contains(string name) + { + return (-1 != IndexOf(name)); } - [MonoTODO] - public int IndexOf(Constraint constraint) { - throw new NotImplementedException (); + public int IndexOf(Constraint constraint) + { + return List.IndexOf(constraint); } - [MonoTODO] - public virtual int IndexOf(string constraintName) { - throw new NotImplementedException (); + public virtual int IndexOf(string constraintName) + { + //LAMESPEC: Spec doesn't say case insensitive + //it should to be consistant with the other + //case insensitive comparisons in this class + + int index = 0; + foreach (Constraint con in List) + { + if (constraintName.ToUpper().CompareTo( con.ConstraintName.ToUpper() ) == 0) + { + return index; + } + + index++; + } + return -1; //not found } - [MonoTODO] public void Remove(Constraint constraint) { - throw new NotImplementedException (); + //LAMESPEC: spec doesn't document the ArgumentException the + //will be thrown if the CanRemove rule is violated + + //LAMESPEC: spec says an exception will be thrown + //if the element is not in the collection. The implementation + //doesn't throw an exception. ArrayList.Remove doesn't throw if the + //element doesn't exist + //ALSO the overloaded remove in the spec doesn't say it throws any exceptions + + //not null + if (null == constraint) throw new ArgumentNullException(); + + List.Remove(constraint); + OnCollectionChanged( new CollectionChangeEventArgs(CollectionChangeAction.Remove,this)); } - [MonoTODO] - public void Remove(string name) { - throw new NotImplementedException (); + public void Remove(string name) + { + //if doesn't exist fail quietly + int index = IndexOf(name); + if (-1 == index) return; + + Remove(this[index]); } - [MonoTODO] - public void RemoveAt(int index) { - throw new NotImplementedException (); + public void RemoveAt(int index) + { + if (index < 0 || index + 1 > List.Count) + throw new IndexOutOfRangeException("Index out of range, index = " + + index.ToString() + "."); + + List.RemoveAt(index); + OnCollectionChanged( new CollectionChangeEventArgs(CollectionChangeAction.Remove,this)); } - [MonoTODO] - public event CollectionChangeEventHandler CollectionChanged; protected override ArrayList List { - [MonoTODO] get{ - throw new NotImplementedException (); + return base.List; } } - [MonoTODO] - protected virtual void OnCollectionChanged( - CollectionChangeEventArgs ccevent) { + protected virtual void OnCollectionChanged( CollectionChangeEventArgs ccevent) + { + if (null != CollectionChanged) + { + CollectionChanged(this, ccevent); + } + } - throw new NotImplementedException (); + private bool _canRemoveConstraint(Constraint constraint ) + { + bool cancel = false; + if (null != ValidateRemoveConstraint) + { + ValidateRemoveConstraint(this, constraint, ref cancel); + } + return !cancel; } } } diff --git a/mcs/class/System.Data/System.Data/DataColumn.cs b/mcs/class/System.Data/System.Data/DataColumn.cs index 91d99f31ec3..51bbda4da2b 100644 --- a/mcs/class/System.Data/System.Data/DataColumn.cs +++ b/mcs/class/System.Data/System.Data/DataColumn.cs @@ -39,7 +39,7 @@ namespace System.Data private int ordinal = -1; private string prefix = null; private bool readOnly = false; - private DataTable table = null; + private DataTable _table = null; private bool unique = false; #endregion // Fields @@ -269,11 +269,11 @@ namespace System.Data readOnly = value; } } - + public DataTable Table { get { - return table; + return _table; } } @@ -324,8 +324,9 @@ namespace System.Data [MonoTODO] internal void SetTable(DataTable table) { - this.table = table; - // FIXME: this will get called by DataTable + _table = table; + // FIXME: this will get called by DataTable + // and DataColumnCollection } #endregion // Methods diff --git a/mcs/class/System.Data/System.Data/DataColumnCollection.cs b/mcs/class/System.Data/System.Data/DataColumnCollection.cs index 616669aaec1..d33d4d364e0 100644 --- a/mcs/class/System.Data/System.Data/DataColumnCollection.cs +++ b/mcs/class/System.Data/System.Data/DataColumnCollection.cs @@ -84,6 +84,8 @@ namespace System.Data { DataColumn column = new DataColumn("Column" + defaultNameIndex.ToString()); CollectionChangeEventArgs e = new CollectionChangeEventArgs(CollectionChangeAction.Add, this); + + column.SetTable(parentTable); base.List.Add(column); OnCollectionChanged(e); defaultNameIndex++; @@ -103,6 +105,8 @@ namespace System.Data else { CollectionChangeEventArgs e = new CollectionChangeEventArgs(CollectionChangeAction.Add, this); + + column.SetTable( parentTable); base.List.Add(column); OnCollectionChanged(e); return; @@ -132,6 +136,7 @@ namespace System.Data DataColumn column = new DataColumn(columnName); CollectionChangeEventArgs e = new CollectionChangeEventArgs(CollectionChangeAction.Add, this); + column.SetTable(parentTable); base.List.Add(column); OnCollectionChanged(e); return column; @@ -160,6 +165,7 @@ namespace System.Data { DataColumn column = new DataColumn(columnName, type); CollectionChangeEventArgs e = new CollectionChangeEventArgs(CollectionChangeAction.Add, this); + column.SetTable(parentTable); base.List.Add(column); OnCollectionChanged(e); return column; @@ -189,6 +195,7 @@ namespace System.Data { DataColumn column = new DataColumn(columnName, type, expression); CollectionChangeEventArgs e = new CollectionChangeEventArgs(CollectionChangeAction.Add, this); + column.SetTable(parentTable); base.List.Add(column); OnCollectionChanged(e); return column; diff --git a/mcs/class/System.Data/System.Data/DataTable.cs b/mcs/class/System.Data/System.Data/DataTable.cs index cb26dc15966..3ca718c79a6 100644 --- a/mcs/class/System.Data/System.Data/DataTable.cs +++ b/mcs/class/System.Data/System.Data/DataTable.cs @@ -60,7 +60,7 @@ namespace System.Data dataSet = null; // _defaultView = null; // FIXME: temporarily commented _columnCollection = new DataColumnCollection(this); - //_constraintCollection = new ConstraintCollection(); TODO: uncomment after ConstraintCollection is built. + _constraintCollection = new ConstraintCollection(); _extendedProperties = null; _tableName = ""; _nameSpace = null; diff --git a/mcs/class/System.Data/System.Data/ForeignKeyConstraint.cs b/mcs/class/System.Data/System.Data/ForeignKeyConstraint.cs index 591398afa9c..756d6ef10a5 100644 --- a/mcs/class/System.Data/System.Data/ForeignKeyConstraint.cs +++ b/mcs/class/System.Data/System.Data/ForeignKeyConstraint.cs @@ -2,8 +2,10 @@ // System.Data.ForeignKeyConstraint.cs // // Author: +// Franklin Wise // Daniel Morgan // +// (C) 2002 Franklin Wise // (C) 2002 Daniel Morgan // diff --git a/mcs/class/System.Data/System.Data/UniqueConstraint.cs b/mcs/class/System.Data/System.Data/UniqueConstraint.cs index 60ec2e9c3a5..fd8b637f20c 100644 --- a/mcs/class/System.Data/System.Data/UniqueConstraint.cs +++ b/mcs/class/System.Data/System.Data/UniqueConstraint.cs @@ -2,10 +2,11 @@ // System.Data.UniqueConstraint.cs // // Author: +// Franklin Wise // Daniel Morgan -// +// +// (C) 2002 Franklin Wise // (C) 2002 Daniel Morgan -// using System; using System.Collections; @@ -104,9 +105,25 @@ namespace System.Data #region Methods - [MonoTODO] public override bool Equals(object key2) { - throw new NotImplementedException (); + UniqueConstraint cst = key2 as UniqueConstraint; + if (null == cst) return false; + + //according to spec if the cols are equal + //then two UniqueConstraints are equal + bool found = false; + foreach (DataColumn thisCol in this.Columns) { + found = false; + foreach (DataColumn col in cst.Columns) { + if (thisCol == col) + found = true; + } + if (false == found) return false; + } + + //if we got here then all columns were found + return true; + } [MonoTODO] diff --git a/mcs/class/System.Data/Test/ChangeLog b/mcs/class/System.Data/Test/ChangeLog index 8b362897dba..6e0a312be6f 100644 --- a/mcs/class/System.Data/Test/ChangeLog +++ b/mcs/class/System.Data/Test/ChangeLog @@ -1,3 +1,15 @@ +2002-08-12 Franklin Wise + * NewFile: Added test for System.Data.UniqueConstraintTest.cs + + * NewFile: Added test for System.Data.ConstraintTest.cs + + * NewFile: Added test for System.Data.ConstraintCollection.cs + + * Added blank test for DataColumnTest so that NUnit won't warn + of no tests + + * Updated System.Data.AllTests.cs to include the new tests + 2002-05-27 Tim Coleman * TestSqlDataAdapter.cs: remove explicit opening of connection. This should occur implicitly now. diff --git a/mcs/class/System.Data/Test/System.Data/AllTests.cs b/mcs/class/System.Data/Test/System.Data/AllTests.cs index bd607633bf6..1752c3bfc7b 100644 --- a/mcs/class/System.Data/Test/System.Data/AllTests.cs +++ b/mcs/class/System.Data/Test/System.Data/AllTests.cs @@ -22,6 +22,9 @@ namespace MonoTests.System.Data get { TestSuite suite = new TestSuite (); suite.AddTest (new TestSuite (typeof (DataColumnTest))); + suite.AddTest (new TestSuite (typeof (UniqueConstraintTest))); + suite.AddTest (new TestSuite (typeof (ConstraintTest))); + suite.AddTest (new TestSuite (typeof (ConstraintCollectionTest))); return suite; } } diff --git a/mcs/class/System.Data/Test/System.Data/ConstraintCollectionTest.cs b/mcs/class/System.Data/Test/System.Data/ConstraintCollectionTest.cs new file mode 100644 index 00000000000..c1d2ddcd1e4 --- /dev/null +++ b/mcs/class/System.Data/Test/System.Data/ConstraintCollectionTest.cs @@ -0,0 +1,111 @@ +// ConstraintCollection.cs - NUnit Test Cases for testing the ConstraintCollection +// class. +// +// +// Franklin Wise (gracenote@earthlink.net) +// +// (C) Franklin Wise +// + + +using NUnit.Framework; +using System; +using System.Data; + + +namespace MonoTests.System.Data +{ + + + public class ConstraintCollectionTest : TestCase + { + private DataTable _table; + private Constraint _constraint1; + private Constraint _constraint2; + + public ConstraintCollectionTest() : base ("MonoTests.System.Data.ConstraintCollectionTest") {} + public ConstraintCollectionTest(string name) : base(name) {} + + public void PublicSetup(){SetUp();} + protected override void SetUp() + { + //Setup DataTable + _table = new DataTable("TestTable"); + _table.Columns.Add("Col1",typeof(int)); + _table.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); + } + + protected override void TearDown() {} + + public static ITest Suite + { + get + { + return new TestSuite(typeof(ConstraintCollectionTest)); + } + } + + public void TestAdd() + { + ConstraintCollection col = _table.Constraints; + col.Add(_constraint1); + col.Add(_constraint2); + + Assertion.AssertEquals("Count doesn't equal added.",2, col.Count); + } + + public void TestAddExceptions() + { + ConstraintCollection col = _table.Constraints; + try + { + col.Add(null); + Assertion.Fail("B1: Failed to throw ArgumentNullException."); + } + catch (ArgumentNullException) {} + catch (AssertionFailedError exc) {throw exc;} + catch + { + Assertion.Fail("A1: Wrong exception type"); + } + + try + { + _constraint1.ConstraintName = "Dog"; + _constraint2.ConstraintName = "dog"; //case insensitive + col.Add(_constraint1); + col.Add(_constraint2); + Assertion.Fail("Failed to throw Duplicate name exception."); + } + catch (DuplicateNameException) {} + catch (AssertionFailedError exc) {throw exc;} + catch (Exception exc) + { + Assertion.Fail("A2: Wrong exception type. " + exc.ToString()); + } + + //Constraint Already exists + try + { + col.Add(_constraint1); + Assertion.Fail("B2: Failed to throw ArgumentException."); + } + catch (ArgumentException) {} + catch (AssertionFailedError exc) {throw exc;} + catch + { + Assertion.Fail("A3: Wrong exception type"); + } + } + + public void TestRemoveExceptions() + { + + + } + } +} diff --git a/mcs/class/System.Data/Test/System.Data/ConstraintTest.cs b/mcs/class/System.Data/Test/System.Data/ConstraintTest.cs new file mode 100644 index 00000000000..a019e9c6b7d --- /dev/null +++ b/mcs/class/System.Data/Test/System.Data/ConstraintTest.cs @@ -0,0 +1,132 @@ +// ConstraintTest.cs - NUnit Test Cases for testing the abstract class System.Data.Constraint +// The tests use an inherited class (UniqueConstraint) to test the Constraint class. +// +// Franklin Wise +// +// (C) 2002 Franklin Wise +// + +using NUnit.Framework; +using System; +using System.Data; + +namespace MonoTests.System.Data +{ +// public class MyUniqueConstraint: UniqueConstraint { +// public MyUniqueConstraint(DataColumn col, bool pk): base(col,pk){} +// string _myval = ""; +// public override string ConstraintName { +// get{ +// return _myval; +// return base.ConstraintName; +// } +// set{ +// Console.WriteLine("NameSet = " + value); +// base.ConstraintName = value; +// _myval = value; +// } +// } +// } + + public class ConstraintTest : TestCase + { + private DataTable _table; + private Constraint _constraint1; + private Constraint _constraint2; + + public ConstraintTest() : base ("MonoTests.System.Data.ConstraintTest") {} + public ConstraintTest(string name) : base(name) {} + + public void PublicSetup(){SetUp();} + protected override void SetUp() { + + //Setup DataTable + _table = new DataTable("TestTable"); + _table.Columns.Add("Col1",typeof(int)); + _table.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); + + } + + + protected override void TearDown() {} + + public static ITest Suite { + get { + return new TestSuite(typeof(ConstraintTest)); + } + } + + public void TestSetConstraintNameNullOrEmptyExceptions() { + bool exceptionCaught = false; + string name = null; + + _table.Constraints.Add (_constraint1); + + Console.WriteLine(_constraint1.ConstraintName); + + for (int i = 0; i <= 1; i++) { + exceptionCaught = false; + if (0 == i) name = null; + if (1 == i) name = String.Empty; + + try { + + //Next line should throw ArgumentException + //Because ConstraintName can't be set to null + //or empty while the constraint is part of the + //collection + _constraint1.ConstraintName = name; + } + catch (ArgumentException){ + exceptionCaught = true; + } + catch { + Assertion.Fail("Wrong exception type thrown."); + } + + Assertion.Assert("Failed to throw exception.", + true == exceptionCaught); + } + } + + public void TestSetConstraintNameDuplicateException() { + _constraint1.ConstraintName = "Dog"; + _constraint2.ConstraintName = "Cat"; + + _table.Constraints.Add(_constraint1); + _table.Constraints.Add(_constraint2); + + try { + //Should throw DuplicateNameException + _constraint2.ConstraintName = "Dog"; + + Assertion.Fail("Failed to throw " + + " DuplicateNameException exception."); + } + catch (DuplicateNameException) {} + catch (AssertionFailedError exc) {throw exc;} + catch { + Assertion.Fail("Wrong exception type thrown."); + } + + } + + public void TestToString() { + //_constraint1.ConstraintName = "Test"; + Assertion.Assert("ToString is the same as constraint name.", _constraint1.ConstraintName.CompareTo( _constraint1.ToString()) == 0); + } + + public void TestGetExtendedProperties() { + PropertyCollection col = _constraint1.ExtendedProperties as + PropertyCollection; + + Assertion.AssertNotNull("ExtendedProperties returned null or didn't " + + "return the correct type", col); + } + + } +} diff --git a/mcs/class/System.Data/Test/System.Data/DataColumnTest.cs b/mcs/class/System.Data/Test/System.Data/DataColumnTest.cs index 87cf31529fb..c6509fcf497 100644 --- a/mcs/class/System.Data/Test/System.Data/DataColumnTest.cs +++ b/mcs/class/System.Data/Test/System.Data/DataColumnTest.cs @@ -26,5 +26,7 @@ namespace MonoTests.System.Data return new TestSuite (typeof (DataColumnTest)); } } + + public void TestBlank() {} //Remove me when we add some tests } } diff --git a/mcs/class/System.Data/Test/System.Data/UniqueConstraintTest.cs b/mcs/class/System.Data/Test/System.Data/UniqueConstraintTest.cs new file mode 100644 index 00000000000..2eaf18de9aa --- /dev/null +++ b/mcs/class/System.Data/Test/System.Data/UniqueConstraintTest.cs @@ -0,0 +1,171 @@ +// UniqueConstraintTest.cs - NUnit Test Cases for testing the class System.Data.UniqueConstraint +// +// Franklin Wise +// +// (C) 2002 Franklin Wise +// + +using NUnit.Framework; +using System; +using System.Data; + +namespace MonoTests.System.Data +{ + public class UniqueConstraintTest : TestCase + { + private DataTable _table; + + public UniqueConstraintTest() : base ("MonoTests.System.Data.UniqueConstraintTest") {} + public UniqueConstraintTest(string name) : base(name) {} + + public void PublicSetup() {this.SetUp();} + protected override void SetUp() { + + //Setup DataTable + _table = new DataTable("TestTable"); + _table.Columns.Add("Col1",typeof(int)); + _table.Columns.Add("Col2",typeof(int)); + + } + + protected override void TearDown() {} + + public static ITest Suite { + get { + return new TestSuite(typeof(UniqueConstraintTest)); + } + } + + public void TestCtorExceptions() { + //UniqueConstraint(string name, DataColumn column, bool isPrimaryKey) + + UniqueConstraint cst; + + //must have DataTable exception + try{ + //Should throw an ArgumentException + //Can only add DataColumns that are attached + //to a DataTable + cst = new UniqueConstraint(new DataColumn("")); + + Assertion.Fail("Failed to throw ArgumentException."); + } + catch (ArgumentException) {} + catch (AssertionFailedError exc) {throw exc;} + catch { + Assertion.Fail("A1: Wrong Exception type."); + } + + //Null exception + try { + //Should throw argument null exception + cst = new UniqueConstraint((DataColumn)null); + } + catch (ArgumentNullException) {} + catch (AssertionFailedError exc) {throw exc;} + catch { + Assertion.Fail("A2: Wrong Exception type."); + } + + + try { + //Should throw exception + //must have at least one valid column + //InvalidConstraintException is thrown by msft ver + cst = new UniqueConstraint(new DataColumn [] {}); + + Assertion.Fail("B1: Failed to throw InvalidConstraintException."); + } + catch (InvalidConstraintException) {} + catch (AssertionFailedError exc) {throw exc;} + catch { + Assertion.Fail("A3: Wrong Exception type."); + } + + DataTable dt = new DataTable("Table1"); + dt.Columns.Add("Col1",typeof(int)); + DataTable dt2 = new DataTable("Table2"); + dt2.Columns.Add("Col1",typeof(int)); + + DataSet ds = new DataSet(); + ds.Tables.Add(dt); + ds.Tables.Add(dt2); + + //columns from two different tables. + try { + //next line should throw + //can't have columns from two different tables + cst = new UniqueConstraint(new DataColumn [] { + dt.Columns[0], dt2.Columns[0]}); + + Assertion.Fail("B2: Failed to throw InvalidConstraintException"); + } + catch (InvalidConstraintException) {} + catch (AssertionFailedError exc) {throw exc;} + catch { + Assertion.Fail("A4: Wrong Exception type."); + } + + + + } + + + public void TestCtor() { + + UniqueConstraint cst; + + //Success case + try { + cst = new UniqueConstraint(_table.Columns[0]); + } + catch (Exception exc) { + Assertion.Fail("A1: Failed to ctor. " + exc.ToString()); + } + + + try { + cst = new UniqueConstraint( new DataColumn [] { + _table.Columns[0], _table.Columns[1]}); + } + catch (Exception exc) { + Assertion.Fail("A2: Failed to ctor. " + exc.ToString()); + } + + + //table is set on ctor + cst = new UniqueConstraint(_table.Columns[0]); + + Assertion.AssertSame("B1", cst.Table, _table); + + //table is set on ctor + cst = new UniqueConstraint( new DataColumn [] { + _table.Columns[0], _table.Columns[1]}); + Assertion.AssertSame ("B2", cst.Table, _table); + + + } + + public void TestEquals() { + UniqueConstraint cst = new UniqueConstraint( new DataColumn [] { + _table.Columns[0], _table.Columns[1]}); + UniqueConstraint cst2 = new UniqueConstraint( new DataColumn [] { + _table.Columns[0], _table.Columns[1]}); + + UniqueConstraint cst3 = new UniqueConstraint(_table.Columns[0]); + + //true + Assertion.Assert(cst.Equals(cst2) == true); + + //false + Assertion.Assert(cst.Equals(23) == false); + Assertion.Assert(cst.Equals(cst3) == false); + + + } + + + + + } +} -- 2.25.1