Source

csconneg / tests / CsConneg.MediaRangeTests.cs

Full commit
namespace CsConneg
{
    using System;
    using System.Linq;
    using System.Collections.Generic;
    //
    using NUnit.Framework;
    using NUnit.Framework.SyntaxHelpers;

    [TestFixture] public class MediaRangeTests
    {
        [Test, ExpectedException(typeof(ArgumentNullException))]
        public void Media_range_throws_on_null_primary_type()
        {
            new MediaRange(null, "xml", new KeyValuePair<string, string>[0]);
        }

        [Test, ExpectedException(typeof(ArgumentNullException))]
        public void Media_range_throws_on_null_subtype()
        {
            new MediaRange("application", null, new KeyValuePair<string, string>[0]);
        }

        [Test, ExpectedException(typeof(ArgumentNullException))]
        public void Media_range_throws_on_null_param_array()
        {
            new MediaRange("application", "xml", null);
        }

        [Test, ExpectedException(typeof(ArgumentException))]
        public void Media_range_throws_on_wildcard_primary_type_and_specific_subtype()
        {
            new MediaRange("*", "xml");
        }

        [Test] public void Media_range_parses_correctly()
        {
            var cases = new[]
            {
                new
                {
                    Input = "application/atomsvc+xml",
                    Expected = new MediaRange("application", "atomsvc+xml"),
                },
                new
                {
                    Input = "application/atom+xml;type=entry",
                    Expected = new MediaRange(
                        "application", "atom+xml",
                        new[] { new KeyValuePair<string, string>("type", "entry"), }),
                },
                new
                {
                    Input = "model/vnd.spam;q=0.12;level=spammy;x=\"bacon!\"",
                    Expected = new MediaRange(
                        "model", "vnd.spam",
                        new[]
                        {
                            new KeyValuePair<string, string>("q", "0.12"),
                            new KeyValuePair<string, string>("level", "spammy"),
                            new KeyValuePair<string, string>("x", "\"bacon!\""),
                        }),
                },
                new
                {
                    Input = "text/*;charset=latin-1",
                    Expected = new MediaRange(
                        "text", "*",
                        new[] { new KeyValuePair<string, string>("charset", "latin-1"), }),
                },
                new
                {
                    Input = "*/*;q=0",
                    Expected = new MediaRange(
                        "*", "*",
                        new[] { new KeyValuePair<string, string>("q", "0"), }),
                },
            };

            foreach (var @case in cases)
            {
                {
                    var parsed = MediaRange.Parse(@case.Input);
                    Assert.That(parsed, Is.EqualTo(@case.Expected));
                }

                {
                    MediaRange parsed;
                    Assert.IsTrue(MediaRange.TryParse(@case.Input, out parsed));
                    Assert.That(parsed, Is.EqualTo(@case.Expected));
                }
            }
        }

        [Test, ExpectedException(typeof(ArgumentNullException))]
        public void Media_range_throws_on_parsing_null()
        {
            MediaRange.Parse(null);
        }

        [Test] public void Media_range_returns_false_on_tryparsing_null()
        {
            MediaRange mr;
            Assert.IsFalse(MediaRange.TryParse(null, out mr));
        }

        [Test] public void Media_range_formats_correctly()
        {
            var cases = new[]
            {
                new
                {
                    Input = new MediaRange("application", "atomsvc+xml"),
                    Expected = "application/atomsvc+xml",
                },
                new
                {
                    Input = new MediaRange(
                        "application", "atom+xml",
                        new[] { new KeyValuePair<string, string>("type", "entry"), }),
                    Expected = "application/atom+xml;type=entry",
                },
                new
                {
                    Input = new MediaRange(
                        "model", "vnd.spam",
                        new[]
                        {
                            new KeyValuePair<string, string>("q", "0.12"),
                            new KeyValuePair<string, string>("level", "spammy"),
                            new KeyValuePair<string, string>("x", "\"bacon!\""),
                        }),
                    Expected = "model/vnd.spam;q=0.12;level=spammy;x=\"bacon!\"",
                },
                new
                {
                    Input = new MediaRange(
                        "text", "*",
                        new[] { new KeyValuePair<string, string>("charset", "latin-1"), }),
                    Expected = "text/*;charset=latin-1",
                },
                new
                {
                    Input = new MediaRange(
                        "*", "*",
                        new[] { new KeyValuePair<string, string>("q", "0"), }),
                    Expected = "*/*;q=0",
                },
            };

            foreach (var @case in cases)
            {
                Assert.That(@case.Input.ToString(), Is.EqualTo(@case.Expected));
            }
        }

        [Test] public void Media_range_compares_correctly_for_equality()
        {
            var a1 = new MediaRange("application", "xml");
            var A1 = new MediaRange("Application", "Xml");
            var a2 = new MediaRange("application", "xml");
            var b1 = new MediaRange(
                "application", "atom+xml",
                new[]
                {
                    new KeyValuePair<string, string>("type", "feed"),
                    new KeyValuePair<string, string>("q", "0.8"),
                });
            var b2 = new MediaRange(
                "application", "atom+xml",
                new[]
                {
                    new KeyValuePair<string, string>("type", "feed"),
                    new KeyValuePair<string, string>("q", "0.8"),
                });
            var c = new MediaRange(
                "application", "atom+xml",
                new[]
                {
                    new KeyValuePair<string, string>("type", "feed"),
                    new KeyValuePair<string, string>("q", "0.9"),
                });
            var d = new MediaRange(
                "application", "atom+xml",
                new[]
                {
                    new KeyValuePair<string, string>("type", "feed"),
                });

            Assert.That(a1, Is.EqualTo(a2));
            Assert.That(a1, Is.EqualTo(A1));
            Assert.That(b1, Is.EqualTo(b2));

            Assert.That(a1, Is.Not.EqualTo(b1));
            Assert.That(b1, Is.Not.EqualTo(c));
            Assert.That(b1, Is.Not.EqualTo(d));
            Assert.That(a1, Is.Not.EqualTo(null));

            Assert.That(a1 == a1);
            Assert.That(a1 == A1);
            Assert.That(a1 == a2);
            Assert.That(a1 != b1);
            Assert.That(a1 != null);
            Assert.That(null != a1);
        }

        [Test] public void Media_range_matching_ignores_q_parameter_by_default()
        {
            var textHtmlLevel1Q05 = new MediaRange(
                "text", "html", new[]
                {
                    new KeyValuePair<string, string>("level", "1"),
                    new KeyValuePair<string, string>("q", "0.5"),
                });
            var textHtmlLevel1Q02 = new MediaRange(
                "text", "html", new[]
                {
                    new KeyValuePair<string, string>("level", "1"),
                    new KeyValuePair<string, string>("q", "0.2"),
                });

            Assert.That(textHtmlLevel1Q05.Match(textHtmlLevel1Q02, false), Is.EqualTo(0));
            Assert.That(textHtmlLevel1Q05.Match(textHtmlLevel1Q02, true), Is.GreaterThan(0));
            Assert.That(textHtmlLevel1Q05.Match(textHtmlLevel1Q02), Is.GreaterThan(0));
        }

        [Test] public void Media_range_matching_ignores_character_case_of_parameter_names()
        {
            var textHtmlCharsetUtf8 = new MediaRange(
                "text", "html", new[]
                {
                    new KeyValuePair<string, string>("charset", "utf-8"),
                    new KeyValuePair<string, string>("level", "1"),
                    new KeyValuePair<string, string>("q", "0.5"),
                });
            var textHtmlCHARSETUtf8 = new MediaRange(
                "text", "html", new[]
                {
                    new KeyValuePair<string, string>("q", "0.2"),
                    new KeyValuePair<string, string>("level", "1"),
                    new KeyValuePair<string, string>("CHARSET", "utf-8"),
                });

            Assert.That(textHtmlCHARSETUtf8.Match(textHtmlCharsetUtf8), Is.GreaterThan(0));
            Assert.That(textHtmlCharsetUtf8.Match(textHtmlCHARSETUtf8), Is.GreaterThan(0));
        }

        [Test] public void Media_range_matching_ignores_character_case_of_parameter_values()
        {
            var textHtmlCharsetUTF8 = new MediaRange(
                "text", "html", new[]
                {
                    new KeyValuePair<string, string>("charset", "UTF-8"),
                    new KeyValuePair<string, string>("q", "0.5"),
                });
            var textHtmlCharsetUtf8 = new MediaRange(
                "text", "html", new[]
                {
                    new KeyValuePair<string, string>("q", "0.2"),
                    new KeyValuePair<string, string>("charset", "utf-8"),
                });

            Assert.That(textHtmlCharsetUtf8.Match(textHtmlCharsetUTF8), Is.GreaterThan(0));
            Assert.That(textHtmlCharsetUTF8.Match(textHtmlCharsetUtf8), Is.GreaterThan(0));
        }

        [Test] public void Media_range_matching_ignores_character_case_of_media_types()
        {
            var TEXTHTML = new MediaRange("TEXT", "HTML");
            var textHtml = new MediaRange("text", "html");

            Assert.That(textHtml.Match(TEXTHTML), Is.GreaterThan(0));
            Assert.That(TEXTHTML.Match(textHtml), Is.GreaterThan(0));
        }

        [Test, ExpectedException(typeof(ArgumentNullException))]
        public void Media_range_matching_throws_on_null()
        {
            var any = new MediaRange("*", "*");
            any.Match(null);
        }

        [Test] public void Media_range_computes_match_score_correctly()
        {
            var any = new MediaRange("*", "*");
            var textAny = new MediaRange("text", "*");
            var textPlain = new MediaRange("text", "plain");
            var textHtml = new MediaRange("text", "html");
            var textHtmlLevel1 = new MediaRange(
                "text", "html",
                new[] { new KeyValuePair<string, string>("level", "1"), });
            var textHtmlLevel1SpamEggs = new MediaRange(
                "text", "html",
                new[]
                {
                    new KeyValuePair<string, string>("level", "1"),
                    new KeyValuePair<string, string>("spam", "eggs"),
                });
            var textHtmlLevel1SpamBacon = new MediaRange(
                "text", "html",
                new[]
                {
                    new KeyValuePair<string, string>("spam", "bacon"),
                    new KeyValuePair<string, string>("level", "1"),
                });

            Assert.That(any.Match(any), Is.EqualTo(50 + 5 + 0.5 + 0.01));
            Assert.That(any.Match(textAny), Is.EqualTo(50 + 5 + 0.5 + 0.01));
            Assert.That(any.Match(textPlain), Is.EqualTo(50 + 5 + 0.5 + 0.01));
            Assert.That(any.Match(textHtml), Is.EqualTo(50 + 5 + 0.5 + 0.01));
            Assert.That(any.Match(textHtmlLevel1), Is.EqualTo(50 + 5 + 0.5));
            Assert.That(any.Match(textHtmlLevel1SpamBacon), Is.EqualTo(50 + 5 + 0.5));
            Assert.That(any.Match(textHtmlLevel1SpamEggs), Is.EqualTo(50 + 5 + 0.5));

            Assert.That(textAny.Match(any), Is.EqualTo(0));
            Assert.That(textAny.Match(textAny), Is.EqualTo(100 + 5 + 0.5 + 0.01));
            Assert.That(textAny.Match(textPlain), Is.EqualTo(100 + 5 + 0.5 + 0.01));
            Assert.That(textAny.Match(textHtml), Is.EqualTo(100 + 5 + 0.5 + 0.01));
            Assert.That(textAny.Match(textHtmlLevel1), Is.EqualTo(100 + 5 + 0.5));
            Assert.That(textAny.Match(textHtmlLevel1SpamBacon), Is.EqualTo(100 + 5 + 0.5));
            Assert.That(textAny.Match(textHtmlLevel1SpamEggs), Is.EqualTo(100 + 5 + 0.5));

            Assert.That(textPlain.Match(any), Is.EqualTo(0));
            Assert.That(textPlain.Match(textAny), Is.EqualTo(0));
            Assert.That(textPlain.Match(textPlain), Is.EqualTo(100 + 10 + 0.5 + 0.01));
            Assert.That(textPlain.Match(textHtml), Is.EqualTo(0));
            Assert.That(textPlain.Match(textHtmlLevel1), Is.EqualTo(0));
            Assert.That(textPlain.Match(textHtmlLevel1SpamBacon), Is.EqualTo(0));
            Assert.That(textPlain.Match(textHtmlLevel1SpamEggs), Is.EqualTo(0));

            Assert.That(textHtml.Match(any), Is.EqualTo(0));
            Assert.That(textHtml.Match(textAny), Is.EqualTo(0));
            Assert.That(textHtml.Match(textPlain), Is.EqualTo(0));
            Assert.That(textHtml.Match(textHtml), Is.EqualTo(100 + 10 + 0.5 + 0.01));
            Assert.That(textHtml.Match(textHtmlLevel1), Is.EqualTo(100 + 10 + 0.5));
            Assert.That(textHtml.Match(textHtmlLevel1SpamBacon), Is.EqualTo(100 + 10 + 0.5));
            Assert.That(textHtml.Match(textHtmlLevel1SpamEggs), Is.EqualTo(100 + 10 + 0.5));

            Assert.That(textHtmlLevel1.Match(any), Is.EqualTo(0));
            Assert.That(textHtmlLevel1.Match(textAny), Is.EqualTo(0));
            Assert.That(textHtmlLevel1.Match(textPlain), Is.EqualTo(0));
            Assert.That(textHtmlLevel1.Match(textHtml), Is.EqualTo(0));
            Assert.That(textHtmlLevel1.Match(textHtmlLevel1), Is.EqualTo(100 + 10 + 1));
            Assert.That(textHtmlLevel1.Match(textHtmlLevel1SpamBacon), Is.EqualTo(0));
            Assert.That(textHtmlLevel1.Match(textHtmlLevel1SpamEggs), Is.EqualTo(0));

            Assert.That(textHtmlLevel1SpamBacon.Match(any), Is.EqualTo(0));
            Assert.That(textHtmlLevel1SpamBacon.Match(textAny), Is.EqualTo(0));
            Assert.That(textHtmlLevel1SpamBacon.Match(textPlain), Is.EqualTo(0));
            Assert.That(textHtmlLevel1SpamBacon.Match(textHtml), Is.EqualTo(0));
            Assert.That(textHtmlLevel1SpamBacon.Match(textHtmlLevel1), Is.EqualTo(0));
            Assert.That(textHtmlLevel1SpamBacon.Match(textHtmlLevel1SpamBacon), Is.EqualTo(100 + 10 + 1));
            Assert.That(textHtmlLevel1SpamBacon.Match(textHtmlLevel1SpamEggs), Is.EqualTo(0));

            Assert.That(textHtmlLevel1SpamEggs.Match(any), Is.EqualTo(0));
            Assert.That(textHtmlLevel1SpamEggs.Match(textAny), Is.EqualTo(0));
            Assert.That(textHtmlLevel1SpamEggs.Match(textPlain), Is.EqualTo(0));
            Assert.That(textHtmlLevel1SpamEggs.Match(textHtml), Is.EqualTo(0));
            Assert.That(textHtmlLevel1SpamEggs.Match(textHtmlLevel1), Is.EqualTo(0));
            Assert.That(textHtmlLevel1SpamEggs.Match(textHtmlLevel1SpamBacon), Is.EqualTo(0));
            Assert.That(textHtmlLevel1SpamEggs.Match(textHtmlLevel1SpamEggs), Is.EqualTo(100 + 10 + 1));
        }
    }
}