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
1 change: 1 addition & 0 deletions Trax.Core.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
<Project Path="tests/Trax.Core.Tests.Unit/Trax.Core.Tests.Unit.csproj" />
<Project Path="tests/Trax.Core.Tests.Integration/Trax.Core.Tests.Integration.csproj" />
<Project Path="tests/Trax.Core.Tests.Analyzers/Trax.Core.Tests.Analyzers.csproj" />
<Project Path="tests/Trax.Core.Tests.Meta/Trax.Core.Tests.Meta.csproj" />
</Folder>
</Solution>
9 changes: 9 additions & 0 deletions tests/Trax.Core.Tests.Meta/GlobalUsings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
global using System;
global using System.Collections.Generic;
global using System.IO;
global using System.Linq;
global using System.Text.RegularExpressions;
global using System.Xml.Linq;
global using FluentAssertions;
global using NUnit.Framework;
global using Trax.Core.Tests.Meta.Infrastructure;
31 changes: 31 additions & 0 deletions tests/Trax.Core.Tests.Meta/Infrastructure/RepoRoot.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
namespace Trax.Core.Tests.Meta.Infrastructure;

/// <summary>
/// Locates the repository root by walking up from the test bin/ directory until a .slnx is found.
/// </summary>
internal static class RepoRoot
{
private static readonly Lazy<string> Cached = new(Resolve);

public static string Path => Cached.Value;

public static string Combine(params string[] segments) =>
System.IO.Path.Combine(new[] { Path }.Concat(segments).ToArray());

public static string Relative(string absolute) =>
System.IO.Path.GetRelativePath(Path, absolute);

private static string Resolve()
{
var dir = new DirectoryInfo(AppContext.BaseDirectory);
while (dir is not null)
{
if (dir.EnumerateFiles("*.slnx").Any())
return dir.FullName;
dir = dir.Parent;
}
throw new InvalidOperationException(
$"Could not locate repository root: no .slnx found walking up from '{AppContext.BaseDirectory}'."
);
}
}
43 changes: 43 additions & 0 deletions tests/Trax.Core.Tests.Meta/Infrastructure/SourceFiles.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
namespace Trax.Core.Tests.Meta.Infrastructure;

internal static class SourceFiles
{
public static IEnumerable<string> CSharp(params string[] subdirs) => Enumerate("*.cs", subdirs);

public static IEnumerable<string> Projects(params string[] subdirs) =>
Enumerate("*.csproj", subdirs);

public static IEnumerable<string> Markdown(params string[] subdirs) =>
Enumerate("*.md", subdirs);

private static IEnumerable<string> Enumerate(string pattern, string[] subdirs)
{
var roots =
subdirs.Length == 0
? new[] { RepoRoot.Path }
: subdirs.Select(s => Path.Combine(RepoRoot.Path, s)).ToArray();

foreach (var root in roots)
{
if (!Directory.Exists(root))
continue;
foreach (
var file in Directory.EnumerateFiles(root, pattern, SearchOption.AllDirectories)
)
{
if (IsExcluded(file))
continue;
yield return file;
}
}
}

private static bool IsExcluded(string path)
{
var s = Path.DirectorySeparatorChar;
return path.Contains($"{s}bin{s}", StringComparison.Ordinal)
|| path.Contains($"{s}obj{s}", StringComparison.Ordinal)
|| path.Contains($"{s}node_modules{s}", StringComparison.Ordinal)
|| path.Contains($"{s}.git{s}", StringComparison.Ordinal);
}
}
54 changes: 54 additions & 0 deletions tests/Trax.Core.Tests.Meta/Infrastructure/SourceText.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
namespace Trax.Core.Tests.Meta.Infrastructure;

