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 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>()); }
/// <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(); } }
/// <inheritdoc /> /// <seealso cref="CallMethod(string, Type, ITemplateProcessor, HierarchicalDataItem)"/> public virtual object CallMethod(string methodCallTemplate, ITemplateProcessor templateProcessor, HierarchicalDataItem dataItem) { return(CallMethod(methodCallTemplate, null, templateProcessor, dataItem)); }
/// <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 }); } } }
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}\""); }
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"); }