Exemplo n.º 1
0
        private IReadOnlyCollection <WeightedRoute> FindWeightedRoutes(IReadOnlyList <Route> routes,
                                                                       PathFinder pathFinder, GameBoard gameBoard, Route max)
        {
            var weighted = new ConcurrentBag <WeightedRoute>();

            Parallel.ForEach(routes, route =>
            {
                var furtherRoute    = FindAnyFurtherRoute(route, pathFinder, max.Length / 2);
                int lookupAreaSize  = max.Length - route.Length;
                var routesInArea    = FindRoutesInArea(route, pathFinder, lookupAreaSize);
                var routeProperties = new RouteProperties
                {
                    IsDeadEnd    = !furtherRoute.Any(),
                    TargetIsFury = route.GoalElement == FuryPill,
                    RoutesInArea = routesInArea,
                    EvilIsNear   = FindEvilNear(route.GoalPoint, pathFinder, FearArea),
                    PreyInArea   = FindPreyInArea(route, pathFinder, FuryArea),

                    BonusesInTarget = FindBonusesConcentration(route.GoalPoint, gameBoard, 6),
                    EnemiesInTarget = FindEnemyConcentration(route.GoalPoint, gameBoard, 6),
                    EnemyIsNear     = FindEnemyConcentration(route.Path.Skip(1).First(), gameBoard, 6),
                    //EvilIsNear = FindEvilSnakesConcentration(route.Path.Skip(1).First(), gameBoard, 6),
                    Hunting    = route.GoalElement.IsEnemy(),
                    StoneEater = route.GoalElement == Stone
                };
                weighted.Add(new WeightedRoute(route, routeProperties));
            });

            return(weighted);
        }
        public void ReadsEmptyDataWithoutRouteValues()
        {
            var data  = new Dictionary <string, string>();
            var props = new RouteProperties(data);

            Assert.That(props.RouteValues, Is.Not.Null, "route values null");
            Assert.That(props.RouteValues.Count, Is.EqualTo(0), "route values empty");
        }
        public void ReadsEmptyDataAsFail()
        {
            var data  = new Dictionary <string, string>();
            var props = new RouteProperties(data);

            Assert.That(props.DataOk, Is.False, "data ok");
            Assert.That(props.Controller, Is.Null, "controller");
            Assert.That(props.Action, Is.Null, "action");
        }
Exemplo n.º 4
0
        public override void ExecuteCmdlet()
        {
            if (ShouldProcess(this.RouteName, Properties.Resources.UpdateIotHubRoute))
            {
                IotHubDescription iotHubDescription;
                if (ParameterSetName.Equals(InputObjectParameterSet))
                {
                    this.ResourceGroupName = this.InputObject.Resourcegroup;
                    this.Name         = this.InputObject.Name;
                    iotHubDescription = IotHubUtils.ConvertObject <PSIotHub, IotHubDescription>(this.InputObject);
                }
                else
                {
                    if (ParameterSetName.Equals(ResourceIdParameterSet))
                    {
                        this.ResourceGroupName = IotHubUtils.GetResourceGroupName(this.ResourceId);
                        this.Name = IotHubUtils.GetIotHubName(this.ResourceId);
                    }

                    iotHubDescription = this.IotHubClient.IotHubResource.Get(this.ResourceGroupName, this.Name);
                }

                if (iotHubDescription.Properties.Routing.Routes.Any(x => x.Name.Equals(this.RouteName, StringComparison.OrdinalIgnoreCase)))
                {
                    RouteProperties routeProperties = iotHubDescription.Properties.Routing.Routes.FirstOrDefault(x => x.Name.Equals(this.RouteName, StringComparison.OrdinalIgnoreCase));
                    if (this.Source.HasValue)
                    {
                        routeProperties.Source = this.Source.Value.ToString();
                    }
                    if (!string.IsNullOrEmpty(this.EndpointName))
                    {
                        routeProperties.EndpointNames = new List <string>()
                        {
                            this.EndpointName
                        };
                    }
                    if (!string.IsNullOrEmpty(this.Condition))
                    {
                        routeProperties.Condition = this.Condition;
                    }
                    if (this.Enabled.IsPresent)
                    {
                        routeProperties.IsEnabled = this.Enabled.IsPresent;
                    }

                    this.IotHubClient.IotHubResource.CreateOrUpdate(this.ResourceGroupName, this.Name, iotHubDescription);
                    IotHubDescription updatedIotHubDescription = this.IotHubClient.IotHubResource.Get(this.ResourceGroupName, this.Name);
                    this.WriteObject(IotHubUtils.ToPSRouteMetadata(updatedIotHubDescription.Properties.Routing.Routes.FirstOrDefault(x => x.Name.Equals(this.RouteName, StringComparison.OrdinalIgnoreCase))), false);
                }
                else
                {
                    throw new ArgumentException("Entered route doesn't exist.");
                }
            }
        }
        public void ReadsNoControllerDataAsFail()
        {
            var data = new Dictionary <string, string>
            {
                { "action", "foo" }
            };

            var props = new RouteProperties(data);

            Assert.That(props.DataOk, Is.False, "data ok");
        }
        public void ReadsControllerAndAction()
        {
            var data = new Dictionary <string, string>
            {
                { "controller", "foo" },
                { "action", "bar" },
            };
            var props = new RouteProperties(data);

            Assert.That(props.DataOk, Is.True, "data ok");
            Assert.That(props.Controller, Is.EqualTo("foo"), "controller");
            Assert.That(props.Action, Is.EqualTo("bar"), "action");
            Assert.That(props.RouteValues.Count, Is.EqualTo(0), "route values empty");
        }
        public void ReadsOtherValuesAsRouteValues()
        {
            var data = new Dictionary <string, string>
            {
                { "controller", "foo" },
                { "action", "bar" },
                { "fish", "hallibut" },
            };
            var props = new RouteProperties(data);

            Assert.That(props.DataOk, Is.True, "data ok");
            Assert.That(props.RouteValues.Count, Is.EqualTo(1), "route values not empty");
            Assert.That(props.RouteValues["fish"], Is.EqualTo("hallibut"), "route value wrong");
        }
Exemplo n.º 8
0
        public void FeatureToggleRoute_Constructor_MapsRoutePropertiesValues()
        {
            var currentRouteProperties = new RouteProperties()
            {
                RouteHandler = new MvcRouteHandler()
            };
            var experimentalRouteProperties = new RouteProperties()
            {
                RouteHandler = new MvcRouteHandler()
            };
            var route = new FeatureToggleRoute("test", (r) => true, currentRouteProperties, experimentalRouteProperties);

            Assert.That(route.Url, Is.EqualTo("test"));
            Assert.That(route.Defaults, Is.Null);
            Assert.That(route.DataTokens, Is.Null);
            Assert.That(route.Constraints, Is.Null);
            Assert.That(route.CurrentRouteProperties, Is.EqualTo(currentRouteProperties));
            Assert.That(route.ExperimentalRouteProperties, Is.EqualTo(experimentalRouteProperties));
        }
Exemplo n.º 9
0
        public static BTResult MoveTo(Animal agent, Vector3 target, bool wandering)
        {
            var routeProps = new RouteProperties {
                MaxTargetLocationHeightDelta = agent.Species.ClimbHeight
            };
            var route = AIUtil.GetRouteFacingTarget(agent.FacingDir, agent.Position, target, agent.Species.GetTraversalData(wandering), agent.Species.HeadDistance * 2, routeProps: routeProps, allowBasic: false);

            if (!route.IsValid)
            {
                return(BTResult.Failure("Can't build route"));
            }

            // Prevent setting route with 0 time length
            var timeToFinishRoute = agent.SetRoute(route, wandering ? AnimalState.Wander : AnimalState.Flee);

            if (timeToFinishRoute < float.Epsilon)
            {
                return(BTResult.Failure("route not set"));
            }
            return(BTResult.RunningChanged("Moving to target"));
        }
Exemplo n.º 10
0
        static BTResult DoSleepNearLeader(Behavior <Animal> beh, Animal agent)
        {
            var leader = GetLeader(agent);

            if (leader == null)
            {
                return(BTResult.Failure("No leader"));
            }
            if (leader == agent)
            {
                return(BTResult.Failure("We are leader"));
            }

            //If the leader is sleeping...
            if (leader.State == AnimalState.Sleeping)
            {
                // and we're already close enough, sleep now.
                if (Vector3.WrappedDistance(agent.Position, leader.Position) < agent.Species.HeadDistance * 3)
                {
                    return(agent.ChangeState(AnimalState.LyingDown, 60f, true));
                }

                //Otherwise, move to them to sleep.
                // TODO: avoid overlapping with other herd members, make the leader pick a spot to sleep that can accommodate the herd
                var routeProps = new RouteProperties {
                    MaxTargetLocationHeightDelta = agent.Species.ClimbHeight
                };
                var route = AIUtil.GetRouteFacingTarget(agent.FacingDir, agent.Position, leader.Position, agent.Species.GetTraversalData(true), agent.Species.HeadDistance * 2, routeProps: routeProps);
                if (!route.IsValid)
                {
                    return(BTResult.Failure("can't get route to leader"));
                }
                agent.SetRoute(route, AnimalState.Wander);
                return(BTResult.Success("walking to sleep near leader"));
            }
            return(BTResult.Failure("leader not sleeping"));
        }
