public IEnumerable <Endpoint> FindEndpoints(RouteValuesAddress address)
        {
            IList <OutboundMatchResult> matchResults = null;

            if (string.IsNullOrEmpty(address.RouteName))
            {
                matchResults = _allMatchesLinkGenerationTree.GetMatches(
                    address.ExplicitValues,
                    address.AmbientValues);
            }
            else if (_namedMatchResults.TryGetValue(address.RouteName, out var namedMatchResults))
            {
                matchResults = namedMatchResults;
            }

            if (matchResults != null)
            {
                var matchCount = matchResults.Count;
                if (matchCount > 0)
                {
                    if (matchResults.Count == 1)
                    {
                        // Special case having a single result to avoid creating iterator state machine
                        return(new[] { (RouteEndpoint)matchResults[0].Match.Entry.Data });
                    }
                    else
                    {
                        // Use separate method since one cannot have regular returns in an iterator method
                        return(GetEndpoints(matchResults, matchCount));
                    }
                }
            }

            return(Array.Empty <Endpoint>());
        }
Esempio n. 2
0
        /// <inheritdoc />
        public VirtualPathData GetVirtualPath(VirtualPathContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            // If it's a named route we will try to generate a link directly and
            // if we can't, we will not try to generate it using an unnamed route.
            if (context.RouteName != null)
            {
                return(GetVirtualPathForNamedRoute(context));
            }

            // The decision tree will give us back all entries that match the provided route data in the correct
            // order. We just need to iterate them and use the first one that can generate a link.
            var matches = _linkGenerationTree.GetMatches(context);

            foreach (var match in matches)
            {
                var path = GenerateVirtualPath(context, match.Entry);
                if (path != null)
                {
                    context.IsBound = true;
                    return(path);
                }
            }

            return(null);
        }
Esempio n. 3
0
    public void SelectMultipleEntries_BothMatch_OrderedByTemplate()
    {
        // Arrange
        var entries = new List <OutboundMatch>();

        var entry1 = CreateMatch(new { controller = "Store", action = "Buy" });

        entry1.Entry.RouteTemplate = TemplateParser.Parse("a");
        entries.Add(entry1);

        var entry2 = CreateMatch(new { controller = "Store", action = "Buy" });

        entry2.Entry.RouteTemplate = TemplateParser.Parse("b");
        entries.Add(entry2);

        var tree = new LinkGenerationDecisionTree(entries);

        var context = CreateContext(new { controller = "Store", action = "Buy" });

        // Act
        var matches = tree.GetMatches(context.Values, context.AmbientValues).Select(m => m.Match).ToList();

        // Assert
        Assert.Equal(entries, matches);
    }
Esempio n. 4
0
    public void SelectMultipleEntries_BothMatch_CriteriaSubset()
    {
        // Arrange
        var entries = new List <OutboundMatch>();

        var entry1 = CreateMatch(new { controller = "Store", action = "Buy" });

        entries.Add(entry1);

        var entry2 = CreateMatch(new { controller = "Store" });

        entry2.Entry.Order = 1;
        entries.Add(entry2);

        var tree = new LinkGenerationDecisionTree(entries);

        var context = CreateContext(
            values: new { controller = "Store" },
            ambientValues: new { controller = "Store", action = "Buy" });

        // Act
        var matches = tree.GetMatches(context.Values, context.AmbientValues).Select(m => m.Match).ToList();

        // Assert
        Assert.Equal(entries, matches);
    }
        public void SelectMultipleEntries_BothMatch_OrderedByPrecedence()
        {
            // Arrange
            var entries = new List <TreeRouteLinkGenerationEntry>();

            var entry1 = CreateEntry(new { controller = "Store", action = "Buy" });

            entry1.GenerationPrecedence = 1;
            entries.Add(entry1);

            var entry2 = CreateEntry(new { controller = "Store", action = "Buy" });

            entry2.GenerationPrecedence = 0;
            entries.Add(entry2);

            var tree = new LinkGenerationDecisionTree(entries);

            var context = CreateContext(new { controller = "Store", action = "Buy" });

            // Act
            var matches = tree.GetMatches(context).Select(m => m.Entry).ToList();

            // Assert
            Assert.Equal(entries, matches);
        }