/// <summary>
/// Helpers for inspecting C# source text without triggering false positives from comments / strings.
/// </summary>
internal static class SourceText
{
private static readonly Regex BlockComment = new(
@"/\*.*?\*/",
RegexOptions.Singleline | RegexOptions.Compiled
);
private static readonly Regex LineComment = new(@"//[^\r\n]*", RegexOptions.Compiled);
private static readonly Regex VerbatimString = new(
@"@""(?:[^""]|"""")*""",
RegexOptions.Compiled
);
private static readonly Regex InterpolatedVerbatim = new(
@"\$@""(?:[^""]|"""")*""",
RegexOptions.Compiled
);
private static readonly Regex RegularString = new(
@"""(?:\\.|[^""\\])*""",
RegexOptions.Compiled
);

/// <summary>
/// Strips comments and string literals so that regex-based pattern matching against C# source
/// does not get false positives from a token appearing inside a documentation comment or string.
/// </summary>
public static string StripCommentsAndStrings(string source)
{
var s = BlockComment.Replace(source, " ");
s = LineComment.Replace(s, " ");
s = InterpolatedVerbatim.Replace(s, "\"\"");
s = VerbatimString.Replace(s, "\"\"");
s = RegularString.Replace(s, "\"\"");
return s;
}

public static IReadOnlyList<(int LineNumber, string Line)> MatchingLines(
string source,
Regex pattern
)
{
var hits = new List<(int, string)>();
var lines = source.Replace("\r\n", "\n").Split('\n');
for (var i = 0; i < lines.Length; i++)
{
if (pattern.IsMatch(lines[i]))
hits.Add((i + 1, lines[i]));
}
return hits;
}
}
194 changes: 194 additions & 0 deletions tests/Trax.Core.Tests.Meta/PublicApi/Trax.Core.received.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
namespace Trax.Core.Exceptions
{
public class TrainException : System.Exception
{
public TrainException(string message) { }
}
[System.Runtime.CompilerServices.RequiredMember]
public class TrainExceptionData
{
[System.Obsolete("Constructors of types with required members are not supported in this version of " +
"your compiler.", true)]
public TrainExceptionData() { }
[System.Runtime.CompilerServices.RequiredMember]
[System.Text.Json.Serialization.JsonPropertyName("junction")]
public string Junction { get; set; }
[System.Runtime.CompilerServices.RequiredMember]
[System.Text.Json.Serialization.JsonPropertyName("message")]
public string Message { get; set; }
[System.Text.Json.Serialization.JsonPropertyName("stackTrace")]
public string? StackTrace { get; set; }
[System.Runtime.CompilerServices.RequiredMember]
[System.Text.Json.Serialization.JsonPropertyName("trainExternalId")]
public string TrainExternalId { get; set; }
[System.Runtime.CompilerServices.RequiredMember]
[System.Text.Json.Serialization.JsonPropertyName("trainName")]
public string TrainName { get; set; }
[System.Runtime.CompilerServices.RequiredMember]
[System.Text.Json.Serialization.JsonPropertyName("type")]
public string Type { get; set; }
}
}
namespace Trax.Core.Extensions
{
public static class FunctionalExtensions
{
public static void AssertEachLoaded<T, U>([System.Diagnostics.CodeAnalysis.NotNull] this System.Collections.Generic.IEnumerable<T> values, System.Func<T, U> selector, [System.Runtime.CompilerServices.CallerArgumentExpression("values")] string? valuesExpr = null, [System.Runtime.CompilerServices.CallerArgumentExpression("selector")] string? selectorExpr = null) { }
public static void AssertLoaded<T>([System.Diagnostics.CodeAnalysis.NotNull] this T? value, [System.Runtime.CompilerServices.CallerArgumentExpression("value")] string? valueExpr = null) { }
}
public static class LoggerExtensions
{
public static dynamic CreateGenericLogger(this Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, System.Type genericType) { }
public static System.Collections.Generic.List<Microsoft.Extensions.Logging.ILoggerProvider> GetLoggerProviders(this Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { }
}
public static class MonadExtensions
{
public static LanguageExt.Unit AddTupleToMemory<TIn, TInput, TReturn>(this Trax.Core.Monad.Monad<TInput, TReturn> monad, TIn input) { }
public static dynamic ExtractTuple<TInput, TReturn>(this Trax.Core.Monad.Monad<TInput, TReturn> monad, System.Type inputType) { }
public static dynamic? ExtractTypeFromMemory<TInput, TReturn>(this Trax.Core.Monad.Monad<TInput, TReturn> monad, System.Type tIn) { }
public static T? ExtractTypeFromMemory<T, TInput, TReturn>(this Trax.Core.Monad.Monad<TInput, TReturn> monad) { }
public static object?[] ExtractTypesFromMemory<TInput, TReturn>(this Trax.Core.Monad.Monad<TInput, TReturn> monad, System.Collections.Generic.IEnumerable<System.Type> types) { }
public static TJunction? InitializeJunction<TJunction, TInput, TReturn>(this Trax.Core.Monad.Monad<TInput, TReturn> monad)
where TJunction : class { }
}
public static class MoqExtensions
{
public static System.Type? GetMockedTypeFromObject(this object mockedObject) { }
public static bool IsMoqProxy(this System.Type type) { }
}
}
namespace Trax.Core.Junction
{
public interface IJunction<TIn, TOut>
{
System.Threading.Tasks.Task<LanguageExt.Either<System.Exception, TOut>> RailwayJunction<TTrainIn, TTrainOut>(LanguageExt.Either<System.Exception, TIn> previousOutput, Trax.Core.Train.Train<TTrainIn, TTrainOut> train);
System.Threading.Tasks.Task<TOut> Run(TIn input);
}
public abstract class Junction<TIn, TOut> : Trax.Core.Junction.IJunction<TIn, TOut>
{
protected Junction() { }
public System.Threading.CancellationToken CancellationToken { get; protected set; }
public Trax.Core.Exceptions.TrainExceptionData? ExceptionData { get; }
public LanguageExt.Either<System.Exception, TIn> PreviousResult { get; }
public LanguageExt.Either<System.Exception, TOut> Result { get; }
public virtual System.Threading.Tasks.Task<LanguageExt.Either<System.Exception, TOut>> RailwayJunction<TTrainIn, TTrainOut>(LanguageExt.Either<System.Exception, TIn> previousOutput, Trax.Core.Train.Train<TTrainIn, TTrainOut> train) { }
public abstract System.Threading.Tasks.Task<TOut> Run(TIn input);
}
}
namespace Trax.Core.Monad
{
public class Monad<TInput, TReturn>
{
public Trax.Core.Monad.Monad<TInput, TReturn> Activate(TInput input, params object[] otherInputs) { }
public Trax.Core.Monad.Monad<TInput, TReturn> AddServices<T1>(T1 service) { }
public Trax.Core.Monad.Monad<TInput, TReturn> AddServices<T1, T2>(T1 service1, T2 service2) { }
public Trax.Core.Monad.Monad<TInput, TReturn> AddServices<T1, T2, T3>(T1 service1, T2 service2, T3 service3) { }
public Trax.Core.Monad.Monad<TInput, TReturn> AddServices<T1, T2, T3, T4>(T1 service1, T2 service2, T3 service3, T4 service4) { }
public Trax.Core.Monad.Monad<TInput, TReturn> AddServices<T1, T2, T3, T4, T5>(T1 service1, T2 service2, T3 service3, T4 service4, T5 service5) { }
public Trax.Core.Monad.Monad<TInput, TReturn> AddServices<T1, T2, T3, T4, T5, T6>(T1 service1, T2 service2, T3 service3, T4 service4, T5 service5, T6 service6) { }
public Trax.Core.Monad.Monad<TInput, TReturn> AddServices<T1, T2, T3, T4, T5, T6, T7>(T1 service1, T2 service2, T3 service3, T4 service4, T5 service5, T6 service6, T7 service7) { }
public Trax.Core.Train.MonadTask<TInput, TReturn> Chain<TJunction>()
where TJunction : class { }
public Trax.Core.Train.MonadTask<TInput, TReturn> Chain<TJunction>(TJunction junctionInstance)
where TJunction : class { }
public Trax.Core.Train.MonadTask<TInput, TReturn> Chain<TJunction, TIn>()
where TJunction : Trax.Core.Junction.IJunction<TIn, LanguageExt.Unit>, new () { }
public Trax.Core.Train.MonadTask<TInput, TReturn> Chain<TJunction, TIn>(TJunction junction)
where TJunction : Trax.Core.Junction.IJunction<TIn, LanguageExt.Unit> { }
public Trax.Core.Train.MonadTask<TInput, TReturn> Chain<TJunction, TIn, TOut>()
where TJunction : Trax.Core.Junction.IJunction<TIn, TOut>, new () { }
public Trax.Core.Train.MonadTask<TInput, TReturn> Chain<TJunction, TIn, TOut>(TJunction junction)
where TJunction : Trax.Core.Junction.IJunction<TIn, TOut> { }
public Trax.Core.Monad.Monad<TInput, TReturn> Extract<TIn, TOut>() { }
public Trax.Core.Monad.Monad<TInput, TReturn> Extract<TIn, TOut>(TIn input) { }
public Trax.Core.Train.MonadTask<TInput, TReturn> IChain<TJunction>()
where TJunction : class { }
public LanguageExt.Either<System.Exception, TReturn> Resolve() { }
public LanguageExt.Either<System.Exception, TReturn> Resolve(LanguageExt.Either<System.Exception, TReturn> returnType) { }
public Trax.Core.Train.MonadTask<TInput, TReturn> ShortCircuit<TJunction>()
where TJunction : class { }
public Trax.Core.Train.MonadTask<TInput, TReturn> ShortCircuit<TJunction>(TJunction junctionInstance)
where TJunction : class { }
}
}
namespace Trax.Core.Route
{
public interface IRoute<in TIn, TOut>
{
System.Threading.Tasks.Task<TOut> Run(TIn input, System.Threading.CancellationToken cancellationToken = default);
}
}
namespace Trax.Core.Train
{
public static class MonadTaskExtensions
{
public static Trax.Core.Train.MonadTask<TInput, TReturn> AsMonadTask<TInput, TReturn>(this System.Threading.Tasks.Task<Trax.Core.Monad.Monad<TInput, TReturn>> source) { }
}
public readonly struct MonadTask<TInput, TReturn>
{
public Trax.Core.Train.MonadTask<TInput, TReturn> AddServices<T1>(T1 service) { }
public Trax.Core.Train.MonadTask<TInput, TReturn> AddServices<T1, T2>(T1 s1, T2 s2) { }
public Trax.Core.Train.MonadTask<TInput, TReturn> AddServices<T1, T2, T3>(T1 s1, T2 s2, T3 s3) { }
public Trax.Core.Train.MonadTask<TInput, TReturn> AddServices<T1, T2, T3, T4>(T1 s1, T2 s2, T3 s3, T4 s4) { }
public Trax.Core.Train.MonadTask<TInput, TReturn> AddServices<T1, T2, T3, T4, T5>(T1 s1, T2 s2, T3 s3, T4 s4, T5 s5) { }
public Trax.Core.Train.MonadTask<TInput, TReturn> AddServices<T1, T2, T3, T4, T5, T6>(T1 s1, T2 s2, T3 s3, T4 s4, T5 s5, T6 s6) { }
public Trax.Core.Train.MonadTask<TInput, TReturn> AddServices<T1, T2, T3, T4, T5, T6, T7>(T1 s1, T2 s2, T3 s3, T4 s4, T5 s5, T6 s6, T7 s7) { }
public System.Threading.Tasks.Task<Trax.Core.Monad.Monad<TInput, TReturn>> AsTask() { }
public Trax.Core.Train.MonadTask<TInput, TReturn> Chain<TJunction>()
where TJunction : class { }
public Trax.Core.Train.MonadTask<TInput, TReturn> Chain<TJunction>(TJunction instance)
where TJunction : class { }
public Trax.Core.Train.MonadTask<TInput, TReturn> Chain<TJunction, TIn>()
where TJunction : Trax.Core.Junction.IJunction<TIn, LanguageExt.Unit>, new () { }
public Trax.Core.Train.MonadTask<TInput, TReturn> Chain<TJunction, TIn>(TJunction junction)
where TJunction : Trax.Core.Junction.IJunction<TIn, LanguageExt.Unit> { }
public Trax.Core.Train.MonadTask<TInput, TReturn> Chain<TJunction, TIn, TOut>()
where TJunction : Trax.Core.Junction.IJunction<TIn, TOut>, new () { }
public Trax.Core.Train.MonadTask<TInput, TReturn> Chain<TJunction, TIn, TOut>(TJunction junction)
where TJunction : Trax.Core.Junction.IJunction<TIn, TOut> { }
public System.Runtime.CompilerServices.ConfiguredTaskAwaitable<Trax.Core.Monad.Monad<TInput, TReturn>> ConfigureAwait(bool continueOnCapturedContext) { }
public Trax.Core.Train.MonadTask<TInput, TReturn> Extract<TIn, TOut>() { }
public Trax.Core.Train.MonadTask<TInput, TReturn> Extract<TIn, TOut>(TIn input) { }
public System.Runtime.CompilerServices.TaskAwaiter<Trax.Core.Monad.Monad<TInput, TReturn>> GetAwaiter() { }
public Trax.Core.Train.MonadTask<TInput, TReturn> IChain<TJunction>()
where TJunction : class { }
public System.Threading.Tasks.Task<LanguageExt.Either<System.Exception, TReturn>> Resolve() { }
public System.Threading.Tasks.Task<LanguageExt.Either<System.Exception, TReturn>> Resolve(LanguageExt.Either<System.Exception, TReturn> returnType) { }
public Trax.Core.Train.MonadTask<TInput, TReturn> ShortCircuit<TJunction>()
where TJunction : class { }
public Trax.Core.Train.MonadTask<TInput, TReturn> ShortCircuit<TJunction>(TJunction instance)
where TJunction : class { }
public static System.Threading.Tasks.Task<Trax.Core.Monad.Monad<TInput, TReturn>> op_Implicit(Trax.Core.Train.MonadTask<TInput, TReturn> mt) { }
}
public abstract class Train<TInput, TReturn> : Trax.Core.Route.IRoute<TInput, TReturn>
{
protected Train() { }
[System.Text.Json.Serialization.JsonIgnore]
public System.Threading.CancellationToken CancellationToken { get; protected set; }
public string ExternalId { get; set; }
public Trax.Core.Monad.Monad<TInput, TReturn> Activate(TInput input, params object[] otherInputs) { }
protected Trax.Core.Monad.Monad<TInput, TReturn> AddServices<T1>(T1 service) { }
protected Trax.Core.Monad.Monad<TInput, TReturn> AddServices<T1, T2>(T1 s1, T2 s2) { }
protected Trax.Core.Monad.Monad<TInput, TReturn> AddServices<T1, T2, T3>(T1 s1, T2 s2, T3 s3) { }
protected Trax.Core.Monad.Monad<TInput, TReturn> AddServices<T1, T2, T3, T4>(T1 s1, T2 s2, T3 s3, T4 s4) { }
protected Trax.Core.Monad.Monad<TInput, TReturn> AddServices<T1, T2, T3, T4, T5>(T1 s1, T2 s2, T3 s3, T4 s4, T5 s5) { }
protected Trax.Core.Monad.Monad<TInput, TReturn> AddServices<T1, T2, T3, T4, T5, T6>(T1 s1, T2 s2, T3 s3, T4 s4, T5 s5, T6 s6) { }
protected Trax.Core.Monad.Monad<TInput, TReturn> AddServices<T1, T2, T3, T4, T5, T6, T7>(T1 s1, T2 s2, T3 s3, T4 s4, T5 s5, T6 s6, T7 s7) { }
protected Trax.Core.Train.MonadTask<TInput, TReturn> Chain<TJunction>()
where TJunction : class { }
protected Trax.Core.Train.MonadTask<TInput, TReturn> Chain<TJunction>(TJunction instance)
where TJunction : class { }
protected Trax.Core.Monad.Monad<TInput, TReturn> Extract<TIn, TOut>() { }
protected Trax.Core.Monad.Monad<TInput, TReturn> Extract<TIn, TOut>(TIn input) { }
protected Trax.Core.Train.MonadTask<TInput, TReturn> IChain<TJunction>()
where TJunction : class { }
protected virtual System.Threading.Tasks.Task<LanguageExt.Either<System.Exception, TReturn>> Junctions() { }
public virtual System.Threading.Tasks.Task<TReturn> Run(TInput input, System.Threading.CancellationToken cancellationToken = default) { }
public System.Threading.Tasks.Task<LanguageExt.Either<System.Exception, TReturn>> RunEither(TInput input) { }
protected virtual System.Threading.Tasks.Task<LanguageExt.Either<System.Exception, TReturn>> RunInternal(TInput input) { }
protected Trax.Core.Train.MonadTask<TInput, TReturn> ShortCircuit<TJunction>()
where TJunction : class { }
protected Trax.Core.Train.MonadTask<TInput, TReturn> ShortCircuit<TJunction>(TJunction instance)
where TJunction : class { }
}
}
Loading
Loading