diff --git a/ConTabs.Tests/GeneratedColumnTests.cs b/ConTabs.Tests/GeneratedColumnTests.cs index 28d3d57..0349ffd 100644 --- a/ConTabs.Tests/GeneratedColumnTests.cs +++ b/ConTabs.Tests/GeneratedColumnTests.cs @@ -4,6 +4,7 @@ using System; using System.Linq; using System.Collections.Generic; +using ConTabs.Exceptions; namespace ConTabs.Tests { @@ -53,31 +54,55 @@ public void ColumnGeneratedUsingLocalFunction() circOfMerc.ShouldBe(7664); } - [Test] - public void ColumnGeneratedUsingComplexTypes() - { - // Arrange - var data = new[] - { - new { Start = new DateTime(2017, 01, 01), End = new DateTime(2018, 01, 01) }, - new { Start = new DateTime(1996, 10, 15), End = DateTime.Now.Date }, - new { Start = new DateTime(1970, 01, 01), End = new DateTime(2038, 01, 19) }, - }; - - var table = Table.Create(data); - - // Act - table.Columns.AddGeneratedColumn( - (start, end) => (end - start).TotalDays, - "Total Days", - table.Columns[0], table.Columns["End"]); + [Test] + public void ColumnGeneratedUsingComplexTypes() + { + // Arrange + var data = new[] + { + new { Start = new DateTime(2017, 01, 01), End = new DateTime(2018, 01, 01) }, + new { Start = new DateTime(1996, 10, 15), End = DateTime.Now.Date }, + new { Start = new DateTime(1970, 01, 01), End = new DateTime(2038, 01, 19) }, + }; + + var table = Table.Create(data); + + // Act + table.Columns.AddGeneratedColumn( + (start, end) => (end - start).TotalDays, + "Total Days", + table.Columns[0], table.Columns["End"]); + + // Assert + table.Columns.Count.ShouldBe(3); + table.Columns["Total Days"].Values[0].ShouldBe(365); + } - // Assert - table.Columns.Count.ShouldBe(3); - table.Columns[2].Values[0].ShouldBe(365); - } + [Test] + public void ColumnGeneratedUsingComplexDifferentTypes() + { + // Arrange + var data = new[] + { + new { Start = new DateTime(2017, 01, 01), Duration = 3 }, + new { Start = new DateTime(1996, 10, 15), Duration = 100 }, + new { Start = new DateTime(1970, 01, 01), Duration = 50 }, + }; + + var table = Table.Create(data); + + // Act + table.Columns.AddGeneratedColumn( + (start, days) => start.AddDays(days), + "End", + table.Columns[0], table.Columns["Duration"]); + + // Assert + table.Columns.Count.ShouldBe(3); + table.Columns["End"].Values[0].ShouldBe(new DateTime(2017,1,4)); + } - [Test] + [Test] public void ColumnGeneratedUsingRangeEntireTable() { // Arrange @@ -137,6 +162,69 @@ int ComputeValues(List numbers) // Assert table.Columns.Count.ShouldBe(5); table.Columns["Sum"].Values[0].ShouldBe(16); - } - } + } + + [Test] + public void SingleInputColumn_WrongType_ShouldThrow() + { + // Arrange + var data = DemoDataProvider.ListOfDemoData(); + var table = Table.Create(data); + + // Act + TestDelegate testDelegate = () => table.Columns.AddGeneratedColumn( + (x) => 12d, + "Twelve", + table.Columns["Diameter"]); + + // Assert + Assert.Throws(testDelegate).Message.ShouldBe("Computed column expected type 'String', but column 'Diameter' is of type 'Int32'."); + } + + [Test] + public void TwoInputColumns_FirstIsWrongType_ShouldThrow() + { + // Arrange + var data = new[] + { + new { Start = new DateTime(2017, 01, 01), Duration = 3 }, + new { Start = new DateTime(1996, 10, 15), Duration = 100 }, + new { Start = new DateTime(1970, 01, 01), Duration = 50 }, + }; + + var table = Table.Create(data); + + // Act + TestDelegate testDelegate = () => table.Columns.AddGeneratedColumn( + (start, days) => DateTime.Parse(start).AddDays(days), + "End", + table.Columns[0], table.Columns["Duration"]); + + // Assert + Assert.Throws(testDelegate).Message.ShouldBe("Computed column expected type 'String', but column 'Start' is of type 'DateTime'."); + } + + [Test] + public void TwoInputColumns_SecondIsWrongType_ShouldThrow() + { + // Arrange + var data = new[] + { + new { Start = new DateTime(2017, 01, 01), Duration = 3 }, + new { Start = new DateTime(1996, 10, 15), Duration = 100 }, + new { Start = new DateTime(1970, 01, 01), Duration = 50 }, + }; + + var table = Table.Create(data); + + // Act + TestDelegate testDelegate = () => table.Columns.AddGeneratedColumn( + (start, days) => start.AddDays(int.Parse(days)), + "End", + table.Columns[0], table.Columns["Duration"]); + + // Assert + Assert.Throws(testDelegate).Message.ShouldBe("Computed column expected type 'String', but column 'Duration' is of type 'Int32'."); + } + } } diff --git a/ConTabs/Columns.cs b/ConTabs/Columns.cs index 90291fc..d25e0fd 100644 --- a/ConTabs/Columns.cs +++ b/ConTabs/Columns.cs @@ -99,6 +99,9 @@ private Column FindColByName(string name) /// The parameter to operate on public void AddGeneratedColumn(Func expression, string columnName, Column column) { + if (column.SourceType != typeof(TInput)) + throw new TypeMismatchException(column.ColumnName, typeof(TInput), column.SourceType); + var results = new List(); for (int i = 0; i < column.Values.Count; i++) @@ -132,6 +135,11 @@ private Column FindColByName(string name) /// The second operand within the given expression public void AddGeneratedColumn(Func expression, string columnName, Column column1, Column column2) { + if (column1.SourceType != typeof(TInput1)) + throw new TypeMismatchException(column1.ColumnName, typeof(TInput1), column1.SourceType); + if (column2.SourceType != typeof(TInput2)) + throw new TypeMismatchException(column2.ColumnName, typeof(TInput2), column2.SourceType); + var results = new List(); for (int i = 0; i < column1.Values.Count; i++)