Exemplo n.º 11
0
        public static IEnumerator <BTResult> FindAndEatSomething(Animal agent, Behavior <Animal> noNearbyFoodBehavior, Func <IEnumerable <Vector3> > getFoodSources, float hungerRestoredPerEat)
        {
            var lastFoodSearchPos = Vector3.Zero;
            var foodSources       = new Queue <Vector3>();

            //While we're still hungry and don't have prey
            while (agent.Hunger > Brain.HungerToStopEating)
            {
                foodSources.Clear();
                while (foodSources.Count == 0)
                {
                    //Look for food sources, if we havent checked already and found it empty or just killed an enemy animal
                    if (Vector3.WrappedDistance(lastFoodSearchPos, agent.Position) > 10 || (agent.TryGetMemory(Animal.IsAnimalKilledMemory, out bool isKilled) && isKilled))
                    {
                        foodSources.AddRange(getFoodSources());
                        lastFoodSearchPos = agent.Position;
                        agent.RemoveMemory(Animal.IsAnimalKilledMemory);
                    }
                    else //None found, get outta here
                    {
                        yield return(new BTResult(noNearbyFoodBehavior.Do(agent), "No food in 10m radius of last query. Moving till we're > 10m from last query."));
                    }
                }

                //Food sources available, find paths to them.
                var routeProps = new RouteProperties()
                {
                    MaxTargetLocationHeightDelta = agent.Species.ClimbHeight
                };
                while (foodSources.Count > 0 && Vector3.WrappedDistance(lastFoodSearchPos, agent.Position) < 10)
                {
                    // Low-effort search for the first option or any other option visited while trying to hit the first with randomizing it in that area
                    var route            = AIUtil.GetRouteToAny(agent.FacingDir, agent.Position, foodSources, agent.Species.GetTraversalData(true), out var targetPosition, 100, 20, agent.Species.HeadDistance, routeProps);
                    var target           = targetPosition.Round;
                    var distanceToTarget = Vector3.WrappedDistanceSq(agent.Position, target);

                    // Move to target if it's far away
                    if (distanceToTarget > 2f)
                    {
                        if (!route.HasValue)
                        {
                            break;
                        }

                        agent.SetRoute(route.Value, AnimalState.LookingForFood, route.Value.EndPosition.Round);
                        yield return(BTResult.RunningChanged("walking to food"));

                        // Stop walking to food if the distance to it has changed or it disappeared
                        var agentTarget = agent.Target;
                        if (agentTarget == null || Vector3.WrappedDistanceSq(agentTarget.Value, target) > 2f)
                        {
                            break;
                        }
                    }

                    // Start eating food if it's close to us
                    if (Vector3.WrappedDistanceSq(target, agent.Position) <= 2f)
                    {
                        agent.ClearRoute();
                        agent.LookAt(target);
                        agent.ChangeState(AnimalState.Eating, 5, false);
                        agent.Hunger -= hungerRestoredPerEat;
                        yield return(BTResult.RunningChanged("chowing down"));

                        agent.LookAt(null);
                        lastFoodSearchPos = Vector3.Zero;
                        //Don't actually destroy the plant, because that's handled in the world layer simulation.
                        //var plant = EcoSim.PlantSim.GetPlant(targetPlantPosition.WorldPosition3i + Vector3i.Up);
                        //if (plant != null) EcoSim.PlantSim.DestroyPlant(plant, DeathType.EatenByAnimal);
                    }
                }
            }
        }
Exemplo n.º 12
0
 public static PSRouteMetadata ToPSRouteMetadata(RouteProperties routeProperties)
 {
     return ConvertObject<RouteProperties, PSRouteMetadata>(routeProperties);
 }
