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();
        }
Ejemplo n.º 2
0
        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;
            }

            IColumnsProvider columnsProvider = _columnsFactory.Create(_data);

            if (columnsProvider == null)
            {
                DeletePanel(this);
                return;
            }

            IList <ExcelDynamicColumn> columns = columnsProvider.GetColumnsList(_data);

            if (!columns.Any())
            {
                DeletePanel(this);
                return;
            }

            ResultRange = ExcelHelper.MergeRanges(Range, RenderHeaders(columns));
            ResultRange = ExcelHelper.MergeRanges(ResultRange, RenderColumnNumbers(columns));

            IXLRange dataRange = RenderDataTemplates(columns);

            if (dataRange != null)
            {
                ResultRange = ExcelHelper.MergeRanges(ResultRange, RenderData(dataRange));
            }

            IXLRange totalsRange = RenderTotalsTemplates(columns);

            if (totalsRange != null)
            {
                ResultRange = ExcelHelper.MergeRanges(ResultRange, RenderTotals(totalsRange));
            }

            RemoveName();
            CallAfterRenderMethod();
        }
        public void TestCopy()
        {
            var          wb                = new XLWorkbook();
            IXLWorksheet ws                = wb.AddWorksheet("Test");
            var          excelReport       = Substitute.For <object>();
            var          templateProcessor = Substitute.For <ITemplateProcessor>();

            IXLRange range = ws.Range(1, 1, 1, 4);

            var parentDataItem = new HierarchicalDataItem {
                Value = 1
            };
            var dataItem = new HierarchicalDataItem {
                Value = "One", Parent = parentDataItem
            };

            var panel = new ExcelDataItemPanel(range, excelReport, templateProcessor)
            {
                RenderPriority         = 10,
                Type                   = PanelType.Horizontal,
                ShiftType              = ShiftType.NoShift,
                BeforeRenderMethodName = "BeforeRenderMethod",
                AfterRenderMethodName  = "AfterRenderMethod",
                DataItem               = dataItem,
            };

            ExcelDataItemPanel copiedPanel = (ExcelDataItemPanel)panel.Copy(ws.Cell(5, 5));

            Assert.AreSame(excelReport, copiedPanel.GetType().GetField("_report", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(copiedPanel));
            Assert.AreSame(templateProcessor, copiedPanel.GetType().GetField("_templateProcessor", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(copiedPanel));
            Assert.AreEqual(ws.Cell(5, 5), copiedPanel.Range.FirstCell());
            Assert.AreEqual(ws.Cell(5, 8), copiedPanel.Range.LastCell());
            Assert.AreEqual(10, copiedPanel.RenderPriority);
            Assert.AreEqual(PanelType.Horizontal, copiedPanel.Type);
            Assert.AreEqual(ShiftType.NoShift, copiedPanel.ShiftType);
            Assert.AreEqual("BeforeRenderMethod", copiedPanel.BeforeRenderMethodName);
            Assert.AreEqual("AfterRenderMethod", copiedPanel.AfterRenderMethodName);
            Assert.AreSame(dataItem, copiedPanel.DataItem);
            Assert.AreSame(parentDataItem, copiedPanel.DataItem.Parent);
            Assert.IsNull(copiedPanel.Parent);

            //wb.SaveAs("test.xlsx");
        }
        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 TestCallMethod()
        {
            ExceptionAssert.Throws <ArgumentNullException>(() => new DefaultMethodCallValueProvider(null, Substitute.For <IInstanceProvider>()));
            ExceptionAssert.Throws <ArgumentNullException>(() => new DefaultMethodCallValueProvider(Substitute.For <ITypeProvider>(), null));

            var typeProvider     = Substitute.For <ITypeProvider>();
            var instanceProvider = Substitute.For <IInstanceProvider>();

            typeProvider.GetType(Arg.Any <string>()).Returns(typeof(TestClass));
            var testInstance = new TestClass();

            instanceProvider.GetInstance(typeof(TestClass)).Returns(testInstance);

            var templateProcessor = Substitute.For <ITemplateProcessor>();
            var dataItem          = new HierarchicalDataItem();

            templateProcessor.LeftTemplateBorder.Returns("<<");
            templateProcessor.RightTemplateBorder.Returns(">>");
            templateProcessor.MemberLabelSeparator.Returns("**");
            templateProcessor.PropertyMemberLabel.Returns("prop");
            templateProcessor.DataItemMemberLabel.Returns("data");
            templateProcessor.MethodCallMemberLabel.Returns("meth");
            templateProcessor.GetValue("prop**Name").Returns("TestName");
            templateProcessor.GetValue("prop**Value", dataItem).Returns(7);

            var methodCallValueProvider = new DefaultMethodCallValueProvider(typeProvider, instanceProvider);

            ExceptionAssert.Throws <ArgumentException>(() => methodCallValueProvider.CallMethod(null, templateProcessor, new HierarchicalDataItem()));
            ExceptionAssert.Throws <ArgumentException>(() => methodCallValueProvider.CallMethod(string.Empty, templateProcessor, new HierarchicalDataItem()));
            ExceptionAssert.Throws <ArgumentException>(() => methodCallValueProvider.CallMethod(" ", templateProcessor, new HierarchicalDataItem()));

            Assert.AreEqual("Str_1", methodCallValueProvider.CallMethod("Method1()", templateProcessor, null));
            typeProvider.Received(1).GetType(null);
            instanceProvider.Received(1).GetInstance(typeof(TestClass));
            templateProcessor.DidNotReceiveWithAnyArgs().GetValue(Arg.Any <string>());

            typeProvider.ClearReceivedCalls();
            instanceProvider.ClearReceivedCalls();
            Assert.AreEqual("Str_2", methodCallValueProvider.CallMethod("TestClass:Method1()", templateProcessor, null));
            typeProvider.Received(1).GetType("TestClass");
            instanceProvider.Received(1).GetInstance(typeof(TestClass));
            templateProcessor.DidNotReceiveWithAnyArgs().GetValue(Arg.Any <string>());

            typeProvider.ClearReceivedCalls();
            instanceProvider.ClearReceivedCalls();
            Assert.AreEqual("Str_3", methodCallValueProvider.CallMethod(" ExcelReportGenerator.Tests.Implementations.Providers : TestClass : Method1() ", templateProcessor, null));
            typeProvider.Received(1).GetType("ExcelReportGenerator.Tests.Implementations.Providers : TestClass");
            instanceProvider.Received(1).GetInstance(typeof(TestClass));
            templateProcessor.DidNotReceiveWithAnyArgs().GetValue(Arg.Any <string>());

            typeProvider.ClearReceivedCalls();
            instanceProvider.ClearReceivedCalls();
            Assert.AreEqual("Str_4", methodCallValueProvider.CallMethod(":TestClass:Method1()", templateProcessor, null));
            typeProvider.Received(1).GetType(":TestClass");
            instanceProvider.Received(1).GetInstance(typeof(TestClass));
            templateProcessor.DidNotReceiveWithAnyArgs().GetValue(Arg.Any <string>());

            typeProvider.ClearReceivedCalls();
            instanceProvider.ClearReceivedCalls();
            Assert.AreEqual("Str_5", methodCallValueProvider.CallMethod("Method1()", typeof(TestClass), templateProcessor, null));
            typeProvider.DidNotReceiveWithAnyArgs().GetType(Arg.Any <string>());
            instanceProvider.Received(1).GetInstance(typeof(TestClass));
            templateProcessor.DidNotReceiveWithAnyArgs().GetValue(Arg.Any <string>());

            instanceProvider.ClearReceivedCalls();
            Assert.AreEqual(25, methodCallValueProvider.CallMethod("Method2(prop**Value, 18)", templateProcessor, dataItem));
            typeProvider.Received(1).GetType(null);
            instanceProvider.DidNotReceiveWithAnyArgs().GetInstance(Arg.Any <Type>());
            templateProcessor.Received(1).GetValue("prop**Value", dataItem);

            typeProvider.ClearReceivedCalls();
            templateProcessor.ClearReceivedCalls();
            Assert.AreEqual(25, methodCallValueProvider.CallMethod(" : TestClass : Method2(prop**Value, 18) ", templateProcessor, dataItem));
            typeProvider.Received(1).GetType(": TestClass");
            instanceProvider.DidNotReceiveWithAnyArgs().GetInstance(Arg.Any <Type>());
            templateProcessor.Received(1).GetValue("prop**Value", dataItem);

            typeProvider.ClearReceivedCalls();
            templateProcessor.ClearReceivedCalls();
            Assert.IsNull(methodCallValueProvider.CallMethod("Method3()", templateProcessor, null));
            typeProvider.Received(1).GetType(null);
            instanceProvider.Received(1).GetInstance(typeof(TestClass));
            templateProcessor.DidNotReceiveWithAnyArgs().GetValue(Arg.Any <string>());

            templateProcessor.GetValue("meth**TestClass:Method5(prop**Desc,  meth**ExcelReportGenerator.Tests.Implementations.Providers:TestClass:Method6(str, data**Field) )").Returns(10);
            templateProcessor.GetValue("meth**Method7()").Returns('c');
            templateProcessor.GetValue("meth**:TestClass2:Method1()").Returns(long.MaxValue);

            typeProvider.ClearReceivedCalls();
            instanceProvider.ClearReceivedCalls();
            object result = methodCallValueProvider.CallMethod(
                "Method4(5, prop**Name, hi,  meth**TestClass:Method5(prop**Desc,  meth**ExcelReportGenerator.Tests.Implementations.Providers:TestClass:Method6(str, data**Field) ) , meth**Method7(), meth**:TestClass2:Method1())",
                templateProcessor, null);

            Assert.AreEqual($"5_TestName_hi_10_c_{long.MaxValue}", result);
            typeProvider.Received(1).GetType(null);
            instanceProvider.Received(1).GetInstance(typeof(TestClass));
            templateProcessor.Received(1).GetValue("prop**Name");
            templateProcessor.Received(1).GetValue("meth**TestClass:Method5(prop**Desc,  meth**ExcelReportGenerator.Tests.Implementations.Providers:TestClass:Method6(str, data**Field) )");
            templateProcessor.Received(1).GetValue("meth**Method7()");
            templateProcessor.Received(1).GetValue("meth**:TestClass2:Method1()");

            typeProvider.ClearReceivedCalls();
            instanceProvider.ClearReceivedCalls();
            templateProcessor.ClearReceivedCalls();
            Assert.AreEqual("_ ", methodCallValueProvider.CallMethod("Method5(\"\", \" \")", templateProcessor, null));
            typeProvider.Received(1).GetType(null);
            instanceProvider.Received(1).GetInstance(typeof(TestClass));
            templateProcessor.DidNotReceiveWithAnyArgs().GetValue(Arg.Any <string>());

            typeProvider.ClearReceivedCalls();
            instanceProvider.ClearReceivedCalls();
            Assert.AreEqual("prop**Name_meth**Method6()", methodCallValueProvider.CallMethod("Method5(\"prop**Name\", \"meth**Method6()\")", templateProcessor, null));
            typeProvider.Received(1).GetType(null);
            instanceProvider.Received(1).GetInstance(typeof(TestClass));
            templateProcessor.DidNotReceiveWithAnyArgs().GetValue(Arg.Any <string>());

            typeProvider.ClearReceivedCalls();
            instanceProvider.ClearReceivedCalls();
            Assert.AreEqual("\"prop**Name\"_\"\"", methodCallValueProvider.CallMethod("Method5(\"\"prop**Name\"\", \"\"\"\")", templateProcessor, null));
            typeProvider.Received(1).GetType(null);
            instanceProvider.Received(1).GetInstance(typeof(TestClass));
            templateProcessor.DidNotReceiveWithAnyArgs().GetValue(Arg.Any <string>());

            ExceptionAssert.Throws <MethodNotFoundException>(() => methodCallValueProvider.CallMethod("TestClass:BadMethod()", templateProcessor, null),
                                                             "Could not find public method \"BadMethod\" in type \"TestClass\" and all its parents. MethodCallTemplate: TestClass:BadMethod()");

            ExceptionAssert.Throws <MethodNotFoundException>(() => methodCallValueProvider.CallMethod("TestClass:BadMethod()", templateProcessor, null),
                                                             "Could not find public method \"BadMethod\" in type \"TestClass\" and all its parents. MethodCallTemplate: TestClass:BadMethod()");

            typeProvider.ClearReceivedCalls();
            instanceProvider.ClearReceivedCalls();
            templateProcessor.ClearReceivedCalls();
            Assert.AreEqual("Str_Parent", methodCallValueProvider.CallMethod("MethodParent()", templateProcessor, null));
            typeProvider.Received(1).GetType(null);
            instanceProvider.Received(1).GetInstance(typeof(TestClass));
            templateProcessor.DidNotReceiveWithAnyArgs().GetValue(Arg.Any <string>());

            typeProvider.ClearReceivedCalls();
            instanceProvider.ClearReceivedCalls();
            Assert.AreEqual("Str_Static_Parent", methodCallValueProvider.CallMethod("MethodStaticParent()", templateProcessor, null));
            typeProvider.Received(1).GetType(null);
            instanceProvider.DidNotReceiveWithAnyArgs().GetInstance(Arg.Any <Type>());
            templateProcessor.DidNotReceiveWithAnyArgs().GetValue(Arg.Any <string>());
        }
Ejemplo n.º 6
0
        /// <inheritdoc />
        /// <exception cref="ArgumentException">Thrown when <paramref name="methodCallTemplate" /> is null, empty string or whitespace</exception>
        /// <exception cref="InvalidTemplateException"></exception>
        /// <exception cref="MethodNotFoundException"></exception>
        /// <exception cref="NotSupportedException"></exception>
        /// <exception cref="InvalidOperationException"></exception>
        public object CallMethod(string methodCallTemplate, Type concreteType, ITemplateProcessor templateProcessor, HierarchicalDataItem dataItem)
        {
            if (string.IsNullOrWhiteSpace(methodCallTemplate))
            {
                throw new ArgumentException(ArgumentHelper.EmptyStringParamMessage, nameof(methodCallTemplate));
            }

            _templateStack.Push(methodCallTemplate.Trim());
            try
            {
                MethodCallTemplateParts templateParts = ParseTemplate(MethodCallTemplate);
                Type type = concreteType ?? TypeProvider.GetType(templateParts.TypeName);
                IList <InputParameter> inputParams = GetInputParametersValues(templateParts.MethodParams, templateProcessor, dataItem);
                MethodInfo             method      = GetMethod(type, templateParts.MemberName, inputParams);
                object instance = GetInstance(type, method.IsStatic);
                return(CallMethod(instance, method, inputParams));
            }
            finally
            {
                _templateStack.Pop();
            }
        }
Ejemplo n.º 7
0
 /// <inheritdoc />
 /// <seealso cref="CallMethod(string, Type, ITemplateProcessor, HierarchicalDataItem)"/>
 public virtual object CallMethod(string methodCallTemplate, ITemplateProcessor templateProcessor, HierarchicalDataItem dataItem)
 {
     return(CallMethod(methodCallTemplate, null, templateProcessor, dataItem));
 }
Ejemplo n.º 8
0
        /// <summary>
        /// Parse input parameters string and returns list of input parameters values
        /// </summary>
        /// <param name="templateProcessor">Template processor that will be used for parameters specified as templates</param>
        /// <param name="dataItem">Data item that will be used for parameters specified as data item templates</param>
        protected virtual IList <InputParameter> GetInputParametersValues(string inputParamsAsString, ITemplateProcessor templateProcessor, HierarchicalDataItem dataItem)
        {
            IList <InputParameter> inputParameters = new List <InputParameter>();
            string pattern = templateProcessor.UnwrapTemplate(templateProcessor.GetFullRegexPattern(), true);

            foreach (string p in ParseInputParams(inputParamsAsString))
            {
                if (p.StartsWith("\"") && p.EndsWith("\""))
                {
                    inputParameters.Add(new InputParameter
                    {
                        Value = p.Substring(1, p.Length - 2),
                        Type  = typeof(string),
                    });
                }
                else if (Regex.IsMatch(p, $@"^{pattern}$"))
                {
                    object value = templateProcessor.GetValue(p, dataItem);
                    inputParameters.Add(new InputParameter
                    {
                        Value = value,
                        Type  = value?.GetType(),
                    });
                }
                else
                {
                    object value = p;
                    Type   type  = null;
                    Match  match = Regex.Match(p, @"^\[(.+)\](.+)$");
                    if (match.Success)
                    {
                        type  = GetTypeByCode(match.Groups[1].Value);
                        value = Convert.ChangeType(match.Groups[2].Value.Trim(), type);
                    }
                    inputParameters.Add(new InputParameter {
                        Value = value, Type = type
                    });
                }
            }
            return(inputParameters);
        }
        private void DoAggregation(IEnumerator enumerator, IList <ParsedAggregationFunc> aggFuncs, HierarchicalDataItem parentDataItem)
        {
            int dataItemsCount = 0;

            while (enumerator.MoveNext())
            {
                dataItemsCount++;
                object item = enumerator.Current;
                foreach (ParsedAggregationFunc aggFunc in aggFuncs)
                {
                    if (aggFunc.AggregateFunction == AggregateFunction.Count)
                    {
                        aggFunc.Result = dataItemsCount;
                        continue;
                    }

                    dynamic value = _templateProcessor.GetValue(aggFunc.ColumnName, new HierarchicalDataItem {
                        Value = item, Parent = parentDataItem
                    });
                    if (aggFunc.AggregateFunction == AggregateFunction.Custom)
                    {
                        if (string.IsNullOrWhiteSpace(aggFunc.CustomFunc))
                        {
                            throw new InvalidOperationException("The custom type of aggregation is specified in the template but custom function is missing");
                        }
                        aggFunc.Result = CallReportMethod(aggFunc.CustomFunc, new object[] { aggFunc.Result, value, dataItemsCount });
                        continue;
                    }

                    if (value == null || value.Equals(DBNull.Value))
                    {
                        continue;
                    }
                    if (aggFunc.Result == null)
                    {
                        aggFunc.Result = value;
                        continue;
                    }

                    switch (aggFunc.AggregateFunction)
                    {
                    case AggregateFunction.Sum:
                    case AggregateFunction.Avg:
                        aggFunc.Result += value;
                        break;

                    case AggregateFunction.Min:
                    case AggregateFunction.Max:
                        var comparable = aggFunc.Result as IComparable;
                        if (comparable != null && aggFunc.Result.GetType() == value.GetType())
                        {
                            int compareResult = comparable.CompareTo(value);
                            if (aggFunc.AggregateFunction == AggregateFunction.Min)
                            {
                                aggFunc.Result = compareResult < 0 ? aggFunc.Result : value;
                            }
                            else
                            {
                                aggFunc.Result = compareResult < 0 ? value : aggFunc.Result;
                            }
                        }
                        else
                        {
                            throw new InvalidOperationException($"For {nameof(AggregateFunction.Min)} and {nameof(AggregateFunction.Max)} aggregation functions data items must implement IComparable interface");
                        }
                        break;

                    default:
                        throw new NotSupportedException("Unsupportable aggregation function");
                    }
                }
            }

            foreach (ParsedAggregationFunc aggFunc in aggFuncs)
            {
                if (aggFunc.Result == null && (aggFunc.AggregateFunction == AggregateFunction.Sum ||
                                               aggFunc.AggregateFunction == AggregateFunction.Avg ||
                                               aggFunc.AggregateFunction == AggregateFunction.Count))
                {
                    aggFunc.Result = 0;
                }

                if (dataItemsCount != 0 && aggFunc.AggregateFunction == AggregateFunction.Avg)
                {
                    aggFunc.Result = (double)aggFunc.Result / dataItemsCount;
                }

                if (!string.IsNullOrWhiteSpace(aggFunc.PostProcessFunction))
                {
                    aggFunc.Result = CallReportMethod(aggFunc.PostProcessFunction, new object[] { aggFunc.Result, dataItemsCount });
                }
            }
        }
Ejemplo n.º 10
0
        public void TestGetValue()
        {
            var propertyValueProvider   = Substitute.For <IPropertyValueProvider>();
            var variableValueProvider   = Substitute.For <SystemVariableProvider>();
            var methodCallValueProvider = Substitute.For <IMethodCallValueProvider>();
            var dataItemValueProvider   = Substitute.For <IGenericDataItemValueProvider <HierarchicalDataItem> >();
            var dataItem = new HierarchicalDataItem();

            ExceptionAssert.Throws <ArgumentNullException>(() => new DefaultTemplateProcessor(null, variableValueProvider, methodCallValueProvider, dataItemValueProvider));
            ExceptionAssert.Throws <ArgumentNullException>(() => new DefaultTemplateProcessor(propertyValueProvider, null, methodCallValueProvider, dataItemValueProvider));
            new DefaultTemplateProcessor(propertyValueProvider, variableValueProvider, null, dataItemValueProvider);
            new DefaultTemplateProcessor(propertyValueProvider, variableValueProvider, methodCallValueProvider);

            var templateProcessor = new DefaultTemplateProcessor(propertyValueProvider, variableValueProvider, methodCallValueProvider, dataItemValueProvider);

            ExceptionAssert.Throws <ArgumentException>(() => templateProcessor.GetValue(null, dataItem));
            ExceptionAssert.Throws <InvalidTemplateException>(() => templateProcessor.GetValue("{p-Name}"), "Invalid template \"{p-Name}\". Cannot find separator \":\" between member label and member template");
            ExceptionAssert.Throws <InvalidTemplateException>(() => templateProcessor.GetValue("{bad:Name}"), "Invalid template \"{bad:Name}\". Unknown member label \"bad\"");

            templateProcessor.GetValue("{p:Name}");

            propertyValueProvider.Received(1).GetValue("Name");
            variableValueProvider.DidNotReceiveWithAnyArgs().GetVariable(Arg.Any <string>());
            methodCallValueProvider.DidNotReceiveWithAnyArgs().CallMethod(null, null, null);
            dataItemValueProvider.DidNotReceiveWithAnyArgs().GetValue(Arg.Any <string>(), null);

            propertyValueProvider.ClearReceivedCalls();
            templateProcessor.GetValue(" { p : Name } ");

            propertyValueProvider.Received(1).GetValue("Name");
            variableValueProvider.DidNotReceiveWithAnyArgs().GetVariable(Arg.Any <string>());
            methodCallValueProvider.DidNotReceiveWithAnyArgs().CallMethod(null, null, null);
            dataItemValueProvider.DidNotReceiveWithAnyArgs().GetValue(Arg.Any <string>(), null);

            propertyValueProvider.ClearReceivedCalls();
            templateProcessor.GetValue(" p:Name ");

            propertyValueProvider.Received(1).GetValue("Name");
            variableValueProvider.DidNotReceiveWithAnyArgs().GetVariable(Arg.Any <string>());
            methodCallValueProvider.DidNotReceiveWithAnyArgs().CallMethod(null, null, null);
            dataItemValueProvider.DidNotReceiveWithAnyArgs().GetValue(Arg.Any <string>(), null);

            propertyValueProvider.ClearReceivedCalls();
            templateProcessor.GetValue("sv:Now");

            variableValueProvider.Received(1).GetVariable("Now");
            propertyValueProvider.DidNotReceiveWithAnyArgs().GetValue(Arg.Any <string>());
            methodCallValueProvider.DidNotReceiveWithAnyArgs().CallMethod(null, null, null);
            dataItemValueProvider.DidNotReceiveWithAnyArgs().GetValue(Arg.Any <string>(), null);

            variableValueProvider.ClearReceivedCalls();
            templateProcessor.GetValue("sf:Format(5567.88, 0)");

            variableValueProvider.DidNotReceiveWithAnyArgs().GetVariable(Arg.Any <string>());
            propertyValueProvider.DidNotReceiveWithAnyArgs().GetValue(Arg.Any <string>());
            methodCallValueProvider.Received(1).CallMethod("Format(5567.88, 0)", typeof(SystemFunctions), templateProcessor, null);
            dataItemValueProvider.DidNotReceiveWithAnyArgs().GetValue(Arg.Any <string>(), null);

            methodCallValueProvider.ClearReceivedCalls();
            templateProcessor.GetValue("{ m:Method() }", dataItem);

            propertyValueProvider.DidNotReceiveWithAnyArgs().GetValue(Arg.Any <string>());
            variableValueProvider.DidNotReceiveWithAnyArgs().GetVariable(Arg.Any <string>());
            methodCallValueProvider.Received(1).CallMethod("Method()", templateProcessor, dataItem);
            dataItemValueProvider.DidNotReceiveWithAnyArgs().GetValue(Arg.Any <string>(), null);

            methodCallValueProvider.ClearReceivedCalls();
            templateProcessor.GetValue("{m:Method()}", dataItem);
            propertyValueProvider.DidNotReceiveWithAnyArgs().GetValue(Arg.Any <string>());
            variableValueProvider.DidNotReceiveWithAnyArgs().GetVariable(Arg.Any <string>());
            methodCallValueProvider.Received(1).CallMethod("Method()", templateProcessor, dataItem);
            dataItemValueProvider.DidNotReceiveWithAnyArgs().GetValue(Arg.Any <string>(), null);

            methodCallValueProvider.ClearReceivedCalls();
            ExceptionAssert.Throws <InvalidOperationException>(() => new DefaultTemplateProcessor(propertyValueProvider, variableValueProvider).GetValue("{m:Method()}"), "Template \"{m:Method()}\" contains method call but methodCallValueProvider is null");
            ExceptionAssert.Throws <InvalidOperationException>(() => new DefaultTemplateProcessor(propertyValueProvider, variableValueProvider).GetValue("{sf:Format(p:Prop, 0))}"), "Template \"{sf:Format(p:Prop, 0))}\" contains system function call but methodCallValueProvider is null");
            ExceptionAssert.Throws <InvalidOperationException>(() => new DefaultTemplateProcessor(propertyValueProvider, variableValueProvider)
            {
                SystemFunctionsType = null
            }.GetValue("{sf:Format(p:Prop, 0))}"), "Template \"{sf:Format(p:Prop, 0))}\" contains system function call but property SystemFunctionsType is null");

            templateProcessor.GetValue("{di:Field}", dataItem);
            propertyValueProvider.DidNotReceiveWithAnyArgs().GetValue(Arg.Any <string>());
            variableValueProvider.DidNotReceiveWithAnyArgs().GetVariable(Arg.Any <string>());
            methodCallValueProvider.DidNotReceiveWithAnyArgs().CallMethod(null, null, null);
            dataItemValueProvider.Received(1).GetValue("Field", dataItem);

            dataItemValueProvider.ClearReceivedCalls();
            ExceptionAssert.Throws <InvalidOperationException>(() => templateProcessor.GetValue("{di:Field}"), "Template \"{di:Field}\" contains data reference but dataItem is null");
            ExceptionAssert.Throws <InvalidOperationException>(() => new DefaultTemplateProcessor(propertyValueProvider, variableValueProvider).GetValue("{di:Field}", dataItem), "Template \"{di:Field}\" contains data reference but dataItemValueProvider is null");
        }
        /// <inheritdoc />
        /// <exception cref="ArgumentException">Thrown when <paramref name="template" /> is null, empty string or whitespace</exception>
        /// <exception cref="InvalidTemplateException"></exception>
        /// <exception cref="InvalidOperationException"></exception>
        public virtual object GetValue(string template, HierarchicalDataItem dataItem = null)
        {
            if (string.IsNullOrWhiteSpace(template))
            {
                throw new ArgumentException(ArgumentHelper.EmptyStringParamMessage, nameof(template));
            }

            string unwrappedTemplate = this.UnwrapTemplate(template.Trim()).Trim();
            int    separatorIndex    = unwrappedTemplate.IndexOf(MemberLabelSeparator, StringComparison.CurrentCultureIgnoreCase);

            if (separatorIndex == -1)
            {
                throw new InvalidTemplateException($"Invalid template \"{template}\". Cannot find separator \"{MemberLabelSeparator}\" between member label and member template");
            }

            string memberLabel    = unwrappedTemplate.Substring(0, separatorIndex).ToLower().Trim();
            string memberTemplate = unwrappedTemplate.Substring(separatorIndex + MemberLabelSeparator.Length).Trim();

            if (memberLabel == PropertyMemberLabel)
            {
                return(PropertyValueProvider.GetValue(memberTemplate));
            }
            if (memberLabel == DataItemMemberLabel)
            {
                if (dataItem == null)
                {
                    throw new InvalidOperationException($"Template \"{template}\" contains data reference but dataItem is null");
                }
                if (DataItemValueProvider == null)
                {
                    throw new InvalidOperationException($"Template \"{template}\" contains data reference but dataItemValueProvider is null");
                }
                return(DataItemValueProvider.GetValue(memberTemplate, dataItem));
            }
            if (memberLabel == MethodCallMemberLabel)
            {
                if (MethodCallValueProvider == null)
                {
                    throw new InvalidOperationException($"Template \"{template}\" contains method call but methodCallValueProvider is null");
                }
                return(MethodCallValueProvider.CallMethod(memberTemplate, this, dataItem));
            }
            if (memberLabel == SystemVariableMemberLabel)
            {
                return(SystemVariableProvider.GetVariable(memberTemplate));
            }
            if (memberLabel == SystemFunctionMemberLabel)
            {
                if (SystemFunctionsType == null)
                {
                    throw new InvalidOperationException($"Template \"{template}\" contains system function call but property SystemFunctionsType is null");
                }
                if (MethodCallValueProvider == null)
                {
                    throw new InvalidOperationException($"Template \"{template}\" contains system function call but methodCallValueProvider is null");
                }
                return(MethodCallValueProvider.CallMethod(memberTemplate, SystemFunctionsType, this, dataItem));
            }

            throw new InvalidTemplateException($"Invalid template \"{template}\". Unknown member label \"{memberLabel}\"");
        }
Ejemplo n.º 12
0
        public void TestGetValue()
        {
            var dataTable = new DataTable();

            dataTable.Columns.Add("Column", typeof(int));
            dataTable.Rows.Add(1);

            TestClass2  dataItem1 = new TestClass2();
            DataRow     dataItem2 = dataTable.Rows[0];
            IDataReader dataItem3 = Substitute.For <IDataReader>();
            TestClass   dataItem4 = new TestClass();

            var hierarchicalDataItem = new HierarchicalDataItem
            {
                Value  = dataItem4,
                Parent = new HierarchicalDataItem
                {
                    Value  = dataItem1,
                    Parent = new HierarchicalDataItem
                    {
                        Value  = dataItem2,
                        Parent = new HierarchicalDataItem
                        {
                            Value = dataItem3,
                        }
                    }
                }
            };

            var factory = Substitute.For <IDataItemValueProviderFactory>();
            var objectPropertyValueProvider = Substitute.For <ObjectPropertyValueProvider>();
            var dataRowValueProvider        = Substitute.For <DataRowValueProvider>();
            var dataReaderValueProvider     = Substitute.For <DataReaderValueProvider>();
            var dataItemValueProvider       = new DefaultDataItemValueProvider(factory)
            {
                DataItemSelfTemplate = "di"
            };

            factory.Create(null).Returns(objectPropertyValueProvider);
            factory.Create(dataItem1).Returns(objectPropertyValueProvider);
            factory.Create(dataItem2).Returns(dataRowValueProvider);
            factory.Create(dataItem3).Returns(dataReaderValueProvider);
            factory.Create(dataItem4).Returns(objectPropertyValueProvider);

            ExceptionAssert.Throws <ArgumentException>(() => dataItemValueProvider.GetValue(null, hierarchicalDataItem));
            ExceptionAssert.Throws <ArgumentException>(() => dataItemValueProvider.GetValue(string.Empty, hierarchicalDataItem));
            ExceptionAssert.Throws <ArgumentException>(() => dataItemValueProvider.GetValue(" ", hierarchicalDataItem));

            ExceptionAssert.Throws <ArgumentNullException>(() => dataItemValueProvider.GetValue("Template", null));
            ExceptionAssert.Throws <ArgumentNullException>(() => dataItemValueProvider.GetValue("Template", null));
            ExceptionAssert.Throws <ArgumentNullException>(() => dataItemValueProvider.GetValue("Template", null));

            objectPropertyValueProvider.ClearReceivedCalls();
            dataItemValueProvider.GetValue("di", hierarchicalDataItem);
            objectPropertyValueProvider.DidNotReceiveWithAnyArgs().GetValue(null, null);
            dataRowValueProvider.DidNotReceiveWithAnyArgs().GetValue(null, null);
            dataReaderValueProvider.DidNotReceiveWithAnyArgs().GetValue(null, null);

            dataItemValueProvider.GetValue("Prop", hierarchicalDataItem);
            objectPropertyValueProvider.Received(1).GetValue("Prop", dataItem4);
            dataRowValueProvider.DidNotReceiveWithAnyArgs().GetValue(null, null);
            dataReaderValueProvider.DidNotReceiveWithAnyArgs().GetValue(null, null);

            dataItemValueProvider.DataItemSelfTemplate = "dataItem";
            objectPropertyValueProvider.ClearReceivedCalls();
            dataItemValueProvider.GetValue("parent:dataItem", hierarchicalDataItem);
            objectPropertyValueProvider.DidNotReceiveWithAnyArgs().GetValue(null, null);
            dataRowValueProvider.DidNotReceiveWithAnyArgs().GetValue(null, null);
            dataReaderValueProvider.DidNotReceiveWithAnyArgs().GetValue(null, null);

            dataItemValueProvider.GetValue("parent:Prop", hierarchicalDataItem);
            objectPropertyValueProvider.Received(1).GetValue("Prop", dataItem1);
            dataRowValueProvider.DidNotReceiveWithAnyArgs().GetValue(null, null);
            dataReaderValueProvider.DidNotReceiveWithAnyArgs().GetValue(null, null);

            objectPropertyValueProvider.ClearReceivedCalls();
            dataItemValueProvider.GetValue("parent:parent", hierarchicalDataItem);
            objectPropertyValueProvider.Received(1).GetValue("parent", dataItem1);
            dataRowValueProvider.DidNotReceiveWithAnyArgs().GetValue(null, null);
            dataReaderValueProvider.DidNotReceiveWithAnyArgs().GetValue(null, null);

            objectPropertyValueProvider.ClearReceivedCalls();
            dataItemValueProvider.GetValue("parent : PARENT: Column", hierarchicalDataItem);
            objectPropertyValueProvider.DidNotReceiveWithAnyArgs().GetValue(null, null);
            dataRowValueProvider.Received(1).GetValue("Column", dataItem2);
            dataReaderValueProvider.DidNotReceiveWithAnyArgs().GetValue(null, null);

            dataRowValueProvider.ClearReceivedCalls();
            dataItemValueProvider.GetValue("parent : PARENT :parent:Column", hierarchicalDataItem);
            objectPropertyValueProvider.DidNotReceiveWithAnyArgs().GetValue(null, null);
            dataRowValueProvider.DidNotReceiveWithAnyArgs().GetValue(null, null);
            dataReaderValueProvider.Received(1).GetValue("Column", dataItem3);

            hierarchicalDataItem.Value = null;
            dataReaderValueProvider.ClearReceivedCalls();
            dataItemValueProvider.GetValue("Prop", hierarchicalDataItem);
            objectPropertyValueProvider.Received(1).GetValue("Prop", null);
            dataRowValueProvider.DidNotReceiveWithAnyArgs().GetValue(null, null);
            dataReaderValueProvider.DidNotReceiveWithAnyArgs().GetValue(null, null);

            ExceptionAssert.Throws <InvalidTemplateException>(() => dataItemValueProvider.GetValue("par:Prop", hierarchicalDataItem), "Template \"par:Prop\" is invalid");
        }