This is the seventeenth part of the SQLxD series. For your convenience you can find other parts in the table of contents in Part 1 – XML Transformation

Last time we implemented aggregates, today we test them. Here are the snippets:

using Model;
using NUnit.Framework;
using QueryLogic.Aggregates;
using QueryLogic.Expressions.CellExpressions;

namespace QueryLogic.Test.Aggregates
{
    internal class CountAggregateTests
    {
        [Test]
        public void Calculate_NotNullValuesPassed_ShouldReturnCount()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "13"));

            var secondRow = new Row();
            secondRow.AddCell(new Cell(columnHeader, "1"));

            var thirdRow = new Row();
            thirdRow.AddCell(new Cell(columnHeader, "10"));

            var relation = new Relation();

            relation.AddRow(firstRow);
            relation.AddRow(secondRow);
            relation.AddRow(thirdRow);

            var expectedColumnHeader = new ColumnHeader("", "");
            var expectedCell = new Cell(expectedColumnHeader, "3");
            var aggregate = new CountAggregate(new GetOriginalCellCellExpression(expectedColumnHeader));

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(result, Is.EqualTo(expectedCell));
        }

        [Test]
        public void Calculate_EmptyRelation_ShouldReturnZero()
        {
            // Arrange
            var relation = new Relation();

            var expectedColumnHeader = new ColumnHeader("", "");
            var aggregate = new CountAggregate(new GetOriginalCellCellExpression(expectedColumnHeader));
            var expectedCell = new Cell(expectedColumnHeader, "0");

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(result, Is.EqualTo(expectedCell));
        }


        [Test]
        public void Calculate_AliasPassed_ShouldReturnCellWithNameSet()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "13"));

            var relation = new Relation();

            relation.AddRow(firstRow);

            var expectedColumnHeader = new ColumnHeader("", "count");
            var expectedCell = new Cell(expectedColumnHeader, "1");
            var aggregate = new CountAggregate(new GetOriginalCellCellExpression(expectedColumnHeader), "count");

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(result, Is.EqualTo(expectedCell));
        }
    }
}
using System;
using Model;
using NUnit.Framework;
using QueryLogic.Aggregates;
using QueryLogic.Expressions.CellExpressions;

namespace QueryLogic.Test.Aggregates
{
    public class CountColumnAggregateTests
    {
        [Test]
        public void Calculate_NotNullValuesPassed_ShouldReturnCount()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "13"));

            var secondRow = new Row();
            secondRow.AddCell(new Cell(columnHeader, "1"));

            var thirdRow = new Row();
            thirdRow.AddCell(new Cell(columnHeader, "10"));

            var relation = new Relation();

            relation.AddRow(firstRow);
            relation.AddRow(secondRow);
            relation.AddRow(thirdRow);

            var aggregate = new CountColumnAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));
            var expectedCell = new Cell(new ColumnHeader("", ""), "3");

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(Convert.ToDouble(result), Is.EqualTo(Convert.ToDouble(expectedCell)));
        }

        [Test]
        public void Calculate_ValuesWithNullPassed_ShouldReturnNonNullCount()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "14"));

            var secondRow = new Row();
            secondRow.AddCell(new Cell(columnHeader, null));

            var thirdRow = new Row();
            thirdRow.AddCell(new Cell(columnHeader, "10"));

            var relation = new Relation();

            relation.AddRow(firstRow);
            relation.AddRow(secondRow);
            relation.AddRow(thirdRow);

            var aggregate = new CountColumnAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));
            var expectedCell = new Cell(new ColumnHeader("", ""), "2");

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(Convert.ToDouble(result), Is.EqualTo(Convert.ToDouble(expectedCell)));
        }

        [Test]
        public void Calculate_NullsPassed_ShouldReturnValueZero()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, null));

            var secondRow = new Row();
            secondRow.AddCell(new Cell(columnHeader, null));

            var relation = new Relation();

            relation.AddRow(firstRow);
            relation.AddRow(secondRow);

            var aggregate = new CountColumnAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));
            var expectedCell = new Cell(new ColumnHeader("", ""), "0");

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(Convert.ToDouble(result), Is.EqualTo(Convert.ToDouble(expectedCell)));
        }

        [Test]
        public void Calculate_EmptyRelation_ShouldReturnValueZero()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");

            var relation = new Relation();

            var aggregate = new CountColumnAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));
            var expectedCell = new Cell(new ColumnHeader("", ""), "0");

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(Convert.ToDouble(result), Is.EqualTo(Convert.ToDouble(expectedCell)));
        }

        [Test]
        public void Calculate_AliasPassed_ShouldReturnCellWithSetName()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "13"));

            var relation = new Relation();

            relation.AddRow(firstRow);

            var aggregate = new CountColumnAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "count")), "count");
            var expectedCell = new Cell(new ColumnHeader("", "count"), "1");

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(Convert.ToDouble(result), Is.EqualTo(Convert.ToDouble(expectedCell)));
        }
    }
}
using System;
using Model;
using NUnit.Framework;
using QueryLogic.Aggregates;
using QueryLogic.Exceptions;
using QueryLogic.Expressions.CellExpressions;

