Replacing argument not null checks in ModelBinding with NotNullAttribute
* Removing not null guard tests in ModelBinding
This commit is contained in:
parent
86ac978451
commit
a2cea18529
|
|
@ -1,25 +1,15 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
// Describes a complex model, but uses a collection rather than individual properties as the data store.
|
// Describes a complex model, but uses a collection rather than individual properties as the data store.
|
||||||
public class ComplexModelDto
|
public class ComplexModelDto
|
||||||
{
|
{
|
||||||
public ComplexModelDto(ModelMetadata modelMetadata, IEnumerable<ModelMetadata> propertyMetadata)
|
public ComplexModelDto([NotNull] ModelMetadata modelMetadata,
|
||||||
|
[NotNull] IEnumerable<ModelMetadata> propertyMetadata)
|
||||||
{
|
{
|
||||||
if (modelMetadata == null)
|
|
||||||
{
|
|
||||||
throw Error.ArgumentNull("modelMetadata");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (propertyMetadata == null)
|
|
||||||
{
|
|
||||||
throw Error.ArgumentNull("propertyMetadata");
|
|
||||||
}
|
|
||||||
|
|
||||||
ModelMetadata = modelMetadata;
|
ModelMetadata = modelMetadata;
|
||||||
PropertyMetadata = new Collection<ModelMetadata>(propertyMetadata.ToList());
|
PropertyMetadata = new Collection<ModelMetadata>(propertyMetadata.ToList());
|
||||||
Results = new Dictionary<ModelMetadata, ComplexModelDtoResult>();
|
Results = new Dictionary<ModelMetadata, ComplexModelDtoResult>();
|
||||||
|
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Globalization;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding.Internal
|
|
||||||
{
|
|
||||||
internal static class Error
|
|
||||||
{
|
|
||||||
internal static ArgumentException ArgumentNull(string paramName)
|
|
||||||
{
|
|
||||||
return new ArgumentNullException(paramName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates an <see cref="ArgumentException"/> with the provided properties.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
|
|
||||||
/// <param name="message">A composite message explaining the reason for the exception.</param>
|
|
||||||
/// <returns>The logged <see cref="Exception"/>.</returns>
|
|
||||||
internal static ArgumentException Argument(string parameterName, string message)
|
|
||||||
{
|
|
||||||
return new ArgumentException(message, parameterName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates an <see cref="ArgumentException"/> with a default message.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
|
|
||||||
/// <returns>The logged <see cref="Exception"/>.</returns>
|
|
||||||
internal static ArgumentException ArgumentNullOrEmpty(string parameterName)
|
|
||||||
{
|
|
||||||
return Error.Argument(parameterName, Resources.FormatArgumentNullOrEmpty(parameterName));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -53,16 +53,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Internal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void ValidateBindingContext(ModelBindingContext bindingContext)
|
internal static void ValidateBindingContext([NotNull] ModelBindingContext bindingContext)
|
||||||
{
|
{
|
||||||
if (bindingContext == null)
|
|
||||||
{
|
|
||||||
throw Error.ArgumentNull("bindingContext");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bindingContext.ModelMetadata == null)
|
if (bindingContext.ModelMetadata == null)
|
||||||
{
|
{
|
||||||
throw Error.Argument("bindingContext", Resources.ModelBinderUtil_ModelMetadataCannotBeNull);
|
throw new ArgumentException("bindingContext", Resources.ModelBinderUtil_ModelMetadataCannotBeNull);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,13 +68,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Internal
|
||||||
if (bindingContext.ModelType != requiredType)
|
if (bindingContext.ModelType != requiredType)
|
||||||
{
|
{
|
||||||
var message = Resources.FormatModelBinderUtil_ModelTypeIsWrong(bindingContext.ModelType, requiredType);
|
var message = Resources.FormatModelBinderUtil_ModelTypeIsWrong(bindingContext.ModelType, requiredType);
|
||||||
throw Error.Argument("bindingContext", message);
|
throw new ArgumentException(message, "bindingContext");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!allowNullModel && bindingContext.Model == null)
|
if (!allowNullModel && bindingContext.Model == null)
|
||||||
{
|
{
|
||||||
var message = Resources.FormatModelBinderUtil_ModelCannotBeNull(requiredType);
|
var message = Resources.FormatModelBinderUtil_ModelCannotBeNull(requiredType);
|
||||||
throw Error.Argument("bindingContext", message);
|
throw new ArgumentException(message, "bindingContext");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bindingContext.Model != null && !bindingContext.ModelType.GetTypeInfo().IsAssignableFrom(requiredType.GetTypeInfo()))
|
if (bindingContext.Model != null && !bindingContext.ModelType.GetTypeInfo().IsAssignableFrom(requiredType.GetTypeInfo()))
|
||||||
|
|
@ -87,7 +82,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Internal
|
||||||
var message = Resources.FormatModelBinderUtil_ModelInstanceIsWrong(
|
var message = Resources.FormatModelBinderUtil_ModelInstanceIsWrong(
|
||||||
bindingContext.Model.GetType(),
|
bindingContext.Model.GetType(),
|
||||||
requiredType);
|
requiredType);
|
||||||
throw Error.Argument("bindingContext", message);
|
throw new ArgumentException(message, "bindingContext");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ using System.Diagnostics.Contracts;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Reflection.Emit;
|
using System.Reflection.Emit;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
|
|
@ -23,14 +22,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(propertyName))
|
if (string.IsNullOrEmpty(propertyName))
|
||||||
{
|
{
|
||||||
throw Error.ArgumentNullOrEmpty("propertyName");
|
throw new ArgumentException(Resources.FormatArgumentNullOrEmpty("propertyName"), "propertyName");
|
||||||
}
|
}
|
||||||
|
|
||||||
var typeInfo = GetTypeInformation(containerType);
|
var typeInfo = GetTypeInformation(containerType);
|
||||||
PropertyInformation propertyInfo;
|
PropertyInformation propertyInfo;
|
||||||
if (!typeInfo.Properties.TryGetValue(propertyName, out propertyInfo))
|
if (!typeInfo.Properties.TryGetValue(propertyName, out propertyInfo))
|
||||||
{
|
{
|
||||||
throw Error.Argument("propertyName", Resources.FormatCommon_PropertyNotFound(containerType, propertyName));
|
throw new ArgumentException(Resources.FormatCommon_PropertyNotFound(containerType, propertyName), "propertyName");
|
||||||
}
|
}
|
||||||
|
|
||||||
return CreatePropertyMetadata(modelAccessor, propertyInfo);
|
return CreatePropertyMetadata(modelAccessor, propertyInfo);
|
||||||
|
|
|
||||||
|
|
@ -18,21 +18,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
private IEnumerable<ModelMetadata> _properties;
|
private IEnumerable<ModelMetadata> _properties;
|
||||||
private Type _realModelType;
|
private Type _realModelType;
|
||||||
|
|
||||||
public ModelMetadata(IModelMetadataProvider provider,
|
public ModelMetadata([NotNull] IModelMetadataProvider provider,
|
||||||
Type containerType,
|
Type containerType,
|
||||||
Func<object> modelAccessor,
|
Func<object> modelAccessor,
|
||||||
Type modelType,
|
[NotNull] Type modelType,
|
||||||
string propertyName)
|
string propertyName)
|
||||||
{
|
{
|
||||||
if (provider == null)
|
|
||||||
{
|
|
||||||
throw Error.ArgumentNull("provider");
|
|
||||||
}
|
|
||||||
if (modelType == null)
|
|
||||||
{
|
|
||||||
throw Error.ArgumentNull("modelType");
|
|
||||||
}
|
|
||||||
|
|
||||||
Provider = provider;
|
Provider = provider;
|
||||||
|
|
||||||
_containerType = containerType;
|
_containerType = containerType;
|
||||||
|
|
|
||||||
|
|
@ -97,13 +97,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
Validate(validationContext, parentNode: null);
|
Validate(validationContext, parentNode: null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Validate(ModelValidationContext validationContext, ModelValidationNode parentNode)
|
public void Validate([NotNull] ModelValidationContext validationContext, ModelValidationNode parentNode)
|
||||||
{
|
{
|
||||||
if (validationContext == null)
|
|
||||||
{
|
|
||||||
throw Error.ArgumentNull("validationContext");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SuppressValidation)
|
if (SuppressValidation)
|
||||||
{
|
{
|
||||||
// no-op
|
// no-op
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
|
|
@ -68,21 +67,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
return (enumeratedProvider != null) ? enumeratedProvider.GetKeysFromPrefix(prefix) : null;
|
return (enumeratedProvider != null) ? enumeratedProvider.GetKeysFromPrefix(prefix) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void InsertItem(int index, IValueProvider item)
|
protected override void InsertItem(int index, [NotNull] IValueProvider item)
|
||||||
{
|
{
|
||||||
if (item == null)
|
|
||||||
{
|
|
||||||
throw Error.ArgumentNull("item");
|
|
||||||
}
|
|
||||||
base.InsertItem(index, item);
|
base.InsertItem(index, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void SetItem(int index, IValueProvider item)
|
protected override void SetItem(int index, [NotNull] IValueProvider item)
|
||||||
{
|
{
|
||||||
if (item == null)
|
|
||||||
{
|
|
||||||
throw Error.ArgumentNull("item");
|
|
||||||
}
|
|
||||||
base.SetItem(index, item);
|
base.SetItem(index, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
|
|
@ -19,13 +18,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
return _values.ContainsKey(key);
|
return _values.ContainsKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueProviderResult GetValue(string key)
|
public ValueProviderResult GetValue([NotNull] string key)
|
||||||
{
|
{
|
||||||
if (key == null)
|
|
||||||
{
|
|
||||||
throw Error.ArgumentNull("key");
|
|
||||||
}
|
|
||||||
|
|
||||||
object value;
|
object value;
|
||||||
if (_values.TryGetValue(key, out value))
|
if (_values.TryGetValue(key, out value))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
private static readonly object _cacheKey = new object();
|
private static readonly object _cacheKey = new object();
|
||||||
|
|
||||||
public Task<IValueProvider> GetValueProviderAsync(RequestContext requestContext)
|
public Task<IValueProvider> GetValueProviderAsync([NotNull] RequestContext requestContext)
|
||||||
{
|
{
|
||||||
if (requestContext == null)
|
|
||||||
{
|
|
||||||
throw Error.ArgumentNull("requestContext");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process the query collection once-per request.
|
// Process the query collection once-per request.
|
||||||
var storage = requestContext.HttpContext.Items;
|
var storage = requestContext.HttpContext.Items;
|
||||||
object value;
|
object value;
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="values">The key value pairs to wrap.</param>
|
/// <param name="values">The key value pairs to wrap.</param>
|
||||||
/// <param name="culture">The culture to return with ValueProviderResult instances.</param>
|
/// <param name="culture">The culture to return with ValueProviderResult instances.</param>
|
||||||
public ReadableStringCollectionValueProvider(IReadableStringCollection values, CultureInfo culture)
|
public ReadableStringCollectionValueProvider([NotNull] IReadableStringCollection values, CultureInfo culture)
|
||||||
{
|
{
|
||||||
if (values == null)
|
|
||||||
{
|
|
||||||
throw Error.ArgumentNull("values");
|
|
||||||
}
|
|
||||||
|
|
||||||
_values = values;
|
_values = values;
|
||||||
_culture = culture;
|
_culture = culture;
|
||||||
}
|
}
|
||||||
|
|
@ -56,24 +51,15 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
return PrefixContainer.ContainsPrefix(prefix);
|
return PrefixContainer.ContainsPrefix(prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual IDictionary<string, string> GetKeysFromPrefix(string prefix)
|
public virtual IDictionary<string, string> GetKeysFromPrefix([NotNull] string prefix)
|
||||||
{
|
{
|
||||||
if (prefix == null)
|
|
||||||
{
|
|
||||||
throw Error.ArgumentNull("prefix");
|
|
||||||
}
|
|
||||||
|
|
||||||
return PrefixContainer.GetKeysFromPrefix(prefix);
|
return PrefixContainer.GetKeysFromPrefix(prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual ValueProviderResult GetValue(string key)
|
|
||||||
{
|
|
||||||
if (key == null)
|
|
||||||
{
|
|
||||||
throw Error.ArgumentNull("key");
|
|
||||||
}
|
|
||||||
|
|
||||||
IList<string> values = _values.GetValues(key);
|
public virtual ValueProviderResult GetValue([NotNull] string key)
|
||||||
|
{
|
||||||
|
var values = _values.GetValues(key);
|
||||||
if (values == null)
|
if (values == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -5,27 +5,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
{
|
{
|
||||||
public class ComplexModelDtoTest
|
public class ComplexModelDtoTest
|
||||||
{
|
{
|
||||||
[Fact]
|
|
||||||
public void ConstructorThrowsIfModelMetadataIsNull()
|
|
||||||
{
|
|
||||||
// Act & assert
|
|
||||||
ExceptionAssert.ThrowsArgumentNull(
|
|
||||||
() => new ComplexModelDto(null, Enumerable.Empty<ModelMetadata>()),
|
|
||||||
"modelMetadata");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void ConstructorThrowsIfPropertyMetadataIsNull()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
ModelMetadata modelMetadata = GetModelMetadata();
|
|
||||||
|
|
||||||
// Act & assert
|
|
||||||
ExceptionAssert.ThrowsArgumentNull(
|
|
||||||
() => new ComplexModelDto(modelMetadata, null),
|
|
||||||
"propertyMetadata");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ConstructorSetsProperties()
|
public void ConstructorSetsProperties()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -10,30 +10,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
{
|
{
|
||||||
public class ModelMetadataTest
|
public class ModelMetadataTest
|
||||||
{
|
{
|
||||||
// Guard clauses
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void NullProviderThrows()
|
|
||||||
{
|
|
||||||
// Act & Assert
|
|
||||||
ExceptionAssert.ThrowsArgumentNull(
|
|
||||||
() => new ModelMetadata(provider: null, containerType: null, modelAccessor: null, modelType: typeof(object), propertyName: null),
|
|
||||||
"provider");
|
|
||||||
}
|
|
||||||
|
|
||||||
#if NET45
|
#if NET45
|
||||||
[Fact]
|
|
||||||
public void NullTypeThrows()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
Mock<IModelMetadataProvider> provider = new Mock<IModelMetadataProvider>();
|
|
||||||
|
|
||||||
// Act & Assert
|
|
||||||
ExceptionAssert.ThrowsArgumentNull(
|
|
||||||
() => new ModelMetadata(provider: provider.Object, containerType: null, modelAccessor: null, modelType: null, propertyName: null),
|
|
||||||
"modelType");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
||||||
|
|
@ -215,18 +215,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
Assert.Empty(log);
|
Assert.Empty(log);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Validate_ThrowsIfControllerContextIsNull()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var node = new ModelValidationNode(GetModelMetadata(), "someKey");
|
|
||||||
|
|
||||||
// Act & assert
|
|
||||||
ExceptionAssert.ThrowsArgumentNull(
|
|
||||||
() => node.Validate(null),
|
|
||||||
"validationContext");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[ReplaceCulture]
|
[ReplaceCulture]
|
||||||
public void Validate_ValidateAllProperties_AddsValidationErrors()
|
public void Validate_ValidateAllProperties_AddsValidationErrors()
|
||||||
|
|
|
||||||
|
|
@ -13,13 +13,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
{
|
{
|
||||||
private readonly QueryStringValueProviderFactory _factory = new QueryStringValueProviderFactory();
|
private readonly QueryStringValueProviderFactory _factory = new QueryStringValueProviderFactory();
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GetValueProvider_WhenrequestContextParameterIsNull_Throws()
|
|
||||||
{
|
|
||||||
// Act and Assert
|
|
||||||
ExceptionAssert.ThrowsArgumentNull(() => _factory.GetValueProviderAsync(requestContext: null), "requestContext");
|
|
||||||
}
|
|
||||||
|
|
||||||
#if NET45
|
#if NET45
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetValueProvider_ReturnsQueryStringValueProviderInstaceWithInvariantCulture()
|
public async Task GetValueProvider_ReturnsQueryStringValueProviderInstaceWithInvariantCulture()
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
{"prefix.null_value", null}
|
{"prefix.null_value", null}
|
||||||
});
|
});
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Constructor_GuardClauses()
|
|
||||||
{
|
|
||||||
// Act & assert
|
|
||||||
ExceptionAssert.ThrowsArgumentNull(
|
|
||||||
() => new ReadableStringCollectionValueProvider(values: null, culture: CultureInfo.InvariantCulture),
|
|
||||||
"values");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ContainsPrefix_GuardClauses()
|
public void ContainsPrefix_GuardClauses()
|
||||||
|
|
@ -91,18 +83,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
Assert.False(result);
|
Assert.False(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GetKeysFromPrefix_GuardClauses()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var valueProvider = new ReadableStringCollectionValueProvider(_backingStore, null);
|
|
||||||
|
|
||||||
// Act & assert
|
|
||||||
ExceptionAssert.ThrowsArgumentNull(
|
|
||||||
() => valueProvider.GetKeysFromPrefix(null),
|
|
||||||
"prefix");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void GetKeysFromPrefix_EmptyPrefix_ReturnsAllPrefixes()
|
public void GetKeysFromPrefix_EmptyPrefix_ReturnsAllPrefixes()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue