public void FormatMessage_caches_reused_pattern() { var parserMock = new Mock<IPatternParser>(); var realParser = new PatternParser(new LiteralParser()); parserMock.Setup(x => x.Parse(It.IsAny<StringBuilder>())) .Returns((StringBuilder sb) => realParser.Parse(sb)); var library = new FormatterLibrary(); var subject = new MessageFormatter(patternParser: parserMock.Object, library: library, useCache: true); var pattern = "Hi {gender, select, male {Sir} female {Ma'am}}!"; var actual = subject.FormatMessage(pattern, new { gender = "male" }); Assert.Equal("Hi Sir!", actual); // '2' because it did not format "Ma'am" yet. parserMock.Verify(x => x.Parse(It.IsAny<StringBuilder>()), Times.Exactly(2)); actual = subject.FormatMessage(pattern, new { gender = "female" }); Assert.Equal("Hi Ma'am!", actual); parserMock.Verify(x => x.Parse(It.IsAny<StringBuilder>()), Times.Exactly(3)); // '3' because it has cached all options actual = subject.FormatMessage(pattern, new { gender = "female" }); Assert.Equal("Hi Ma'am!", actual); parserMock.Verify(x => x.Parse(It.IsAny<StringBuilder>()), Times.Exactly(3)); }
private static string getMessage(int count, object[] inputs, MessageFormatter formatter) { var sb = new StringBuilder(); sb.AppendFormat("Expected {0} messages, but the following {1} were generated:", count, inputs.Length); sb.AppendLine(); foreach (var input in inputs) { sb.AppendLine(formatter.FormatMessage(input)); } sb.AppendLine("--End of expected messages--"); return sb.ToString(); }
public void FormatMessage() { var patternParserMock = new Mock<IPatternParser>(); var libraryMock = new Mock<IFormatterLibrary>(); var collectionMock = new Mock<IFormatterRequestCollection>(); var formatterMock1 = new Mock<IFormatter>(); var formatterMock2 = new Mock<IFormatter>(); var subject = new MessageFormatter(patternParserMock.Object, libraryMock.Object, false, locale: "en"); // I can use a bogus plural argument. Mocks <3 var pattern = "{name} has {messages, plural, 123}."; var expected = "Jeff has 123 messages."; var args = new Dictionary<string, object> { { "name", "Jeff" }, { "messages", 1 } }; var requests = new[] { new FormatterRequest( new Literal(0, 5, 1, 7, new StringBuilder("name")), "name", null, null), new FormatterRequest( new Literal(11, 33, 1, 7, new StringBuilder("messages, plural, 123")), "messages", "plural", " 123") }; formatterMock1.Setup(x => x.Format("en", requests[0], args, subject)).Returns("Jeff"); formatterMock2.Setup(x => x.Format("en", requests[1], args, subject)).Returns("123 messages"); collectionMock.Setup(x => x.GetEnumerator()).Returns(EnumeratorMock(requests)); libraryMock.Setup(x => x.GetFormatter(requests[0])).Returns(formatterMock1.Object); libraryMock.Setup(x => x.GetFormatter(requests[1])).Returns(formatterMock2.Object); patternParserMock.Setup(x => x.Parse(It.IsAny<StringBuilder>())).Returns(collectionMock.Object); // First request, and "name" is 4 chars. collectionMock.Setup(x => x.ShiftIndices(0, 4)).Callback( (int index, int length) => { // The '- 2' is also done in the used implementation. requests[1].SourceLiteral.ShiftIndices(length - 2, requests[0].SourceLiteral); }); var actual = subject.FormatMessage(pattern, args); collectionMock.Verify(x => x.ShiftIndices(0, 4), Times.Once); Assert.Equal(expected, actual); }
public void FormatMessage_debug() { var source = @"{gender, select, male {He} female {She} other {They} } said: You have {count, plural, zero {no notifications} one {just one notification} =42 {a universal amount of notifications} other {# notifications} }. Have a nice day!"; var expected = "He said: You have 5 notifications. Have a nice day!"; var args = new Dictionary<string, object> { { "gender", "male" }, { "count", 5 } }; var subject = new MessageFormatter(false); string result = subject.FormatMessage(source, args); Assert.Equal(expected, result); }
public void FormatMessage_nesting_with_brace_escaping() { var subject = new MessageFormatter(false); var pattern = @"{s1, select, 1 {{s2, select, 2 {\{} }} }"; var actual = subject.FormatMessage(pattern, new { s1 = 1, s2 = 2 }); this.outputHelper.WriteLine(actual); Assert.Equal("{", actual); }
public void FormatMessage_with_reflection_overload() { var subject = new MessageFormatter(false); var pattern = "You have {UnreadCount, plural, " + "zero {no unread messages}" + "one {just one unread message}" + "other {# unread messages}" + "} today."; var actual = subject.FormatMessage(pattern, new { UnreadCount = 0 }); Assert.Equal("You have no unread messages today.", actual); // The absence of UnreadCount means it will be treated as "zero". actual = subject.FormatMessage(pattern, new { }); Assert.Equal("You have no unread messages today.", actual); actual = subject.FormatMessage(pattern, new { UnreadCount = 1 }); Assert.Equal("You have just one unread message today.", actual); actual = subject.FormatMessage(pattern, new { UnreadCount = 2 }); Assert.Equal("You have 2 unread messages today.", actual); actual = subject.FormatMessage(pattern, new { UnreadCount = 3 }); Assert.Equal("You have 3 unread messages today.", actual); }
public void ReadMe_test_to_make_sure_I_dont_look_like_a_fool() { { var mf = new MessageFormatter(false); var str = @"You have {notifications, plural, zero {no notifications} one {one notification} =42 {a universal amount of notifications} other {# notifications} }. Have a nice day, {name}!"; var formatted = mf.FormatMessage( str, new Dictionary<string, object> { { "notifications", 4 }, { "name", "Jeff" } }); Assert.Equal("You have 4 notifications. Have a nice day, Jeff!", formatted); } { var mf = new MessageFormatter(false); var str = @"You {NUM_ADDS, plural, offset:1 =0{didnt add this to your profile} zero{added this to your profile} one{and one other person added this to their profile} other{and # others added this to their profiles} }."; var formatted = mf.FormatMessage(str, new Dictionary<string, object> { { "NUM_ADDS", 0 } }); Assert.Equal("You didnt add this to your profile.", formatted); formatted = mf.FormatMessage(str, new Dictionary<string, object> { { "NUM_ADDS", 1 } }); Assert.Equal("You added this to your profile.", formatted); formatted = mf.FormatMessage(str, new Dictionary<string, object> { { "NUM_ADDS", 2 } }); Assert.Equal("You and one other person added this to their profile.", formatted); formatted = mf.FormatMessage(str, new Dictionary<string, object> { { "NUM_ADDS", 3 } }); Assert.Equal("You and 2 others added this to their profiles.", formatted); } { var mf = new MessageFormatter(false); var str = @"{GENDER, select, male {He} female {She} other {They} } found {NUM_RESULTS, plural, one {1 result} other {# results} } in {NUM_CATEGORIES, plural, one {1 category} other {# categories} }."; var formatted = mf.FormatMessage( str, new Dictionary<string, object> { { "GENDER", "male" }, { "NUM_RESULTS", 1 }, { "NUM_CATEGORIES", 2 } }); Assert.Equal(formatted, "He found 1 result in 2 categories."); formatted = mf.FormatMessage( str, new Dictionary<string, object> { { "GENDER", "male" }, { "NUM_RESULTS", 1 }, { "NUM_CATEGORIES", 1 } }); Assert.Equal(formatted, "He found 1 result in 1 category."); formatted = mf.FormatMessage( str, new Dictionary<string, object> { { "GENDER", "female" }, { "NUM_RESULTS", 2 }, { "NUM_CATEGORIES", 1 } }); Assert.Equal(formatted, "She found 2 results in 1 category."); } { var mf = new MessageFormatter(false); var str = @"Your {NUM, plural, one{message} other{messages}} go here."; var formatted = mf.FormatMessage(str, new Dictionary<string, object> { { "NUM", 1 } }); Assert.Equal(formatted, "Your message go here."); formatted = mf.FormatMessage(str, new Dictionary<string, object> { { "NUM", 3 } }); Assert.Equal(formatted, "Your messages go here."); } { var mf = new MessageFormatter(false); var str = @"His name is {LAST_NAME}... {FIRST_NAME} {LAST_NAME}"; var formatted = mf.FormatMessage( str, new Dictionary<string, object> { { "FIRST_NAME", "James" }, { "LAST_NAME", "Bond" } }); Assert.Equal(formatted, "His name is Bond... James Bond"); } { var mf = new MessageFormatter(false); var str = @"{GENDER, select, male{He} female{She} other{They}} liked this."; var formatted = mf.FormatMessage(str, new Dictionary<string, object> { { "GENDER", "male" } }); Assert.Equal(formatted, "He liked this."); formatted = mf.FormatMessage(str, new Dictionary<string, object> { { "GENDER", "female" } }); Assert.Equal(formatted, "She liked this."); formatted = mf.FormatMessage(str, new Dictionary<string, object> { { "GENDER", "somethingelse" } }); Assert.Equal(formatted, "They liked this."); formatted = mf.FormatMessage(str, new Dictionary<string, object> { }); Assert.Equal(formatted, "They liked this."); } { var mf = new MessageFormatter(true, "en"); mf.Pluralizers["en"] = n => { // ´n´ is the number being pluralized. if (n == 0) { return "zero"; } if (n == 1) { return "one"; } if (n > 1000) { return "thatsalot"; } return "other"; }; var actual = mf.FormatMessage( "You have {number, plural, thatsalot {a shitload of notifications} other {# notifications}}", new Dictionary<string, object> { { "number", 1001 } }); Assert.Equal("You have a shitload of notifications", actual); } }
public void FormatMessage(string source, Dictionary<string, object> args, string expected) { var subject = new MessageFormatter(false); // Warmup subject.FormatMessage(source, args); Benchmark.Start("Formatting", this.outputHelper); string result = subject.FormatMessage(source, args); Benchmark.End(this.outputHelper); Assert.Equal(expected, result); this.outputHelper.WriteLine(result); }
public void FormatMessage_lets_non_ascii_characters_right_through() { var input = "中test中国话不用彁字。"; var subject = new MessageFormatter(false); var actual = subject.FormatMessage(input, new Dictionary<string, object>()); Assert.Equal(input, actual); }
public void FormatMessage_using_real_parser_and_library_mock(string source, string expected) { var mockLibary = new Mock<IFormatterLibrary>(); var dummyFormatter = new Mock<IFormatter>(); var subject = new MessageFormatter( new PatternParser(new LiteralParser()), mockLibary.Object, false); var args = new Dictionary<string, object>(); args.Add("name", "Jeff"); dummyFormatter.Setup(x => x.Format("en", It.IsAny<FormatterRequest>(), args, "Jeff", subject)) .Returns("Jeff"); mockLibary.Setup(x => x.GetFormatter(It.IsAny<FormatterRequest>())).Returns(dummyFormatter.Object); // Warm up Benchmark.Start("Warm-up", this.outputHelper); subject.FormatMessage(source, args); Benchmark.End(this.outputHelper); Benchmark.Start("Aaaand a few after warm-up", this.outputHelper); for (int i = 0; i < 1000; i++) { subject.FormatMessage(source, args); } Benchmark.End(this.outputHelper); Assert.Equal(expected, subject.FormatMessage(source, args)); }
public void DescribeTo(SpecInfo spec, MessageFormatter formatter) { spec.ReportExpectation(formatter.FormatMessage(_expected)); }
/// <summary> /// The benchmark. /// </summary> /// <param name="subject"> /// The subject. /// </param> private void Benchmark(MessageFormatter subject) { var pattern = "\r\n----\r\nOh {name}? And if we were " + "to surround {gender, select, " + "male {his} " + "female {her}" + "} name with \\{ and \\}, it would look " + "like \\{{name}\\}? Yeah, I know {gender, select, " + "male {him} " + "female {her}" + "}. {gender, select, " + "male {He's}" + "female {She's}" + "} got {messageCount, plural, " + "zero {no messages}" + "one {just one message}" + "=42 {a universal amount of messages}" + "other {uuhm... let's see.. Oh yeah, # messages - and here's a pound: \\#}" + "}!"; int iterations = 100000; var args = new Dictionary<string, object>[iterations]; var rnd = new Random(); for (int i = 0; i < iterations; i++) { var val = rnd.Next(50); args[i] = new { gender = val % 2 == 0 ? "male" : "female", name = val % 2 == 0 ? "Jeff" : "Amanda", messageCount = val }.ToDictionary(); } TestHelpers.Benchmark.Start("Formatting message " + iterations + " times, no warm-up.", this.outputHelper); var output = new StringBuilder(); for (int i = 0; i < iterations; i++) { output.AppendLine(subject.FormatMessage(pattern, args[i])); } TestHelpers.Benchmark.End(this.outputHelper); this.outputHelper.WriteLine(output.ToString()); }
public void DescribeTo(Func<string, SpecInfo> func, MessageFormatter formatter) { func(_description ?? formatter.FormatMessage(_message)); }
public void FormatMessage_with_reflection_overload() { var subject = new MessageFormatter(false); const string Pattern = "You have {UnreadCount, plural, " + "zero {no unread messages}" + "one {just one unread message}" + "other {# unread messages}" + "} today."; var actual = subject.FormatMessage(Pattern, new { UnreadCount = 0 }); Assert.Equal("You have no unread messages today.", actual); // The absence of UnreadCount should make it throw. var ex = Assert.Throws<VariableNotFoundException>(() => subject.FormatMessage(Pattern, new { })); Assert.Equal("UnreadCount", ex.MissingVariable); actual = subject.FormatMessage(Pattern, new { UnreadCount = 1 }); Assert.Equal("You have just one unread message today.", actual); actual = subject.FormatMessage(Pattern, new { UnreadCount = 2 }); Assert.Equal("You have 2 unread messages today.", actual); actual = subject.FormatMessage(Pattern, new { UnreadCount = 3 }); Assert.Equal("You have 3 unread messages today.", actual); }
/// <summary> /// Persists message <paramref name="message"/>. /// </summary> /// <param name="message">Message to be persisted.</param> public override void Persist(IMessage message) { Debug.WriteLine(MessageFormatter.FormatMessage(message, FormatString)); }