// DataColumnTest.cs - NUnit Test Cases for System.Data.DataColumn // // Authors: // Franklin Wise // Rodrigo Moya // Daniel Morgan // Martin Willemoes Hansen // // (C) Copyright 2002 Franklin Wise // (C) Copyright 2002 Rodrigo Moya // (C) Copyright 2003 Daniel Morgan // (C) Copyright 2003 Martin Willemoes Hansen // (C) Copyright 2011 Xamarin Inc // // Copyright 2011 Xamarin Inc (http://www.xamarin.com) // 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 System; using System.ComponentModel; using System.Data; using System.Data.SqlTypes; using NUnit.Framework; namespace MonoTests.System.Data { [TestFixture] public class DataColumnTest { private DataTable _tbl; [SetUp] public void GetReady () { _tbl = new DataTable(); } [Test] public void Ctor() { string colName = "ColName"; DataColumn col = new DataColumn (); //These should all ctor without an exception col = new DataColumn (colName); col = new DataColumn (colName, typeof(int)); col = new DataColumn (colName, typeof(int), null); col = new DataColumn (colName, typeof(int), null, MappingType.Attribute); } [Test] public void Constructor3_DataType_Null () { try { new DataColumn ("ColName", (Type) null); Assert.Fail ("#1"); } catch (ArgumentNullException ex) { Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2"); Assert.IsNull (ex.InnerException, "#3"); // Never premise English. // Assert.IsNotNull (ex.Message, "#4"); Assert.IsNotNull (ex.ParamName, "#5"); Assert.AreEqual ("dataType", ex.ParamName, "#6"); } } [Test] public void AllowDBNull() { DataColumn col = new DataColumn("NullCheck",typeof(int)); _tbl.Columns.Add(col); col.AllowDBNull = true; _tbl.Rows.Add(_tbl.NewRow()); _tbl.Rows[0]["NullCheck"] = DBNull.Value; try { col.AllowDBNull = false; Assert.Fail ("DC8b: Failed to throw DataException."); } catch (DataException) { } } [Test] public void AllowDBNull1() { DataTable tbl = _tbl; tbl.Columns.Add ("id", typeof (int)); tbl.Columns.Add ("name", typeof (string)); tbl.PrimaryKey = new DataColumn [] { tbl.Columns ["id"] }; tbl.Rows.Add (new object [] { 1, "RowState 1" }); tbl.Rows.Add (new object [] { 2, "RowState 2" }); tbl.Rows.Add (new object [] { 3, "RowState 3" }); tbl.AcceptChanges (); // Update Table with following changes: Row0 unmodified, // Row1 modified, Row2 deleted, Row3 added, Row4 not-present. tbl.Rows [1] ["name"] = "Modify 2"; tbl.Rows [2].Delete (); DataColumn col = tbl.Columns ["name"]; col.AllowDBNull = true; col.AllowDBNull = false; Assert.IsFalse (col.AllowDBNull); } [Test] public void AutoIncrement() { DataColumn col = new DataColumn("Auto",typeof (string)); col.AutoIncrement = true; //Check for Correct Default Values Assert.AreEqual (0L, col.AutoIncrementSeed, "#1"); Assert.AreEqual (1L, col.AutoIncrementStep, "#2"); //Check for auto type convert Assert.AreEqual (typeof (int), col.DataType, "#3"); } [Test] public void AutoIncrementExceptions() { DataColumn col = new DataColumn(); col.Expression = "SomeExpression"; //if computed column exception is thrown try { col.AutoIncrement = true; Assert.Fail ("DC12: Failed to throw ArgumentException"); } catch (ArgumentException) { } } [Test] public void Caption() { DataColumn col = new DataColumn("ColName"); //Caption not set at this point Assert.AreEqual (col.ColumnName, col.Caption, "#1"); //Set caption col.Caption = "MyCaption"; Assert.AreEqual ("MyCaption", col.Caption, "#2"); //Clear caption col.Caption = null; Assert.AreEqual (string.Empty, col.Caption, "#3"); } [Test] public void DateTimeMode_Valid () { DataColumn col = new DataColumn ("birthdate", typeof (DateTime)); col.DateTimeMode = DataSetDateTime.Local; Assert.AreEqual (DataSetDateTime.Local, col.DateTimeMode, "#1"); col.DateTimeMode = DataSetDateTime.Unspecified; Assert.AreEqual (DataSetDateTime.Unspecified, col.DateTimeMode, "#2"); col.DateTimeMode = DataSetDateTime.Utc; Assert.AreEqual (DataSetDateTime.Utc, col.DateTimeMode, "#3"); } [Test] public void DateTime_DataType_Invalid () { DataColumn col = new DataColumn ("birthdate", typeof (int)); try { col.DateTimeMode = DataSetDateTime.Local; Assert.Fail ("#1"); } catch (InvalidOperationException ex) { // The DateTimeMode can be set only on DataColumns // of type DateTime Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); Assert.IsNull (ex.InnerException, "#3"); Assert.IsNotNull (ex.Message, "#4"); Assert.IsTrue (ex.Message.IndexOf ("DateTimeMode") != -1, "#5"); Assert.IsTrue (ex.Message.IndexOf ("DateTime") != -1, "#6"); } } [Test] public void DateTimeMode_Invalid () { DataColumn col = new DataColumn ("birthdate", typeof (DateTime)); try { col.DateTimeMode = (DataSetDateTime) 666; Assert.Fail ("#1"); } catch (InvalidEnumArgumentException ex) { // The DataSetDateTime enumeration value, 666, is invalid Assert.AreEqual (typeof (InvalidEnumArgumentException), ex.GetType (), "#2"); Assert.IsNull (ex.InnerException, "#3"); Assert.IsNotNull (ex.Message, "#4"); Assert.IsTrue (ex.Message.IndexOf ("DataSetDateTime") != -1, "#5"); Assert.IsTrue (ex.Message.IndexOf ("666") != -1, "#6"); Assert.IsNull (ex.ParamName, "#7"); } } [Test] public void ForColumnNameException() { DataColumn col = new DataColumn(); DataColumn col2 = new DataColumn(); DataColumn col3 = new DataColumn(); DataColumn col4 = new DataColumn(); col.ColumnName = "abc"; Assert.AreEqual ("abc", col.ColumnName, "#1"); _tbl.Columns.Add(col); //Duplicate name exception try { col2.ColumnName = "abc"; _tbl.Columns.Add(col2); Assert.AreEqual ("abc", col2.ColumnName, "#2"); Assert.Fail ("#3"); } catch (DuplicateNameException) { } // Make sure case matters in duplicate checks col3.ColumnName = "ABC"; _tbl.Columns.Add(col3); } [Test] public void DefaultValue() { DataTable tbl = new DataTable(); tbl.Columns.Add("MyCol", typeof(int)); //Set default Value if Autoincrement is true tbl.Columns[0].AutoIncrement = true; try { tbl.Columns[0].DefaultValue = 2; Assert.Fail ("DC19: Failed to throw ArgumentException."); } catch (ArgumentException) { } tbl.Columns[0].AutoIncrement = false; //Set default value to an incompatible datatype try { tbl.Columns[0].DefaultValue = "hello"; Assert.Fail ("DC21: Failed to throw FormatException."); } catch (FormatException) { } //TODO: maybe add tests for setting default value for types that can implict //cast } [Test] public void SetDataType () { //test for DataAlready exists and change the datatype //supported datatype //AutoInc column dataType supported } [Test] public void Defaults1 () { //Check for defaults - ColumnName not set at the beginning DataTable table = new DataTable(); DataColumn column = new DataColumn(); Assert.AreEqual (String.Empty, column.ColumnName, "#A1"); Assert.AreEqual (typeof (string), column.DataType, "#A2"); table.Columns.Add(column); Assert.AreEqual ("Column1", table.Columns [0].ColumnName, "#B1"); Assert.AreEqual (typeof (string), table.Columns [0].DataType, "#B2"); DataRow row = table.NewRow(); table.Rows.Add(row); DataRow dataRow = table.Rows[0]; object v = dataRow.ItemArray [0]; Assert.AreEqual (typeof (DBNull), v.GetType (), "#C1"); Assert.AreEqual (DBNull.Value, v, "#C2"); } [Test] public void Defaults2 () { //Check for defaults - ColumnName set at the beginning string blah = "Blah"; //Check for defaults - ColumnName not set at the beginning DataTable table = new DataTable(); DataColumn column = new DataColumn(blah); Assert.AreEqual (blah, column.ColumnName, "#A1"); Assert.AreEqual (typeof (string), column.DataType, "#A2"); table.Columns.Add(column); Assert.AreEqual (blah, table.Columns[0].ColumnName, "#B1"); Assert.AreEqual (typeof (string), table.Columns[0].DataType, "#B2"); DataRow row = table.NewRow(); table.Rows.Add(row); DataRow dataRow = table.Rows[0]; object v = dataRow.ItemArray[0]; Assert.AreEqual (typeof (DBNull), v.GetType (), "#C1"); Assert.AreEqual (DBNull.Value, v, "#C2"); } [Test] public void Defaults3 () { DataColumn col = new DataColumn ("foo", typeof (SqlBoolean)); Assert.AreEqual (SqlBoolean.Null, col.DefaultValue, "#1"); col.DefaultValue = SqlBoolean.True; // FIXME: not working yet //col.DefaultValue = true; //Assert.AreEqual (SqlBoolean.True, col.DefaultValue, "#2"); // not bool but SqlBoolean col.DefaultValue = DBNull.Value; Assert.AreEqual (SqlBoolean.Null, col.DefaultValue, "#3"); // not DBNull } [Test] [ExpectedException (typeof (DataException))] public void ChangeTypeAfterSettingDefaultValue () { DataColumn col = new DataColumn ("foo", typeof (SqlBoolean)); col.DefaultValue = true; col.DataType = typeof (int); } [Test] public void ExpressionSubstringlimits () { DataTable t = new DataTable (); t.Columns.Add ("aaa"); t.Rows.Add (new object [] {"xxx"}); DataColumn c = t.Columns.Add ("bbb"); try { c.Expression = "SUBSTRING(aaa, 6000000000000000, 2)"; Assert.Fail ("#1"); } catch (OverflowException) { } } [Test] public void ExpressionFunctions () { DataTable T = new DataTable ("test"); DataColumn C = new DataColumn ("name"); T.Columns.Add (C); C = new DataColumn ("age"); C.DataType = typeof (int); T.Columns.Add (C); C = new DataColumn ("id"); C.Expression = "substring (name, 1, 3) + len (name) + age"; T.Columns.Add (C); DataSet Set = new DataSet ("TestSet"); Set.Tables.Add (T); DataRow Row = null; for (int i = 0; i < 100; i++) { Row = T.NewRow (); Row [0] = "human" + i; Row [1] = i; T.Rows.Add (Row); } Row = T.NewRow (); Row [0] = "h*an"; Row [1] = DBNull.Value; T.Rows.Add (Row); Assert.AreEqual ("hum710", T.Rows [10] [2], "#A1"); Assert.AreEqual ("hum64", T.Rows [4] [2], "#A2"); C = T.Columns [2]; C.Expression = "isnull (age, 'succ[[]]ess')"; Assert.AreEqual ("succ[[]]ess", T.Rows [100] [2], "#A3"); C.Expression = "iif (age = 24, 'hurrey', 'boo')"; Assert.AreEqual ("boo", T.Rows [50] [2], "#B1"); Assert.AreEqual ("hurrey", T.Rows [24] [2], "#B2"); C.Expression = "convert (age, 'System.Boolean')"; Assert.AreEqual (Boolean.TrueString, T.Rows [50] [2], "#C1"); Assert.AreEqual (Boolean.FalseString, T.Rows [0] [2], "#C2"); // // Exceptions // try { // The expression contains undefined function call iff(). C.Expression = "iff (age = 24, 'hurrey', 'boo')"; Assert.Fail ("#D"); } catch (EvaluateException) { } catch (SyntaxErrorException) { } //The following two cases fail on mono. MS.net evaluates the expression //immediatly upon assignment. We don't do this yet hence we don't throw //an exception at this point. try { C.Expression = "iif (nimi = 24, 'hurrey', 'boo')"; Assert.Fail ("#E1"); } catch (EvaluateException e) { Assert.AreEqual (typeof (EvaluateException), e.GetType (), "#E2"); // Never premise English. //Assert.AreEqual ("Cannot find column [nimi].", e.Message, "#E3"); } try { C.Expression = "iif (name = 24, 'hurrey', 'boo')"; Assert.Fail ("#F1"); } catch (EvaluateException e) { Assert.AreEqual (typeof (EvaluateException), e.GetType (), "#F2"); //AssertEquals ("DC41", "Cannot perform '=' operation on System.String and System.Int32.", e.Message); } try { C.Expression = "convert (age, Boolean)"; Assert.Fail ("#G1"); } catch (EvaluateException e) { Assert.AreEqual (typeof (EvaluateException), e.GetType (), "#G2"); // Never premise English. //Assert.AreEqual ("Invalid type name 'Boolean'.", e.Message, "#G3"); } } [Test] public void ExpressionAggregates () { DataTable T = new DataTable ("test"); DataTable T2 = new DataTable ("test2"); DataColumn C = new DataColumn ("name"); T.Columns.Add (C); C = new DataColumn ("age"); C.DataType = typeof (int); T.Columns.Add (C); C = new DataColumn ("childname"); T.Columns.Add (C); C = new DataColumn ("expression"); T.Columns.Add (C); DataSet Set = new DataSet ("TestSet"); Set.Tables.Add (T); Set.Tables.Add (T2); DataRow Row = null; for (int i = 0; i < 100; i++) { Row = T.NewRow (); Row [0] = "human" + i; Row [1] = i; Row [2] = "child" + i; T.Rows.Add (Row); } Row = T.NewRow (); Row [0] = "h*an"; Row [1] = DBNull.Value; T.Rows.Add (Row); C = new DataColumn ("name"); T2.Columns.Add (C); C = new DataColumn ("age"); C.DataType = typeof (int); T2.Columns.Add (C); for (int i = 0; i < 100; i++) { Row = T2.NewRow (); Row [0] = "child" + i; Row [1] = i; T2.Rows.Add (Row); Row = T2.NewRow (); Row [0] = "child" + i; Row [1] = i - 2; T2.Rows.Add (Row); } DataRelation Rel = new DataRelation ("Rel", T.Columns [2], T2.Columns [0]); Set.Relations.Add (Rel); C = T.Columns [3]; C.Expression = "Sum (Child.age)"; Assert.AreEqual ("-2", T.Rows [0] [3], "#A1"); Assert.AreEqual ("98", T.Rows [50] [3], "#A2"); C.Expression = "Count (Child.age)"; Assert.AreEqual ("2", T.Rows [0] [3], "#B1"); Assert.AreEqual ("2", T.Rows [60] [3], "#B2"); C.Expression = "Avg (Child.age)"; Assert.AreEqual ("-1", T.Rows [0] [3], "#C1"); Assert.AreEqual ("59", T.Rows [60] [3], "#C2"); C.Expression = "Min (Child.age)"; Assert.AreEqual ("-2", T.Rows [0] [3], "#D1"); Assert.AreEqual ("58", T.Rows [60] [3], "#D2"); C.Expression = "Max (Child.age)"; Assert.AreEqual ("0", T.Rows [0] [3], "#E1"); Assert.AreEqual ("60", T.Rows [60] [3], "#E2"); C.Expression = "stdev (Child.age)"; Assert.AreEqual ((1.4142135623731).ToString (T.Locale), T.Rows [0] [3], "#F1"); Assert.AreEqual ((1.4142135623731).ToString (T.Locale), T.Rows [60] [3], "#F2"); C.Expression = "var (Child.age)"; Assert.AreEqual ("2", T.Rows [0] [3], "#G1"); Assert.AreEqual ("2", T.Rows [60] [3], "#G2"); } [Test] public void ExpressionOperator () { DataTable T = new DataTable ("test"); DataColumn C = new DataColumn ("name"); T.Columns.Add (C); C = new DataColumn ("age"); C.DataType = typeof (int); T.Columns.Add (C); C = new DataColumn ("id"); C.Expression = "substring (name, 1, 3) + len (name) + age"; T.Columns.Add (C); DataSet Set = new DataSet ("TestSet"); Set.Tables.Add (T); DataRow Row = null; for (int i = 0; i < 100; i++) { Row = T.NewRow (); Row [0] = "human" + i; Row [1] = i; T.Rows.Add (Row); } Row = T.NewRow (); Row [0] = "h*an"; Row [1] = DBNull.Value; T.Rows.Add (Row); C = T.Columns [2]; C.Expression = "age + 4"; Assert.AreEqual ("68", T.Rows [64] [2], "#A"); C.Expression = "age - 4"; Assert.AreEqual ("60", T.Rows [64] [2], "#B"); C.Expression = "age * 4"; Assert.AreEqual ("256", T.Rows [64] [2], "#C"); C.Expression = "age / 4"; Assert.AreEqual ("16", T.Rows [64] [2], "#D"); C.Expression = "age % 5"; Assert.AreEqual ("4", T.Rows [64] [2], "#E"); C.Expression = "age in (5, 10, 15, 20, 25)"; Assert.AreEqual ("False", T.Rows [64] [2], "#F1"); Assert.AreEqual ("True", T.Rows [25] [2], "#F2"); C.Expression = "name like 'human1%'"; Assert.AreEqual ("True", T.Rows [1] [2], "#G1"); Assert.AreEqual ("False", T.Rows [25] [2], "#G2"); C.Expression = "age < 4"; Assert.AreEqual ("False", T.Rows [4] [2], "#H1"); Assert.AreEqual ("True", T.Rows [3] [2], "#H2"); C.Expression = "age <= 4"; Assert.AreEqual ("True", T.Rows [4] [2], "#I1"); Assert.AreEqual ("False", T.Rows [5] [2], "#I2"); C.Expression = "age > 4"; Assert.AreEqual ("False", T.Rows [4] [2], "#J1"); Assert.AreEqual ("True", T.Rows [5] [2], "#J2"); C.Expression = "age >= 4"; Assert.AreEqual ("True", T.Rows [4] [2], "#K1"); Assert.AreEqual ("False", T.Rows [1] [2], "#K2"); C.Expression = "age = 4"; Assert.AreEqual ("True", T.Rows [4] [2], "#L1"); Assert.AreEqual ("False", T.Rows [1] [2], "#L2"); C.Expression = "age <> 4"; Assert.AreEqual ("False", T.Rows [4] [2], "#M1"); Assert.AreEqual ("True", T.Rows [1] [2], "#M2"); } [Test] public void SetMaxLengthException () { // Setting MaxLength on SimpleContent -> exception DataSet ds = new DataSet("Example"); ds.Tables.Add("MyType"); ds.Tables["MyType"].Columns.Add(new DataColumn("Desc", typeof (string), "", MappingType.SimpleContent)); try { ds.Tables ["MyType"].Columns ["Desc"].MaxLength = 32; Assert.Fail ("#1"); } catch (ArgumentException) { } } [Test] public void SetMaxLengthNegativeValue () { // however setting MaxLength on SimpleContent is OK DataSet ds = new DataSet ("Example"); ds.Tables.Add ("MyType"); ds.Tables ["MyType"].Columns.Add ( new DataColumn ("Desc", typeof (string), "", MappingType.SimpleContent)); ds.Tables ["MyType"].Columns ["Desc"].MaxLength = -1; } [Test] public void AdditionToConstraintCollectionTest() { DataTable myTable = new DataTable("myTable"); DataColumn idCol = new DataColumn("id", typeof (int)); idCol.Unique = true; myTable.Columns.Add(idCol); ConstraintCollection cc = myTable.Constraints; //cc just contains a single UniqueConstraint object. UniqueConstraint uc = cc[0] as UniqueConstraint; Assert.AreEqual ("id", uc.Columns[0].ColumnName); } [Test] // bug #77025 public void CalcStatisticalFunction_SingleElement() { DataTable table = new DataTable (); table.Columns.Add ("test", typeof (int)); table.Rows.Add (new object [] {0}); table.Columns.Add ("result_var", typeof (double), "var(test)"); table.Columns.Add ("result_stdev", typeof (double), "stdev(test)"); // Check DBNull.Value is set as the result Assert.AreEqual (typeof (DBNull), (table.Rows[0]["result_var"]).GetType (), "#1"); Assert.AreEqual (typeof (DBNull), (table.Rows [0] ["result_stdev"]).GetType (), "#2"); } [Test] public void Aggregation_CheckIfChangesDynamically() { DataTable table = new DataTable (); table.Columns.Add ("test", typeof (int)); table.Columns.Add ("result_count", typeof (int), "count(test)"); table.Columns.Add ("result_sum", typeof (int), "sum(test)"); table.Columns.Add ("result_avg", typeof (int), "avg(test)"); table.Columns.Add ("result_max", typeof (int), "max(test)"); table.Columns.Add ("result_min", typeof (int), "min(test)"); table.Columns.Add ("result_var", typeof (double), "var(test)"); table.Columns.Add ("result_stdev", typeof (double), "stdev(test)"); // Adding the rows after all the expression columns are added table.Rows.Add (new object[] {0}); Assert.AreEqual (1, table.Rows [0] ["result_count"], "#A1"); Assert.AreEqual (0, table.Rows [0] ["result_sum"], "#A2"); Assert.AreEqual (0, table.Rows [0] ["result_avg"], "#A3"); Assert.AreEqual (0, table.Rows [0] ["result_max"], "#A4"); Assert.AreEqual (0, table.Rows [0] ["result_min"], "#A5"); Assert.AreEqual (DBNull.Value, table.Rows [0] ["result_var"], "#A6"); Assert.AreEqual (DBNull.Value, table.Rows [0] ["result_stdev"], "#A7"); table.Rows.Add (new object[] {1}); table.Rows.Add (new object[] {-2}); // Check if the aggregate columns are updated correctly Assert.AreEqual (3, table.Rows [0] ["result_count"], "#B1"); Assert.AreEqual (-1, table.Rows [0] ["result_sum"], "#B2"); Assert.AreEqual (0, table.Rows [0] ["result_avg"], "#B3"); Assert.AreEqual (1, table.Rows [0] ["result_max"], "#B4"); Assert.AreEqual (-2, table.Rows [0] ["result_min"], "#B5"); Assert.AreEqual ((7.0 / 3), table.Rows [0] ["result_var"], "#B6"); Assert.AreEqual (Math.Sqrt (7.0 / 3), table.Rows [0] ["result_stdev"], "#B7"); } [Test] public void Aggregation_CheckIfChangesDynamically_ChildTable () { DataSet ds = new DataSet (); DataTable table = new DataTable (); DataTable table2 = new DataTable (); ds.Tables.Add (table); ds.Tables.Add (table2); table.Columns.Add ("test", typeof (int)); table2.Columns.Add ("test", typeof (int)); table2.Columns.Add ("val", typeof (int)); DataRelation rel = new DataRelation ("rel", table.Columns[0], table2.Columns[0]); ds.Relations.Add (rel); table.Columns.Add ("result_count", typeof (int), "count(child.test)"); table.Columns.Add ("result_sum", typeof (int), "sum(child.test)"); table.Columns.Add ("result_avg", typeof (int), "avg(child.test)"); table.Columns.Add ("result_max", typeof (int), "max(child.test)"); table.Columns.Add ("result_min", typeof (int), "min(child.test)"); table.Columns.Add ("result_var", typeof (double), "var(child.test)"); table.Columns.Add ("result_stdev", typeof (double), "stdev(child.test)"); table.Rows.Add (new object[] {1}); table.Rows.Add (new object[] {2}); // Add rows to the child table for (int j=0; j<10; j++) table2.Rows.Add (new object[] {1,j}); // Check the values for the expression columns in parent table Assert.AreEqual (10, table.Rows [0] ["result_count"], "#A1"); Assert.AreEqual (0, table.Rows [1] ["result_count"], "#A2"); Assert.AreEqual (10, table.Rows [0] ["result_sum"], "#B1"); Assert.AreEqual (DBNull.Value, table.Rows [1] ["result_sum"], "#B2"); Assert.AreEqual (1, table.Rows [0] ["result_avg"], "#C1"); Assert.AreEqual (DBNull.Value, table.Rows [1] ["result_avg"], "#C2"); Assert.AreEqual (1, table.Rows [0] ["result_max"], "#D1"); Assert.AreEqual (DBNull.Value, table.Rows [1] ["result_max"], "#D2"); Assert.AreEqual (1, table.Rows [0] ["result_min"], "#E1"); Assert.AreEqual (DBNull.Value, table.Rows [1] ["result_min"], "#E2"); Assert.AreEqual (0, table.Rows [0] ["result_var"], "#F1"); Assert.AreEqual (DBNull.Value, table.Rows [1] ["result_var"], "#F2"); Assert.AreEqual (0, table.Rows [0] ["result_stdev"], "#G1"); Assert.AreEqual (DBNull.Value, table.Rows [1] ["result_stdev"], "#G2"); } [Test] public void Aggregation_TestForSyntaxErrors () { string error = "Aggregation functions cannot be called on Singular(Parent) Columns"; DataSet ds = new DataSet (); DataTable table1 = new DataTable (); DataTable table2 = new DataTable (); DataTable table3 = new DataTable (); table1.Columns.Add ("test", typeof(int)); table2.Columns.Add ("test", typeof(int)); table3.Columns.Add ("test", typeof(int)); ds.Tables.Add (table1); ds.Tables.Add (table2); ds.Tables.Add (table3); DataRelation rel1 = new DataRelation ("rel1", table1.Columns[0], table2.Columns[0]); DataRelation rel2 = new DataRelation ("rel2", table2.Columns[0], table3.Columns[0]); ds.Relations.Add (rel1); ds.Relations.Add (rel2); error = "Aggregation Functions cannot be called on Columns Returning Single Row (Parent Column)"; try { table2.Columns.Add ("result", typeof (int), "count(parent.test)"); Assert.Fail ("#1" + error); } catch (SyntaxErrorException) { } error = "Numerical or Functions cannot be called on Columns Returning Multiple Rows (Child Column)"; // Check arithematic operator try { table2.Columns.Add ("result", typeof (int), "10*(child.test)"); Assert.Fail ("#2" + error); } catch (SyntaxErrorException) { } // Check rel operator try { table2.Columns.Add ("result", typeof (int), "(child.test) > 10"); Assert.Fail ("#3" + error); } catch (SyntaxErrorException) { } // Check predicates try { table2.Columns.Add ("result", typeof (int), "(child.test) IN (1,2,3)"); Assert.Fail ("#4" + error); } catch (SyntaxErrorException) { } try { table2.Columns.Add ("result", typeof (int), "(child.test) LIKE 1"); Assert.Fail ("#5" + error); } catch (SyntaxErrorException) { } try { table2.Columns.Add ("result", typeof (int), "(child.test) IS null"); Assert.Fail ("#6" + error); } catch (SyntaxErrorException) { } // Check Calc Functions try { table2.Columns.Add ("result", typeof (int), "isnull(child.test,10)"); Assert.Fail ("#7" + error); } catch (SyntaxErrorException) { } } [Test] [Ignore ("passes in ms.net but looks more like a bug in ms.net")] public void ExpressionColumns_CheckConversions () { DataTable table = new DataTable (); table.Columns.Add ("result_int_div", typeof (int), "(5/10) + 0.5"); table.Columns.Add ("result_float_div", typeof (int), "(5.0/10) + 0.5"); table.Rows.Add (new object[] {}); // ms.net behavior.. seems to covert all numbers to double Assert.AreEqual (1, table.Rows [0] [0], "#1"); Assert.AreEqual (1, table.Rows [0] [1], "#2"); } [Test] public void CheckValuesAfterRemovedFromCollection () { DataTable table = new DataTable ("table1"); DataColumn col1 = new DataColumn ("col1", typeof (int)); DataColumn col2 = new DataColumn ("col2", typeof (int)); Assert.AreEqual (-1, col1.Ordinal, "#A1"); Assert.IsNull (col1.Table, "#A2"); table.Columns.Add (col1); table.Columns.Add (col2); Assert.AreEqual (0, col1.Ordinal, "#B1"); Assert.AreEqual (table, col1.Table, "#B2"); table.Columns.RemoveAt(0); Assert.AreEqual (-1, col1.Ordinal, "#C1"); Assert.IsNull (col1.Table, "#C2"); table.Columns.Clear (); Assert.AreEqual (-1, col2.Ordinal, "#D1"); Assert.IsNull (col2.Table, "#D2"); } [Test] public void B565616_NonIConvertibleTypeTest () { try { DataTable dt = new DataTable (); Guid id = Guid.NewGuid(); dt.Columns.Add ("ID", typeof(string)); DataRow row = dt.NewRow (); row["ID"]= id; Assert.AreEqual (id.ToString(), row["ID"], "#N1"); } catch (InvalidCastException ex) { Assert.Fail ("#NonIConvertibleType Test"); } } [Test] public void B623451_SetOrdinalTest () { try { DataTable t = new DataTable(); t.Columns.Add("one"); t.Columns.Add("two"); t.Columns.Add("three"); Assert.AreEqual ("one", t.Columns[0].ColumnName, "#SO1-1"); Assert.AreEqual ("two", t.Columns[1].ColumnName, "#SO1-2"); Assert.AreEqual ("three", t.Columns[2].ColumnName, "#SO1-3"); t.Columns["three"].SetOrdinal(0); Assert.AreEqual ("three", t.Columns[0].ColumnName, "S02-1"); Assert.AreEqual ("one", t.Columns[1].ColumnName, "S02-2"); Assert.AreEqual ("two", t.Columns[2].ColumnName, "S02-3"); t.Columns["three"].SetOrdinal(1); Assert.AreEqual ("one", t.Columns[0].ColumnName, "S03-1"); Assert.AreEqual ("three", t.Columns[1].ColumnName, "S03-2"); Assert.AreEqual ("two", t.Columns[2].ColumnName, "S03-3"); } catch (ArgumentOutOfRangeException ex) { Assert.Fail ("SetOrdinalTest failed"); } } [Test] public void Xamarin665 () { var t = new DataTable() ; var c1 = t.Columns.Add ("c1"); var c2 = t.Columns.Add ("c2"); c2.Expression = "TRIM(ISNULL(c1,' '))"; c2.Expression = "SUBSTRING(ISNULL(c1,' '), 1, 10)"; } DataColumn MakeColumn (string col, string test) { return new DataColumn () { ColumnName = col, Expression = test }; } #if false // Check Windows output for the row [0] value [Test] public void NullStrings () { var a = MakeColumn ("nullbar", "null+'bar'"); var b = MakeColumn ("barnull", "'bar'+null"); var c = MakeColumn ("foobar", "'foo'+'bar'"); var table = new DataTable(); table.Columns.Add(a); table.Columns.Add(b); table.Columns.Add(c); var row = table.NewRow(); table.Rows.Add(row); Assert.AreEqual (row [0], DBNull.Value, "#1"); Assert.AreEqual (row [1], DBNull.Value, "#2"); Assert.AreEqual (row [2], "foobar", "#3"); } #endif } }