namespace QueryLogic.Test.Aggregates
{
    internal class AverageAggregateTests
    {
        [Test]
        public void Calculate_NotNullDoublesPassed_ShouldReturnAverageValue()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "13"));

            var secondRow = new Row();
            secondRow.AddCell(new Cell(columnHeader, "1"));

            var thirdRow = new Row();
            thirdRow.AddCell(new Cell(columnHeader, "10"));

            var relation = new Relation();

            relation.AddRow(firstRow);
            relation.AddRow(secondRow);
            relation.AddRow(thirdRow);

            var aggregate = new AverageAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));
            var expectedCell = new Cell(new ColumnHeader("", ""), "8");

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(Convert.ToDouble(result), Is.EqualTo(Convert.ToDouble(expectedCell)));
        }

        [Test]
        public void Calculate_DoublesWithNullPassed_ShouldReturnAverageValue()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "14"));

            var secondRow = new Row();
            secondRow.AddCell(new Cell(columnHeader, null));

            var thirdRow = new Row();
            thirdRow.AddCell(new Cell(columnHeader, "10"));

            var relation = new Relation();

            relation.AddRow(firstRow);
            relation.AddRow(secondRow);
            relation.AddRow(thirdRow);

            var aggregate = new AverageAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));
            var expectedCell = new Cell(new ColumnHeader("", ""), "12");

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(Convert.ToDouble(result), Is.EqualTo(Convert.ToDouble(expectedCell)));
        }

        [Test]
        public void Calculate_NullsPassed_ShouldReturnNull()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, null));

            var secondRow = new Row();
            secondRow.AddCell(new Cell(columnHeader, null));

            var relation = new Relation();

            relation.AddRow(firstRow);
            relation.AddRow(secondRow);

            var aggregate = new AverageAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(result.Value, Is.Null);
        }

        [Test]
        public void Calculate_EmptyRelation_ShouldReturnNull()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");

            var relation = new Relation();

            var aggregate = new AverageAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(result.Value, Is.Null);
        }

        [Test]
        [ExpectedException(typeof(InvalidCellTypeException))]
        public void Calculate_ColumnTypeNotDouble_ShouldThrowInvalidCellTypeException()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "abc"));

            var relation = new Relation();

            relation.AddRow(firstRow);

            var aggregate = new AverageAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(columnHeader));

            // Act
            // ReSharper disable once UnusedVariable
            Cell result = aggregate.Calculate(relation);
        }

        [Test]
        public void Calculate_AliasPassed_ShouldReturnCellWithSetName()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "13"));

            var relation = new Relation();

            relation.AddRow(firstRow);

            var aggregate = new AverageAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "avg")), "avg");
            var expectedCell = new Cell(new ColumnHeader("", "avg"), "13");

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(Convert.ToDouble(result), Is.EqualTo(Convert.ToDouble(expectedCell)));
        }

        [Test]
        public void Calculate_ManyTimesCalled_ShouldReturnCorrectValueForEachRelation()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "13"));

            var relation = new Relation();

            relation.AddRow(firstRow);

            var aggregate = new AverageAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));
            var expectedCell = new Cell(new ColumnHeader("", ""), "13");

            // Act
            Cell firstResult = aggregate.Calculate(relation);
            Cell secondResult = aggregate.Calculate(relation);

            // Assert
            Assert.That(Convert.ToDouble(firstResult), Is.EqualTo(Convert.ToDouble(expectedCell)));
            Assert.That(Convert.ToDouble(secondResult), Is.EqualTo(Convert.ToDouble(expectedCell)));
        }

        [Test]
        public void Calculate_ManyTimesCalled_ShouldReturnCorrectValueForEachInvocation()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRelation = new Relation(new[]
            {
                new Row(new[]
                {
                    new Cell(columnHeader, "13")
                })
            });

            var secondRelation = new Relation(new[]
            {
                new Row(new[]
                {
                    new Cell(columnHeader, "11")
                })
            });

            var thirdRelation = new Relation(new[]
            {
                new Row(new[]
                {
                    new Cell(columnHeader, null)
                })
            });

            var aggregate = new AverageAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));
            var firstExpectedCell = new Cell(new ColumnHeader("", ""), "13");
            var secondExpectedCell = new Cell(new ColumnHeader("", ""), "11");
            var thirdExpectedCell = new Cell(new ColumnHeader("", ""), null);

            // Act
            Cell firstResult = aggregate.Calculate(firstRelation);
            Cell secondResult = aggregate.Calculate(secondRelation);
            Cell thirdResult = aggregate.Calculate(thirdRelation);

            // Assert
            Assert.That(Convert.ToDouble(firstResult), Is.EqualTo(Convert.ToDouble(firstExpectedCell)));
            Assert.That(Convert.ToDouble(secondResult), Is.EqualTo(Convert.ToDouble(secondExpectedCell)));
            Assert.That(thirdResult, Is.EqualTo(thirdExpectedCell));
        }
    }
}
using System;
using Model;
using NUnit.Framework;
using QueryLogic.Aggregates;
using QueryLogic.Exceptions;
using QueryLogic.Expressions.CellExpressions;

