Ответ 1
Глядя на код, это довольно умный.
Магия происходит в классе ActualCodeTextGetter
. Во-первых, он извлекает строку файла исходного кода с помощью StackTrace:
StackTrace stackTrace = trace ?? new StackTrace(true);
// Cut for brevity
StackFrame stackFrame = frame;
this.ShouldlyFrameIndex = index - 1;
string fileName = stackFrame.GetFileName();
this._determinedOriginatingFrame = fileName != null && File.Exists(fileName);
this._shouldMethod = this.ShouldlyFrame.GetMethod().Name;
this.FileName = fileName;
this.LineNumber = stackFrame.GetFileLineNumber() - 1;
Как только у него есть имя файла исходного кода, а также строка и смещение инструкции, это просто вопрос непосредственно чтения файла:
private string GetCodePart()
{
string str = "Shouldly uses your source code to generate its great error messages, build your test project with full debug information to get better error messages\nThe provided expression";
if (this._determinedOriginatingFrame)
{
string codeLines = string.Join("\n", ((IEnumerable<string>) File.ReadAllLines(this.FileName)).Skip<string>(this.LineNumber).ToArray<string>());
int indexOfMethod = codeLines.IndexOf(this._shouldMethod);
if (indexOfMethod > 0)
str = codeLines.Substring(0, indexOfMethod - 1).Trim();
str = !str.EndsWith("Should") ? str.RemoveVariableAssignment().RemoveBlock() : this.GetCodePartFromParameter(indexOfMethod, codeLines, str);
}
return str;
}
Здесь гораздо больше логики, чтобы изолировать именно утверждение, но, в общем, трюк:
- Используйте StackTrace для извлечения местоположения исходного кода и строки оператора
- Разберите исходный код для получения точной инструкции
Конечно, он может работать только в том случае, если вы запускаете его на том же компьютере, который использовался для компиляции кода.