diff --git a/.github/workflows/update-dependencies.yml b/.github/workflows/update-dependencies.yml
index 4d72867..4b0c48b 100644
--- a/.github/workflows/update-dependencies.yml
+++ b/.github/workflows/update-dependencies.yml
@@ -19,3 +19,4 @@ jobs:
secrets: inherit
with:
solutionsToCheck: 'nanoFramework.TestFramework.sln'
+ exclusionList: 'NFUnit Test Demo,NFUnit Test DemoByReference'
diff --git a/poc/TestOfTestFrameworkByReference/NFUnitTestByReference.nfproj b/poc/TestOfTestFrameworkByReference/NFUnitTestByReference.nfproj
index 9e2ef89..ab8367f 100644
--- a/poc/TestOfTestFrameworkByReference/NFUnitTestByReference.nfproj
+++ b/poc/TestOfTestFrameworkByReference/NFUnitTestByReference.nfproj
@@ -25,6 +25,7 @@
$(MSBuildProjectDirectory)\nano.runsettings
+ latest
@@ -49,6 +50,9 @@
..\packages\nanoFramework.Runtime.Native.1.6.12\lib\nanoFramework.Runtime.Native.dll
+
+ ..\packages\nanoFramework.System.Runtime.1.0.27\lib\nanoFramework.System.Runtime.dll
+
diff --git a/poc/TestOfTestFrameworkByReference/Test.cs b/poc/TestOfTestFrameworkByReference/Test.cs
index 8927799..22d44ab 100644
--- a/poc/TestOfTestFrameworkByReference/Test.cs
+++ b/poc/TestOfTestFrameworkByReference/Test.cs
@@ -5,6 +5,7 @@
//
using System;
+using System.Runtime.CompilerServices;
using System.Threading;
using nanoFramework.TestFramework;
using NFUnitTest.Mock;
@@ -263,7 +264,7 @@ private static void ThrowsException()
public class SomethingElse
{
- public void NothingReally()
+ public void NothingReally(object value, [CallerArgumentExpression(nameof(value))] string parameter = null)
{
Console.WriteLine("Only classes marked with [TestClass] will run tests.");
}
diff --git a/poc/TestOfTestFrameworkByReference/packages.config b/poc/TestOfTestFrameworkByReference/packages.config
index 5acdbc7..93b3aa9 100644
--- a/poc/TestOfTestFrameworkByReference/packages.config
+++ b/poc/TestOfTestFrameworkByReference/packages.config
@@ -2,4 +2,5 @@
+
\ No newline at end of file
diff --git a/source/TestFramework/CallerArgumentExpressionAttribute.cs b/source/TestFramework/CallerArgumentExpressionAttribute.cs
new file mode 100644
index 0000000..ec3fb98
--- /dev/null
+++ b/source/TestFramework/CallerArgumentExpressionAttribute.cs
@@ -0,0 +1,27 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+// ReSharper disable once CheckNamespace
+namespace System.Runtime.CompilerServices
+{
+ ///
+ /// Indicates that a parameter captures the expression passed for another parameter as a string.
+ ///
+ [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
+ internal sealed class CallerArgumentExpressionAttribute : Attribute
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The name of the parameter whose expression should be captured as a string.
+ public CallerArgumentExpressionAttribute(string parameterName)
+ {
+ ParameterName = parameterName;
+ }
+
+ ///
+ /// Gets the name of the parameter whose expression should be captured as a string.
+ ///
+ public string ParameterName { get; }
+ }
+}
\ No newline at end of file
diff --git a/source/TestFramework/NullableAttributes.cs b/source/TestFramework/NullableAttributes.cs
new file mode 100644
index 0000000..e36c7e6
--- /dev/null
+++ b/source/TestFramework/NullableAttributes.cs
@@ -0,0 +1,181 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+// ReSharper disable once CheckNamespace
+namespace System.Diagnostics.CodeAnalysis
+{
+ ///
+ /// Specifies that is allowed as an input even if the corresponding type disallows it.
+ ///
+ ///
+ /// To override a method that has a parameter annotated with this attribute, use the ? operator. For more information, see Nullable static analysis in the C# guide.
+ ///
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
+ internal sealed class AllowNullAttribute : Attribute
+ { }
+
+ ///
+ /// Specifies that null is disallowed as an input even if the corresponding type allows it.
+ ///
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
+ internal sealed class DisallowNullAttribute : Attribute
+ { }
+
+ ///
+ /// Specifies that an output may be null even if the corresponding type disallows it.
+ ///
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
+ internal sealed class MaybeNullAttribute : Attribute
+ { }
+
+ ///
+ /// Specifies that an output will not be null even if the corresponding type allows it. Specifies that an input argument was not null when the call returns.
+ ///
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
+ internal sealed class NotNullAttribute : Attribute
+ { }
+
+ ///
+ /// Specifies that when a method returns , the parameter may be null even if the corresponding type disallows it.
+ ///
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+ internal sealed class MaybeNullWhenAttribute : Attribute
+ {
+ ///
+ /// Initializes the attribute with the specified return value condition.
+ ///
+ ///
+ /// The return value condition. If the method returns this value, the associated parameter may be null.
+ ///
+ internal MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
+
+ ///
+ /// Gets the return value condition.
+ ///
+ internal bool ReturnValue { get; }
+ }
+
+ ///
+ /// Specifies that when a method returns , the parameter will not be null even if the corresponding type allows it.
+ ///
+ internal sealed class NotNullWhenAttribute : Attribute
+ {
+ /// Initializes the attribute with the specified return value condition.
+ ///
+ /// The return value condition. If the method returns this value, the associated parameter will not be null.
+ ///
+ internal NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
+
+ /// Gets the return value condition.
+ internal bool ReturnValue { get; }
+ }
+
+ ///
+ /// Specifies that the output will be non-null if the named parameter is non-null.
+ ///
+ [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
+ internal sealed class NotNullIfNotNullAttribute : Attribute
+ {
+ /// Initializes the attribute with the associated parameter name.
+ ///
+ /// The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null.
+ ///
+ internal NotNullIfNotNullAttribute(string parameterName) => ParameterName = parameterName;
+
+ /// Gets the associated parameter name.
+ internal string ParameterName { get; }
+ }
+
+ ///
+ /// Applied to a method that will never return under any circumstance.
+ ///
+ [AttributeUsage(AttributeTargets.Method, Inherited = false)]
+ internal sealed class DoesNotReturnAttribute : Attribute
+ { }
+
+ ///
+ /// Specifies that the method will not return if the associated Boolean parameter is passed the specified value.
+ ///
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+ internal sealed class DoesNotReturnIfAttribute : Attribute
+ {
+ /// Initializes the attribute with the specified parameter value.
+ ///
+ /// The condition parameter value. Code after the method will be considered unreachable by diagnostics if the argument to
+ /// the associated parameter matches this value.
+ ///
+ internal DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue;
+
+ ///
+ /// Gets the condition parameter value.
+ ///
+ internal bool ParameterValue { get; }
+ }
+
+ ///
+ /// Specifies that the method or property will ensure that the listed field and property members have not-null values.
+ ///
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
+ internal sealed class MemberNotNullAttribute : Attribute
+ {
+ /// Initializes the attribute with a field or property member.
+ ///
+ /// The field or property member that is promised to be not-null.
+ ///
+ internal MemberNotNullAttribute(string member) => Members = new[] { member };
+
+ /// Initializes the attribute with the list of field and property members.
+ ///
+ /// The list of field and property members that are promised to be not-null.
+ ///
+ internal MemberNotNullAttribute(params string[] members) => Members = members;
+
+ ///
+ /// Gets field or property member names.
+ ///
+ internal string[] Members { get; }
+ }
+
+ ///
+ /// Specifies that the method or property will ensure that the listed field and property members have not-null values when returning with the specified return value condition.
+ ///
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
+ internal sealed class MemberNotNullWhenAttribute : Attribute
+ {
+ /// Initializes the attribute with the specified return value condition and a field or property member.
+ ///
+ /// The return value condition. If the method returns this value, the associated parameter will not be null.
+ ///
+ ///
+ /// The field or property member that is promised to be not-null.
+ ///
+ internal MemberNotNullWhenAttribute(bool returnValue, string member)
+ {
+ ReturnValue = returnValue;
+ Members = new[] { member };
+ }
+
+ /// Initializes the attribute with the specified return value condition and list of field and property members.
+ ///
+ /// The return value condition. If the method returns this value, the associated parameter will not be null.
+ ///
+ ///
+ /// The list of field and property members that are promised to be not-null.
+ ///
+ internal MemberNotNullWhenAttribute(bool returnValue, params string[] members)
+ {
+ ReturnValue = returnValue;
+ Members = members;
+ }
+
+ ///
+ /// Gets the return value condition.
+ ///
+ internal bool ReturnValue { get; }
+
+ ///
+ /// Gets field or property member names.
+ ///
+ internal string[] Members { get; }
+ }
+}
diff --git a/source/TestFramework/nanoFramework.TestFramework.nfproj b/source/TestFramework/nanoFramework.TestFramework.nfproj
index ed41c19..b81f2cb 100644
--- a/source/TestFramework/nanoFramework.TestFramework.nfproj
+++ b/source/TestFramework/nanoFramework.TestFramework.nfproj
@@ -41,7 +41,9 @@
Assert.cs
+
+
@@ -57,9 +59,6 @@
..\..\packages\nanoFramework.CoreLibrary.1.15.5\lib\mscorlib.dll
True
-
- ..\..\packages\nanoFramework.System.Runtime.1.0.27\lib\nanoFramework.System.Runtime.dll
-
diff --git a/source/TestFramework/packages.config b/source/TestFramework/packages.config
index 0b25966..b466781 100644
--- a/source/TestFramework/packages.config
+++ b/source/TestFramework/packages.config
@@ -1,6 +1,5 @@
-
+
-
\ No newline at end of file
diff --git a/source/TestFramework/packages.lock.json b/source/TestFramework/packages.lock.json
index 11aa244..be631b7 100644
--- a/source/TestFramework/packages.lock.json
+++ b/source/TestFramework/packages.lock.json
@@ -8,12 +8,6 @@
"resolved": "1.15.5",
"contentHash": "u2+GvAp1uxLrGdILACAZy+EVKOs28EQ52j8Lz7599egXZ3GBGejjnR2ofhjMQwzrJLlgtyrsx8nSLngDfJNsAg=="
},
- "nanoFramework.System.Runtime": {
- "type": "Direct",
- "requested": "[1.0.27, 1.0.27]",
- "resolved": "1.0.27",
- "contentHash": "aMwvQV6AR+XlDc+dHR/fWWnTe5dc7LDaqZS0ccfmd31Y39dZnmX3iQB2wXWtZGvXLCC+obc3IF3Vc70FiG0raw=="
- },
"Nerdbank.GitVersioning": {
"type": "Direct",
"requested": "[3.6.139, 3.6.139]",