public void TestDoAggregationWithBadData() { IList <Test> data = GetTestData(); var totalPanel = new ExcelTotalsPanel(data, Substitute.For <IXLNamedRange>(), Substitute.For <object>(), new TestReport().TemplateProcessor); IEnumerator enumerator = EnumeratorFactory.Create(data); IList <ExcelTotalsPanel.ParsedAggregationFunc> totalCells = new List <ExcelTotalsPanel.ParsedAggregationFunc> { new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Sum, "di:TestColumn4"), }; MethodInfo method = totalPanel.GetType().GetMethod("DoAggregation", BindingFlags.Instance | BindingFlags.NonPublic); ExceptionAssert.ThrowsBaseException <RuntimeBinderException>(() => method.Invoke(totalPanel, new object[] { enumerator, totalCells, null })); enumerator.Reset(); totalCells = new List <ExcelTotalsPanel.ParsedAggregationFunc> { new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Min, "di:BadColumn"), }; ExceptionAssert.ThrowsBaseException <InvalidOperationException>(() => method.Invoke(totalPanel, new object[] { enumerator, totalCells, null }), "For Min and Max aggregation functions data items must implement IComparable interface"); enumerator.Reset(); totalCells = new List <ExcelTotalsPanel.ParsedAggregationFunc> { new ExcelTotalsPanel.ParsedAggregationFunc((AggregateFunction)6, "di:TestColumn1"), }; ExceptionAssert.ThrowsBaseException <NotSupportedException>(() => method.Invoke(totalPanel, new object[] { enumerator, totalCells, null }), "Unsupportable aggregation function"); }
public void TestAggregationPostOperation() { IList <Test> data = GetTestData(); var totalPanel = new ExcelTotalsPanel(data, Substitute.For <IXLNamedRange>(), new TestReportForAggregation(), new TestReport().TemplateProcessor); IEnumerator enumerator = EnumeratorFactory.Create(data); IList <ExcelTotalsPanel.ParsedAggregationFunc> totalCells = new List <ExcelTotalsPanel.ParsedAggregationFunc> { new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Sum, "di:TestColumn2") { PostProcessFunction = "PostSumOperation" }, new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Min, "di:TestColumn3") { PostProcessFunction = "PostMinOperation" }, new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Custom, "di:TestColumn2") { CustomFunc = "CustomAggregation", PostProcessFunction = "PostCustomAggregation", }, }; MethodInfo method = totalPanel.GetType().GetMethod("DoAggregation", BindingFlags.Instance | BindingFlags.NonPublic); method.Invoke(totalPanel, new object[] { enumerator, totalCells, null }); Assert.AreEqual(22.033.ToString("F3"), totalCells[0].Result); Assert.AreEqual("ABC", totalCells[1].Result); Assert.AreEqual(24, totalCells[2].Result); }
public IEnumerator <TOutput> GetEnumerator() { if (typeof(TOutput) == typeof(bool) || typeof(TOutput) == typeof(bool?)) { return(BoolEnumerator()); } return(EnumeratorFactory.Create <TOutput>(_input)); }
public override void Render() { // Receive parent data item context HierarchicalDataItem parentDataItem = GetDataContext(); _data = _isDataReceivedDirectly ? _data : _templateProcessor.GetValue(_dataSourceTemplate, parentDataItem); bool isCanceled = CallBeforeRenderMethod(); if (isCanceled) { ResultRange = ExcelHelper.CloneRange(Range); return; } ICustomEnumerator enumerator = null; try { enumerator = EnumeratorFactory.Create(_data) ?? new EnumerableEnumerator(new object[] { }); IDictionary <IXLCell, IList <ParsedAggregationFunc> > totalCells = ParseTotalCells(); DoAggregation(enumerator, totalCells.SelectMany(t => t.Value).ToArray(), parentDataItem); IXLWorksheet ws = Range.Worksheet; dynamic dataSource = new ExpandoObject(); var dataSourceAsDict = (IDictionary <string, object>)dataSource; foreach (KeyValuePair <IXLCell, IList <ParsedAggregationFunc> > totalCell in totalCells) { IList <ParsedAggregationFunc> aggFuncs = totalCell.Value; foreach (ParsedAggregationFunc f in aggFuncs) { dataSourceAsDict[$"AggFunc_{f.UniqueName}"] = f.Result; } } string rangeName = $"AggFuncs_{Guid.NewGuid():N}"; Range.AddToNamed(rangeName, XLScope.Worksheet); var dataPanel = new ExcelDataSourcePanel(new[] { dataSource }, ws.NamedRange(rangeName), _report, _templateProcessor) { Parent = Parent }; dataPanel.Render(); ResultRange = ExcelHelper.MergeRanges(Range, dataPanel.ResultRange); } finally { (enumerator as IDisposable)?.Dispose(); } RemoveName(); CallAfterRenderMethod(); }
public void TestDoAggregationWithIntData() { int[] data = new DataProvider().GetIntData(); var totalPanel = new ExcelTotalsPanel(data, Substitute.For <IXLNamedRange>(), Substitute.For <object>(), new TestReport().TemplateProcessor); IEnumerator enumerator = EnumeratorFactory.Create(data); IList <ExcelTotalsPanel.ParsedAggregationFunc> totalCells = new List <ExcelTotalsPanel.ParsedAggregationFunc> { new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Sum, "di:di"), new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Avg, "di:di"), }; MethodInfo method = totalPanel.GetType().GetMethod("DoAggregation", BindingFlags.Instance | BindingFlags.NonPublic); method.Invoke(totalPanel, new object[] { enumerator, totalCells, null }); Assert.AreEqual(55, totalCells[0].Result); Assert.AreEqual(5.5, totalCells[1].Result); }
public void TestCreate() { Assert.IsNull(EnumeratorFactory.Create(null)); Assert.IsInstanceOf <EnumerableEnumerator>(EnumeratorFactory.Create(new List <string>())); Assert.IsInstanceOf <EnumerableEnumerator>(EnumeratorFactory.Create(new int[0])); Assert.IsInstanceOf <EnumerableEnumerator>(EnumeratorFactory.Create(new Dictionary <string, object>())); Assert.IsInstanceOf <EnumerableEnumerator>(EnumeratorFactory.Create(new HashSet <string>())); Assert.IsInstanceOf <EnumerableEnumerator>(EnumeratorFactory.Create(new Hashtable())); Assert.IsInstanceOf <EnumerableEnumerator>(EnumeratorFactory.Create(new ArrayList())); var dataSet = new DataSet(); dataSet.Tables.Add(new DataTable()); Assert.IsInstanceOf <DataSetEnumerator>(EnumeratorFactory.Create(dataSet)); Assert.IsInstanceOf <DataTableEnumerator>(EnumeratorFactory.Create(new DataTable())); var dataReader = Substitute.For <IDataReader>(); Assert.IsInstanceOf <DataReaderEnumerator>(EnumeratorFactory.Create(dataReader)); }
public void TestCustomAggregation() { IList <Test> data = GetTestData(); var totalPanel = new ExcelTotalsPanel(data, Substitute.For <IXLNamedRange>(), new TestReportForAggregation(), new TestReport().TemplateProcessor); IEnumerator enumerator = EnumeratorFactory.Create(data); IList <ExcelTotalsPanel.ParsedAggregationFunc> totalCells = new List <ExcelTotalsPanel.ParsedAggregationFunc> { new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Custom, "di:TestColumn2") { CustomFunc = "CustomAggregation", }, }; MethodInfo method = totalPanel.GetType().GetMethod("DoAggregation", BindingFlags.Instance | BindingFlags.NonPublic); method.Invoke(totalPanel, new object[] { enumerator, totalCells, null }); Assert.AreEqual(24.18125m, totalCells.First().Result); enumerator.Reset(); totalCells.First().CustomFunc = null; ExceptionAssert.ThrowsBaseException <InvalidOperationException>(() => method.Invoke(totalPanel, new object[] { enumerator, totalCells, null }), "The custom type of aggregation is specified in the template but custom function is missing"); enumerator.Reset(); totalCells.First().CustomFunc = string.Empty; ExceptionAssert.ThrowsBaseException <InvalidOperationException>(() => method.Invoke(totalPanel, new object[] { enumerator, totalCells, null }), "The custom type of aggregation is specified in the template but custom function is missing"); enumerator.Reset(); totalCells.First().CustomFunc = " "; ExceptionAssert.ThrowsBaseException <InvalidOperationException>(() => method.Invoke(totalPanel, new object[] { enumerator, totalCells, null }), "The custom type of aggregation is specified in the template but custom function is missing"); enumerator.Reset(); totalCells.First().CustomFunc = "BadMethod"; ExceptionAssert.ThrowsBaseException <MethodNotFoundException>(() => method.Invoke(totalPanel, new object[] { enumerator, totalCells, null }), $"Cannot find public instance method \"BadMethod\" in type \"{nameof(TestReportForAggregation)}\""); }
public void TestDoAggregationWithEmptyData() { var data = new List <Test>(); var totalPanel = new ExcelTotalsPanel(data, Substitute.For <IXLNamedRange>(), Substitute.For <object>(), Substitute.For <ITemplateProcessor>()); IEnumerator enumerator = EnumeratorFactory.Create(data); IList <ExcelTotalsPanel.ParsedAggregationFunc> totalCells = new List <ExcelTotalsPanel.ParsedAggregationFunc> { new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Sum, "TestColumn1"), new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Count, "TestColumn1"), new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Avg, "TestColumn1"), new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Min, "TestColumn1"), new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Max, "TestColumn1"), }; MethodInfo method = totalPanel.GetType().GetMethod("DoAggregation", BindingFlags.Instance | BindingFlags.NonPublic); method.Invoke(totalPanel, new object[] { enumerator, totalCells, null }); Assert.AreEqual(0, totalCells[0].Result); Assert.AreEqual(0, totalCells[1].Result); Assert.AreEqual(0, totalCells[2].Result); Assert.IsNull(totalCells[3].Result); Assert.IsNull(totalCells[4].Result); }
public override void Render() { // Receive parent data item context HierarchicalDataItem parentDataItem = GetDataContext(); _data = _isDataReceivedDirectly ? _data : _templateProcessor.GetValue(_dataSourceTemplate, parentDataItem); bool isCanceled = CallBeforeRenderMethod(); if (isCanceled) { ResultRange = ExcelHelper.CloneRange(Range); return; } ICustomEnumerator enumerator = null; try { enumerator = EnumeratorFactory.Create(_data); // Removing the template if there are no data if (enumerator == null || enumerator.RowCount == 0) { DeletePanel(this); return; } // Creating the panel template which will be replicated then ExcelDataItemPanel templatePanel = CreateTemplatePanel(); _templatePanelRowCount = templatePanel.Range.RowCount(); _templatePanelColumnCount = templatePanel.Range.ColumnCount(); // Allocating space for data if (enumerator.RowCount > 1) { AllocateSpaceForData(templatePanel, enumerator.RowCount); } int rowNum = 0; while (enumerator.MoveNext()) { object currentItem = enumerator.Current; ExcelDataItemPanel currentPanel; if (rowNum != enumerator.RowCount - 1) { IXLCell templateFirstCell = templatePanel.Range.FirstCell(); // The template itself is moved down or right, depending on the type of panel MoveTemplatePanel(templatePanel); // Copying the template on its previous place for the panel which the current data item will be rendered in currentPanel = (ExcelDataItemPanel)templatePanel.Copy(templateFirstCell); } else { // Rendering data directly in the template if there is the last data item currentPanel = templatePanel; } currentPanel.DataItem = new HierarchicalDataItem { Value = currentItem, Parent = parentDataItem }; // Fill template with data currentPanel.Render(); ResultRange = ExcelHelper.MergeRanges(ResultRange, currentPanel.ResultRange); RemoveAllNamesRecursive(currentPanel); rowNum++; } RemoveName(); } finally { (enumerator as IDisposable)?.Dispose(); } GroupResult(); CallAfterRenderMethod(); }
public void TestDoAggregation() { var dataTable = new DataTable(); dataTable.Columns.Add(new DataColumn("TestColumn1", typeof(int))); dataTable.Columns.Add(new DataColumn("TestColumn2", typeof(decimal))); dataTable.Columns.Add(new DataColumn("TestColumn3", typeof(string))); dataTable.Columns.Add(new DataColumn("TestColumn4", typeof(bool))); dataTable.Rows.Add(3, 20.7m, "abc", false); dataTable.Rows.Add(1, 10.5m, "jkl", true); dataTable.Rows.Add(null, null, null, null); dataTable.Rows.Add(2, 30.9m, "def", false); var totalPanel = new ExcelTotalsPanel(dataTable, Substitute.For <IXLNamedRange>(), Substitute.For <object>(), new TestReport().TemplateProcessor); IEnumerator enumerator = EnumeratorFactory.Create(dataTable); IList <ExcelTotalsPanel.ParsedAggregationFunc> totalCells = new List <ExcelTotalsPanel.ParsedAggregationFunc> { new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Sum, "di:TestColumn1"), new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Sum, "di:TestColumn2"), new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Sum, "di:TestColumn3"), new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Count, "di:TestColumn1"), new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Count, "di:TestColumn3"), new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Avg, "di:TestColumn1"), new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Avg, "di:TestColumn2"), new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Min, "di:TestColumn1"), new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Max, "di:TestColumn1"), new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Min, "di:TestColumn2"), new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Max, "di:TestColumn2"), new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Min, "di:TestColumn3"), new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Max, "di:TestColumn3"), new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Min, "di:TestColumn4"), new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Max, "di:TestColumn4"), }; MethodInfo method = totalPanel.GetType().GetMethod("DoAggregation", BindingFlags.Instance | BindingFlags.NonPublic); method.Invoke(totalPanel, new object[] { enumerator, totalCells, null }); Assert.AreEqual(6, totalCells[0].Result); Assert.AreEqual(62.1m, totalCells[1].Result); Assert.AreEqual("abcjkldef", totalCells[2].Result); Assert.AreEqual(4, totalCells[3].Result); Assert.AreEqual(4, totalCells[4].Result); Assert.AreEqual((double)6 / 4, totalCells[5].Result); Assert.AreEqual(62.1 / 4, totalCells[6].Result); Assert.AreEqual(1, totalCells[7].Result); Assert.AreEqual(3, totalCells[8].Result); Assert.AreEqual(10.5m, totalCells[9].Result); Assert.AreEqual(30.9m, totalCells[10].Result); Assert.AreEqual("abc", totalCells[11].Result); Assert.AreEqual("jkl", totalCells[12].Result); Assert.AreEqual(false, totalCells[13].Result); Assert.AreEqual(true, totalCells[14].Result); // Reset all results before next test foreach (ExcelTotalsPanel.ParsedAggregationFunc totalCell in totalCells) { totalCell.Result = null; } IList <Test> data = GetTestData(); enumerator = EnumeratorFactory.Create(data); totalCells.Add(new ExcelTotalsPanel.ParsedAggregationFunc(AggregateFunction.Sum, "di:Result.Amount")); method.Invoke(totalPanel, new object[] { enumerator, totalCells, null }); Assert.AreEqual(6, totalCells[0].Result); Assert.AreEqual(62.1m, totalCells[1].Result); Assert.AreEqual("abcjkldef", totalCells[2].Result); Assert.AreEqual(4, totalCells[3].Result); Assert.AreEqual(4, totalCells[4].Result); Assert.AreEqual((double)6 / 4, totalCells[5].Result); Assert.AreEqual(62.1 / 4, totalCells[6].Result); Assert.AreEqual(1, totalCells[7].Result); Assert.AreEqual(3, totalCells[8].Result); Assert.AreEqual(10.5m, totalCells[9].Result); Assert.AreEqual(30.9m, totalCells[10].Result); Assert.AreEqual("abc", totalCells[11].Result); Assert.AreEqual("jkl", totalCells[12].Result); Assert.AreEqual(false, totalCells[13].Result); Assert.AreEqual(true, totalCells[14].Result); Assert.AreEqual(410.59m, totalCells[15].Result); }