Exemplo n.º 13
0
        public static BTResult AmphibiousMovement(Animal agent, Vector2 generalDirection, bool wandering, AnimalState state, float minDistance = 2f, float maxDistance = 20f)
        {
            var startPathPos = agent.Position.WorldPosition3i;

            //Plop us into water if we're above it.
            if (World.World.GetBlock((Vector3i)startPathPos.Down()).GetType() == typeof(WaterBlock))
            {
                startPathPos = startPathPos.Down();
            }

            if (!World.World.IsUnderwater(startPathPos))
            {
                startPathPos = RouteManager.NearestWalkablePathPos(agent.Position.WorldPosition3i); //Boot us down/up to the surface if we're on land.
            }
            if (!startPathPos.IsValid)
            {
                return(LandMovement(agent, generalDirection, wandering, state, minDistance, maxDistance));
            }

            generalDirection = generalDirection == Vector2.zero ? Vector2.right.Rotate(RandomUtil.Range(0f, 360)) : generalDirection.Normalized;

            // Take random ground position in the given direction
            var targetGround = (agent.Position + (generalDirection * RandomUtil.Range(minDistance, maxDistance)).X_Z()).WorldPosition3i;

            // Floating animals will stick to water surface or land, non floating - land or return to swimming state
            if (World.World.IsUnderwater(targetGround) && agent.Species.FloatOnSurface)
            {
                targetGround.y = World.World.MaxWaterHeight[targetGround];
            }
            else
            {
                targetGround = RouteManager.NearestWalkableXYZ(targetGround, 5);
                if (!agent.Species.FloatOnSurface && !targetGround.IsValid)
                {
                    agent.Floating = false;
                    return(BTResult.Failure("Can't float, continue swimming"));
                }
            }

            // This is a low-effort search that includes water surface and should occasionally fail, just pick a semi-random node that was visited when it fails
            var routeProps = new RouteProperties()
            {
                MaxTargetLocationHeightDelta = agent.Species.ClimbHeight
            };
            var allowWaterSearch = new AStarSearch(RouteCacheData.NeighborsIncludeWater, agent.FacingDir, startPathPos, targetGround, 30, routeProps, false);

            if (allowWaterSearch.Status != SearchStatus.PathFound)
            {
                targetGround = allowWaterSearch.GroundNodes.Last().Key;
                allowWaterSearch.GetPathToWaterPos(targetGround);
            }

            // Apply land movement only for land positions
            if (!World.World.IsUnderwater(agent.Position.WorldPosition3i))
            {
                if (allowWaterSearch.GroundPath.Count < 2)
                {
                    return(LandMovement(agent, generalDirection, wandering, state, minDistance, maxDistance, skipRouteProperties: true));
                }
                if (allowWaterSearch.Status == SearchStatus.Unpathable && allowWaterSearch.GroundNodes.Count < RouteRegions.MinimumRegionSize)
                {
                    // Search region was unexpectedly small and agent is on land, might be trapped by player construction.
                    // Try regular land movement so region checks can apply & the agent can get unstuck (or die)
                    return(LandMovement(agent, generalDirection, wandering, state, minDistance, maxDistance));
                }
            }

            var smoothed = allowWaterSearch.LineOfSightSmoothWaterPosition(agent.GroundPosition);
            var route    = new Route(agent.Species.GetTraversalData(wandering), agent.FacingDir, smoothed);

            if (!route.IsValid)
            {
                route = Route.Basic(agent.Species.GetTraversalData(wandering), agent.FacingDir, agent.GroundPosition, route.EndPosition);
            }
            var routeTime = agent.SetRoute(route, state, null);

            return(routeTime < float.Epsilon ? BTResult.Failure("route not set") : BTResult.Success($"swimming path"));
        }
Exemplo n.º 14
0
        private ARMModel getARMTemplate(string id, string env)
        {
            var jsonModel = getServiceTagsModel(env);

            ARMModel arm = new ARMModel();

            arm.schema         = "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#";
            arm.contentVersion = "1.0.0.0";
            arm.filename       = "template.json";

            ParameterOptions paraoptions = new ParameterOptions();

            paraoptions.type         = "String";
            paraoptions.defaultValue = "Routetable";

            Parameters para = new Parameters();

            para.name = paraoptions;

            arm.parameters = para;

            Properties prop = new Properties();

            prop.routes = new List <Route>();

            String[] ids = id.Split(';');
            arm.filename = jsonModel.cloud;

            foreach (ValuesModel values in jsonModel.values)
            {
                if (Array.IndexOf(ids, values.id) != -1)
                {
                    var i = 1;
                    foreach (String prefix in values.properties.addressPrefixes)
                    {
                        Route route = new Route();
                        route.name = $"{jsonModel.cloud}.{values.id}-{i:000}";

                        RouteProperties routeprop = new RouteProperties();
                        routeprop.addressPrefix = prefix;
                        routeprop.nextHopType   = "Internet";

                        route.properties = routeprop;

                        prop.routes.Add(route);

                        i++;
                    }

                    arm.filename += "." + values.id;
                }
            }

            arm.filename += ".arm.json";

            Resources res = new Resources();

            res.type       = "Microsoft.Network/routeTables";
            res.name       = "[parameters('name')]";
            res.apiVersion = "2017-10-01";
            res.location   = "[resourceGroup().location]";
            res.properties = prop;

            arm.resources = new List <Resources>();
            arm.resources.Add(res);

            return(arm);
        }
