public void Accept(string key, object value) { if (!_acceptedValues.ContainsKey(key)) { _acceptedValues.Add(key, value); } }
public void ContainsKey_PropertyStorage_True_CaseInsensitive() { // Arrange var dict = new DispatcherValueCollection(new { key = "value" }); // Act var result = dict.ContainsKey("kEy"); // Assert Assert.True(result); Assert.IsType <DispatcherValueCollection.PropertyStorage>(dict._storage); }
public void ContainsKey_PropertyStorage_False() { // Arrange var dict = new DispatcherValueCollection(new { key = "value" }); // Act var result = dict.ContainsKey("other"); // Assert Assert.False(result); Assert.IsType <DispatcherValueCollection.PropertyStorage>(dict._storage); }
public void ContainsKey_EmptyStorage() { // Arrange var dict = new DispatcherValueCollection(); // Act var result = dict.ContainsKey("key"); // Assert Assert.False(result); Assert.IsType <DispatcherValueCollection.EmptyStorage>(dict._storage); }
public void ContainsKey_ListStorage_True_CaseInsensitive() { // Arrange var dict = new DispatcherValueCollection() { { "key", "value" }, }; // Act var result = dict.ContainsKey("kEy"); // Assert Assert.True(result); Assert.IsType <DispatcherValueCollection.ListStorage>(dict._storage); }
public void ContainsKey_ListStorage_False() { // Arrange var dict = new DispatcherValueCollection() { { "key", "value" }, }; // Act var result = dict.ContainsKey("other"); // Assert Assert.False(result); Assert.IsType <DispatcherValueCollection.ListStorage>(dict._storage); }
public void TryMatch_DoesNotSetOptionalParameter_EmptyString() { // Arrange var route = CreateMatcher("{controller?}"); var url = ""; var values = new DispatcherValueCollection(); // Act var match = route.TryMatch(url, values); // Assert Assert.True(match); Assert.Empty(values); Assert.False(values.ContainsKey("controller")); }
public void TryMatch_DoesNotSetOptionalParameter() { // Arrange var route = CreateMatcher("{controller}/{action?}"); var url = "/Home"; var values = new DispatcherValueCollection(); // Act var match = route.TryMatch(url, values); // Assert Assert.True(match); Assert.Single(values); Assert.Equal("Home", values["controller"]); Assert.False(values.ContainsKey("action")); }
public void TryMatch_MultipleOptionalParameters() { // Arrange var route = CreateMatcher("{controller}/{action?}/{id?}"); var url = "/Home/Index"; var values = new DispatcherValueCollection(); // Act var match = route.TryMatch(url, values); // Assert Assert.True(match); Assert.Equal(2, values.Count); Assert.Equal("Home", values["controller"]); Assert.Equal("Index", values["action"]); Assert.False(values.ContainsKey("id")); }
public bool TryMatch(PathString path, DispatcherValueCollection values) { if (values == null) { throw new ArgumentNullException(nameof(values)); } var i = 0; var pathTokenizer = new PathTokenizer(path); // Perf: We do a traversal of the request-segments + route-segments twice. // // For most segment-types, we only really need to any work on one of the two passes. // // On the first pass, we're just looking to see if there's anything that would disqualify us from matching. // The most common case would be a literal segment that doesn't match. // // On the second pass, we're almost certainly going to match the URL, so go ahead and allocate the 'values' // and start capturing strings. foreach (var stringSegment in pathTokenizer) { if (stringSegment.Length == 0) { return(false); } var pathSegment = i >= RoutePattern.PathSegments.Count ? null : RoutePattern.PathSegments[i]; if (pathSegment == null && stringSegment.Length > 0) { // If pathSegment is null, then we're out of route segments. All we can match is the empty // string. return(false); } else if (pathSegment.IsSimple && pathSegment.Parts[0] is RoutePatternParameter parameter && parameter.IsCatchAll) { // Nothing to validate for a catch-all - it can match any string, including the empty string. // // Also, a catch-all has to be the last part, so we're done. break; } if (!TryMatchLiterals(i++, stringSegment, pathSegment)) { return(false); } } for (; i < RoutePattern.PathSegments.Count; i++) { // We've matched the request path so far, but still have remaining route segments. These need // to be all single-part parameter segments with default values or else they won't match. var pathSegment = RoutePattern.PathSegments[i]; Debug.Assert(pathSegment != null); if (!pathSegment.IsSimple) { // If the segment is a complex segment, it MUST contain literals, and we've parsed the full // path so far, so it can't match. return(false); } var part = pathSegment.Parts[0]; if (part.IsLiteral || part.IsSeparator) { // If the segment is a simple literal - which need the URL to provide a value, so we don't match. return(false); } var parameter = (RoutePatternParameter)part; if (parameter.IsCatchAll) { // Nothing to validate for a catch-all - it can match any string, including the empty string. // // Also, a catch-all has to be the last part, so we're done. break; } // If we get here, this is a simple segment with a parameter. We need it to be optional, or for the // defaults to have a value. if (!_hasDefaultValue[i] && !parameter.IsOptional) { // There's no default for this (non-optional) parameter so it can't match. return(false); } } // At this point we've very likely got a match, so start capturing values for real. i = 0; foreach (var requestSegment in pathTokenizer) { var pathSegment = RoutePattern.PathSegments[i++]; if (SavePathSegmentsAsValues(i, values, requestSegment, pathSegment)) { break; } if (!pathSegment.IsSimple) { if (!MatchComplexSegment(pathSegment, requestSegment.ToString(), Defaults, values)) { return(false); } } } for (; i < RoutePattern.PathSegments.Count; i++) { // We've matched the request path so far, but still have remaining route segments. We already know these // are simple parameters that either have a default, or don't need to produce a value. var pathSegment = RoutePattern.PathSegments[i]; Debug.Assert(pathSegment != null); Debug.Assert(pathSegment.IsSimple); var part = pathSegment.Parts[0]; Debug.Assert(part.IsParameter); // It's ok for a catch-all to produce a null value if (part is RoutePatternParameter parameter && (parameter.IsCatchAll || _hasDefaultValue[i])) { // Don't replace an existing value with a null. var defaultValue = _defaultValues[i]; if (defaultValue != null || !values.ContainsKey(parameter.Name)) { values[parameter.Name] = defaultValue; } } } // Copy all remaining default values to the route data foreach (var kvp in Defaults) { if (!values.ContainsKey(kvp.Key)) { values.Add(kvp.Key, kvp.Value); } } return(true); }