Esempio n. 6
0
    public void GetMatches_LinkToPageFromController_WithActionValueAmbiguous()
    {
        // Arrange
        var entries = new List <OutboundMatch>();

        var entry1 = CreateMatch(new { controller = "Home", action = "Index", area = (string)null, page = (string)null, });

        entry1.Entry.RouteTemplate = TemplateParser.Parse("a");
        entries.Add(entry1);

        var entry2 = CreateMatch(new { page = "/Store/Buy", area = (string)null, controller = (string)null, action = (string)null, });

        entry2.Entry.RouteTemplate = TemplateParser.Parse("b");
        entries.Add(entry2);

        var tree = new LinkGenerationDecisionTree(entries);

        var context = CreateContext(new { page = "/Store/Buy", action = "Index", }, new { controller = "Home", action = "Index", page = "16", });

        // Act
        var matches = tree.GetMatches(context.Values, context.AmbientValues).Select(m => m.Match).ToList();

        // Assert
        Assert.Empty(matches);
    }
Esempio n. 7
0
    public void GetMatches_PagesWithArea_AllValuesAmbient()
    {
        // Arrange
        var entries = new List <OutboundMatch>();

        var entry1 = CreateMatch(new { page = "/Store/Buy", area = (string)null, });

        entry1.Entry.RouteTemplate = TemplateParser.Parse("a");
        entries.Add(entry1);

        var entry2 = CreateMatch(new { page = "/Store/Buy", area = "Admin" });

        entry2.Entry.RouteTemplate = TemplateParser.Parse("b");
        entries.Add(entry2);

        var tree = new LinkGenerationDecisionTree(entries);

        var context = CreateContext(new { }, new { page = "/Store/Buy", area = "Admin", });

        // Act
        var matches = tree.GetMatches(context.Values, context.AmbientValues).Select(m => m.Match).ToList();

        // Assert
        Assert.Collection(
            matches,
            m => { Assert.Same(entry2, m); },
            m => { Assert.Same(entry1, m); });
    }
Esempio n. 8
0
        /// <inheritdoc />
        public VirtualPathData GetVirtualPath(VirtualPathContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            // If it's a named route we will try to generate a link directly and
            // if we can't, we will not try to generate it using an unnamed route.
            if (context.RouteName != null)
            {
                return(GetVirtualPathForNamedRoute(context));
            }

            // The decision tree will give us back all entries that match the provided route data in the correct
            // order. We just need to iterate them and use the first one that can generate a link.
            var matches = _linkGenerationTree.GetMatches(context.Values, context.AmbientValues);

            if (matches == null)
            {
                return(null);
            }

            for (var i = 0; i < matches.Count; i++)
            {
                var path = GenerateVirtualPath(context, matches[i].Match.Entry, matches[i].Match.TemplateBinder);
                if (path != null)
                {
                    return(path);
                }
            }

            return(null);
        }
Esempio n. 9
0
    public void SelectMultipleEntries_OneDoesntMatch()
    {
        // Arrange
        var entries = new List <OutboundMatch>();

        var entry1 = CreateMatch(new { controller = "Store", action = "Buy" });

        entries.Add(entry1);

        var entry2 = CreateMatch(new { controller = "Store", action = "Cart" });

        entries.Add(entry2);

        var tree = new LinkGenerationDecisionTree(entries);

        var context = CreateContext(
            values: new { controller = "Store" },
            ambientValues: new { controller = "Store", action = "Buy" });

        // Act
        var matches = tree.GetMatches(context.Values, context.AmbientValues);

        // Assert
        Assert.Same(entry1, Assert.Single(matches).Match);
    }
        public void SelectSingleEntry_MultipleCriteria()
        {
            // Arrange
            var entries = new List<AttributeRouteLinkGenerationEntry>();

            var entry = CreateEntry(new { controller = "Store", action = "Buy" });
            entries.Add(entry);

            var tree = new LinkGenerationDecisionTree(entries);

            var context = CreateContext(new { controller = "Store", action = "Buy" });

            // Act
            var matches = tree.GetMatches(context);

            // Assert
            Assert.Same(entry, Assert.Single(matches).Entry);
        }
        public void SelectSingleEntry_NoCriteria()
        {
            // Arrange
            var entries = new List<TreeRouteLinkGenerationEntry>();

            var entry = CreateEntry(new { });
            entries.Add(entry);

            var tree = new LinkGenerationDecisionTree(entries);

            var context = CreateContext(new { });

            // Act
            var matches = tree.GetMatches(context);

            // Assert
            Assert.Same(entry, Assert.Single(matches).Entry);
        }
        public void SelectSingleEntry_NoCriteria()
        {
            // Arrange
            var entries = new List <OutboundMatch>();

            var entry = CreateMatch(new { });

            entries.Add(entry);

            var tree = new LinkGenerationDecisionTree(entries);

            var context = CreateContext(new { });

            // Act
            var matches = tree.GetMatches(context);

            // Assert
            Assert.Same(entry, Assert.Single(matches).Match);
        }
        public void SelectSingleEntry_MultipleCriteria()
        {
            // Arrange
            var entries = new List <TreeRouteLinkGenerationEntry>();

            var entry = CreateEntry(new { controller = "Store", action = "Buy" });

            entries.Add(entry);

            var tree = new LinkGenerationDecisionTree(entries);

            var context = CreateContext(new { controller = "Store", action = "Buy" });

            // Act
            var matches = tree.GetMatches(context);

            // Assert
            Assert.Same(entry, Assert.Single(matches).Entry);
        }
