public void AppendsToEnd() { ApplicationDataPath path = new ApplicationDataPath(); path.Append("Foo", 42); path.Append("Bar", 16); Assert.AreEqual(16, path.Last().Index); }
public void HasCorrectNumberOfItems() { ApplicationDataPath path = new ApplicationDataPath(); path.Append("Foo", 42); path.Append("Bar", 16); Assert.AreEqual(2, path.Count); }
public void DefaultIndex() { ApplicationDataPath path = new ApplicationDataPath("Foo[1].Bar"); Assert.AreEqual(2, path.Count); Assert.AreEqual("Bar", path.Last().Name); Assert.IsNull(path.Last().Index); }
/// <summary> /// Recurses up through the control tree and adds any repeater controls to <paramref name="path"/>. /// </summary> /// <param name="control">The control which acts as the this instance.</param> /// <param name="controlList">The control list.</param> /// <param name="path">A <see cref="ApplicationDataPath"/> to update.</param> private static void CreatePathTemplate(this Control control, ControlList controlList, ApplicationDataPath path) { Control parent = control.GetRepeaterAncestor(controlList); if (parent != null) { path.Prepend(parent.Name); parent.CreatePathTemplate(controlList, path); } }
public void MatchesOriginal() { ApplicationDataPath original = new ApplicationDataPath(); original.Prepend("Bar", 42); original.Prepend("Foo", 10); ApplicationDataPath copy = new ApplicationDataPath(original); Assert.AreEqual(original.Count, copy.Count); Assert.AreEqual(original.Last().Name, copy.Last().Name); Assert.AreEqual(original.Last().Index, copy.Last().Index); }
public void IsNotOriginal() { ApplicationDataPath original = new ApplicationDataPath(); original.Prepend("Bar", 42); original.Prepend("Foo", 10); ApplicationDataPath copy = new ApplicationDataPath(original); copy.TraverseDown(); Assert.AreNotEqual(original.Count, copy.Count); }
/// <summary> /// Implements the validation logic for the receiver. /// </summary> /// <param name="objectToValidate">The object to validate.</param> /// <param name="currentTarget">The object on the behalf of which the validation is performed.</param> /// <param name="key">The key that identifies the source of objectToValidate.</param> /// <param name="validationResults">The validation results to which the outcome of the validation should be stored.</param> public override void DoValidate(object objectToValidate, object currentTarget, string key, ValidationResults validationResults) { if (objectToValidate == null) { return; } object[] arr = (object[])objectToValidate; Dictionary<string, object>[] items = arr.Length > 0 ? objectToValidate as Dictionary<string, object>[] : new Dictionary<string, object>[0]; for (int i = 0; i < items.Length; i++) { Dictionary<string, object> item = items[i]; ApplicationDataPath path = new ApplicationDataPath(key); path.Last().Index = i; this.WrappedValidator.DoValidate(item, currentTarget, path.ToString(), validationResults); } }
/// <summary> /// Implements the validation logic for the receiver. /// </summary> /// <param name="objectToValidate">The object to validate.</param> /// <param name="currentTarget">The object on the behalf of which the validation is performed.</param> /// <param name="key">The key that identifies the source of objectToValidate.</param> /// <param name="validationResults">The validation results to which the outcome of the validation should be stored.</param> public override void DoValidate(object objectToValidate, object currentTarget, string key, ValidationResults validationResults) { if (objectToValidate == null) { return; } ControlValueValidator controlValueValidator = this.WrappedValidator as ControlValueValidator; LikertControl likert = this.AllControls.FindRecursive<LikertControl>(key); Dictionary<string, object> items = objectToValidate as Dictionary<string, object>; ApplicationDataPath path = new ApplicationDataPath(key); foreach (KeyValuePair<string, object> item in items) { string tag = likert.Questions.First(q => q.Name == item.Key).Label; controlValueValidator.SetTag(tag); this.WrappedValidator.DoValidate(item.Value, currentTarget, path.ToString(item.Key), validationResults); } }
/// <summary> /// Runs a calculation and adds the result to <paramref name="resultsContainer"/>. /// </summary> /// <param name="control">The calculation to run.</param> /// <param name="resultsContainer">A dictionary of results.</param> /// <param name="exceptionList">A list that <see cref="ExpressionEvaluatorException"/>s will be added to before returning to the client.</param> private void Calculate(CalculationControl control, Dictionary<string, object> resultsContainer, List<ExpressionEvaluatorException> exceptionList) { ApplicationDataPath absolutePath = control.CreatePathTemplate(this.controlList); if (control.IsRepeaterDescendant(this.controlList)) { ApplicationDataPath relativePath = new ApplicationDataPath(absolutePath); this.CalculateRepeater(control, relativePath, absolutePath, resultsContainer, this.Application.ApplicationData, exceptionList); return; } try { resultsContainer[control.Name] = this.Evaluate(control.CalculationExpression, absolutePath); this.Application.ApplicationData.SetValue(control.Name, resultsContainer[control.Name], true); } catch (ExpressionEvaluatorException e) { e.Tag = control.Name; exceptionList.Add(e); } }
/// <summary> /// The token key, which might be a property of the <paramref name="application"/> object or an /// application value in the application data. /// </summary> /// <param name="application">The application to source data from.</param> /// <param name="token">The token key.</param> /// <param name="path">Specifies the path to the token. Defaults to <see langword="null"/>.</param> /// <returns>The value of the token.</returns> /// <remarks>Order of precedence: (1) <paramref name="application"/> object; (2) application data.</remarks> public static object GetTokenValue(this Application application, string token, ApplicationDataPath path = null) { object tokenValue; if (application.TryGetPropertyValue(token, '.', out tokenValue)) { return tokenValue; } // We are going to be be popping items so we should create our own copy of the path. ApplicationDataPath pathIterator = new ApplicationDataPath(path ?? new ApplicationDataPath()); string tokenPath = pathIterator.ToString(token); tokenValue = application.ApplicationData.GetValue<object>(tokenPath, null); while (tokenValue == null && pathIterator.Count != 0) { pathIterator.TraverseUp(); tokenPath = pathIterator.ToString(token); tokenValue = application.ApplicationData.GetValue<object>(tokenPath, null); } return tokenValue; }
public void TraverseTreeBottom() { Application application = new Application(); application.ApplicationData.Add("RootChild", "RootChild Value"); var outerRepeater = new List<Dictionary<string, object>> { new Dictionary<string, object>() }; var innerRepeater = new List<Dictionary<string, object>> { new Dictionary<string, object>() }; innerRepeater[0].Add("InnerChild", "InnerChild Value"); outerRepeater[0].Add("InnerRepeater", innerRepeater.ToArray()); outerRepeater[0].Add("OuterChild", "OuterChild Value"); application.ApplicationData.Add("OuterRepeater", outerRepeater.ToArray()); ApplicationDataPath path = new ApplicationDataPath(); path.Prepend("InnerRepeater", 0); path.Prepend("OuterRepeater", 0); string value = application.GetTokenValue("InnerChild", path).ToString(); Assert.AreEqual("InnerChild Value", value); }
public void TestRepeaterCalculation() { ExpressionEvaluator evaluator = new ExpressionEvaluator(new Application(this.postedData)); ApplicationDataPath path = new ApplicationDataPath(); path.Append("key4"); path.First().Index = 0; Assert.AreEqual(50, evaluator.Evaluate<int>("{%child1%} - {%child2%}", path)); path.First().Index = 1; Assert.AreEqual(150, evaluator.Evaluate<int>("{%child1%} - {%child2%}", path)); }
public void NullString() { ApplicationDataPath path = new ApplicationDataPath((string)null); Assert.AreEqual(0, path.Count); }
public void EmptyString() { ApplicationDataPath path = new ApplicationDataPath(string.Empty); Assert.AreEqual(0, path.Count); }
/// <summary> /// Gets the replacement string for a token. /// </summary> /// <param name="token">The token being replaced.</param> /// <param name="format">A format string.</param> /// <param name="application">The application to source data from.</param> /// <param name="controls">The controls.</param> /// <param name="path">Specifies the path to the token.</param> /// <param name="defaultReplaceValue">The default replace value.</param> /// <returns> /// The replacement string. /// </returns> /// <remarks> /// Order of precedence: (1) Timestamp; (2) <paramref name="application" /> object; (3) application data. /// </remarks> private string GetReplacementString(string token, string format, Application application, ControlList controls, ApplicationDataPath path, string defaultReplaceValue) { Control control = controls.FindRecursive(c => c.Name == token); object value = this.GetTokenValue(token, application, control, path); if (value == null) { return defaultReplaceValue; } if (value is Array) { object[] valueArray = value as object[]; StringBuilder builder = new StringBuilder(); if (valueArray.Length == 0) { return defaultReplaceValue; } string appendFormat = valueArray[0] is string ? "'{0}'" : "{0}"; builder.AppendFormat(appendFormat, valueArray[0]); for (var i = 1; i < valueArray.Length; i++) { builder.Append(","); builder.AppendFormat(appendFormat, valueArray[i]); } return builder.ToString(); } string formatString = string.IsNullOrEmpty(format) ? "{0}" : string.Format("{{0:{0}}}", format.Substring(1, format.Length - 2)); return string.Format(CultureInfo.CurrentCulture, formatString, value); }
/// <summary> /// Gets the value of a token. /// </summary> /// <param name="token">The token being replaced.</param> /// <param name="application">The application to source data from.</param> /// <param name="control">The control.</param> /// <param name="path">Specifies the path to the token.</param> /// <returns> /// The value of the token. /// </returns> /// <remarks> /// Order of precedence: (1) Timestamp; (2) Application URL (3) <paramref name="application" /> object; (4) application data. /// </remarks> private object GetTokenValue(string token, Application application, Control control, ApplicationDataPath path) { if (token.StartsWith(FormatterResources.TimestampToken, StringComparison.CurrentCultureIgnoreCase)) { return DateTime.Now; } if (token.StartsWith(FormatterResources.ApplicationUrlToken, StringComparison.CurrentCultureIgnoreCase)) { string url = string.Format(FormatterResources.ApplicationUrlFormat, this.BaseUrl, application.FormId, application.Id); return string.Format(FormatterResources.ApplicationAnchor, url); } if (application == null) { return null; } string valueStr = application.GetTokenValue(token, path) as string; if (control is DateControl) { DateTime dateValue; if (valueStr != null && DateTime.TryParseExact(valueStr, DateControl.SYSTEM_FORMAT, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateValue)) { return dateValue.ToString(DateControl.USER_FORMAT); } } var calculationControl = control as CalculationControl; if (calculationControl == null || !calculationControl.FormatAsCurrency || valueStr == null) { return application.GetTokenValue(token, path); } decimal decimalVal; bool parsed = decimal.TryParse(valueStr, out decimalVal); if (parsed) { return string.Format("{0:C}", decimalVal); } return application.GetTokenValue(token, path); }
public bool IsEqual(LDDEnvironment other) { return(ProgramFilesPath.Equals(other.ProgramFilesPath, StringComparison.InvariantCultureIgnoreCase) && ApplicationDataPath.Equals(other.ApplicationDataPath, StringComparison.InvariantCultureIgnoreCase)); }
/// <summary> /// Creates a <see cref="ApplicationDataPath"/> template - with default indices - /// for <paramref name="control"/>. /// </summary> /// <param name="control">The control which acts as the this instance.</param> /// <param name="controlList">The control list.</param> /// <returns>A <see cref="ApplicationDataPath"/> template - with default indices - /// for <paramref name="control"/>.</returns> public static ApplicationDataPath CreatePathTemplate(this Control control, ControlList controlList) { ApplicationDataPath path = new ApplicationDataPath(); control.CreatePathTemplate(controlList, path); return path; }
public void TokenAtRoot() { ApplicationDataPath path = new ApplicationDataPath(); Assert.AreEqual("token", path.ToString("token")); }
public void NestedRepeaterValueUsingIndex() { Application application = new Application(); Dictionary<string, object>[] outerRepeater = new Dictionary<string, object>[1]; outerRepeater[0] = new Dictionary<string, object> { { "child-of-outer-1", "outer 1 text" } }; Dictionary<string, object>[] innerRepeater = new Dictionary<string, object>[1]; innerRepeater[0] = new Dictionary<string, object> { { "child-of-inner-1", "inner 1 text 1" }, { "child-of-inner-2", "inner 1 text 2" } }; outerRepeater[0].Add("child-of-outer-2", innerRepeater); application.ApplicationData.Add("control-at-root", "root"); application.ApplicationData.Add("repeater-at-root", outerRepeater); ApplicationDataPath path = new ApplicationDataPath(); path.Prepend("child-of-outer-2", 0); path.Prepend("repeater-at-root", 0); string replacedAppValue1 = this.formatterNullDefault.Format(@"{%child-of-inner-2%}", application, new ControlList(), string.Empty, string.Empty, string.Empty, path); Assert.AreEqual("inner 1 text 2", replacedAppValue1); }
public void TokenAtLevelTwo() { ApplicationDataPath path = new ApplicationDataPath(); path.Prepend("Inner", 3); path.Prepend("Outer", 2); Assert.AreEqual("Outer[2].Inner[3].token", path.ToString("token")); }
public void TokenAtLevelOne() { ApplicationDataPath path = new ApplicationDataPath(); path.Prepend("Repeater1", 2); Assert.AreEqual("Repeater1[2].token", path.ToString("token")); }
public void HasEmptyIndex() { ApplicationDataPath path = new ApplicationDataPath(); path.Prepend("Inner", null); Assert.AreEqual("Inner.token", path.ToString("token")); }
/// <summary> /// Replaces tokens within <paramref name="str" /> with values from <paramref name="application" />. /// </summary> /// <param name="str">The string to search and replace in.</param> /// <param name="application">The application to source data from.</param> /// <param name="pageList">The page list.</param> /// <param name="defaultReplaceValue">The default replace value which will override the value set via /// <see cref="StringFormatter(string, string, string)" />.</param> /// <param name="nonReplacementPrefix">A prefix to be included in the pattern search but retained when substituting a value.</param> /// <param name="nonReplacementSuffix">A suffix to be included in the pattern search but retained when substituting a value.</param> /// <param name="path">Specifies the path to the token. Defaults to <see langword="null" />.</param> /// <returns> /// A formatted string with values from <paramref name="application" />. /// </returns> /// <remarks> /// Passing in <see langword="null" /> for <paramref name="defaultReplaceValue" /> means no replacement will take place when no suitable replacement value can be found. /// The token will remain in place. /// </remarks> public string Format(string str, Application application, PageList pageList, string defaultReplaceValue, string nonReplacementPrefix = "", string nonReplacementSuffix = "", ApplicationDataPath path = null) { ApplicationDataPath thisPath = path; string pattern = string.Format( @"{0}({1})([^({2}[)]+)(\[[^(\])]+\])?\.?([^({2}[)]*)({2}){3}", !string.IsNullOrEmpty(nonReplacementPrefix) ? string.Format("(?<={0})", nonReplacementPrefix) : string.Empty, this.PlaceHolderPrefix, this.PlaceHolderSuffix, !string.IsNullOrEmpty(nonReplacementSuffix) ? string.Format("(?={0})", nonReplacementSuffix) : string.Empty); Regex r = new Regex(pattern, RegexOptions.IgnoreCase); str = r.Replace(str, match => this.ReplaceTokens(match, application, pageList, thisPath, defaultReplaceValue)); return str; }
public void TwoLevels() { ApplicationDataPath path = new ApplicationDataPath("Foo[1].Bar[3]"); Assert.AreEqual(2, path.Count); Assert.AreEqual("Bar", path.Last().Name); Assert.AreEqual(3, path.Last().Index); }
/// <summary> /// Replaces the match with the appropriate email token. /// </summary> /// <param name="match">The matched token.</param> /// <param name="application">The application.</param> /// <param name="pageList">The page list.</param> /// <param name="thisPath">The this path.</param> /// <param name="defaultReplaceValue">The default replace value.</param> /// <returns> /// The replaced email token. /// </returns> private string ReplaceTokens(Match match, Application application, PageList pageList, ApplicationDataPath thisPath, string defaultReplaceValue) { SummaryControl summary = null; string token = match.Groups[2].Value; List<Page> pagesToOutput = new List<Page>(); foreach (Page page in pageList) { summary = page.Controls.FindRecursive<SummaryControl>(c => c.Type == ControlType.Summary && c.Name == token); if (summary == null) { pagesToOutput.Add(page); } else { break; } } if (summary == null) { return match.Value; } if (!summary.IncludedControls.All) { pagesToOutput = pageList.Where(p => p.Controls.Any(c => summary.IncludedControls.Controls.Contains(c.Name))).ToList(); } StringBuilder sb = new StringBuilder(); sb.AppendLine(string.Format("<table style='{0}'>", FormatterResources.TableStyles)); foreach (var page in pagesToOutput) { this.WriteHeaderRow(sb, page.PageTitle, FormatterResources.PageStyles); ControlList controlsToOutput = summary.IncludedControls.All ? page.Controls : new ControlList(page.Controls.FindAllRecursive(c => summary.IncludedControls.Controls.Contains(c.Name) && (c is ValueControl || c is RepeaterControl))); foreach (var control in controlsToOutput) { if (control is RepeaterControl) { this.WriteRepeater(sb, control as RepeaterControl, summary.IncludedControls, application.ApplicationData); } else if (control is LikertControl) { this.WriteLikert(sb, control as LikertControl, application.ApplicationData); } else if (control is IControlWithOptions) { this.WriteOptionValue(sb, control as ControlWithOptions, application.ApplicationData); } else if (control is CalculationControl) { var controlWithLabel = control as IControlWithLabel; this.WriteRow(sb, controlWithLabel.Label, this.GetValueToWrite(control, application.ApplicationData.GetValue<string>(control.Name))); } else { var valueControl = control as ValueControl; if (valueControl != null && controlsToOutput.All(c => c.Id != control.ParentId)) { this.WriteRow(sb, valueControl.Label, this.GetValueToWrite(control, application.ApplicationData.GetValue<string>(control.Name))); } } } } sb.AppendLine("</table>"); return sb.ToString(); }
public void OneLevelIntegerAsName() { ApplicationDataPath path = new ApplicationDataPath("10"); Assert.AreEqual(1, path.Count); Assert.AreEqual("10", path.Last().Name); Assert.IsNull(path.Last().Index); }
public void LeavesObjectInCorrectState() { ApplicationDataPath path = new ApplicationDataPath(); path.Append("Foo", 42); path.Append("Bar", 16); path.TraverseUp(); Assert.AreEqual(42, path.First().Index); }
public void PrependsToStart() { ApplicationDataPath path = new ApplicationDataPath(); path.Prepend("Foo", 42); path.Prepend("Bar", 16); Assert.AreEqual(42, path.Last().Index); }
public void ReturnsFirstItem() { ApplicationDataPath path = new ApplicationDataPath(); path.Append("Foo", 42); path.Append("Bar", 16); ApplicationDataPathSegment segment = path.TraverseUp(); Assert.AreEqual(16, segment.Index); }
/// <summary> /// Replaces the match with the appropriate email token. /// </summary> /// <param name="match">The matched token.</param> /// <param name="application">The application.</param> /// <param name="controls">The controls.</param> /// <param name="thisPath">The this path.</param> /// <param name="defaultReplaceValue">The default replace value.</param> /// <returns> /// The replaced email token. /// </returns> private string ReplaceTokens(Match match, Application application, ControlList controls, ApplicationDataPath thisPath, string defaultReplaceValue) { string token = match.Groups[2].Value; string format = match.Groups[3].Value; ApplicationDataPath path; if (thisPath == null && !string.IsNullOrWhiteSpace(match.Groups[4].Value)) { token = match.Groups[4].Value; path = new ApplicationDataPath(string.Format(@"{0}[{1}]", match.Groups[2].Value, match.Groups[3].Value)); } else { path = thisPath; } string replacementString = this.GetReplacementString(token, format, application, controls, path, defaultReplaceValue); if (replacementString == null) { return match.ToString(); } return this.replacements.Aggregate(replacementString, (current, kvp) => current.Replace(kvp.Key, kvp.Value)); }