public static void GetCell_sectionCellLocator___Should_throw_CellNotFoundException___When_addressing_slotted_cell_and_SlotId_not_specified_and_SlotSelectionStrategy_is_ThrowIfSlotIdNotSpecified()
        {
            // Arrange
            var report = A.Dummy <Report>().Whose(_ => _.Sections.Any(s => s.TreeTable.GetAllCells().Any(c => c is ISlottedCell)));

            var section = report.Sections.First(_ => _.TreeTable.GetAllCells().Any(c => c is ISlottedCell));

            var allCells = section.TreeTable.GetAllCells();

            var cell = allCells.First(_ => _ is ISlottedCell);

            var currentCell = allCells.First(_ => !_.Equals(cell));

            var sectionCellLocator = new SectionCellLocator(cell.Id, null, SlotSelectionStrategy.ThrowIfSlotIdNotSpecified);

            var expectedReportCellLocator = new ReportCellLocator(section.Id, sectionCellLocator.CellId, sectionCellLocator.SlotId);

            var systemUnderTest = new ReportCache(report);

            // Act
            var actual = Record.Exception(() => systemUnderTest.GetCell(sectionCellLocator, currentCell));

            // Assert
            actual.AsTest().Must().BeOfType <CellNotFoundException>();
            actual.Message.AsTest().Must().ContainString(Invariant($"The operation addresses an {nameof(ISlottedCell)} (and not a slot within that cell) and {nameof(SlotSelectionStrategy)} is {nameof(SlotSelectionStrategy.ThrowIfSlotIdNotSpecified)}."));
            ((CellNotFoundException)actual).CellLocator.AsTest().Must().BeEqualTo((CellLocatorBase)expectedReportCellLocator);
        }
        public static void GetCell_sectionCellLocator___Should_throw_CellNotFoundException___When_addressing_slotted_cell_but_there_is_no_slot_having_slotId()
        {
            // Arrange
            var report = A.Dummy <Report>().Whose(_ => _.Sections.Any(s => s.TreeTable.GetAllCells().Any(c => c is ISlottedCell)));

            var section = report.Sections.First(_ => _.TreeTable.GetAllCells().Any(c => c is ISlottedCell));

            var allCells = section.TreeTable.GetAllCells();

            var cell = allCells.First(_ => _ is ISlottedCell);

            var currentCell = allCells.First(_ => !_.Equals(cell));

            var sectionCellLocator = new SectionCellLocator(cell.Id, A.Dummy <string>());

            var expectedReportCellLocator = new ReportCellLocator(section.Id, sectionCellLocator.CellId, sectionCellLocator.SlotId);

            var systemUnderTest = new ReportCache(report);

            // Act
            var actual = Record.Exception(() => systemUnderTest.GetCell(sectionCellLocator, currentCell));

            // Assert
            actual.AsTest().Must().BeOfType <CellNotFoundException>();
            actual.Message.AsTest().Must().ContainString(Invariant($"Slot id '{sectionCellLocator.SlotId}' was specified, but the addressed cell '{cell.Id}' in section '{section.Id}' does not contain a slot having that id."));
            ((CellNotFoundException)actual).CellLocator.AsTest().Must().BeEqualTo((CellLocatorBase)expectedReportCellLocator);
        }
        public static void GetCell_reportCellLocator___Should_throw_CellNotFoundException___When_section_is_not_found()
        {
            // Arrange
            var report = A.Dummy <Report>();

            var reportCellLocator = new ReportCellLocator(A.Dummy <string>(), report.Sections.First().TreeTable.GetAllCells().First().Id);

            var systemUnderTest = new ReportCache(report);

            // Act
            var actual = Record.Exception(() => systemUnderTest.GetCell(reportCellLocator));

            // Assert
            actual.AsTest().Must().BeOfType <CellNotFoundException>();
            actual.Message.AsTest().Must().ContainString(Invariant($"There is no section with id '{reportCellLocator.SectionId}'."));
            ((CellNotFoundException)actual).CellLocator.AsTest().Must().BeEqualTo((CellLocatorBase)reportCellLocator);
        }
        public static void GetCell_reportCellLocator___Should_return_cell___When_cell_is_not_slotted()
        {
            // Arrange
            var report = A.Dummy <Report>();

            var section = report.Sections.First();

            var expected = section.TreeTable.GetAllCells().First(_ => _ is INotSlottedCell);

            var reportCellLocator = new ReportCellLocator(section.Id, expected.Id);

            var systemUnderTest = new ReportCache(report);

            // Act
            var actual = systemUnderTest.GetCell(reportCellLocator);

            // Assert
            actual.AsTest().Must().BeSameReferenceAs(expected);
        }
        public static void GetCell_reportCellLocator___Should_throw_CellNotFoundException___When_cell_with_specified_id_is_not_found()
        {
            // Arrange
            var report = A.Dummy <Report>();

            var section = report.Sections.First();

            var reportCellLocator = new ReportCellLocator(section.Id, A.Dummy <string>());

            var systemUnderTest = new ReportCache(report);

            // Act
            var actual = Record.Exception(() => systemUnderTest.GetCell(reportCellLocator));

            // Assert
            actual.AsTest().Must().BeOfType <CellNotFoundException>();
            actual.Message.AsTest().Must().ContainString(Invariant($"There is no cell with id '{reportCellLocator.CellId}' in section '{section.Id}'."));
            ((CellNotFoundException)actual).CellLocator.AsTest().Must().BeEqualTo((CellLocatorBase)reportCellLocator);
        }
        public static void GetCell_reportCellLocator___Should_return_cell_in_default_slot___When_addressing_slotted_cell_and_SlotSelectionStrategy_is_DefaultSlot()
        {
            // Arrange
            var report = A.Dummy <Report>().Whose(_ => _.Sections.Any(s => s.TreeTable.GetAllCells().Any(c => c is ISlottedCell)));

            var section = report.Sections.First(_ => _.TreeTable.GetAllCells().Any(c => c is ISlottedCell));

            var cell = section.TreeTable.GetAllCells().OfType <ISlottedCell>().First();

            var expected = (ICell)cell.SlotIdToCellMap[cell.DefaultSlotId];

            var reportCellLocator = new ReportCellLocator(section.Id, cell.Id, null, SlotSelectionStrategy.DefaultSlot);

            var systemUnderTest = new ReportCache(report);

            // Act
            var actual = systemUnderTest.GetCell(reportCellLocator);

            // Assert
            actual.AsTest().Must().BeSameReferenceAs(expected);
        }
        public static void GetCell_reportCellLocator___Should_throw_CellNotFoundException___When_slotId_specified_for_cell_that_is_not_slotted()
        {
            // Arrange
            var report = A.Dummy <Report>();

            var section = report.Sections.First();

            var cell = section.TreeTable.GetAllCells().First(_ => _ is INotSlottedCell);

            var reportCellLocator = new ReportCellLocator(section.Id, cell.Id, A.Dummy <string>());

            var systemUnderTest = new ReportCache(report);

            // Act
            var actual = Record.Exception(() => systemUnderTest.GetCell(reportCellLocator));

            // Assert
            actual.AsTest().Must().BeOfType <CellNotFoundException>();
            actual.Message.AsTest().Must().ContainString(Invariant($"Slot id '{reportCellLocator.SlotId}' was specified, but the addressed cell '{cell.Id}' in section '{section.Id}' is not a slotted cell"));
            ((CellNotFoundException)actual).CellLocator.AsTest().Must().BeEqualTo((CellLocatorBase)reportCellLocator);
        }
        static ReportCellLocatorTest()
        {
            ConstructorArgumentValidationTestScenarios
            .RemoveAllScenarios()
            .AddScenario(() =>
                         new ConstructorArgumentValidationTestScenario <ReportCellLocator>
            {
                Name             = "constructor should throw ArgumentNullException when parameter 'sectionId' is null scenario",
                ConstructionFunc = () =>
                {
                    var referenceObject = A.Dummy <ReportCellLocator>();

                    var result = new ReportCellLocator(
                        null,
                        referenceObject.CellId,
                        referenceObject.SlotId,
                        referenceObject.SlotSelectionStrategy);

                    return(result);
                },
                ExpectedExceptionType            = typeof(ArgumentNullException),
                ExpectedExceptionMessageContains = new[] { "sectionId", },
            })
            .AddScenario(() =>
                         new ConstructorArgumentValidationTestScenario <ReportCellLocator>
            {
                Name             = "constructor should throw ArgumentException when parameter 'sectionId' is white space scenario",
                ConstructionFunc = () =>
                {
                    var referenceObject = A.Dummy <ReportCellLocator>();

                    var result = new ReportCellLocator(
                        Invariant($"  {Environment.NewLine}  "),
                        referenceObject.CellId,
                        referenceObject.SlotId,
                        referenceObject.SlotSelectionStrategy);

                    return(result);
                },
                ExpectedExceptionType            = typeof(ArgumentException),
                ExpectedExceptionMessageContains = new[] { "sectionId", "white space", },
            })
            .AddScenario(() =>
                         new ConstructorArgumentValidationTestScenario <ReportCellLocator>
            {
                Name             = "constructor should throw ArgumentNullException when parameter 'cellId' is null scenario",
                ConstructionFunc = () =>
                {
                    var referenceObject = A.Dummy <ReportCellLocator>();

                    var result = new ReportCellLocator(
                        referenceObject.SectionId,
                        null,
                        referenceObject.SlotId,
                        referenceObject.SlotSelectionStrategy);

                    return(result);
                },
                ExpectedExceptionType            = typeof(ArgumentNullException),
                ExpectedExceptionMessageContains = new[] { "cellId", },
            })
            .AddScenario(() =>
                         new ConstructorArgumentValidationTestScenario <ReportCellLocator>
            {
                Name             = "constructor should throw ArgumentException when parameter 'cellId' is white space scenario",
                ConstructionFunc = () =>
                {
                    var referenceObject = A.Dummy <ReportCellLocator>();

                    var result = new ReportCellLocator(
                        referenceObject.SectionId,
                        Invariant($"  {Environment.NewLine}  "),
                        referenceObject.SlotId,
                        referenceObject.SlotSelectionStrategy);

                    return(result);
                },
                ExpectedExceptionType            = typeof(ArgumentException),
                ExpectedExceptionMessageContains = new[] { "cellId", "white space", },
            })
            .AddScenario(() =>
                         new ConstructorArgumentValidationTestScenario <ReportCellLocator>
            {
                Name             = "constructor should throw ArgumentOutOfRangeException when parameter 'slotSelectionStrategy' is SlotSelectionStrategy.Unknown",
                ConstructionFunc = () =>
                {
                    var referenceObject = A.Dummy <ReportCellLocator>();

                    var result = new ReportCellLocator(
                        referenceObject.SectionId,
                        referenceObject.CellId,
                        referenceObject.SlotId,
                        SlotSelectionStrategy.Unknown);

                    return(result);
                },
                ExpectedExceptionType            = typeof(ArgumentOutOfRangeException),
                ExpectedExceptionMessageContains = new[] { "slotSelectionStrategy", "Unknown", },
            });
        }