Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Microsoft.TypeSpec.Generator.Statements;
using static Microsoft.TypeSpec.Generator.Snippets.ArgumentSnippets;
using static Microsoft.TypeSpec.Generator.Snippets.Snippet;
using static Microsoft.TypeSpec.Generator.Snippets.StringSnippets;

namespace Microsoft.TypeSpec.Generator.Providers
{
Expand All @@ -20,6 +21,9 @@ private class Template<T> { }

private const string AssertNotNullMethodName = "AssertNotNull";
private const string AssertNotNullOrEmptyMethodName = "AssertNotNullOrEmpty";
private const string AssertNotNullOrWhiteSpaceMethodName = "AssertNotNullOrWhiteSpace";
private const string AssertInRangeMethodName = "AssertInRange";
private const string CheckNotNullOrEmptyMethodName = "CheckNotNullOrEmpty";

private readonly CSharpType _t = typeof(Template<>).GetGenericArguments()[0];
private readonly ParameterProvider _nameParam = new ParameterProvider("name", $"The name.", typeof(string));
Expand Down Expand Up @@ -65,9 +69,60 @@ protected internal override MethodProvider[] BuildMethods()
BuildAssertNotNullStruct(),
BuildAssertNotNullOrEmptyCollection(),
BuildAssertNotNullOrEmptyString(),
BuildAssertNotNullOrWhiteSpace(),
BuildAssertInRange(),
BuildCheckNotNullOrEmpty(),
];
}

private MethodProvider BuildAssertNotNullOrWhiteSpace()
{
var valueParam = new ParameterProvider("value", $"The value.", typeof(string));
var signature = GetSignature(AssertNotNullOrWhiteSpaceMethodName, [valueParam, _nameParam]);
return new MethodProvider(signature, new MethodBodyStatement[]
{
AssertNotNullSnippet(valueParam),
new IfStatement(IsNullOrWhiteSpace(valueParam.As<string>()))
{
ThrowArgumentException("Value cannot be empty or contain only white-space characters.")
}
},
this);
}

private MethodProvider BuildAssertInRange()
{
var valueParam = new ParameterProvider("value", $"The value.", _t);
var minimumParam = new ParameterProvider("minimum", $"The minimum value.", _t);
var maximumParam = new ParameterProvider("maximum", $"The maximum value.", _t);
var whereExpression = Where.NotNull(_t).And(new CSharpType(typeof(IComparable<>), _t));
var signature = GetSignature(AssertInRangeMethodName, [valueParam, minimumParam, maximumParam, _nameParam], [_t], [whereExpression]);
return new MethodProvider(signature, new MethodBodyStatement[]
{
new IfStatement(minimumParam.Invoke("CompareTo", valueParam).GreaterThan(Literal(0)))
{
Throw(New.ArgumentOutOfRangeException(_nameParam, "Value is less than the minimum allowed.", false))
},
new IfStatement(maximumParam.Invoke("CompareTo", valueParam).LessThan(Literal(0)))
{
Throw(New.ArgumentOutOfRangeException(_nameParam, "Value is greater than the maximum allowed.", false))
}
},
this);
}

private MethodProvider BuildCheckNotNullOrEmpty()
{
var valueParam = new ParameterProvider("value", $"The value.", typeof(string));
var signature = GetSignature(CheckNotNullOrEmptyMethodName, [valueParam, _nameParam], returnType: typeof(string));
return new MethodProvider(signature, new MethodBodyStatement[]
{
Static<ArgumentDefinition>().Invoke(AssertNotNullOrEmptyMethodName, [valueParam, _nameParam]).Terminate(),
Return(valueParam)
},
this);
}

private MethodProvider BuildAssertNotNullOrEmptyString()
{
var valueParam = new ParameterProvider("value", $"The value.", typeof(string));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,71 @@ public void NotNullOrEmptyStringThrowsOnEmpty()
Assert.Throws<ArgumentException>(() => Argument.AssertNotNullOrEmpty(string.Empty, "value"));
}

[Test]
public void NotNullOrWhiteSpace()
{
string value = "test";
Argument.AssertNotNullOrWhiteSpace(value, "value");
}

[Test]
public void NotNullOrWhiteSpaceThrowsOnNull()
{
string? value = null;
Assert.Throws<ArgumentNullException>(() => Argument.AssertNotNullOrWhiteSpace(value, "value"));
}

[Test]
public void NotNullOrWhiteSpaceThrowsOnWhiteSpace()
{
Assert.Throws<ArgumentException>(() => Argument.AssertNotNullOrWhiteSpace(" ", "value"));
}

[Test]
public void NotNullOrWhiteSpaceThrowsOnEmpty()
{
Assert.Throws<ArgumentException>(() => Argument.AssertNotNullOrWhiteSpace(string.Empty, "value"));
}

[Test]
public void AssertInRange()
{
Argument.AssertInRange(5, 1, 10, "value");
}

[Test]
public void AssertInRangeThrowsWhenBelowMinimum()
{
Assert.Throws<ArgumentOutOfRangeException>(() => Argument.AssertInRange(0, 1, 10, "value"));
}

[Test]
public void AssertInRangeThrowsWhenAboveMaximum()
{
Assert.Throws<ArgumentOutOfRangeException>(() => Argument.AssertInRange(11, 1, 10, "value"));
}

[Test]
public void CheckNotNullOrEmpty()
{
string value = "test";
string result = Argument.CheckNotNullOrEmpty(value, "value");
Assert.AreEqual("test", result);
}

[Test]
public void CheckNotNullOrEmptyThrowsOnNull()
{
string? value = null;
Assert.Throws<ArgumentNullException>(() => Argument.CheckNotNullOrEmpty(value, "value"));
}

[Test]
public void CheckNotNullOrEmptyThrowsOnEmpty()
{
Assert.Throws<ArgumentException>(() => Argument.CheckNotNullOrEmpty(string.Empty, "value"));
}

private readonly struct TestStructure : IEquatable<TestStructure>
{
internal readonly string A;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,44 @@ public static void AssertNotNullOrEmpty(string value, string name)
throw new ArgumentException("Value cannot be an empty string.", name);
}
}

/// <param name="value"> The value. </param>
/// <param name="name"> The name. </param>
public static void AssertNotNullOrWhiteSpace(string value, string name)
{
if (value is null)
{
throw new ArgumentNullException(name);
}
if (string.IsNullOrWhiteSpace(value))
{
throw new ArgumentException("Value cannot be empty or contain only white-space characters.", name);
}
}

/// <param name="value"> The value. </param>
/// <param name="minimum"> The minimum value. </param>
/// <param name="maximum"> The maximum value. </param>
/// <param name="name"> The name. </param>
public static void AssertInRange<T>(T value, T minimum, T maximum, string name)
where T : notnull, IComparable<T>
{
if (minimum.CompareTo(value) > 0)
{
throw new ArgumentOutOfRangeException(name, "Value is less than the minimum allowed.");
}
if (maximum.CompareTo(value) < 0)
{
throw new ArgumentOutOfRangeException(name, "Value is greater than the maximum allowed.");
}
}

/// <param name="value"> The value. </param>
/// <param name="name"> The name. </param>
public static string CheckNotNullOrEmpty(string value, string name)
{
AssertNotNullOrEmpty(value, name);
return value;
}
}
}
Loading