Beispiel #1
0
 private static void TryWriteFootnotes(this StandardStreamWriter stream, string?footnotes)
 {
     if (!string.IsNullOrWhiteSpace(footnotes))
     {
         stream.WithForegroundColor(ConsoleColor.DarkGray, (o) => o.WriteLine(TextUtils.AdjustNewLines(footnotes)));
         stream.WriteLine();
     }
 }
        public TestConsole(
            Func <TestConsole, string> onReadLine        = null,
            IEnumerable <string> pipedInput              = null,
            Func <TestConsole, ConsoleKeyInfo> onReadKey = null)
        {
            _onReadKey        = onReadKey;
            IsInputRedirected = pipedInput != null;

            if (pipedInput != null)
            {
                if (onReadLine != null)
                {
                    throw new Exception($"{nameof(onReadLine)} and {nameof(pipedInput)} cannot both be specified. " +
                                        "Windows will throw 'System.IO.IOException: The handle is invalid' on an attempt to ");
                }

                if (pipedInput is ICollection <string> inputs)
                {
                    var queue = new Queue <string>(inputs);
                    onReadLine = console => queue.Count == 0 ? null : queue.Dequeue();
                }
                else
                {
                    onReadLine = console => pipedInput.Take(1).FirstOrDefault();
                }
            }

            var joined = new StandardStreamWriter();

            Joined = joined;
            Out    = new StandardStreamWriter(joined);
            Error  = new StandardStreamWriter(joined);
            In     = new StandardStreamReader(
                () =>
            {
                var input = onReadLine?.Invoke(this);
                // write to joined output so it can be logged for debugging
                joined.WriteLine();
                joined.WriteLine($"IConsole.ReadLine > {input}");
                joined.WriteLine();
                return(input);
            });
        }
Beispiel #3
0
        private static void WriteTableBody <TElement>(this StandardStreamWriter stream, IEnumerable <TElement> collection, Func <TElement, string>[] columnFunctions, int[] columnWidths)
        {
            foreach (TElement item in collection)
            {
                for (int i = 0; i < columnWidths.Length; ++i)
                {
                    Func <TElement, string> column = columnFunctions[i];
                    stream.Write(' ');

                    string value       = columnFunctions[i].Invoke(item);
                    int    targetWidth = columnWidths[i];

                    stream.Write(value.PadRight(targetWidth));

                    if (i + 1 < columnWidths.Length)
                    {
                        stream.WithForegroundColor(ConsoleColor.Magenta, (o) => o.Write(" |"));
                    }
                }

                stream.WriteLine();
            }
        }
Beispiel #4
0
        private static void WriteTableHeader(this StandardStreamWriter stream, IEnumerable <string> headers, int[] columnWidths, int totalWidth)
        {
            if (headers.Any())
            {
                for (int i = 0; i < columnWidths.Length; ++i)
                {
                    string header      = headers.ElementAtOrDefault(i) ?? string.Empty;
                    int    targetWidth = columnWidths[i];

                    stream.Write(' ');
                    stream.WithForegroundColor(ConsoleColor.DarkYellow, (o) => o.Write(header.PadRight(targetWidth)));

                    if (i + 1 < columnWidths.Length)
                    {
                        stream.WithForegroundColor(ConsoleColor.Magenta, (o) => o.Write(" |"));
                    }
                }
                stream.WriteLine();

                //Write middle line
                stream.WriteBorder(totalWidth);
            }
        }
Beispiel #5
0
        private static void WriteException(this StandardStreamWriter output, Exception exception, int indentLevel)
        {
            Type exceptionType = exception.GetType();

            string indentationShared = new string(' ', 4 * indentLevel);
            string indentationLocal  = new string(' ', 2);

            // Fully qualified exception type
            output.Write(indentationShared);
            output.WithForegroundColor(ConsoleColor.DarkGray, (o) =>
            {
                o.Write(exceptionType.Namespace);
                o.Write('.');
            });
            output.WithForegroundColor(ConsoleColor.White, (o) => o.Write(exceptionType.Name));
            output.Write(": ");

            // Exception message
            output.WithForegroundColor(ConsoleColor.Red, (o) => o.WriteLine(exception.Message));

            // Recurse into inner exceptions
            if (exception.InnerException is not null)
            {
                output.WriteException(exception.InnerException, indentLevel + 1);
            }

            if (exception.StackTrace is null)
            {
                return;
            }

            // Try to parse and pretty-print the stack trace
            try
            {
                foreach (StackFrame stackFrame in StackTraceParser.ParseMany(exception.StackTrace))
                {
                    output.Write(indentationShared);
                    output.Write(indentationLocal);
                    output.WithForegroundColor(ConsoleColor.Green, (o) => o.Write("at "));

                    // "Typin.Demo.Commands.BookAddCommand."
                    output.WithForegroundColor(ConsoleColor.DarkGray, (o) =>
                    {
                        o.Write(stackFrame.ParentType);
                        o.Write('.');
                    });

                    // "ExecuteAsync"
                    output.WithForegroundColor(ConsoleColor.Yellow, (o) => o.Write(stackFrame.MethodName));

                    output.Write('(');

                    for (int i = 0; i < stackFrame.Parameters.Count; ++i)
                    {
                        StackFrameParameter parameter = stackFrame.Parameters[i];

                        // "IConsole"
                        output.WithForegroundColor(ConsoleColor.Blue, (o) => o.Write(parameter.Type));

                        if (!string.IsNullOrWhiteSpace(parameter.Name))
                        {
                            output.Write(' ');

                            // "console"
                            output.WithForegroundColor(ConsoleColor.White, (o) => o.Write(parameter.Name));
                        }

                        // Separator
                        if (stackFrame.Parameters.Count > 1 && i < stackFrame.Parameters.Count - 1)
                        {
                            output.Write(", ");
                        }
                    }

                    output.Write(") ");

                    // Location
                    if (!string.IsNullOrWhiteSpace(stackFrame.FilePath))
                    {
                        output.WithForegroundColor(ConsoleColor.Magenta, (o) => o.Write("in"));
                        output.WriteLine();
                        output.Write(indentationShared);
                        output.Write(indentationLocal);
                        output.Write(indentationLocal);

                        // "C:\Projects\Typin\Typin.Demo\Commands\"
                        var stackFrameDirectoryPath = Path.GetDirectoryName(stackFrame.FilePath);
                        output.WithForegroundColor(ConsoleColor.DarkGray, (o) =>
                        {
                            o.Write(stackFrameDirectoryPath);
                            o.Write(Path.DirectorySeparatorChar);
                        });

                        // "BookAddCommand.cs"
                        string stackFrameFileName = Path.GetFileName(stackFrame.FilePath) ?? string.Empty;
                        output.WithForegroundColor(ConsoleColor.Cyan, (o) => o.Write(stackFrameFileName));

                        if (!string.IsNullOrWhiteSpace(stackFrame.LineNumber))
                        {
                            output.Write(':');

                            // "35"
                            output.WithForegroundColor(ConsoleColor.Magenta, (o) => o.Write(stackFrame.LineNumber));
                        }
                    }

                    output.WriteLine();
                }
            }
            // If any point of parsing has failed - print the stack trace without any formatting
            catch
            {
                output.WriteLine(exception.StackTrace);
            }
        }