Exemplo n.º 15
0
        public void FeatureToggleRoute_GetRouteData_Test()
        {
            var currentRouteProperties = new RouteProperties()
            {
                Defaults    = null,
                Constraints = new { id = @"\d+" }.ToRouteValueDictionary(),
                DataTokens = new { routename = "OfferDetailsWebForms" }.ToRouteValueDictionary(),
                RouteHandler = new PageRouteHandler("~/Pages/Offer/Details.aspx", true)
            };
            var experimentalRouteProperties = new RouteProperties()
            {
                Defaults = new { controller = "Offers", action = "Details" }.ToRouteValueDictionary(),
                Constraints = new { id = @"\d+" }.ToRouteValueDictionary(),
                DataTokens = new { routename = "OfferDetailsMvc" }.ToRouteValueDictionary(),
                RouteHandler = new MvcRouteHandler()
            };
            bool ftValue = false;

            var route = new FeatureToggleRoute("jobs/job-{title}_{id}", (r) => ftValue, currentRouteProperties, experimentalRouteProperties);

            Assert.That(route.Url, Is.EqualTo("jobs/job-{title}_{id}"));
            Assert.That(route.Defaults, Is.Null);
            Assert.That(route.DataTokens, Is.Null);
            Assert.That(route.Constraints, Is.Null);
            Assert.That(route.CurrentRouteProperties, Is.EqualTo(currentRouteProperties));
            Assert.That(route.ExperimentalRouteProperties, Is.EqualTo(experimentalRouteProperties));

            var mockHttpRequest = new Mock <HttpRequestBase>();

            mockHttpRequest.SetupGet(p => p.AppRelativeCurrentExecutionFilePath).Returns("~/jobs/job-project-manager_1554");
            mockHttpRequest.SetupGet(p => p.PathInfo).Returns("");

            var mockHttpContext = new Mock <HttpContextBase>();

            mockHttpContext.SetupGet(p => p.Request).Returns(mockHttpRequest.Object);

            var routeData = route.GetRouteData(mockHttpContext.Object);

            Assert.That(routeData, Is.Not.Null);
            Assert.That(routeData.RouteHandler, Is.InstanceOf <PageRouteHandler>());
            Assert.That(routeData.Values, Is.Not.Null);
            Assert.That(routeData.Values.ContainsKey("controller"), Is.False);
            Assert.That(routeData.Values.ContainsKey("action"), Is.False);
            Assert.That(routeData.Values["title"], Is.EqualTo("project-manager"));
            Assert.That(routeData.Values["id"], Is.EqualTo("1554"));
            Assert.That(routeData.DataTokens, Is.Not.Null);
            Assert.That(routeData.DataTokens["routename"], Is.EqualTo("OfferDetailsWebForms"));

            Assert.That(route.Url, Is.EqualTo("jobs/job-{title}_{id}"));
            Assert.That(route.Defaults, Is.Null);
            Assert.That(route.DataTokens, Is.Null);
            Assert.That(route.Constraints, Is.Null);
            Assert.That(route.CurrentRouteProperties, Is.EqualTo(currentRouteProperties));
            Assert.That(route.ExperimentalRouteProperties, Is.EqualTo(experimentalRouteProperties));

            ftValue   = true;
            routeData = route.GetRouteData(mockHttpContext.Object);

            Assert.That(routeData, Is.Not.Null);
            Assert.That(routeData.RouteHandler, Is.InstanceOf <MvcRouteHandler>());
            Assert.That(routeData.Values, Is.Not.Null);
            Assert.That(routeData.Values["controller"], Is.EqualTo("Offers"));
            Assert.That(routeData.Values["action"], Is.EqualTo("Details"));
            Assert.That(routeData.Values["title"], Is.EqualTo("project-manager"));
            Assert.That(routeData.Values["id"], Is.EqualTo("1554"));
            Assert.That(routeData.DataTokens, Is.Not.Null);
            Assert.That(routeData.DataTokens["routename"], Is.EqualTo("OfferDetailsMvc"));

            Assert.That(route.Url, Is.EqualTo("jobs/job-{title}_{id}"));
            Assert.That(route.Defaults, Is.Null);
            Assert.That(route.DataTokens, Is.Null);
            Assert.That(route.Constraints, Is.Null);
            Assert.That(route.CurrentRouteProperties, Is.EqualTo(currentRouteProperties));
            Assert.That(route.ExperimentalRouteProperties, Is.EqualTo(experimentalRouteProperties));
        }
