为什么仅当在 NUnit 测试中使用时,CSharpOptParseUsageBuilder 才会因 XPathException 而失败?

发布于 2024-07-13 00:26:13 字数 3781 浏览 3 评论 0原文

这个问题的根本原因是什么? CSharpOptParse、XslTransform.Transform(...) 还是 NUnit? 如果这个问题无法修复,并且得到积极支持,我可以使用其他哪些等效库来代替?

我正在使用 CSharpOptParse 版本 1.0.1,最后一次修改是在 2005 年 2 月

。下面的类(当然是针对这个示例进行了简化)与 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 有什么问题,所以这可能是 .NET 的 XslTransform 类或 NUnit 中的问题吗?

还有其他人遇到过这个问题吗? 有人对如何追踪问题或切换到更好的库有任何建议吗?

What is the root cause of this issue? CSharpOptParse, XslTransform.Transform(...), or NUnit? What other equivalent library could I use instead, if this problem is unfixable, that is being actively supported?

I'm using version 1.0.1 of CSharpOptParse which was last modified in Feb 2005.

I've have the following class (simplified for this example of course) to use along with 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; }
   }
}

Here is a bit of unit test code that replicates the issue:

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

Is it possible that I'm causing the problem by not setting up the UsageBuilder with the correct sections? Possibly this might be causing problems in the xslt file???

When I run that code I get the following exception:

    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)

I have no idea what is causing this problem....and the weirdest part is that is only occurs within my NUnit test. When this code is called via "Console.exe --help" it runs fine with no exceptions. I can't see anything wrong with CSharpOptParse so could this be a problem in .NET's XslTransform class or in NUnit?

Has anyone else experienced this issue? Does anyone have any advice on how to track down the issue or switch to a better library?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

满意归宿 2024-07-20 00:26:13

我知道这是一个老问题。 但是..

引起异常的原因是 ToText() 方法尝试确定控制台的宽度,但当您写入非真正控制台的任何内容时,该方法会失败。

修复方法很简单:设置固定宽度。

将对 ToText 的调用更改为:

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

现在,如果正常调用失败,它将尝试故障安全调用。

I know this is an old question. But..

The exception is caused because the ToText() method tries to determine the width of the console and it fails when you're writing to anything that is not a real console.

The fix is simple: Set a fixed width.

Change the call to ToText to:

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

Now if the normal call fails, it will try a fail-safe one.

风吹短裙飘 2024-07-20 00:26:13

为什么不将调试器附加到 NUnit,打开 First-Chance 异常,并找出发生了什么?

Why don't you attach a debugger to NUnit, turn on First-Chance exceptions, and find out what's going on?

抚笙 2024-07-20 00:26:13

我遇到了同样的问题,并且似乎已经解决了它(不确定这样做会导致什么问题,但一切似乎都正常)。

查找:

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# 函数),然后进一步查看异常和调试。

我希望这有帮助。

约翰·伦尼梅尔

I ran into the same issue and have seemed to have fixed it (not sure of the issues it would cause doing this but everything seems to work okay).

Find:

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;
                }
            }
        }

and then modify it to the following:

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
            }
        }
    }

The reason it was blowing up was because in the FormatText function it has the following if statement which was supposed to be hit if a columnwidth was not defined or was -1. The function for me would always return 0 which would cause the below if statement to not get hit and then cause an "ArgumentOutOfRange" exception. This was on Windows Server 2008:

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

I was able to debug it by seeing the "ext:FormatText" failed error and then setting breakpoints on all FormatText functions (the xslt was calling the C# function) and then looking at the exception and debugging in further.

I hope this helps.

John Rennemeyer

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文