Skip to content

Commit

Permalink
Remove delegates parameter from ctor.
Browse files Browse the repository at this point in the history
  • Loading branch information
mayuki committed Jan 2, 2022
1 parent c2df8bf commit a884438
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 80 deletions.
29 changes: 6 additions & 23 deletions src/Cocona.Core/Command/CoconaCommandProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ public class CoconaCommandProvider : ICoconaCommandProvider
private readonly CommandProviderOptions _options;
private readonly ICoconaServiceProviderIsService _serviceProviderIsService;

public CoconaCommandProvider(Type[] targetTypes, Delegate[]? targetDelegates = default, CommandProviderOptions options = CommandProviderOptions.TreatPublicMethodAsCommands, ICoconaServiceProviderIsService? serviceProviderIsService = null)
public CoconaCommandProvider(Type[] targetTypes, CommandProviderOptions options = CommandProviderOptions.TreatPublicMethodAsCommands, ICoconaServiceProviderIsService? serviceProviderIsService = null)
{
_options = options;
_commandDataSet = CreateCommandDataSetFromTypesAndDelegates(targetTypes, targetDelegates ?? Array.Empty<Delegate>(), Array.Empty<object>());
_commandDataSet = CreateCommandDataSetFromTypes(targetTypes, Array.Empty<object>());
_serviceProviderIsService = serviceProviderIsService ?? NullCoconaServiceProviderIsService.Instance;
}

