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);
        }
Пример #2
0
        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));
        }
Пример #3
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;
        }
Пример #5
0
        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));
        }
Пример #6
0
        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);
        }
Пример #7
0
        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);
        }
Пример #8
0
        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);
            }
        }
Пример #9
0
        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);
            }
        }
Пример #10
0
        public void CanNotCreateIfSuppressed()
        {
            Type             type    = typeof(SuppressedListMock);
            FormatterRequest request = new FormatterRequest(type, isPolymorph: false);

            Assert.IsFalse(_builder.CanCreate(request));
        }
Пример #11
0
        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();
 }
Пример #13
0
        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));
 }
Пример #17
0
        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);
        }
Пример #18
0
        /// <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());
            }
        }
Пример #19
0
        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);
        }
Пример #20
0
        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);
        }
Пример #21
0
        /// <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);
        }
Пример #22
0
        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);
        }
Пример #23
0
 public bool CanCreate(FormatterRequest request)
 => request.Type.IsValueType &&
 request.Type.IsGenericType &&
 request.Type.GetGenericTypeDefinition() == typeof(Nullable <>);
Пример #24
0
 /// <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))
 {
 }
Пример #26
0
 public bool CanCreate(FormatterRequest request) => request.Type == typeof(bool);
Пример #27
0
 /// <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;
 }
Пример #29
0
 public bool CanCreate(FormatterRequest request) => !request.IsPolymorph &&
 typeof(ICustomFormatted).IsAssignableFrom(request.Type);
Пример #30
0
 public bool CanCreate(FormatterRequest request) => _formatters.ContainsKey(request.Type);
Пример #31
0
 public bool CanCreate(FormatterRequest request) => request.Type.IsEnum;
 public bool CanCreate(FormatterRequest request) => request.IsPolymorph;
Пример #33
0
 /// <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";
 }
Пример #34
0
        /// <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);
        }
Пример #35
0
 /// <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");
 }
Пример #36
0
 public bool CanCreate(FormatterRequest request) => !request.IsPolymorph &&
 FieldProviderResolver.Instance.IsSupported(request.Type);
Пример #37
0
 /// <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";
 }