Perché CSharpOptParse UsageBuilder non riesce a causa di XPathException solo se utilizzato in un test NUnit?

StackOverflow https://stackoverflow.com/questions/486119

  •  20-08-2019
  •  | 
  •  

Domanda

Qual è la causa principale di questo problema? CSharpOptParse, XslTransform.Transform (...) o NUnit? Quale altra libreria equivalente potrei usare invece, se questo problema non è risolvibile, che è attivamente supportato?

Sto usando la versione 1.0.1 di CSharpOptParse che è stata modificata l'ultima volta nel febbraio 2005.

Ho la seguente classe (semplificata per questo esempio ovviamente) da usare insieme a 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; }
   }
}

Ecco un po 'di codice unit test che replica il problema:

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

È possibile che io stia causando il problema non configurando UsageBuilder con le sezioni corrette? Forse questo potrebbe causare problemi nel file xslt ???

Quando eseguo quel codice ottengo la seguente eccezione:

    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)

Non ho idea di cosa stia causando questo problema .... e la parte più strana è che si verifica solo nel mio test NUnit. Quando questo codice viene chiamato tramite & Quot; Console.exe --help & Quot; funziona benissimo senza eccezioni. Non riesco a vedere nulla di sbagliato in CSharpOptParse quindi potrebbe essere un problema nella classe XslTransform di .NET o in NUnit?

Qualcun altro ha riscontrato questo problema? Qualcuno ha qualche consiglio su come rintracciare il problema o passare a una libreria migliore?

È stato utile?

Soluzione

So che questa è una vecchia domanda. Ma ..

L'eccezione è causata dal fatto che il metodo ToText() tenta di determinare la larghezza della console e non riesce quando si scrive su qualcosa che non è una console reale.

La correzione è semplice: imposta una larghezza fissa.

Cambia la chiamata in ToText in:

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

Ora, se la normale chiamata fallisce, ne proverà una sicura.

Altri suggerimenti

Perché non collegare un debugger a NUnit, attivare le eccezioni di prima opportunità e scoprire cosa sta succedendo?

Ho riscontrato lo stesso problema e mi è sembrato di averlo risolto (non sono sicuro dei problemi che causerebbe farlo, ma tutto sembra funzionare bene).

Ricerca:

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

e quindi modificarlo come segue:

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

Il motivo per cui stava saltando era perché nella funzione FormatText aveva la seguente istruzione if che avrebbe dovuto essere colpita se una larghezza di colonna non era stata definita o era -1. La funzione per me restituirebbe sempre 0 che causerebbe la mancata riuscita dell'istruzione if di seguito e quindi la quot &; ArgumentOutOfRange & Quot; eccezione. Questo era su Windows Server 2008:

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

Sono stato in grado di eseguire il debug vedendo il " ext: FormatText " errore non riuscito e quindi impostazione dei punti di interruzione su tutte le funzioni FormatText (la xslt stava chiamando la funzione C #) e quindi osservando l'eccezione e eseguendo il debug ulteriormente.

Spero che questo aiuti.

John Rennemeyer

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top