Esempio n. 14
0
    public void GetMatches_AllowsNullAmbientValues()
    {
        // Arrange
        var entries = new List <OutboundMatch>();

        var entry = CreateMatch(new { });

        entries.Add(entry);

        var tree = new LinkGenerationDecisionTree(entries);

        var context = CreateContext(new { });

        // Act
        var matches = tree.GetMatches(context.Values, ambientValues: null);

        // Assert
        Assert.Same(entry, Assert.Single(matches).Match);
    }
        public void SelectSingleEntry_MultipleCriteria_NoMatch()
        {
            // Arrange
            var entries = new List <OutboundMatch>();

            var entry = CreateMatch(new { controller = "Store", action = "Buy" });

            entries.Add(entry);

            var tree = new LinkGenerationDecisionTree(entries);

            var context = CreateContext(new { controller = "Store", action = "AddToCart" });

            // Act
            var matches = tree.GetMatches(context);

            // Assert
            Assert.Empty(matches);
        }
Esempio n. 16
0
    public void SelectSingleEntry_MultipleCriteria()
    {
        // Arrange
        var entries = new List <OutboundMatch>();

        var entry = CreateMatch(new { controller = "Store", action = "Buy" });

        entries.Add(entry);

        var tree = new LinkGenerationDecisionTree(entries);

        var context = CreateContext(new { controller = "Store", action = "Buy" });

        // Act
        var matches = tree.GetMatches(context.Values, context.AmbientValues);

        // Assert
        Assert.Same(entry, Assert.Single(matches).Match);
    }
        public void SelectSingleEntry_MultipleCriteria_AmbientValues()
        {
            // Arrange
            var entries = new List<AttributeRouteLinkGenerationEntry>();

            var entry = CreateEntry(new { controller = "Store", action = "Buy" });
            entries.Add(entry);

            var tree = new LinkGenerationDecisionTree(entries);

            var context = CreateContext(values: null, ambientValues: new { controller = "Store", action = "Buy" });

            // Act
            var matches = tree.GetMatches(context);

            // Assert
            var match = Assert.Single(matches);
            Assert.Same(entry, match.Entry);
            Assert.False(match.IsFallbackMatch);
        }
        public void SelectSingleEntry_MultipleCriteria_AmbientValue_NoMatch()
        {
            // Arrange
            var entries = new List <TreeRouteLinkGenerationEntry>();

            var entry = CreateEntry(new { controller = "Store", action = "Buy" });

            entries.Add(entry);

            var tree = new LinkGenerationDecisionTree(entries);

            var context = CreateContext(
                values: new { controller = "Store" },
                ambientValues: new { controller = "Store", action = "Cart" });

            // Act
            var matches = tree.GetMatches(context);

            // Assert
            Assert.Empty(matches);
        }
        public void SelectSingleEntry_MultipleCriteria_AmbientValues()
        {
            // Arrange
            var entries = new List <TreeRouteLinkGenerationEntry>();

            var entry = CreateEntry(new { controller = "Store", action = "Buy" });

            entries.Add(entry);

            var tree = new LinkGenerationDecisionTree(entries);

            var context = CreateContext(values: null, ambientValues: new { controller = "Store", action = "Buy" });

            // Act
            var matches = tree.GetMatches(context);

            // Assert
            var match = Assert.Single(matches);

            Assert.Same(entry, match.Entry);
            Assert.False(match.IsFallbackMatch);
        }
Esempio n. 20
0
    public void SelectSingleEntry_MultipleCriteria_Replaced()
    {
        // Arrange
        var entries = new List <OutboundMatch>();

        var entry = CreateMatch(new { controller = "Store", action = "Buy" });

        entries.Add(entry);

        var tree = new LinkGenerationDecisionTree(entries);

        var context = CreateContext(
            values: new { action = "Buy" },
            ambientValues: new { controller = "Store", action = "Cart" });

        // Act
        var matches = tree.GetMatches(context.Values, context.AmbientValues);

        // Assert
        var match = Assert.Single(matches);

        Assert.Same(entry, match.Match);
        Assert.False(match.IsFallbackMatch);
    }
        public void SelectMultipleEntries_BothMatch_NonOverlappingCriteria()
        {
            // Arrange
            var entries = new List <TreeRouteLinkGenerationEntry>();

            var entry1 = CreateEntry(new { controller = "Store", action = "Buy" });

            entries.Add(entry1);

            var entry2 = CreateEntry(new { slug = "1234" });

            entry2.Order = 1;
            entries.Add(entry2);

            var tree = new LinkGenerationDecisionTree(entries);

            var context = CreateContext(new { controller = "Store", action = "Buy", slug = "1234" });

            // Act
            var matches = tree.GetMatches(context).Select(m => m.Entry).ToList();

            // Assert
            Assert.Equal(entries, matches);
        }
        public IEnumerable <Endpoint> FindEndpoints(RouteValuesAddress address)
        {
            IEnumerable <OutboundMatchResult> matchResults = null;

            if (string.IsNullOrEmpty(address.RouteName))
            {
                matchResults = _allMatchesLinkGenerationTree.GetMatches(
                    address.ExplicitValues,
                    address.AmbientValues);
            }
            else if (_namedMatchResults.TryGetValue(address.RouteName, out var namedMatchResults))
            {
                matchResults = namedMatchResults;
            }

            if (matchResults == null || !matchResults.Any())
            {
                return(Array.Empty <Endpoint>());
            }

            return(matchResults
                   .Select(matchResult => matchResult.Match)
                   .Select(match => (MatcherEndpoint)match.Entry.Data));
        }
        public void SelectMultipleEntries_BothMatch_CriteriaSubset()
        {
            // Arrange
            var entries = new List<TreeRouteLinkGenerationEntry>();

            var entry1 = CreateEntry(new { controller = "Store", action = "Buy" });
            entries.Add(entry1);

            var entry2 = CreateEntry(new { controller = "Store" });
            entry2.Order = 1;
            entries.Add(entry2);

            var tree = new LinkGenerationDecisionTree(entries);

            var context = CreateContext(
                values: new { controller = "Store" },
                ambientValues: new { controller = "Store", action = "Buy" });

            // Act
            var matches = tree.GetMatches(context).Select(m => m.Entry).ToList();

            // Assert
            Assert.Equal(entries, matches);
        }
        public void SelectMultipleEntries_BothMatch_OrderedByTemplate()
        {
            // Arrange
            var entries = new List<AttributeRouteLinkGenerationEntry>();

            var entry1 = CreateEntry(new { controller = "Store", action = "Buy" });
            entry1.TemplateText = "a";
            entries.Add(entry1);

            var entry2 = CreateEntry(new { controller = "Store", action = "Buy" });
            entry2.TemplateText = "b";
            entries.Add(entry2);

            var tree = new LinkGenerationDecisionTree(entries);

            var context = CreateContext(new { controller = "Store", action = "Buy" });

            // Act
            var matches = tree.GetMatches(context).Select(m => m.Entry).ToList();

            // Assert
            Assert.Equal(entries, matches);
        }
        public void SelectMultipleEntries_BothMatch_NonOverlappingCriteria()
        {
            // Arrange
            var entries = new List<AttributeRouteLinkGenerationEntry>();

            var entry1 = CreateEntry(new { controller = "Store", action = "Buy" });
            entries.Add(entry1);

            var entry2 = CreateEntry(new { slug = "1234" });
            entry2.Order = 1;
            entries.Add(entry2);

            var tree = new LinkGenerationDecisionTree(entries);

            var context = CreateContext(new { controller = "Store", action = "Buy", slug = "1234" });

            // Act
            var matches = tree.GetMatches(context).Select(m => m.Entry).ToList();

            // Assert
            Assert.Equal(entries, matches);
        }
        public void SelectMultipleEntries_OneDoesntMatch()
        {
            // Arrange
            var entries = new List<AttributeRouteLinkGenerationEntry>();

            var entry1 = CreateEntry(new { controller = "Store", action = "Buy" });
            entries.Add(entry1);

            var entry2 = CreateEntry(new { controller = "Store", action = "Cart" });
            entries.Add(entry2);

            var tree = new LinkGenerationDecisionTree(entries);

            var context = CreateContext(
                values: new { controller = "Store" },
                ambientValues: new { controller = "Store", action = "Buy" });

            // Act
            var matches = tree.GetMatches(context);

            // Assert
            Assert.Same(entry1, Assert.Single(matches).Entry);
        }
        public void SelectSingleEntry_MultipleCriteria_AmbientValue_NoMatch()
        {
            // Arrange
            var entries = new List<AttributeRouteLinkGenerationEntry>();

            var entry = CreateEntry(new { controller = "Store", action = "Buy" });
            entries.Add(entry);

            var tree = new LinkGenerationDecisionTree(entries);

            var context = CreateContext(
                values: new { controller = "Store" },
                ambientValues: new { controller = "Store", action = "Cart" });

            // Act
            var matches = tree.GetMatches(context);

            // Assert
            Assert.Empty(matches);
        }