namespace QueryLogic.Test.Aggregates
{
    internal class MaximumAggregateTests
    {
        [Test]
        public void Calculate_NotNullDoublesPassed_ShouldReturnMaximumDouble()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "13"));

            var secondRow = new Row();
            secondRow.AddCell(new Cell(columnHeader, "1"));

            var thirdRow = new Row();
            thirdRow.AddCell(new Cell(columnHeader, "10"));

            var relation = new Relation();

            relation.AddRow(firstRow);
            relation.AddRow(secondRow);
            relation.AddRow(thirdRow);

            var aggregate = new MaximumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));
            var expectedCell = new Cell(new ColumnHeader("", ""), "13");

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(Convert.ToDouble(result), Is.EqualTo(Convert.ToDouble(expectedCell)));
        }

        [Test]
        public void Calculate_DoublesWithNullPassed_ShouldReturnMaximumDouble()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, null));

            var secondRow = new Row();
            secondRow.AddCell(new Cell(columnHeader, "1"));

            var thirdRow = new Row();
            thirdRow.AddCell(new Cell(columnHeader, "10"));

            var relation = new Relation();

            relation.AddRow(firstRow);
            relation.AddRow(secondRow);
            relation.AddRow(thirdRow);

            var aggregate = new MaximumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));
            var expectedCell = new Cell(new ColumnHeader("", ""), "10");

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(Convert.ToDouble(result), Is.EqualTo(Convert.ToDouble(expectedCell)));
        }

        [Test]
        public void Calculate_NullsPassed_ShouldReturnNull()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, null));

            var secondRow = new Row();
            secondRow.AddCell(new Cell(columnHeader, null));

            var relation = new Relation();

            relation.AddRow(firstRow);
            relation.AddRow(secondRow);

            var aggregate = new MaximumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(result.Value, Is.Null);
        }

        [Test]
        public void Calculate_NotNullDatesPassed_ShouldReturnMaximumDate()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "2003-12-23"));

            var secondRow = new Row();
            secondRow.AddCell(new Cell(columnHeader, "2003-12-21"));

            var thirdRow = new Row();
            thirdRow.AddCell(new Cell(columnHeader, "2003-12-27"));

            var relation = new Relation();

            relation.AddRow(firstRow);
            relation.AddRow(secondRow);
            relation.AddRow(thirdRow);

            var aggregate = new MaximumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));
            var expectedCell = new Cell(new ColumnHeader("", ""), "2003-12-27");

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(Convert.ToDateTime(result), Is.EqualTo(Convert.ToDateTime(expectedCell)));
        }


        [Test]
        public void Calculate_DatesWithNullPassed_ShouldReturnMaximumDate()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "2003-12-23"));

            var secondRow = new Row();
            secondRow.AddCell(new Cell(columnHeader, null));

            var thirdRow = new Row();
            thirdRow.AddCell(new Cell(columnHeader, "2003-12-27"));

            var relation = new Relation();

            relation.AddRow(firstRow);
            relation.AddRow(secondRow);
            relation.AddRow(thirdRow);

            var aggregate = new MaximumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));
            var expectedCell = new Cell(new ColumnHeader("", ""), "2003-12-27");

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(Convert.ToDateTime(result), Is.EqualTo(Convert.ToDateTime(expectedCell)));
        }

        [Test]
        public void Calculate_EmptyRelation_ShouldReturnNull()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");

            var relation = new Relation();

            var aggregate = new MaximumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(result.Value, Is.Null);
        }

        [Test]
        [ExpectedException(typeof(InvalidCellTypeException))]
        public void Calculate_ColumnTypeOtherThanDateTimeOrDouble_ShouldThrowInvalidCellTypeException()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "abc"));

            var relation = new Relation();

            relation.AddRow(firstRow);

            var aggregate = new MaximumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));

            // Act
            // ReSharper disable once UnusedVariable
            Cell result = aggregate.Calculate(relation);
        }

        [Test]
        [ExpectedException(typeof(InvalidCellTypeException))]
        public void Calculate_CellsWithMixedColumnType_ShouldThrowInvalidCellTypeException()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "123"));
            var secondRow = new Row();
            secondRow.AddCell(new Cell(columnHeader, "2003-12-27"));

            var relation = new Relation();

            relation.AddRow(firstRow);
            relation.AddRow(secondRow);

            var aggregate = new MaximumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));

            // Act
            // ReSharper disable once UnusedVariable
            Cell result = aggregate.Calculate(relation);
        }

        [Test]
        public void Calculate_AliasPassed_ShouldReturnCellWithNameSet()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "13"));

            var relation = new Relation();

            relation.AddRow(firstRow);

            var aggregate = new MaximumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "max")), "max");
            var expectedCell = new Cell(new ColumnHeader("", "max"), "13");

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(Convert.ToDouble(result), Is.EqualTo(Convert.ToDouble(expectedCell)));
        }

        [Test]
        public void Calculate_ManyTimesCalled_ShouldReturnCorrectValueForEachInvocation()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRelation = new Relation(new[]
            {
                new Row(new[]
                {
                    new Cell(columnHeader, "13")
                }),
                new Row(new[]
                {
                    new Cell(columnHeader, "12")
                })
            });

            var secondRelation = new Relation(new[]
            {
                new Row(new[]
                {
                    new Cell(columnHeader, "11")
                }),
                new Row(new[]
                {
                    new Cell(columnHeader, "12")
                })
            });

            var thirdRelation = new Relation(new[]
            {
                new Row(new[]
                {
                    new Cell(columnHeader, null)
                })
            });

            var aggregate = new MaximumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));
            var firstExpectedCell = new Cell(new ColumnHeader("", ""), "13");
            var secondExpectedCell = new Cell(new ColumnHeader("", ""), "12");
            var thirdExpectedCell = new Cell(new ColumnHeader("", ""), null);

            // Act
            Cell firstResult = aggregate.Calculate(firstRelation);
            Cell secondResult = aggregate.Calculate(secondRelation);
            Cell thirdResult = aggregate.Calculate(thirdRelation);

            // Assert
            Assert.That(Convert.ToDouble(firstResult), Is.EqualTo(Convert.ToDouble(firstExpectedCell)));
            Assert.That(Convert.ToDouble(secondResult), Is.EqualTo(Convert.ToDouble(secondExpectedCell)));
            Assert.That(thirdResult, Is.EqualTo(thirdExpectedCell));
        }
    }
}
using System;
using Model;
using NUnit.Framework;
using QueryLogic.Aggregates;
using QueryLogic.Exceptions;
using QueryLogic.Expressions.CellExpressions;

