public void Parser_Multiples() { CommandLineParser parser; IEnumerable<ArgumentInstance> instances; TestLogger logger; string[] args = new string[] { "zzzv1", "zzzv2", "zzzv3" }; // 1. Don't allow multiples ArgumentDescriptor d1 = new ArgumentDescriptor("id", new string[] { "zzz" }, true, "desc1", false /* no multiples */); parser = new CommandLineParser(new ArgumentDescriptor[] { d1 }, false); logger = CheckProcessingFails(parser, args); logger.AssertSingleErrorExists("zzzv2", "v1"); logger.AssertSingleErrorExists("zzzv3", "v1"); logger.AssertErrorsLogged(2); // 2. Allow multiples d1 = new ArgumentDescriptor("id", new string[] { "zzz" }, true, "desc1", true /* allow multiple */); parser = new CommandLineParser(new ArgumentDescriptor[] { d1 }, true); logger = new TestLogger(); instances = CheckProcessingSucceeds(parser, logger, args); AssertExpectedValues("id", instances, "v1", "v2", "v3"); AssertExpectedInstancesCount(3, instances); }
public void Parser_UnrecognizedArguments() { CommandLineParser parser; IEnumerable<ArgumentInstance> instances; TestLogger logger; string[] args = new string[] { "/a:XXX", "/unrecognized" }; ArgumentDescriptor d1 = new ArgumentDescriptor("id1", new string[] { "/a:" }, true, "desc1", false); // 1. Don't allow unrecognized parser = new CommandLineParser(new ArgumentDescriptor[] { d1 }, false); logger = CheckProcessingFails(parser, args); logger.AssertSingleErrorExists("/unrecognized"); logger.AssertErrorsLogged(1); // 2. Allow unrecognized parser = new CommandLineParser(new ArgumentDescriptor[] { d1 }, true); logger = new TestLogger(); instances = CheckProcessingSucceeds(parser, logger, args); AssertExpectedValue("id1", "XXX", instances); AssertExpectedInstancesCount(1, instances); logger.AssertMessagesLogged(0); // expecting unrecognized arguments to be ignored silently }
public void Parser_DuplicateDescriptorIds() { ArgumentDescriptor d1 = new ArgumentDescriptor("id1", new string[] { "a" }, true, "desc1", false); ArgumentDescriptor d2 = new ArgumentDescriptor("id1", new string[] { "b" }, true, "desc2", false); AssertException.Expects<ArgumentException>(() => new CommandLineParser( new ArgumentDescriptor[] { d1, d2 }, true)); }
public void Parser_CaseSensitivity() { string[] args = new string[] { "aaa:all lowercase", "AAA:all uppercase", "aAa: mixed case" }; ArgumentDescriptor d1 = new ArgumentDescriptor("id", new string[] { "AAA:" }, true/* allow multiples */ , "desc1", true /* allow multiple */); CommandLineParser parser = new CommandLineParser(new ArgumentDescriptor[] { d1 }, true /* allow unrecognized */); // Act IEnumerable<ArgumentInstance> instances = CheckProcessingSucceeds(parser, new TestLogger(), args); AssertExpectedValue("id", "all uppercase", instances); AssertExpectedInstancesCount(1, instances); }
public void Parser_Verbs_Required() { CommandLineParser parser; IEnumerable <ArgumentInstance> instances; TestLogger logger; var emptyArgs = new string[] { }; var matchingPrefixArgs = new string[] { "AAAa" }; // 1a. Argument is required but is missing -> error var d1 = new ArgumentDescriptor("id", new string[] { "AAA" }, true /* required */, "desc1", false /* no multiples */, true); parser = new CommandLineParser(new ArgumentDescriptor[] { d1 }, false); logger = CheckProcessingFails(parser, emptyArgs); logger.AssertSingleErrorExists("desc1"); logger.AssertErrorsLogged(1); // 1b. Argument is required but is only partial match -> missing -> error2 logger = CheckProcessingFails(parser, matchingPrefixArgs); logger.AssertSingleErrorExists("desc1"); // missing arg logger.AssertSingleErrorExists("AAAa"); // unrecognized since not exact match logger.AssertErrorsLogged(2); // 2a. Argument is not required, missing -> ok d1 = new ArgumentDescriptor("id", new string[] { "AAA" }, false /* not required */, "desc1", false /* no multiples */, true); parser = new CommandLineParser(new ArgumentDescriptor[] { d1 }, true); logger = new TestLogger(); instances = CheckProcessingSucceeds(parser, logger, emptyArgs); AssertExpectedInstancesCount(0, instances); // 2b. Argument is not required, partial -> missing -> ok logger = new TestLogger(); instances = CheckProcessingSucceeds(parser, logger, matchingPrefixArgs); AssertExpectedInstancesCount(0, instances); }
private static void HandleObjectType( ITypeCompletionContext completionContext, ObjectTypeDefinition definition, ISpatialConvention convention) { foreach (var field in definition.Fields) { foreach (var arg in field.Arguments) { if (arg.Type is not null && completionContext.IsNamedType <IGeoJsonInputType>(arg.Type)) { arg.Formatters.Add( new GeometryTransformerInputFormatter( convention.TransformerFactory, convention.DefaultSrid)); } } if (field.Type is not null && completionContext.IsNamedType <IGeoJsonObjectType>(field.Type)) { var argument = ArgumentDescriptor.New( completionContext.DescriptorContext, CrsFieldName); argument .Type <IntType>() .Description(Transformation_Argument_Crs_Description); field.Arguments.Add(argument.CreateDefinition()); field.MiddlewareComponents.Insert(0, FieldClassMiddlewareFactory.Create <GeometryTransformationMiddleware>( (typeof(IGeometryTransformerFactory), convention.TransformerFactory), (typeof(int), convention.DefaultSrid))); } } }
public void CmdLineArgProperties_DynamicProperties() { // Arrange TestLogger logger = new TestLogger(); IList<ArgumentInstance> args = new List<ArgumentInstance>(); ArgumentDescriptor dummyDescriptor = new ArgumentDescriptor("dummy", new string[] { "dummy prefix" }, false, "dummy desc", true); ArgumentDescriptor dummyDescriptor2 = new ArgumentDescriptor("dummy2", new string[] { "dummy prefix 2" }, false, "dummy desc 2", true); args.Add(new ArgumentInstance(dummyDescriptor, "should be ignored")); args.Add(new ArgumentInstance(dummyDescriptor2, "should be ignored")); AddDynamicArguments(args, "key1=value1", "key2=value two with spaces"); // Act IAnalysisPropertyProvider provider = CheckProcessingSucceeds(args, logger); // Assert provider.AssertExpectedPropertyValue("key1", "value1"); provider.AssertExpectedPropertyValue("key2", "value two with spaces"); provider.AssertExpectedPropertyCount(2); }
public void Parser_Verbs_Multiples() { CommandLineParser parser; IEnumerable <ArgumentInstance> instances; TestLogger logger; string[] args = new string[] { "verb" }; ArgumentDescriptor verb1 = new ArgumentDescriptor("v1", new string[] { "noMult" }, false /* required */, "noMult desc", false /* no multiples */, true); ArgumentDescriptor verb2 = new ArgumentDescriptor("v2", new string[] { "multOk" }, false /* required */, "multOk desc", true /* allow multiples */, true); parser = new CommandLineParser(new ArgumentDescriptor[] { verb1, verb2 }, true /* allow unrecognised */); // 1. Allowed multiples logger = new TestLogger(); instances = CheckProcessingSucceeds(parser, logger, "multOk", "multOk"); AssertExpectedInstancesCount(2, instances); // 2. Disallowed multiples logger = CheckProcessingFails(parser, new string[] { "noMult", "noMult" }); logger.AssertSingleErrorExists("noMult"); logger.AssertErrorsLogged(1); }
public void CmdLineArgProperties_DynamicProperties() { // Arrange var logger = new TestLogger(); IList <ArgumentInstance> args = new List <ArgumentInstance>(); var dummyDescriptor = new ArgumentDescriptor("dummy", new string[] { "dummy prefix" }, false, "dummy desc", true); var dummyDescriptor2 = new ArgumentDescriptor("dummy2", new string[] { "dummy prefix 2" }, false, "dummy desc 2", true); args.Add(new ArgumentInstance(dummyDescriptor, "should be ignored")); args.Add(new ArgumentInstance(dummyDescriptor2, "should be ignored")); AddDynamicArguments(args, "key1=value1", "key2=value two with spaces"); // Act var provider = CheckProcessingSucceeds(args, logger); // Assert provider.AssertExpectedPropertyValue("key1", "value1"); provider.AssertExpectedPropertyValue("key2", "value two with spaces"); provider.AssertExpectedPropertyCount(2); }
public void Parser_Verbs_ExactMatchesOnly() { CommandLineParser parser; IEnumerable<ArgumentInstance> instances; TestLogger logger; ArgumentDescriptor verb1 = new ArgumentDescriptor("v1", new string[] { "begin" }, false /* not required */, "desc1", false /* no multiples */, true); parser = new CommandLineParser(new ArgumentDescriptor[] { verb1 }, true /* allow unrecognised */); // 1. Exact match -> matched logger = new TestLogger(); instances = CheckProcessingSucceeds(parser, logger, "begin"); AssertExpectedValue("v1", "", instances); AssertExpectedInstancesCount(1, instances); // 2. Partial match -> not matched logger = new TestLogger(); instances = CheckProcessingSucceeds(parser, logger, "beginX"); AssertExpectedInstancesCount(0, instances); // 3. Combination -> only exact matches matched logger = new TestLogger(); instances = CheckProcessingSucceeds(parser, logger, "beginX", "begin", "beginY"); Assert.AreEqual(string.Empty, instances.First().Value, "Value for verb should be empty"); AssertExpectedInstancesCount(1, instances); AssertExpectedValue("v1", "", instances); }
public static ArgumentDescriptor ToDescriptor( this ArgumentDefinition definition, IDescriptorContext context) => ArgumentDescriptor.From(context, definition);
private bool TryParseArguments(ParameterInfo[] parameters, string[] arguments, out object[] parsedArguments) { parsedArguments = null; if (arguments.Length > parameters.Length) { return(false); } var args = new ArgumentDescriptor[parameters.Length]; var positionalArgumentIndex = 0; var namedArgumentDetected = false; var pattern = new Regex(@"^([a-zA-Z0-9_]+)=(.+)"); foreach (var argument in arguments) { object result; int position; string valueToParse; // check if it's a named argument var m = pattern.Match(argument); if (m.Success) { namedArgumentDetected = true; var name = m.Groups[1].Value; var param = parameters.SingleOrDefault(x => x.Name == name); if (param == null) { return(false); } if (args[param.Position].IsParsed) { throw new ArgumentException("Named argument `{0}' specified multiple times", name); } position = param.Position; valueToParse = m.Groups[2].Value; } else { if (namedArgumentDetected) { // this is a serious error throw new ArgumentException("Named arguments must appear after the positional arguments"); } position = positionalArgumentIndex++; valueToParse = argument; } if (!SmartParser.Instance.TryParse(valueToParse, parameters[position].ParameterType, out result)) { return(false); } args[position].IsParsed = true; args[position].Value = result; } for (var i = 0; i < args.Length; i++) { if (args[i].IsParsed) { continue; } if (!parameters[i].HasDefaultValue) { return(false); } args[i].IsParsed = true; args[i].Value = parameters[i].DefaultValue; } parsedArguments = args.Select(x => x.Value).ToArray(); return(true); }
private IEnumerable<ArgumentDescriptor> RetrieveCommandArguments(Type runnableType) { var runnableProperties = runnableType.GetProperties(); var runnablePropertiesWithAttribute = runnableProperties.Select(property => new { PropertyInformation = property, Attribute = property.GetCustomAttributes(typeof (ParameterAttribute), true) .OfType<ParameterAttribute>() .SingleOrDefault() }); var properties = runnablePropertiesWithAttribute.Where(property => property.Attribute != null); var position = 0; foreach (var property in properties) { var descriptor = new ArgumentDescriptor { ArgumentName = property.Attribute.PropertyName, ArgumentType = property.PropertyInformation.PropertyType, DefaultValue = null, IsOptional = true, Position = position }; yield return descriptor; position++; } }
private static string DirectionToString(ArgumentDescriptor.EArgDirection dir) { switch (dir) { case ArgumentDescriptor.EArgDirection.In: return "in"; case ArgumentDescriptor.EArgDirection.InOut: return "inout"; case ArgumentDescriptor.EArgDirection.Out: return "out"; default: throw new NotImplementedException(); } }
protected override string Generate(ArgumentDescriptor descriptor) { return($"ctx.{nameof(IResolverContext.FieldSelection)}"); }
private Task PublishAsync(IEnumerable <HandlerDescriptor> handlers, ArgumentDescriptor argument, object eventPayload, bool isEnvelopeDelayUsed) { try { bool hasContextHandler = handlers.Any(d => d.IsContext); bool hasEnvelopeHandler = hasContextHandler || handlers.Any(d => d.IsEnvelope); object payload = eventPayload; object context = null; Envelope envelope = null; IEvent eventWithKey = null; if (argument.IsContext) { // If passed argument is context, throw. throw Ensure.Exception.NotSupported("PersistentEventDispatcher doesn't support passing in event handler context."); } else { // If passed argument is not context, try to create it if needed. if (argument.IsEnvelope) { // If passed argument is envelope, extract payload. envelope = (Envelope)payload; payload = envelope.Body; } else { eventWithKey = payload as IEvent; hasEnvelopeHandler = hasEnvelopeHandler || eventWithKey != null; // If passed argument is not envelope, try to create it if needed. if (hasEnvelopeHandler) { envelope = EnvelopeFactory.Create(payload, argument.ArgumentType); } } if (hasContextHandler) { Type contextType = typeof(DefaultEventHandlerContext <>).MakeGenericType(argument.ArgumentType); context = Activator.CreateInstance(contextType, envelope, this, this); } } if (eventWithKey == null) { eventWithKey = payload as IEvent; } log.Info(eventWithKey, "Got an event."); // If isEnvelopeDelayUsed, try to schedule the execution. // If succeeded, return. if (isEnvelopeDelayUsed && TrySchedule(envelope, context, handlers, argument)) { return(Async.CompletedTask); } // Distribute the execution. return(DistributeExecution(payload, context, envelope, eventWithKey, handlers)); } catch (Exception e) { DispatcherExceptionHandlers.Handle(e); return(Async.CompletedTask); } }
public static ArgumentDescriptorAssertions Should(this ArgumentDescriptor instance) => new ArgumentDescriptorAssertions(instance);
protected override string Generate( ArgumentDescriptor descriptor) { return("ct"); }
public void Parser_Required() { CommandLineParser parser; IEnumerable<ArgumentInstance> instances; TestLogger logger; string[] args = new string[] { }; // 1. Argument is required ArgumentDescriptor d1 = new ArgumentDescriptor("id", new string[] { "AAA" }, true /* required */, "desc1", false /* no multiples */); parser = new CommandLineParser(new ArgumentDescriptor[] { d1 }, false); logger = CheckProcessingFails(parser, args); logger.AssertSingleErrorExists("desc1"); logger.AssertErrorsLogged(1); // 2. Argument is not required d1 = new ArgumentDescriptor("id", new string[] { "AAA" }, false /* not required */, "desc1", false /* no multiples */); parser = new CommandLineParser(new ArgumentDescriptor[] { d1 }, true); logger = new TestLogger(); instances = CheckProcessingSucceeds(parser, logger, args); AssertExpectedInstancesCount(0, instances); }
private bool TrySchedule(Envelope envelope, object handlerContext, IEnumerable <HandlerDescriptor> handlers, ArgumentDescriptor argument) { if (schedulingProvider.IsLaterExecutionRequired(envelope)) { log.Info(envelope, "Scheduling for later execution."); ScheduleEventContext context = new ScheduleEventContext(handlers, argument, envelope, handlerContext, OnScheduledEvent); schedulingProvider.Schedule(context); return(true); } return(false); }
public void ShouldReturnSpecifiedArgumentsInRunnableDescriptorAttribute_WhenOneRunnableIsPassed() { // Act + Arrange var result = underTest.GetCommandDescriptors().SingleOrDefault(); // Assert Assert.That(result, Is.Not.Null); var myParameterDescriptor = new ArgumentDescriptor() { ArgumentName = "my-parameter", ArgumentType = typeof (String), DefaultValue = null, IsOptional = true, Position = 0 }; var anotherParameterDescriptor = new ArgumentDescriptor { ArgumentName = "another-parameter", ArgumentType = typeof (Int32), DefaultValue = null, IsOptional = true, Position = 1 }; var parameters = Array(myParameterDescriptor, anotherParameterDescriptor); Assert.That(result.Arguments, Is.EquivalentTo(parameters)); }
public void Parser_Verbs_Multiples() { CommandLineParser parser; IEnumerable<ArgumentInstance> instances; TestLogger logger; ArgumentDescriptor verb1 = new ArgumentDescriptor("v1", new string[] { "noMult" }, false /* required */, "noMult desc", false /* no multiples */, true); ArgumentDescriptor verb2 = new ArgumentDescriptor("v2", new string[] { "multOk" }, false /* required */, "multOk desc", true /* allow multiples */, true); parser = new CommandLineParser(new ArgumentDescriptor[] { verb1, verb2 }, true /* allow unrecognised */ ); // 1. Allowed multiples logger = new TestLogger(); instances = CheckProcessingSucceeds(parser, logger, "multOk", "multOk"); AssertExpectedInstancesCount(2, instances); // 2. Disallowed multiples logger = CheckProcessingFails(parser, new string[] { "noMult", "noMult" }); logger.AssertSingleErrorExists("noMult"); logger.AssertErrorsLogged(1); }
private async Task HandleInternalAsync(HandlerDescriptor handler, ArgumentDescriptor argument, object commandPayload, bool isPersistenceUsed, bool isEnvelopeDelayUsed) { try { bool hasContextHandler = handler.IsContext; bool hasEnvelopeHandler = hasContextHandler || handler.IsEnvelope; object payload = commandPayload; object context = null; Envelope envelope = null; ICommand commandWithKey = null; if (argument.IsContext) { // If passed argument is context, throw. log.Fatal("Passed in a context object."); throw Ensure.Exception.NotSupported("PersistentCommandDispatcher doesn't support passing in a command handler context."); } else { // If passed argument is not context, try to create it if needed. if (argument.IsEnvelope) { // If passed argument is envelope, extract payload. envelope = (Envelope)payload; payload = envelope.Body; } else { commandWithKey = payload as ICommand; hasEnvelopeHandler = hasEnvelopeHandler || commandWithKey != null; // If passed argument is not envelope, try to create it if needed. if (hasEnvelopeHandler) { envelope = EnvelopeFactory.Create(payload, argument.ArgumentType); } } if (hasContextHandler) { log.Fatal("Context handler not supported."); throw Ensure.Exception.NotSupported("PersistentCommandDispatcher doesn't support command handler context."); } } if (commandWithKey == null) { commandWithKey = payload as ICommand; } log.Info(commandWithKey, "Got a command."); log.Info(commandWithKey, "Execution on the handler '{0}'.", handler); // If we have command with the key, serialize it for persisten delivery. if (store != null && isPersistenceUsed && commandWithKey != null) { string serializedEnvelope = await formatter.SerializeAsync(envelope); store.Save(new CommandModel(commandWithKey.Key, serializedEnvelope)); log.Debug(commandWithKey, "Saved to the store."); } // If isEnvelopeDelayUsed, try to schedule the execution. // If succeeded, return. if (isEnvelopeDelayUsed && TrySchedule(envelope, handler, argument)) { return; } // Distribute the execution. DistributeExecution(payload, context, envelope, commandWithKey, handler); } catch (Exception e) { DispatcherExceptionHandlers.Handle(e); } }
public void Parser_Verbs_Required() { CommandLineParser parser; IEnumerable<ArgumentInstance> instances; TestLogger logger; string[] emptyArgs = new string[] { }; string[] matchingPrefixArgs = new string[] { "AAAa" }; // 1a. Argument is required but is missing -> error ArgumentDescriptor d1 = new ArgumentDescriptor("id", new string[] { "AAA" }, true /* required */, "desc1", false /* no multiples */, true); parser = new CommandLineParser(new ArgumentDescriptor[] { d1 }, false); logger = CheckProcessingFails(parser, emptyArgs); logger.AssertSingleErrorExists("desc1"); logger.AssertErrorsLogged(1); // 1b. Argument is required but is only partial match -> missing -> error2 logger = CheckProcessingFails(parser, matchingPrefixArgs); logger.AssertSingleErrorExists("desc1"); // missing arg logger.AssertSingleErrorExists("AAAa"); // unrecognized since not exact match logger.AssertErrorsLogged(2); // 2a. Argument is not required, missing -> ok d1 = new ArgumentDescriptor("id", new string[] { "AAA" }, false /* not required */, "desc1", false /* no multiples */, true); parser = new CommandLineParser(new ArgumentDescriptor[] { d1 }, true); logger = new TestLogger(); instances = CheckProcessingSucceeds(parser, logger, emptyArgs); AssertExpectedInstancesCount(0, instances); // 2b. Argument is not required, partial -> missing -> ok logger = new TestLogger(); instances = CheckProcessingSucceeds(parser, logger, matchingPrefixArgs); AssertExpectedInstancesCount(0, instances); }
protected override string Generate(ArgumentDescriptor descriptor) { return($"ctx.{nameof(IResolverContext.ObjectType)}"); }
public void Parser_OverlappingVerbsAndPrefixes() { // Tests handling of verbs and non-verbs that start with the same values CommandLineParser parser; IEnumerable<ArgumentInstance> instances; TestLogger logger; ArgumentDescriptor verb1 = new ArgumentDescriptor("v1", new string[] { "X" }, false /* not required */, "verb1 desc", false /* no multiples */, true); ArgumentDescriptor prefix1 = new ArgumentDescriptor("p1", new string[] { "XX" }, false /* not required */, "prefix1 desc", false /* no multiples */, false); ArgumentDescriptor verb2 = new ArgumentDescriptor("v2", new string[] { "XXX" }, false /* not required */, "verb2 desc", false /* no multiples */, true); ArgumentDescriptor prefix2 = new ArgumentDescriptor("p2", new string[] { "XXXX" }, false /* not required */, "prefix2 desc", false /* no multiples */, false); // NOTE: this test only works because the descriptors are supplied to parser ordered // by decreasing prefix length parser = new CommandLineParser(new ArgumentDescriptor[] { prefix2, verb2, prefix1, verb1 }, true /* allow unrecognised */); // 1. Exact match -> matched logger = new TestLogger(); instances = CheckProcessingSucceeds(parser, logger, "X", // verb 1 - exact match "XXAAA", // prefix 1 - has value A, "XXX", // verb 2 - exact match, "XXXXB" // prefix 2 - has value B, ); AssertExpectedValue("v1", "", instances); AssertExpectedValue("p1", "AAA", instances); AssertExpectedValue("v2", "", instances); AssertExpectedValue("p2", "B", instances); }