TestContext
Provide the context information of the current test.
This is an adapter for the internal ExecutionContext
class, hiding the internals from the user test.
using NUnit.Framework.Constraints;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Execution;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading;
namespace NUnit.Framework
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public class TestContext
{
[System.Runtime.CompilerServices.NullableContext(2)]
[System.Runtime.CompilerServices.Nullable(0)]
public class TestAdapter
{
[System.Runtime.CompilerServices.Nullable(1)]
private readonly Test _test;
[System.Runtime.CompilerServices.Nullable(1)]
public string ID {
[System.Runtime.CompilerServices.NullableContext(1)]
get {
return _test.Id;
}
}
[System.Runtime.CompilerServices.Nullable(1)]
public string Name {
[System.Runtime.CompilerServices.NullableContext(1)]
get {
return _test.Name;
}
}
public string Namespace => _test.TypeInfo?.Namespace;
public string DisplayName => _test.TypeInfo?.GetDisplayName();
public string MethodName => (_test as TestMethod)?.Method.Name;
public IMethodInfo Method => (_test as TestMethod)?.Method;
public Type Type => _test.TypeInfo?.Type;
[System.Runtime.CompilerServices.Nullable(1)]
public string FullName {
[System.Runtime.CompilerServices.NullableContext(1)]
get {
return _test.FullName;
}
}
public string ClassName => _test.ClassName;
[System.Runtime.CompilerServices.Nullable(1)]
public PropertyBagAdapter Properties {
[System.Runtime.CompilerServices.NullableContext(1)]
get {
return new PropertyBagAdapter(_test.Properties);
}
}
[System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})]
public object[] Arguments {
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})]
get {
return _test.Arguments;
}
}
public object ExpectedResult => (_test as TestMethod)?.ExpectedResult;
public ITest Parent => _test.Parent;
[System.Runtime.CompilerServices.NullableContext(1)]
public TestAdapter(Test test)
{
_test = test;
}
[System.Runtime.CompilerServices.NullableContext(1)]
public IDictionary<PropertyHierachyItem, IList> PropertyHierarchy()
{
Dictionary<PropertyHierachyItem, IList> dictionary = new Dictionary<PropertyHierachyItem, IList>();
ITest test = _test;
do {
foreach (string key in test.Properties.Keys) {
IList list = test.Properties[key];
if (list.Count > 0)
dictionary.Add(new PropertyHierachyItem(key, test.Name ?? string.Empty), list);
}
test = test.Parent;
} while (test != null);
return dictionary;
}
[System.Runtime.CompilerServices.NullableContext(1)]
private IList<PropertyValueHierarchyItem> PropertyValues(string property)
{
List<PropertyValueHierarchyItem> list = new List<PropertyValueHierarchyItem>();
ITest test = _test;
do {
IList propValues = test.Properties[property];
list.Add(new PropertyValueHierarchyItem(test.Name, propValues));
test = test.Parent;
} while (test != null);
return list;
}
[System.Runtime.CompilerServices.NullableContext(1)]
public IEnumerable<object> AllPropertyValues(string property)
{
List<object> list = new List<object>();
IList<PropertyValueHierarchyItem> list2 = PropertyValues(property);
foreach (PropertyValueHierarchyItem item in list2) {
list.AddRange((IEnumerable<object>)item.Values);
}
return list.Distinct();
}
[System.Runtime.CompilerServices.NullableContext(1)]
public IEnumerable<string> AllCategories()
{
return (from o in AllPropertyValues("Category")
select (string)o).ToList();
}
}
[System.Runtime.CompilerServices.Nullable(0)]
public class PropertyHierachyItem
{
public string Name { get; } = string.Empty;
public string Level { get; } = string.Empty;
public PropertyHierachyItem()
{
}
public PropertyHierachyItem(string name, string level)
{
Name = name;
Level = level;
}
}
[System.Runtime.CompilerServices.Nullable(0)]
public class PropertyValueHierarchyItem
{
public IList Values { get; set; }
public string Level { get; set; }
public PropertyValueHierarchyItem(string testName, IList propValues)
{
Level = testName;
Values = propValues;
}
}
[System.Runtime.CompilerServices.Nullable(0)]
public class ResultAdapter
{
private readonly TestResult _result;
public ResultState Outcome => _result.ResultState;
public IEnumerable<AssertionResult> Assertions => _result.AssertionResults;
public string Message => _result.Message;
[System.Runtime.CompilerServices.Nullable(2)]
public virtual string StackTrace {
[System.Runtime.CompilerServices.NullableContext(2)]
get {
return _result.StackTrace;
}
}
public int FailCount => _result.FailCount;
public int WarningCount => _result.WarningCount;
public int PassCount => _result.PassCount;
public int SkipCount => _result.SkipCount;
public int InconclusiveCount => _result.InconclusiveCount;
public ResultAdapter(TestResult result)
{
_result = result;
}
}
[System.Runtime.CompilerServices.Nullable(0)]
public class PropertyBagAdapter
{
private readonly IPropertyBag _source;
public IEnumerable<object> this[string key] {
get {
if (_source.TryGet(key, out IList values)) {
foreach (object item in values) {
yield return item;
}
}
}
}
public ICollection<string> Keys => _source.Keys;
public PropertyBagAdapter(IPropertyBag source)
{
_source = source;
}
[return: System.Runtime.CompilerServices.Nullable(2)]
public object Get(string key)
{
return _source.Get(key);
}
public bool ContainsKey(string key)
{
return _source.ContainsKey(key);
}
public int Count(string key)
{
if (!_source.TryGet(key, out IList values))
return 0;
return values.Count;
}
}
private readonly TestExecutionContext _testExecutionContext;
[System.Runtime.CompilerServices.Nullable(2)]
private TestAdapter _test;
[System.Runtime.CompilerServices.Nullable(2)]
private ResultAdapter _result;
public static TextWriter Error = new EventListenerTextWriter("Error", Console.Error);
public static readonly TextWriter Progress = new EventListenerTextWriter("Progress", Console.Error);
public static readonly TestParameters Parameters = new TestParameters();
[System.Runtime.CompilerServices.Nullable(2)]
internal static string DefaultWorkDirectory;
public static TestContext CurrentContext => new TestContext(TestExecutionContext.CurrentContext);
public static TextWriter Out => TestExecutionContext.CurrentContext.OutWriter;
public TestAdapter Test => _test ?? (_test = new TestAdapter(_testExecutionContext.CurrentTest));
public ResultAdapter Result => _result ?? (_result = new ResultAdapter(_testExecutionContext.CurrentResult));
[System.Runtime.CompilerServices.Nullable(2)]
public string WorkerId {
[System.Runtime.CompilerServices.NullableContext(2)]
get {
return _testExecutionContext.TestWorker?.Name;
}
}
public string TestDirectory {
get {
Assembly assembly = _testExecutionContext?.CurrentTest?.TypeInfo?.Assembly;
if ((object)assembly != null)
return AssemblyHelper.GetDirectoryName(assembly);
return AssemblyHelper.GetDirectoryName(Assembly.GetCallingAssembly());
}
}
public string WorkDirectory {
get {
string defaultWorkDirectory = DefaultWorkDirectory;
if (defaultWorkDirectory == null)
throw new InvalidOperationException("TestContext.WorkDirectory must not be accessed before DefaultTestAssemblyBuilder.Build runs.");
return defaultWorkDirectory;
}
}
public Randomizer Random => _testExecutionContext.RandomGenerator;
public int AssertCount => _testExecutionContext.AssertCount;
public int CurrentRepeatCount => _testExecutionContext.CurrentRepeatCount;
public CancellationToken CancellationToken => _testExecutionContext.CancellationToken;
public TestContext(TestExecutionContext testExecutionContext)
{
_testExecutionContext = testExecutionContext;
}
public static void Write(bool value)
{
Out.Write(value);
}
public static void Write(char value)
{
Out.Write(value);
}
[System.Runtime.CompilerServices.NullableContext(2)]
public static void Write(char[] value)
{
Out.Write(value);
}
public static void Write(double value)
{
Out.Write(value);
}
public static void Write(int value)
{
Out.Write(value);
}
public static void Write(long value)
{
Out.Write(value);
}
public static void Write(decimal value)
{
Out.Write(value);
}
[System.Runtime.CompilerServices.NullableContext(2)]
public static void Write(object value)
{
Out.Write(value);
}
public static void Write(float value)
{
Out.Write(value);
}
[System.Runtime.CompilerServices.NullableContext(2)]
public static void Write(string value)
{
Out.Write(value);
}
[CLSCompliant(false)]
public static void Write(uint value)
{
Out.Write(value);
}
[CLSCompliant(false)]
public static void Write(ulong value)
{
Out.Write(value);
}
public static void Write(string format, [System.Runtime.CompilerServices.Nullable(2)] object arg1)
{
Out.Write(format, arg1);
}
[System.Runtime.CompilerServices.NullableContext(2)]
public static void Write([System.Runtime.CompilerServices.Nullable(1)] string format, object arg1, object arg2)
{
Out.Write(format, arg1, arg2);
}
[System.Runtime.CompilerServices.NullableContext(2)]
public static void Write([System.Runtime.CompilerServices.Nullable(1)] string format, object arg1, object arg2, object arg3)
{
Out.Write(format, arg1, arg2, arg3);
}
public static void Write(string format, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})] params object[] args)
{
Out.Write(format, args);
}
public static void WriteLine()
{
Out.WriteLine();
}
public static void WriteLine(bool value)
{
Out.WriteLine(value);
}
public static void WriteLine(char value)
{
Out.WriteLine(value);
}
[System.Runtime.CompilerServices.NullableContext(2)]
public static void WriteLine(char[] value)
{
Out.WriteLine(value);
}
public static void WriteLine(double value)
{
Out.WriteLine(value);
}
public static void WriteLine(int value)
{
Out.WriteLine(value);
}
public static void WriteLine(long value)
{
Out.WriteLine(value);
}
public static void WriteLine(decimal value)
{
Out.WriteLine(value);
}
[System.Runtime.CompilerServices.NullableContext(2)]
public static void WriteLine(object value)
{
Out.WriteLine(value);
}
public static void WriteLine(float value)
{
Out.WriteLine(value);
}
[System.Runtime.CompilerServices.NullableContext(2)]
public static void WriteLine(string value)
{
Out.WriteLine(value);
}
[CLSCompliant(false)]
public static void WriteLine(uint value)
{
Out.WriteLine(value);
}
[CLSCompliant(false)]
public static void WriteLine(ulong value)
{
Out.WriteLine(value);
}
public static void WriteLine(string format, [System.Runtime.CompilerServices.Nullable(2)] object arg1)
{
Out.WriteLine(format, arg1);
}
[System.Runtime.CompilerServices.NullableContext(2)]
public static void WriteLine([System.Runtime.CompilerServices.Nullable(1)] string format, object arg1, object arg2)
{
Out.WriteLine(format, arg1, arg2);
}
[System.Runtime.CompilerServices.NullableContext(2)]
public static void WriteLine([System.Runtime.CompilerServices.Nullable(1)] string format, object arg1, object arg2, object arg3)
{
Out.WriteLine(format, arg1, arg2, arg3);
}
public static void WriteLine(string format, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})] params object[] args)
{
Out.WriteLine(format, args);
}
public static void AddFormatter(ValueFormatterFactory formatterFactory)
{
TestExecutionContext.CurrentContext.AddFormatter(formatterFactory);
}
public static void AddTestAttachment(string filePath, [System.Runtime.CompilerServices.Nullable(2)] string description = null)
{
Guard.ArgumentNotNull(filePath, "filePath");
Guard.ArgumentValid(filePath.IndexOfAny(Path.GetInvalidPathChars()) == -1, "Test attachment file path contains invalid path characters. " + filePath, "filePath");
if (!Path.IsPathRooted(filePath))
filePath = Path.Combine(CurrentContext.WorkDirectory, filePath);
string empty = string.Empty;
if (!File.Exists(empty + filePath))
throw new FileNotFoundException("Test attachment file path could not be found.", filePath);
TestResult currentResult = TestExecutionContext.CurrentContext.CurrentResult;
currentResult.AddTestAttachment(new TestAttachment(filePath, description));
}
public static void AddFormatter<[System.Runtime.CompilerServices.Nullable(2)] TSupported>(ValueFormatter formatter)
{
AddFormatter((ValueFormatter next) => delegate(object val) {
if (!(val is TSupported))
return next(val);
return formatter(val);
});
}
}
}