Expand All @@ -51,9 +51,9 @@ public CoconaCommandProvider(IReadOnlyList<ICommandData> commands, CommandProvid
public CommandCollection GetCommandCollection()
=> CreateCommandCollectionFromCommandDataSet(_commandDataSet);

private IReadOnlyList<ICommandData> CreateCommandDataSetFromTypesAndDelegates(IReadOnlyList<Type> types, IReadOnlyList<Delegate> delegates, IReadOnlyList<object> typeCommandMetadata)
private IReadOnlyList<ICommandData> CreateCommandDataSetFromTypes(IReadOnlyList<Type> types, IReadOnlyList<object> typeCommandMetadata)
{
var commands = new List<ICommandData>(types.Count + delegates.Count);
var commands = new List<ICommandData>(types.Count);
foreach (var type in types)
{
// Command types
Expand Down Expand Up @@ -85,7 +85,7 @@ private IReadOnlyList<ICommandData> CreateCommandDataSetFromTypesAndDelegates(IR
{
if (subCommandsAttr.Type == type) throw new InvalidOperationException("Sub-commands type must not be same as command type.");

var subCommandDataSet = CreateCommandDataSetFromTypesAndDelegates(new[] { subCommandsAttr.Type }, Array.Empty<Delegate>(), typeCommandMetadata);
var subCommandDataSet = CreateCommandDataSetFromTypes(new[] { subCommandsAttr.Type }, typeCommandMetadata);
var commandName = subCommandsAttr.Type.Name;
if (!string.IsNullOrWhiteSpace(subCommandsAttr.CommandName))
{
Expand All @@ -97,17 +97,6 @@ private IReadOnlyList<ICommandData> CreateCommandDataSetFromTypesAndDelegates(IR
}
}

foreach (var @delegate in delegates)
{
var attrs = @delegate.Method.GetCustomAttributes(inherit: true);
var commandName = attrs.OfType<CommandAttribute>().Select(x => x.Name).FirstOrDefault(x => string.IsNullOrEmpty(x));
var delegateMetadata = (commandName != null)
? new object[] { new CommandNameMetadata(commandName) } // == AddCommand(string, Delegate)
: new object[] { new PrimaryCommandAttribute() }; // == AddCommand(Delegate)
delegateMetadata = new[] { new CommandNameMetadata(@delegate.Method.Name) };
commands.Add(new DelegateCommandData(@delegate.Method, @delegate.Target, typeCommandMetadata.Concat(attrs).Concat(delegateMetadata).ToArray()));
}

return commands;
}

Expand Down Expand Up @@ -176,12 +165,6 @@ private CommandCollection CreateCommandCollectionFromCommandDataSet(IReadOnlyLis
}
}

// Allow only one unnamed primary command.
if (command.Flags.HasFlag(CommandFlags.Unnamed) && command.IsPrimaryCommand && commands.Any(x => x.Flags.HasFlag(CommandFlags.Unnamed) && x.IsPrimaryCommand))
{
throw new CoconaException($"One unnamed primary command can be registered. An unnamed primary command has been already registered.");
}

commands.Add(command);
}

Expand All @@ -196,7 +179,7 @@ void ProcessCommandData(ICommandData commandData)
{
// Commands Type
case TypeCommandData typeCommandData:
foreach (var commandDataInner in CreateCommandDataSetFromTypesAndDelegates(new[] { typeCommandData.Type }, Array.Empty<Delegate>(), typeCommandData.Metadata))
foreach (var commandDataInner in CreateCommandDataSetFromTypes(new[] { typeCommandData.Type }, typeCommandData.Metadata))
{
ProcessCommandData(commandDataInner);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,17 @@ void TestMethod() { }
collection.All[0].Name.Should().Be("TestMethod");
}

[Fact]
public void DelegateCommandData_Static()
{
var provider = new CoconaCommandProvider(new[] { new DelegateCommandData(new Action<string>(CommandTest_Static.A).Method, null, new[] { new CommandNameMetadata("A") }) });
var collection = provider.GetCommandCollection();
collection.All.Should().HaveCount(1);
collection.All[0].Name.Should().Be("A");
collection.All[0].Target.Should().BeNull();
collection.All[0].Method.IsStatic.Should().BeTrue();
}

[Fact]
public void TypeCommandData_SingleCommand()
{
Expand All @@ -70,6 +81,18 @@ public void TypeCommandData_SingleCommand()
collection.All[0].Name.Should().Be("A");
}

[Fact]
public void TypeCommandData_PrimaryCommand_Duplicate()
{
var provider = new CoconaCommandProvider(new[]
{
new TypeCommandData(typeof(CommandTestSingleCommand), new object[] { new CommandNameMetadata("A"), new PrimaryCommandAttribute() }),
new TypeCommandData(typeof(CommandTestSingleCommand), new object[] { new CommandNameMetadata("B"), new PrimaryCommandAttribute() }),
});

Assert.Throws<CoconaException>(() => provider.GetCommandCollection()).Message.Should().Contain("The commands contains more then one primary command.");
}

[Fact]
public void TypeCommandData_MultipleCommands()
{
Expand All @@ -96,7 +119,10 @@ public void TypeCommandData_HasSameNameCommands()
var provider = new CoconaCommandProvider(new[] { new TypeCommandData(typeof(CommandTestSingleCommand), Array.Empty<object>()), new TypeCommandData(typeof(CommandTestMultipleCommand), Array.Empty<object>()) });
Assert.Throws<CoconaException>(() => provider.GetCommandCollection());
}

public static class CommandTest_Static
{
public static void A(string name) { }
}
public class CommandTestSingleCommand
{
public void A(string name) { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,61 +236,6 @@ public void Static_MultipleCommands()
commands.All[1].Method.IsStatic.Should().BeTrue();
}

[Fact]
public void Delegate_Static_SingleCommand()
{
Func<bool, bool, int> methodA = CommandTest_Static_MultipleCommands.A;
var provider = new CoconaCommandProvider(Array.Empty<Type>(), new[] { methodA });
var commands = provider.GetCommandCollection();
commands.Should().NotBeNull();
commands.All.Should().HaveCount(1);
commands.All[0].Name.Should().Be("A");
}

[Fact]
public void Delegate_Static_MultipleCommands()
{
Func<bool, bool, int> methodA = CommandTest_Static_MultipleCommands.A;
Action methodB = CommandTest_Static_MultipleCommands.B;
var provider = new CoconaCommandProvider(Array.Empty<Type>(), new[] { (Delegate)methodA, methodB });
var commands = provider.GetCommandCollection();
commands.Should().NotBeNull();
commands.All.Should().HaveCount(2);
commands.All[0].Name.Should().Be("A");
commands.All[1].Name.Should().Be("B");
}

[Fact]
public void Delegate()
{
Action<string> methodA = new CommandTestSingleCommand().A;
var provider = new CoconaCommandProvider(Array.Empty<Type>(), new[] { methodA });
var commands = provider.GetCommandCollection();
commands.Should().NotBeNull();
commands.All.Should().HaveCount(1);
commands.All[0].Name.Should().Be("A");
commands.All[0].CommandType.Should().Be<CommandTestSingleCommand>();
}

[Fact]
public void Delegate_Unnamed_Single()
{
Action<string> methodA = (string name) => {};
var provider = new CoconaCommandProvider(Array.Empty<Type>(), new[] { methodA });
var commands = provider.GetCommandCollection();
commands.Should().NotBeNull();
commands.All.Should().HaveCount(1);
}

[Fact]
public void Delegate_Unnamed_Multiple()
{
Action<string> methodA = (string name) => {};
Action<string> methodB = (string name) => {};
var provider = new CoconaCommandProvider(Array.Empty<Type>(), new[] { methodA, methodB });
Assert.Throws<CoconaException>(() => provider.GetCommandCollection());
}

public class CommandTestDefaultPrimaryCommand_Argument
{
public void A([Argument]string[] args) { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public void Unnamed_SingleCommand_Duplicated()
app.Run();
});

stdErr.Should().Contain("One unnamed primary command can be registered");
stdErr.Should().Contain("The commands contains more then one primary command");
exitCode.Should().Be(1);
}

Expand Down

0 comments on commit a884438

Please sign in to comment.