Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add string syntax attributes #4425

Merged
merged 6 commits into from Jul 28, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions src/NUnitFramework/framework/Attributes/IgnoreAttribute.cs
Expand Up @@ -39,6 +39,7 @@ public IgnoreAttribute(string reason)
/// property set which will appear in the test results.
/// </remarks>
/// <exception cref="FormatException">The string does not contain a valid string representation of a date and time.</exception>
[StringSyntax(StringSyntaxAttribute.DateTimeFormat)]
[DisallowNull]
public string? Until
{
Expand Down
Expand Up @@ -266,6 +266,7 @@ public bool Explicit
/// <summary>
/// Gets and sets the ignore until date for this test case.
/// </summary>
[StringSyntax(StringSyntaxAttribute.DateTimeFormat)]
[DisallowNull]
public string? Until
{
Expand Down
@@ -0,0 +1,76 @@
// Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt

#if !NET7_0_OR_GREATER

namespace System.Diagnostics.CodeAnalysis
{
/// <summary>Specifies the syntax used in a string.</summary>
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
internal sealed class StringSyntaxAttribute : Attribute
{
/// <summary>The syntax identifier for strings containing composite formats for string formatting.</summary>
public const string CompositeFormat = nameof(CompositeFormat);

/// <summary>The syntax identifier for strings containing date format specifiers.</summary>
public const string DateOnlyFormat = nameof(DateOnlyFormat);

/// <summary>The syntax identifier for strings containing date and time format specifiers.</summary>
public const string DateTimeFormat = nameof(DateTimeFormat);

/// <summary>The syntax identifier for strings containing <see cref="Enum"/> format specifiers.</summary>
public const string EnumFormat = nameof(EnumFormat);

/// <summary>The syntax identifier for strings containing <see cref="Guid"/> format specifiers.</summary>
public const string GuidFormat = nameof(GuidFormat);

/// <summary>The syntax identifier for strings containing JavaScript Object Notation (JSON).</summary>
public const string Json = nameof(Json);

/// <summary>The syntax identifier for strings containing numeric format specifiers.</summary>
public const string NumericFormat = nameof(NumericFormat);

/// <summary>The syntax identifier for strings containing regular expressions.</summary>
public const string Regex = nameof(Regex);

/// <summary>The syntax identifier for strings containing time format specifiers.</summary>
public const string TimeOnlyFormat = nameof(TimeOnlyFormat);

/// <summary>The syntax identifier for strings containing <see cref="TimeSpan"/> format specifiers.</summary>
public const string TimeSpanFormat = nameof(TimeSpanFormat);

/// <summary>The syntax identifier for strings containing URIs.</summary>
public const string Uri = nameof(Uri);

/// <summary>The syntax identifier for strings containing XML.</summary>
public const string Xml = nameof(Xml);

/// <summary>
/// Initializes a new instance of the <see cref="StringSyntaxAttribute"/> class with the identifier of the syntax used.
/// </summary>
/// <param name="syntax">The syntax identifier.</param>
public StringSyntaxAttribute(string syntax)
{
Syntax = syntax;
Arguments = Array.Empty<object?>();
}

/// <summary>
/// Initializes a new instance of the <see cref="StringSyntaxAttribute"/> class with the identifier of the syntax used.
/// </summary>
/// <param name="syntax">The syntax identifier.</param>
/// <param name="arguments">Optional arguments associated with the specific syntax employed.</param>
public StringSyntaxAttribute(string syntax, params object?[] arguments)
{
Syntax = syntax;
Arguments = arguments;
}

/// <summary>Gets the identifier of the syntax used.</summary>
public string Syntax { get; }

/// <summary>Gets optional arguments associated with the specific syntax employed.</summary>
public object?[] Arguments { get; }
}
}

#endif
Expand Up @@ -2,6 +2,7 @@

using System;
using System.Collections;
using System.Diagnostics.CodeAnalysis;
using System.Text.RegularExpressions;

namespace NUnit.Framework.Constraints
Expand Down Expand Up @@ -768,7 +769,7 @@ public EndsWithConstraint EndsWith(string expected)
/// Returns a constraint that succeeds if the actual
/// value matches the regular expression supplied as an argument.
/// </summary>
public RegexConstraint Match(string pattern)
public RegexConstraint Match([StringSyntax(StringSyntaxAttribute.Regex)] string pattern)
{
return (RegexConstraint)Append(new RegexConstraint(pattern));
}
Expand All @@ -786,7 +787,7 @@ public RegexConstraint Match(Regex regex)
/// Returns a constraint that succeeds if the actual
/// value matches the regular expression supplied as an argument.
/// </summary>
public RegexConstraint Matches(string pattern)
public RegexConstraint Matches([StringSyntax(StringSyntaxAttribute.Regex)] string pattern)
{
return (RegexConstraint)Append(new RegexConstraint(pattern));
}
Expand Down
3 changes: 2 additions & 1 deletion src/NUnitFramework/framework/Constraints/RegexConstraint.cs
@@ -1,5 +1,6 @@
// Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt

using System.Diagnostics.CodeAnalysis;
using System.Text.RegularExpressions;

namespace NUnit.Framework.Constraints
Expand Down Expand Up @@ -34,7 +35,7 @@ public override string Description
/// Initializes a new instance of the <see cref="RegexConstraint"/> class.
/// </summary>
/// <param name="pattern">The pattern.</param>
public RegexConstraint(string pattern) : base(pattern)
public RegexConstraint([StringSyntax(StringSyntaxAttribute.Regex)] string pattern) : base(pattern)
{
_regex = new Regex(pattern);
}
Expand Down
3 changes: 2 additions & 1 deletion src/NUnitFramework/framework/Does.cs
@@ -1,5 +1,6 @@
// Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt

using System.Diagnostics.CodeAnalysis;
using System.Text.RegularExpressions;
using NUnit.Framework.Constraints;

Expand Down Expand Up @@ -109,7 +110,7 @@ public static EndsWithConstraint EndWith(string expected)
/// Returns a constraint that succeeds if the actual
/// value matches the regular expression supplied as an argument.
/// </summary>
public static RegexConstraint Match(string pattern)
public static RegexConstraint Match([StringSyntax(StringSyntaxAttribute.Regex)] string pattern)
{
return new RegexConstraint(pattern);
}
Expand Down