Exemplo n.º 16
0
        public void FeatureToggleRoute_GetVirtualPath_Test()
        {
            var currentRouteProperties = new RouteProperties()
            {
                Defaults    = null,
                Constraints = new { id = @"\d+" }.ToRouteValueDictionary(),
                DataTokens = new { routename = "OfferDetailsWebForms" }.ToRouteValueDictionary(),
                RouteHandler = new PageRouteHandler("~/Pages/Offer/Details.aspx", true)
            };
            var experimentalRouteProperties = new RouteProperties()
            {
                Defaults = new { controller = "Offers", action = "Details" }.ToRouteValueDictionary(),
                Constraints = new { id = @"\d+" }.ToRouteValueDictionary(),
                DataTokens = new { routename = "OfferDetailsMvc" }.ToRouteValueDictionary(),
                RouteHandler = new MvcRouteHandler()
            };
            bool ftValue = false;

            var route = new FeatureToggleRoute("jobs/job-{title}_{id}", (r) => ftValue, currentRouteProperties, experimentalRouteProperties);

            Assert.That(route.Url, Is.EqualTo("jobs/job-{title}_{id}"));
            Assert.That(route.Defaults, Is.Null);
            Assert.That(route.DataTokens, Is.Null);
            Assert.That(route.Constraints, Is.Null);
            Assert.That(route.CurrentRouteProperties, Is.EqualTo(currentRouteProperties));
            Assert.That(route.ExperimentalRouteProperties, Is.EqualTo(experimentalRouteProperties));

            var ctx = new RequestContext(new Mock <HttpContextBase>().Object, new RouteData());
            var vpd = route.GetVirtualPath(ctx, new { id = 1554, title = "project-manager" }.ToRouteValueDictionary());

            Assert.That(vpd, Is.Not.Null);
            Assert.That(vpd.DataTokens, Is.Not.Null);
            Assert.That(vpd.DataTokens.Count, Is.EqualTo(1));
            Assert.That(vpd.DataTokens["routename"], Is.EqualTo("OfferDetailsWebForms"));
            Assert.That(vpd.Route, Is.EqualTo(route));
            Assert.That(vpd.VirtualPath, Is.EqualTo("jobs/job-project-manager_1554"));

            Assert.That(route.Url, Is.EqualTo("jobs/job-{title}_{id}"));
            Assert.That(route.Defaults, Is.Null);
            Assert.That(route.DataTokens, Is.Null);
            Assert.That(route.Constraints, Is.Null);
            Assert.That(route.CurrentRouteProperties, Is.EqualTo(currentRouteProperties));
            Assert.That(route.ExperimentalRouteProperties, Is.EqualTo(experimentalRouteProperties));

            ftValue = true;
            vpd     = route.GetVirtualPath(ctx, new { id = 1554, title = "project-manager" }.ToRouteValueDictionary());

            Assert.That(vpd, Is.Not.Null);
            Assert.That(vpd.DataTokens, Is.Not.Null);
            Assert.That(vpd.DataTokens.Count, Is.EqualTo(1));
            Assert.That(vpd.DataTokens["routename"], Is.EqualTo("OfferDetailsMvc"));
            Assert.That(vpd.Route, Is.EqualTo(route));
            Assert.That(vpd.VirtualPath, Is.EqualTo("jobs/job-project-manager_1554"));

            Assert.That(route.Url, Is.EqualTo("jobs/job-{title}_{id}"));
            Assert.That(route.Defaults, Is.Null);
            Assert.That(route.DataTokens, Is.Null);
            Assert.That(route.Constraints, Is.Null);
            Assert.That(route.CurrentRouteProperties, Is.EqualTo(currentRouteProperties));
            Assert.That(route.ExperimentalRouteProperties, Is.EqualTo(experimentalRouteProperties));
        }