-
Notifications
You must be signed in to change notification settings - Fork 1
Refactor TestRecord class and add interop features for test execution context #2250
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -9,30 +9,32 @@ | |||||
| /// <remarks> | ||||||
| /// The xunit test context | ||||||
| /// </remarks> | ||||||
| /// <param name="context"></param> | ||||||
| /// <param name="logEventLevel"></param> | ||||||
| /// <param name="outputTemplate"></param> | ||||||
| /// <param name="configureLogger"></param> | ||||||
| [PublicAPI] | ||||||
| public abstract class TUnitTestRecord<TContext>( | ||||||
| TestContext context, | ||||||
| LogEventLevel logEventLevel = LogEventLevel.Verbose, | ||||||
| string? outputTemplate = null, | ||||||
| Action<TContext, LoggerConfiguration>? configureLogger = null | ||||||
| ) : RocketSurgeryTestContext<TContext>( | ||||||
| configureLogger, | ||||||
| logEventLevel, | ||||||
| outputTemplate | ||||||
| ) | ||||||
| where TContext : RocketSurgeryTestContext<TContext>, ILoggingTestContext | ||||||
| public abstract partial class TestRecord<TContext> | ||||||
| (LogEventLevel logEventLevel = LogEventLevel.Verbose, string? outputTemplate = null, Action<TContext, LoggerConfiguration>? configureLogger = null) | ||||||
| : RocketSurgeryTestContext<TContext>(configureLogger, logEventLevel, outputTemplate) | ||||||
| where TContext : RocketSurgeryTestContext<TContext> | ||||||
| { | ||||||
| private readonly TestContext _context = context; | ||||||
| /// <summary> | ||||||
| /// Represents the current test context for xUnit tests. | ||||||
| /// </summary> | ||||||
| /// <remarks> | ||||||
| /// Provides access to the active test context during the execution of a test. | ||||||
| /// This property is typically used to retrieve contextual information or perform | ||||||
| /// test-specific logging operations. | ||||||
| /// </remarks> | ||||||
| public TestContext TestContext { get; } = TestContext.Current!; | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 HIGH RISK The TestContext property relies on TestContext.Current, which may be null if accessed outside of a TUnit test execution. Explicitly checking for null and throwing a clear exception is recommended to avoid confusing NullReferenceExceptions.
Suggested change
|
||||||
|
|
||||||
| private readonly LogEventLevel _logEventLevel = logEventLevel; | ||||||
|
|
||||||
| /// <inheritdoc /> | ||||||
| protected override void ConfigureLogger(TContext context, LoggerConfiguration loggerConfiguration) => loggerConfiguration | ||||||
| .MinimumLevel.Is(_logEventLevel) | ||||||
| .WriteTo.Sink(new Sink(_context)); | ||||||
| protected override void ConfigureLogger(TContext context, LoggerConfiguration loggerConfiguration) => | ||||||
| loggerConfiguration | ||||||
| .MinimumLevel.Is(_logEventLevel) | ||||||
| .WriteTo.Sink(new Sink(TestContext)); | ||||||
| } | ||||||
|
|
||||||
| /// <summary> | ||||||
|
|
@@ -41,22 +43,19 @@ | |||||
| [PublicAPI] | ||||||
| public class TestRecord | ||||||
| ( | ||||||
| TestContext context, | ||||||
| LogEventLevel logEventLevel = LogEventLevel.Verbose, | ||||||
| string? outputTemplate = null, | ||||||
| Action<TestRecord, LoggerConfiguration>? configureLogger = null) | ||||||
| : TUnitTestRecord<TestRecord>(context, logEventLevel, outputTemplate, configureLogger) | ||||||
| : TestRecord<TestRecord>(logEventLevel, outputTemplate, configureLogger) | ||||||
| { | ||||||
| /// <summary> | ||||||
| /// Create the test record | ||||||
| /// </summary> | ||||||
| /// <param name="testContext"></param> | ||||||
| /// <param name="logEventLevel"></param> | ||||||
| /// <param name="outputTemplate"></param> | ||||||
| /// <returns></returns> | ||||||
| public static TestRecord Create( | ||||||
| TestContext testContext, | ||||||
| LogEventLevel logEventLevel = LogEventLevel.Verbose, | ||||||
| string? outputTemplate = null | ||||||
| ) => new(testContext, logEventLevel, outputTemplate); | ||||||
| ) => new(logEventLevel, outputTemplate); | ||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| {{~for method in methods~}} | ||
| /// <inheritdoc /> | ||
| public {{method.is_async?"async ":""}}{{method.return_type}} {{method.name}}({{method.arguments_definition}}) | ||
| { | ||
| {{~if method.is_async~}} | ||
| {{~for reference in references~}} | ||
| var temp{{for.index}} = (({{interface}})this.{{reference}}).{{method.name}}({{method.call_arguments}}).ConfigureAwait(false); | ||
| {{~end~}} | ||
| {{~for reference in references~}} | ||
| {{for.last && method.return_expected ? "return " : ""}}await temp{{for.index}}; | ||
| {{~end~}} | ||
| {{~else~}} | ||
| {{~for reference in references~}} | ||
| {{for.last && method.return_expected ? "return " : ""}}(({{interface}})this.{{reference}}).{{method.name}}({{method.call_arguments}}); | ||
| {{~end~}} | ||
| {{~end~}} | ||
| } | ||
|
|
||
| {{~end~}} | ||
| {{~for property in properties~}} | ||
| /// <inheritdoc /> | ||
| public {{property.type}} {{property.name}} | ||
| { | ||
| {{~if property.have_getter~}} | ||
| get | ||
| { | ||
| return (({{interface}})this.{{references[0]}}).{{property.name}}; | ||
| } | ||
| {{~end~}} | ||
| {{~if property.have_setter~}} | ||
| set | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 HIGH RISK The property setter implementation is empty and ignores the 'value' parameter. It should delegate the assignment to the underlying reference to prevent silent failures when setting properties on the context. |
||
| { | ||
| } | ||
| {{~end~}} | ||
| } | ||
|
|
||
| {{~end~}} | ||
| {{~for indexer in indexers~}} | ||
| /// <inheritdoc /> | ||
| public {{indexer.type}} {{indexer.name}}[{{indexer.parameters_definition}}] | ||
| { | ||
| {{~if indexer.have_getter~}} | ||
| get | ||
| { | ||
| return (({{interface}})this.{{references[0]}})[{{indexer.call_parameters}}]; | ||
| } | ||
| {{~end~}} | ||
| {{~if indexer.have_setter~}} | ||
| set | ||
| { | ||
|
Comment on lines
+49
to
+50
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 HIGH RISK The indexer setter implementation is empty. Any attempt to set a value via an indexer on the generated classes will be silently ignored. This should delegate to the underlying reference. |
||
| } | ||
| {{~end~}} | ||
| } | ||
|
|
||
| {{~end~}} | ||
| {{~for event in events~}} | ||
| /// <inheritdoc /> | ||
| public event {{event.type}} {{event.name}} | ||
| { | ||
| add | ||
| { | ||
| {{~for reference in references~}} | ||
| (({{interface}})this.{{reference}}).{{event.name}} += value; | ||
| {{~end~}} | ||
| } | ||
| remove | ||
| { | ||
| {{~for reference in references~}} | ||
| (({{interface}})this.{{reference}}).{{event.name}} -= value; | ||
| {{~end~}} | ||
| } | ||
| } | ||
|
|
||
| {{~end~}} | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⚪ LOW RISK
Nitpick: The documentation here refers to 'xunit test context', but this class is part of the TUnit implementation. Update all XML summaries and remarks to correctly reflect TUnit.