public string Format( string locale, FormatterRequest request, Dictionary<string, object> args, object value, IMessageFormatter messageFormatter) { var parsed = this.ParseArguments(request); KeyedBlock other = null; foreach (var keyedBlock in parsed.KeyedBlocks) { var str = Convert.ToString(value); if (str == keyedBlock.Key) { return messageFormatter.FormatMessage(keyedBlock.BlockText, args); } if (keyedBlock.Key == OtherKey) { other = keyedBlock; } } if (other == null) { throw new MessageFormatterException( "'other' option not found in pattern, and variable was not present in collection."); } return messageFormatter.FormatMessage(other.BlockText, args); }
public void ParseKeyedBlocks_unclosed_escape_sequence(string args) { var subject = new BaseFormatterImpl(); var req = new FormatterRequest(new Literal(1, 1, 1, 1, new StringBuilder()), string.Empty, null, args); Assert.Throws <MalformedLiteralException>(() => subject.ParseKeyedBlocks(req, 0)); }
public void CanNotCreateIfPolymorph() { Type type = typeof(DictionaryMock); FormatterRequest request = new FormatterRequest(type, isPolymorph: true); Assert.IsFalse(_builder.CanCreate(request)); }
/// <summary> /// Using the specified parameters and arguments, a formatted string shall be returned. /// The <see cref="IMessageFormatter" /> is being provided as well, to enable /// nested formatting. This is only called if <see cref="CanFormat" /> returns true. /// The <see cref="args" /> will always contain the <see cref="FormatterRequest.Variable" />. /// </summary> /// <param name="locale"> /// The locale being used. It is up to the formatter what they do with this information. /// </param> /// <param name="request"> /// The parameters. /// </param> /// <param name="args"> /// The arguments. /// </param> /// <param name="messageFormatter"> /// The message formatter. /// </param> /// <returns> /// The <see cref="string" />. /// </returns> public string Format( string locale, FormatterRequest request, Dictionary<string, object> args, IMessageFormatter messageFormatter) { var arguments = this.ParseArguments(request); double offset = 0; var offsetExtension = arguments.Extensions.FirstOrDefault(x => x.Extension == "offset"); if (offsetExtension != null) { offset = Convert.ToDouble(offsetExtension.Value); } double n = 0; object varResult = null; if (args.TryGetValue(request.Variable, out varResult)) { n = Convert.ToDouble(varResult); } var pluralized = new StringBuilder(this.Pluralize(locale, arguments, n, offset)); var result = this.ReplaceNumberLiterals(pluralized, n - offset); var formatted = messageFormatter.FormatMessage(result, args); return formatted; }
public string Format( string locale, FormatterRequest request, IDictionary <string, object> args, object value, IMessageFormatter messageFormatter) { var parsed = this.ParseArguments(request); KeyedBlock other = null; foreach (var keyedBlock in parsed.KeyedBlocks) { var str = Convert.ToString(value); if (str == keyedBlock.Key) { return(messageFormatter.FormatMessage(keyedBlock.BlockText, args)); } if (keyedBlock.Key == OtherKey) { other = keyedBlock; } } if (other == null) { throw new MessageFormatterException( "'other' option not found in pattern, and variable was not present in collection."); } return(messageFormatter.FormatMessage(other.BlockText, args)); }
public void ParseExtensions(string args, string extension, string value, int expectedIndex) { var subject = new BaseFormatterImpl(); int index; var req = new FormatterRequest(new Literal(1, 1, 1, 1, new StringBuilder()), string.Empty, null, args); // Warmup subject.ParseExtensions(req, out index); Benchmark.Start("Parsing extensions a few times (warmed up)", this.outputHelper); for (int i = 0; i < 1000; i++) { subject.ParseExtensions(req, out index); } Benchmark.End(this.outputHelper); var actual = subject.ParseExtensions(req, out index); Assert.NotEmpty(actual); var first = actual.First(); Assert.Equal(extension, first.Extension); Assert.Equal(value, first.Value); Assert.Equal(expectedIndex, index); }
public string Format( string locale, FormatterRequest request, IDictionary <string, object> args, object value, IMessageFormatter messageFormatter) { var d = CastDate(value); var c = new CultureInfo(locale).DateTimeFormat; if (request.FormatterArguments == "short") { return(d.ToString("d", c)); } if (request.FormatterArguments == "long") { return(d.ToString("D", c)); } if (request.FormatterArguments == "full") { return(d.ToString("D", c)); } if (request.FormatterArguments == "" || request.FormatterArguments == "default") { return(d.ToString("D", c)); } throw new FormatException("Invalid date format: " + request.FormatterArguments); }
public void ParseArguments( string args, string[] extensionKeys, string[] extensionValues, string[] keys, string[] blocks) { var subject = new BaseFormatterImpl(); var req = new FormatterRequest(new Literal(1, 1, 1, 1, new StringBuilder()), string.Empty, null, args); var actual = subject.ParseArguments(req); Assert.Equal(extensionKeys.Length, actual.Extensions.Count()); Assert.Equal(keys.Length, actual.KeyedBlocks.Count()); for (int i = 0; i < actual.Extensions.ToArray().Length; i++) { var extension = actual.Extensions.ToArray()[i]; Assert.Equal(extensionKeys[i], extension.Extension); Assert.Equal(extensionValues[i], extension.Value); } for (int i = 0; i < actual.KeyedBlocks.ToArray().Length; i++) { var block = actual.KeyedBlocks.ToArray()[i]; Assert.Equal(keys[i], block.Key); Assert.Equal(blocks[i], block.BlockText); } }
public void ParseKeyedBlocks(string args, string[] keys, string[] values) { var subject = new BaseFormatterImpl(); var req = new FormatterRequest(new Literal(1, 1, 1, 1, new StringBuilder()), string.Empty, null, args); // Warm-up subject.ParseKeyedBlocks(req, 0); Benchmark.Start("Parsing keyed blocks..", this.outputHelper); for (int i = 0; i < 10000; i++) { subject.ParseKeyedBlocks(req, 0); } Benchmark.End(this.outputHelper); var actual = subject.ParseKeyedBlocks(req, 0); Assert.Equal(keys.Length, actual.Count()); this.outputHelper.WriteLine("Input: " + args); this.outputHelper.WriteLine("-----"); for (int index = 0; index < actual.ToArray().Length; index++) { var keyedBlock = actual.ToArray()[index]; var expectedKey = keys[index]; var expectedValue = values[index]; Assert.Equal(expectedKey, keyedBlock.Key); Assert.Equal(expectedValue, keyedBlock.BlockText); this.outputHelper.WriteLine("Key: " + keyedBlock.Key); this.outputHelper.WriteLine("Block: " + keyedBlock.BlockText); } }
public void CanNotCreateIfSuppressed() { Type type = typeof(SuppressedListMock); FormatterRequest request = new FormatterRequest(type, isPolymorph: false); Assert.IsFalse(_builder.CanCreate(request)); }
public void CanCreate() { Type type = typeof(ListMock); FormatterRequest request = new FormatterRequest(type, isPolymorph: false); Assert.IsTrue(_builder.CanCreate(request)); }
/// <summary> /// Using the specified parameters and arguments, a formatted string shall be returned. /// The <see cref="IMessageFormatter" /> is being provided as well, to enable /// nested formatting. This is only called if <see cref="CanFormat" /> returns true. /// The <see cref="args" /> will always contain the <see cref="FormatterRequest.Variable" />. /// </summary> /// <param name="locale"> /// The locale being used. It is up to the formatter what they do with this information. /// </param> /// <param name="request"> /// The parameters. /// </param> /// <param name="args"> /// The arguments. /// </param> /// <param name="messageFormatter"> /// The message formatter. /// </param> /// <returns> /// The <see cref="string" />. /// </returns> public string Format( string locale, FormatterRequest request, Dictionary<string, object> args, IMessageFormatter messageFormatter) { return args[request.Variable].ToString(); }
public void ParseArguments_invalid(string args) { var subject = new BaseFormatterImpl(); var req = new FormatterRequest(new Literal(1, 1, 1, 1, new StringBuilder()), string.Empty, null, args); var ex = Assert.Throws <MalformedLiteralException>(() => subject.ParseArguments(req)); this.outputHelper.WriteLine(ex.Message); }
/// <summary> /// Using the specified parameters and arguments, a formatted string shall be returned. /// The <see cref="IMessageFormatter" /> is being provided as well, to enable /// nested formatting. This is only called if <see cref="CanFormat" /> returns true. /// The <see cref="args" /> will always contain the <see cref="FormatterRequest.Variable" />. /// </summary> /// <param name="locale">The locale being used. It is up to the formatter what they do with this information.</param> /// <param name="request">The parameters.</param> /// <param name="args">The arguments.</param> /// <param name="value">The value of <see cref="FormatterRequest.Variable" /> from the given <see cref="args" /> dictionary. Can be null.</param> /// <param name="messageFormatter">The message formatter.</param> /// <returns> /// The <see cref="string" />. /// </returns> public string Format( string locale, FormatterRequest request, Dictionary<string, object> args, object value, IMessageFormatter messageFormatter) { return value != null ? value.ToString() : string.Empty; }
/// <summary> /// Using the specified parameters and arguments, a formatted string shall be returned. /// The <see cref="IMessageFormatter" /> is being provided as well, to enable /// nested formatting. This is only called if <see cref="CanFormat" /> returns true. /// The <see cref="args" /> will always contain the <see cref="FormatterRequest.Variable" />. /// </summary> /// <param name="locale">The locale being used. It is up to the formatter what they do with this information.</param> /// <param name="request">The parameters.</param> /// <param name="args">The arguments.</param> /// <param name="value">The value of <see cref="FormatterRequest.Variable" /> from the given <see cref="args" /> dictionary. Can be null.</param> /// <param name="messageFormatter">The message formatter.</param> /// <returns> /// The <see cref="string" />. /// </returns> public string Format( string locale, FormatterRequest request, IDictionary <string, object> args, object value, IMessageFormatter messageFormatter) { return(value != null?value.ToString() : string.Empty); }
/// <summary> /// Builds the message. /// </summary> /// <param name="request"> /// The request. /// </param> /// <returns> /// The <see cref="string" />. /// </returns> private static string BuildMessage(FormatterRequest request) { return (string.Format( "Format '{0}' could not be resolved.\r\n" + "Line {1}, position {2}\r\n" + "Source literal: '{3}'", request.FormatterName, request.SourceLiteral.SourceLineNumber, request.SourceLiteral.SourceColumnNumber, request.SourceLiteral.InnerText)); }
public void Format(string formatterArgs, string gender, string expectedBlock) { var subject = new SelectFormatter(); var messageFormatterMock = new Mock <IMessageFormatter>(); messageFormatterMock.Setup(x => x.FormatMessage(It.IsAny <string>(), It.IsAny <Dictionary <string, object?> >())) .Returns((string input, Dictionary <string, object> a) => input); var req = new FormatterRequest( new Literal(1, 1, 1, 1, new StringBuilder()), "gender", "select", formatterArgs); var args = new Dictionary <string, object?> { { "gender", gender } }; var result = subject.Format("en", req, args, gender, messageFormatterMock.Object); Assert.Equal(expectedBlock, result); }
/// <summary> /// Using the specified parameters and arguments, a formatted string shall be returned. /// The <see cref="IMessageFormatter" /> is being provided as well, to enable /// nested formatting. This is only called if <see cref="CanFormat" /> returns true. /// The <see cref="args" /> will always contain the <see cref="FormatterRequest.Variable" />. /// </summary> /// <param name="locale">The locale being used. It is up to the formatter what they do with this information.</param> /// <param name="request">The parameters.</param> /// <param name="args">The arguments.</param> /// <param name="value">The value of <see cref="FormatterRequest.Variable" /> from the given <see cref="args" /> dictionary. Can be null.</param> /// <param name="messageFormatter">The message formatter.</param> /// <returns> /// The <see cref="string" />. /// </returns> public string Format( string locale, FormatterRequest request, IDictionary <string, object> args, object value, IMessageFormatter messageFormatter) { switch (value) { case null: return(string.Empty); case IFormattable formattable: return(formattable.ToString(null, GetCultureInfo(locale))); default: return(value.ToString()); } }
public void Pluralize(double n, string expected) { var subject = new PluralFormatter(); var args = new Dictionary <string, object> { { "test", n } }; var arguments = new ParsedArguments( new[] { new KeyedBlock("zero", "nothing"), new KeyedBlock("one", "just one"), new KeyedBlock("other", "wow") }, new FormatterExtension[0]); var request = new FormatterRequest(new Literal(1, 1, 1, 1, new StringBuilder()), "test", "plural", null); var actual = subject.Pluralize("en", arguments, Convert.ToDouble(args[request.Variable]), 0); Assert.Equal(expected, actual); }
public void GetFormatter() { var subject = new FormatterLibrary(); var mock1 = new Mock <IFormatter>(); var mock2 = new Mock <IFormatter>(); var req = new FormatterRequest(new Literal(1, 1, 1, 1, new StringBuilder()), "test", "dawg", null); subject.Add(mock1.Object); subject.Add(mock2.Object); Assert.Throws <FormatterNotFoundException>(() => subject.GetFormatter(req)); mock2.Setup(x => x.CanFormat(req)).Returns(true); var actual = subject.GetFormatter(req); Assert.Same(mock2.Object, actual); mock1.Setup(x => x.CanFormat(req)).Returns(true); actual = subject.GetFormatter(req); Assert.Same(mock1.Object, actual); }
/// <summary> /// Using the specified parameters and arguments, a formatted string shall be returned. /// The <see cref="IMessageFormatter" /> is being provided as well, to enable /// nested formatting. This is only called if <see cref="CanFormat" /> returns true. /// The args will always contain the <see cref="FormatterRequest.Variable" />. /// </summary> /// <param name="locale"> /// The locale being used. It is up to the formatter what they do with this information. /// </param> /// <param name="request"> /// The parameters. /// </param> /// <param name="args"> /// The arguments. /// </param> /// <param name="value">The value of <see cref="FormatterRequest.Variable"/> from the given args dictionary. Can be null.</param> /// <param name="messageFormatter"> /// The message formatter. /// </param> /// <returns> /// The <see cref="string" />. /// </returns> public string Format( string locale, FormatterRequest request, IDictionary <string, object> args, object value, IMessageFormatter messageFormatter) { var arguments = this.ParseArguments(request); double offset = 0; var offsetExtension = arguments.Extensions.FirstOrDefault(x => x.Extension == "offset"); if (offsetExtension != null) { offset = Convert.ToDouble(offsetExtension.Value); } var n = Convert.ToDouble(value); var pluralized = new StringBuilder(this.Pluralize(locale, arguments, n, offset)); var result = this.ReplaceNumberLiterals(pluralized, n - offset); var formatted = messageFormatter.FormatMessage(result, args); return(formatted); }
public void ParseExtensions_multiple() { var subject = new BaseFormatterImpl(); int index; var args = " offset:2 code:js "; var expectedIndex = 17; var req = new FormatterRequest(new Literal(1, 1, 1, 1, new StringBuilder()), string.Empty, null, args); var actual = subject.ParseExtensions(req, out index); Assert.NotEmpty(actual); var result = actual.First(); Assert.Equal("offset", result.Extension); Assert.Equal("2", result.Value); result = actual.ElementAt(1); Assert.Equal("code", result.Extension); Assert.Equal("js", result.Value); Assert.Equal(expectedIndex, index); }
public bool CanCreate(FormatterRequest request) => request.Type.IsValueType && request.Type.IsGenericType && request.Type.GetGenericTypeDefinition() == typeof(Nullable <>);
/// <summary> /// Determines whether this instance can format a message based on the specified parameters. /// </summary> /// <param name="request"> /// The parameters. /// </param> /// <returns> /// The <see cref="bool" />. /// </returns> public bool CanFormat(FormatterRequest request) { return(request.FormatterName == null); }
/// <summary> /// Initializes a new instance of the <see cref="FormatterNotFoundException" /> class. /// </summary> /// <param name="request"> /// The request. /// </param> public FormatterNotFoundException(FormatterRequest request) : base(BuildMessage(request)) { }
public bool CanCreate(FormatterRequest request) => request.Type == typeof(bool);
/// <summary> /// Determines whether this instance can format a message based on the specified parameters. /// </summary> /// <param name="request"> /// The parameters. /// </param> /// <returns> /// The <see cref="bool" />. /// </returns> public bool CanFormat(FormatterRequest request) { return(request.FormatterName == "select"); }
/// <summary> /// Determines whether this instance can format a message based on the specified parameters. /// </summary> /// <param name="request"> /// The parameters. /// </param> /// <returns> /// The <see cref="bool" />. /// </returns> public bool CanFormat(FormatterRequest request) { return request.FormatterName == null; }
public bool CanCreate(FormatterRequest request) => !request.IsPolymorph && typeof(ICustomFormatted).IsAssignableFrom(request.Type);
public bool CanCreate(FormatterRequest request) => _formatters.ContainsKey(request.Type);
public bool CanCreate(FormatterRequest request) => request.Type.IsEnum;
public bool CanCreate(FormatterRequest request) => request.IsPolymorph;
/// <summary> /// Determines whether this instance can format a message based on the specified parameters. /// </summary> /// <param name="request"> /// The parameters. /// </param> /// <returns> /// The <see cref="bool" />. /// </returns> public bool CanFormat(FormatterRequest request) { return request.FormatterName == "select"; }
/// <summary> /// Creates the request. /// </summary> /// <returns> /// The <see cref="FormatterRequest" />. /// </returns> private static FormatterRequest CreateRequest() { var req = new FormatterRequest(new Literal(1, 10, 1, 1, new StringBuilder()), "test", null, null); return(req); }
/// <summary> /// Determines whether this instance can format a message based on the specified parameters. /// </summary> /// <param name="request"> /// The parameters. /// </param> /// <returns> /// The <see cref="bool" />. /// </returns> public bool CanFormat(FormatterRequest request) { return(request.FormatterName == "plural"); }
public bool CanCreate(FormatterRequest request) => !request.IsPolymorph && FieldProviderResolver.Instance.IsSupported(request.Type);
/// <summary> /// Determines whether this instance can format a message based on the specified parameters. /// </summary> /// <param name="request"> /// The parameters. /// </param> /// <returns> /// The <see cref="bool" />. /// </returns> public bool CanFormat(FormatterRequest request) { return request.FormatterName == "plural"; }