namespace QueryLogic.Test.Aggregates
{
    internal class MinimumAggregateTests
    {
        [Test]
        public void Calculate_NotNullDoublesPassed_ShouldReturnMinimumDouble()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "13"));

            var secondRow = new Row();
            secondRow.AddCell(new Cell(columnHeader, "1"));

            var thirdRow = new Row();
            thirdRow.AddCell(new Cell(columnHeader, "10"));

            var relation = new Relation();

            relation.AddRow(firstRow);
            relation.AddRow(secondRow);
            relation.AddRow(thirdRow);

            var aggregate = new MinimumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));
            var expectedCell = new Cell(new ColumnHeader("", ""), "1");

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(Convert.ToDouble(result), Is.EqualTo(Convert.ToDouble(expectedCell)));
        }

        [Test]
        public void Calculate_DoublesWithNullPassed_ShouldReturnMinimumDouble()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, null));

            var secondRow = new Row();
            secondRow.AddCell(new Cell(columnHeader, "1"));

            var thirdRow = new Row();
            thirdRow.AddCell(new Cell(columnHeader, "10"));

            var relation = new Relation();

            relation.AddRow(firstRow);
            relation.AddRow(secondRow);
            relation.AddRow(thirdRow);

            var aggregate = new MinimumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));
            var expectedCell = new Cell(new ColumnHeader("", ""), "1");

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(Convert.ToDouble(result), Is.EqualTo(Convert.ToDouble(expectedCell)));
        }


        [Test]
        public void Calculate_NullsPassed_ShouldReturnNull()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, null));

            var secondRow = new Row();
            secondRow.AddCell(new Cell(columnHeader, null));

            var relation = new Relation();

            relation.AddRow(firstRow);
            relation.AddRow(secondRow);

            var aggregate = new MinimumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(result.Value, Is.Null);
        }

        [Test]
        public void Calculate_NotNullDatesPassed_ShouldReturnMinimumDate()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "2003-12-23"));

            var secondRow = new Row();
            secondRow.AddCell(new Cell(columnHeader, "2003-12-21"));

            var thirdRow = new Row();
            thirdRow.AddCell(new Cell(columnHeader, "2003-12-27"));

            var relation = new Relation();

            relation.AddRow(firstRow);
            relation.AddRow(secondRow);
            relation.AddRow(thirdRow);

            var aggregate = new MinimumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));
            var expectedCell = new Cell(new ColumnHeader("", ""), "2003-12-21");

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(Convert.ToDateTime(result), Is.EqualTo(Convert.ToDateTime(expectedCell)));
        }

        [Test]
        public void Calculate_DatesWithNullPassed_ShouldReturnMinimumDate()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, null));

            var secondRow = new Row();
            secondRow.AddCell(new Cell(columnHeader, "2003-12-21"));

            var thirdRow = new Row();
            thirdRow.AddCell(new Cell(columnHeader, "2003-12-27"));

            var relation = new Relation();

            relation.AddRow(firstRow);
            relation.AddRow(secondRow);
            relation.AddRow(thirdRow);

            var aggregate = new MinimumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));
            var expectedCell = new Cell(new ColumnHeader("", ""), "2003-12-21");

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(Convert.ToDateTime(result), Is.EqualTo(Convert.ToDateTime(expectedCell)));
        }

        [Test]
        public void Calculate_EmptyRelation_ShouldReturnNull()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");

            var relation = new Relation();

            var aggregate = new MinimumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(result.Value, Is.Null);
        }

        [Test]
        [ExpectedException(typeof(InvalidCellTypeException))]
        public void Calcluate_ColumnTypeDifferentThanDateTimeOrDouble_ShouldThrowInvalidCellTypeException()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "abc"));

            var relation = new Relation();

            relation.AddRow(firstRow);

            var aggregate = new MinimumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));

            // Act
            // ReSharper disable once UnusedVariable
            Cell result = aggregate.Calculate(relation);
        }

        [Test]
        [ExpectedException(typeof(InvalidCellTypeException))]
        public void Calculate_CellsWithMixedColumnType_ShouldThrowInvalidCellTypeException()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "123"));
            var secondRow = new Row();
            secondRow.AddCell(new Cell(columnHeader, "2003-12-27"));

            var relation = new Relation();

            relation.AddRow(firstRow);
            relation.AddRow(secondRow);

            var aggregate = new MinimumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));

            // Act
            // ReSharper disable once UnusedVariable
            Cell result = aggregate.Calculate(relation);
        }

        [Test]
        public void Calculate_AliasPassed_ShouldReturnCellWithNameSet()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "13"));

            var relation = new Relation();

            relation.AddRow(firstRow);

            var aggregate = new MinimumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "min")), "min");
            var expectedCell = new Cell(new ColumnHeader("", "min"), "13");

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(Convert.ToDouble(result), Is.EqualTo(Convert.ToDouble(expectedCell)));
        }

        [Test]
        public void Calculate_ManyTimesCalled_ShouldReturnCorrectValueForEachInvocation()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRelation = new Relation(new[]
            {
                new Row(new[]
                {
                    new Cell(columnHeader, "13")
                }),
                new Row(new[]
                {
                    new Cell(columnHeader, "12")
                })
            });

            var secondRelation = new Relation(new[]
            {
                new Row(new[]
                {
                    new Cell(columnHeader, "13")
                }),
                new Row(new[]
                {
                    new Cell(columnHeader, "14")
                })
            });

            var thirdRelation = new Relation(new[]
            {
                new Row(new[]
                {
                    new Cell(columnHeader, null)
                })
            });

            var aggregate = new MinimumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));
            var firstExpectedCell = new Cell(new ColumnHeader("", ""), "12");
            var secondExpectedCell = new Cell(new ColumnHeader("", ""), "13");
            var thirdExpectedCell = new Cell(new ColumnHeader("", ""), null);

            // Act
            Cell firstResult = aggregate.Calculate(firstRelation);
            Cell secondResult = aggregate.Calculate(secondRelation);
            Cell thirdResult = aggregate.Calculate(thirdRelation);

            // Assert
            Assert.That(Convert.ToDouble(firstResult), Is.EqualTo(Convert.ToDouble(firstExpectedCell)));
            Assert.That(Convert.ToDouble(secondResult), Is.EqualTo(Convert.ToDouble(secondExpectedCell)));
            Assert.That(thirdResult, Is.EqualTo(thirdExpectedCell));
        }
    }
}
using System;
using Model;
using NUnit.Framework;
using QueryLogic.Aggregates;
using QueryLogic.Exceptions;
using QueryLogic.Expressions.CellExpressions;

