dotnet / dotnet/command-line-api

How to test parseArgument

Open
#2,262 3 comments 0 reactions 0 assignees View on GitHub
Area-API question
Dominant language
C#
Stars
3.7k
Forks
428
PR merge metrics
No merged PRs in 30d

Description

So given

```
var myOptions = new Option(
name: "--my",
description: "items",
parseArgument: ParseMyItems);
```

and
```
internal static string[] ParseMyItems(ArgumentResult result)
{
//manipulate/validate/parse items
return result.Values();
}
```

I want to test `ParseMyItems`. so i need to be able to create an instance of `ArgumentResult`. but the constructor is internal
```
internal ArgumentResult(
Argument argument,
SymbolResult? parent) : base(argument, parent)
{
Argument = argument;
}
```

So how do i get an instance of `ArgumentResult`.

Currently i have this hack:

```
public static class ArgumentBuilder
{
static Func construct;

static ArgumentBuilder()
{
var tokensField = typeof(ArgumentResult).GetField("_tokens", BindingFlags.NonPublic | BindingFlags.Instance)!;
var constructor = typeof(ArgumentResult).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance)
.Single();
construct = inputs =>
{
var invoke = constructor.Invoke(
new object?[]
{
new Argument(_ => inputs),
null
})!;
var result = (ArgumentResult) invoke;
var tokens = (List) tokensField.GetValue(result)!;
tokens.AddRange(inputs.Select(_ => new Token(_, TokenType.Argument, null!)));
return result;
};
}

public static ArgumentResult Build(params string[] values) =>
construct(values);
}
```

then i can do

```
var argument = ArgumentBuilder.Build("value1", "value2");
ParseMyItems(argument)
```

but there must be a better way

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.