Почему происходит сбой CSharpOptParse UsageBuilder из-за XPathException только при использовании в тесте NUnit? - PullRequest
0 голосов
/ 28 января 2009

Какова основная причина этой проблемы? CSharpOptParse, XslTransform.Transform (...) или NUnit? Какую другую эквивалентную библиотеку я мог бы использовать вместо этого, если эта проблема не решаема, которая активно поддерживается?

Я использую версию 1.0.1 CSharpOptParse , которая была в последний раз изменена в феврале 2005 года.

У меня есть следующий класс (упрощенный для этого примера, конечно) для использования вместе с CSharpOptParse:

public enum CommandType
{
   Usage
}

public class Options
{
   [OptDef(OptValType.Flag)]
   [LongOptionName("help")]
   [Description("Displays this help")]
   public bool Help { get; set; }

   public CommandType CommandType
   {
      get { return CommandType.Usage; }
   }
}

Вот немного кода модульного теста, который повторяет проблему:

TextWriter output = Console.Out;

Options options = new Options { Help = true };
Parser p = ParserFactory.BuildParser(options);
p.Parse();

output.WriteLine("Usage: Console [--a]");
UsageBuilder builder = new UsageBuilder();
builder.BeginSection("Arguments:"); 
builder.AddOptions(p.GetOptionDefinitions()); //could the issue be created here?
builder.EndSection();
builder.ToText(output, OptStyle.Unix, true); //The problem occurs here

Возможно ли, что я вызываю проблему, не настроив UsageBuilder с правильными разделами? Возможно, это может вызвать проблемы в файле xslt ???

Когда я запускаю этот код, я получаю следующее исключение:

    System.Xml.XPath.XPathException : Function 'ext:FormatText()' has failed.
    ----> System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation.
      ----> System.ArgumentOutOfRangeException : Index was out of range. Must be non-negative and less than the size of the collection.
    Parameter name: startIndex
       at MS.Internal.Xml.XPath.FunctionQuery.Evaluate(XPathNodeIterator nodeIterator)
       at System.Xml.Xsl.XsltOld.Processor.ValueOf(ActionFrame context, Int32 key)
       at System.Xml.Xsl.XsltOld.ValueOfAction.Execute(Processor processor, ActionFrame frame)
       at System.Xml.Xsl.XsltOld.ActionFrame.Execute(Processor processor)
       at System.Xml.Xsl.XsltOld.Processor.Execute()
       at System.Xml.Xsl.XsltOld.Processor.Execute(TextWriter writer)
       at System.Xml.Xsl.XslTransform.Transform(XPathNavigator input, XsltArgumentList args, TextWriter output, XmlResolver resolver)
       at System.Xml.Xsl.XslTransform.Transform(IXPathNavigable input, XsltArgumentList args, TextWriter output, XmlResolver resolver)
       at CommandLine.OptParse.UsageBuilder.ToText(TextWriter writer, OptStyle optStyle, Boolean includeDefaultValues, Int32 maxColumns)
--TargetInvocationException
    at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
    at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
    at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
    at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
    at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
    at System.Xml.Xsl.XsltOld.XsltCompileContext.FuncExtension.Invoke(XsltContext xsltContext, Object[] args, XPathNavigator docContext)
    at MS.Internal.Xml.XPath.FunctionQuery.Evaluate(XPathNodeIterator nodeIterator)
    --ArgumentOutOfRangeException
    at System.String.LastIndexOfAny(Char[] anyOf, Int32 startIndex, Int32 count)

Я понятия не имею, что вызывает эту проблему .... и самая странная часть - это то, что происходит только в моем тесте NUnit. Когда этот код вызывается через «Console.exe --help», он работает без исключений. Я не вижу ничего плохого в CSharpOptParse, поэтому может ли это быть проблемой в классе XNET или в NUnit .NET?

Кто-нибудь еще сталкивался с этой проблемой? У кого-нибудь есть советы, как отследить проблему или перейти на более качественную библиотеку?

Ответы [ 3 ]

1 голос
/ 30 декабря 2011

Я знаю, что это старый вопрос. Но ..

Исключение вызвано тем, что метод ToText() пытается определить ширину консоли и завершается ошибкой, когда вы записываете что-либо, что не является настоящей консолью.

Исправление простое: установите фиксированную ширину.

Измените вызов на ToText на:

try
{
    usage.ToText(Console.Out, OptStyle.Unix, true);
}
catch
{
    usage.ToText(Console.Out, OptStyle.Unix, true, 90);
}

Теперь при сбое обычного вызова он попытается выполнить отказоустойчивый.

0 голосов
/ 08 июля 2009

Я столкнулся с той же проблемой и, похоже, исправил ее (не уверен в том, какие проблемы это может вызвать, но все работает нормально).

Найти:

public TextTransformHelper(int maxColumns)
        {
            _maxColumns = maxColumns;

            if (_maxColumns == -1)
            {
                // try to determine console width
                string os = Environment.GetEnvironmentVariable("OS");

                if (os != null && os.StartsWith("Win"))
                {
                    ConsoleUtils.ConsoleHelper ch = new ConsoleUtils.ConsoleHelper();
                    _maxColumns = ch.GetScreenInfo().Size.X;
                }
            }
        }

, а затем измените его следующим образом:

public TextTransformHelper(int maxColumns)
    {
        _maxColumns = maxColumns;

        if (_maxColumns == -1)
        {
            // try to determine console width
            string os = Environment.GetEnvironmentVariable("OS");

            if (os != null && os.StartsWith("Win"))
            {
                ConsoleUtils.ConsoleHelper ch = new ConsoleUtils.ConsoleHelper();
                _maxColumns = ch.GetScreenInfo().Size.X;
                if(_maxColumns == 0) //added
                    _maxColumns = -1; //added
            }
        }
    }

Причина, по которой он взрывался, заключалась в том, что в функции FormatText он имеет следующий оператор if, который должен был выполняться, если ширина столбца не была определена или была равна -1. Функция для меня всегда будет возвращать 0, что приведет к тому, что оператор if ниже не попадет, а затем вызовет исключение «ArgumentOutOfRange». Это было на Windows Server 2008:

if (_maxColumns == -1)
                {
                    output.Append((first) ? indentStr : handingIndentStr);
                    output.Append(line);
                    output.Append(Environment.NewLine);
                    first = false;
                    continue;
                }

Я смог отладить его, увидев ошибку «ext: FormatText» и затем установив точки останова для всех функций FormatText (xslt вызывал функцию C #), а затем посмотрел на исключение и продолжил отладку.

Надеюсь, это поможет.

Джон Реннемайер

0 голосов
/ 28 января 2009

Почему бы вам не присоединить отладчик к NUnit, включить исключения первого шанса и узнать, что происходит?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...