namespace QueryLogic.Test.Aggregates
{
    internal class SumAggregateTests
    {
        [Test]
        public void Calculate_NotNullDoublesPassed_ShouldReturnSum()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "13"));

            var secondRow = new Row();
            secondRow.AddCell(new Cell(columnHeader, "1"));

            var thirdRow = new Row();
            thirdRow.AddCell(new Cell(columnHeader, "10"));

            var relation = new Relation();

            relation.AddRow(firstRow);
            relation.AddRow(secondRow);
            relation.AddRow(thirdRow);

            var aggregate = new SumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));
            var expectedCell = new Cell(new ColumnHeader("", ""), "24");

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(Convert.ToDouble(result), Is.EqualTo(Convert.ToDouble(expectedCell)));
        }

        [Test]
        public void Calculate_DoublesAndNullPassed_ShouldReturnSum()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, null));

            var secondRow = new Row();
            secondRow.AddCell(new Cell(columnHeader, "1"));

            var thirdRow = new Row();
            thirdRow.AddCell(new Cell(columnHeader, "10"));

            var relation = new Relation();

            relation.AddRow(firstRow);
            relation.AddRow(secondRow);
            relation.AddRow(thirdRow);

            var aggregate = new SumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));
            var expectedCell = new Cell(new ColumnHeader("", ""), "11");

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(Convert.ToDouble(result), Is.EqualTo(Convert.ToDouble(expectedCell)));
        }


        [Test]
        public void Calculate_NullsPassed_ShouldReturnNull()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, null));

            var secondRow = new Row();
            secondRow.AddCell(new Cell(columnHeader, null));

            var relation = new Relation();

            relation.AddRow(firstRow);
            relation.AddRow(secondRow);

            var aggregate = new SumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(result.Value, Is.Null);
        }

        [Test]
        public void Calculate_EmptyRelation_ShouldReturnNull()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");

            var relation = new Relation();

            var aggregate = new SumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(result.Value, Is.Null);
        }

        [Test]
        [ExpectedException(typeof(InvalidCellTypeException))]
        public void Calculate_TypeNotDouble_ShouldThrowInvalidCellTypeException()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "abc"));

            var relation = new Relation();

            relation.AddRow(firstRow);

            var aggregate = new SumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));

            // Act
            // ReSharper disable once UnusedVariable
            Cell result = aggregate.Calculate(relation);
        }


        [Test]
        public void Calculate_AliasPassed_ShouldReturnCellWithNameSet()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "13"));

            var relation = new Relation();

            relation.AddRow(firstRow);

            var aggregate = new SumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "sum")), "sum");
            var expectedCell = new Cell(new ColumnHeader("", "sum"), "13");

            // Act
            Cell result = aggregate.Calculate(relation);

            // Assert
            Assert.That(Convert.ToDouble(result), Is.EqualTo(Convert.ToDouble(expectedCell)));
        }

        [Test]
        public void Calculate_ManyTimesCalled_ShouldReturnCorrectValueForEachInvocation()
        {
            // Arrange
            var columnHeader = new ColumnHeader("schema", "Column1");
            var firstRow = new Row();
            firstRow.AddCell(new Cell(columnHeader, "13"));

            var relation = new Relation();

            relation.AddRow(firstRow);

            var aggregate = new SumAggregate(new GetOriginalCellCellExpression(columnHeader), new GetOriginalCellCellExpression(new ColumnHeader("", "")));
            var expectedCell = new Cell(new ColumnHeader("", ""), "13");

            // Act
            Cell firstResult = aggregate.Calculate(relation);
            Cell secondResult = aggregate.Calculate(relation);

            // Assert
            Assert.That(Convert.ToDouble(firstResult), Is.EqualTo(Convert.ToDouble(expectedCell)));
            Assert.That(Convert.ToDouble(secondResult), Is.EqualTo(Convert.ToDouble(expectedCell)));
        }
    }
}

That’s all. In the next part we will implement various functions for dates, strings, etc.