PageRenderTime 3703ms CodeModel.GetById 34ms RepoModel.GetById 10ms app.codeStats 0ms

/src/DotConsole.Tests/v20/TrunkMonkey.cs

https://github.com/jpoehls/dotconsole
C# | 312 lines | 205 code | 46 blank | 61 comment | 20 complexity | 2525a7294acf29be838eb9169fae944c MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel.Composition;
  4. using System.ComponentModel.Composition.Hosting;
  5. using System.ComponentModel.DataAnnotations;
  6. using System.Linq;
  7. using System.Reflection;
  8. using System.Text;
  9. using Xunit;
  10. namespace DotConsole.Tests.v20
  11. {
  12. // dnm.exe --ConfigFile "value here" --Environment LOCAL --ResetDatabase --WarnOnHashChange
  13. // dnm.exe -rw --ConfigFile "value here" --Environment LOCAL
  14. // dnm.exe -rwc "value here" --Environment LOCAL
  15. // dnm.exe "value here" DEV -rw
  16. // dnm.exe LOCAL
  17. // ConfigFile - Position: 1
  18. // Environment - Position: 2
  19. // ResetDatabase
  20. public class RawArgSet : Dictionary<string, List<string>>
  21. {
  22. public List<string> AnonymousValues { get; private set; }
  23. public RawArgSet()
  24. {
  25. AnonymousValues = new List<string>();
  26. }
  27. public static RawArgSet Parse(IEnumerable<string> args)
  28. {
  29. var set = new RawArgSet();
  30. string lastKey = null;
  31. foreach (var cmdLine in args)
  32. {
  33. if (cmdLine.StartsWith("--"))
  34. {
  35. lastKey = cmdLine.Substring(2).ToLowerInvariant();
  36. if (!set.ContainsKey(lastKey))
  37. set.Add(lastKey, new List<string>());
  38. }
  39. else if (cmdLine.StartsWith("-"))
  40. {
  41. foreach (var c in cmdLine.Substring(1))
  42. {
  43. lastKey = c.ToString();
  44. if (!set.ContainsKey(lastKey))
  45. set.Add(lastKey, new List<string>());
  46. }
  47. }
  48. else
  49. {
  50. if (lastKey == null)
  51. {
  52. set.AnonymousValues.Add(cmdLine);
  53. }
  54. else
  55. {
  56. set[lastKey].Add(cmdLine);
  57. }
  58. }
  59. }
  60. return set;
  61. }
  62. }
  63. public class CommandLocator
  64. {
  65. [ImportMany(typeof(ICommand))]
  66. protected List<Lazy<ICommand, ICommandMetadata>> Commands { get; set; }
  67. public CommandLocator()
  68. {
  69. var catalog = new AggregateCatalog();
  70. //catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
  71. catalog.Catalogs.Add(new TypeCatalog(typeof(InvokeCommand)));
  72. var container = new CompositionContainer(catalog);
  73. container.ComposeParts(this);
  74. }
  75. public ICommand GetDefaultCommand()
  76. {
  77. var found = Commands.FirstOrDefault(x => x.Metadata.Default);
  78. if (found != null)
  79. {
  80. return found.Value;
  81. }
  82. return null;
  83. }
  84. public ICommand GetCommandByName(string commandName)
  85. {
  86. // try to match the command name in the metadata first
  87. ICommand cmd = Commands
  88. .Where(x => x.Metadata.Name == commandName)
  89. .Select(x => x.Value)
  90. .FirstOrDefault();
  91. // then try to match based on the command's type name
  92. if (cmd == null)
  93. cmd = Commands
  94. .Select(x => new
  95. {
  96. x.Value,
  97. TypeName = x.Value.GetType().Name
  98. })
  99. .Where(x => x.TypeName == commandName || x.TypeName == commandName + "Command")
  100. .Select(x => x.Value)
  101. .FirstOrDefault();
  102. return cmd;
  103. }
  104. }
  105. public class CommandFiller
  106. {
  107. public void Fill(ICommand cmd, RawArgSet args)
  108. {
  109. }
  110. }
  111. public class CommandValidator
  112. {
  113. public void Validate(ICommand cmd)
  114. {
  115. }
  116. }
  117. public static class Commander
  118. {
  119. public static void Run()
  120. {
  121. var args = Environment.GetCommandLineArgs().Skip(1);
  122. var set = RawArgSet.Parse(args);
  123. var cmd = (new CommandLocator()).GetCommandByName(set.AnonymousValues[0]);
  124. }
  125. }
  126. public class RawArg
  127. {
  128. [Fact]
  129. public void Tests()
  130. {
  131. // string[] line = new string[]
  132. // {
  133. // "abcdef",
  134. // "-rw",
  135. // "--ConfigFile",
  136. // "\"value here\"",
  137. // "--Environment",
  138. // "LOCAL",
  139. // "--ConfigFile",
  140. // "another value"
  141. // };
  142. //
  143. // var results = Parse(line);
  144. // PrintResults(results);
  145. //
  146. // Assert.True(results.ContainsKey("r"), "No 'r' key.");
  147. // Assert.True(results.ContainsKey("w"), "No 'w' key.");
  148. // Assert.True(results.ContainsKey("ConfigFile"), "No 'ConfigFile' key.");
  149. // Assert.True(results.ContainsKey("Environment"), "No 'Environment' key.");
  150. //
  151. // Assert.Empty(results["r"]);
  152. // Assert.Empty(results["w"]);
  153. // Assert.True(results["ConfigFile"].Count == 2, "No 'ConfigFile' value.");
  154. // Assert.Equal("\"value here\"", results["ConfigFile"][0]);
  155. // Assert.Equal("another value", results["ConfigFile"][1]);
  156. // Assert.True(results["Environment"].Count == 1, "No 'Environment' value.");
  157. // Assert.Equal("LOCAL", results["Environment"][0]);
  158. }
  159. [Fact]
  160. public void Should_find_command_by_name()
  161. {
  162. // var cmd = GetCommand(new Dictionary<string, List<string>>()
  163. // {
  164. // {
  165. // string.Empty, new List<string>()
  166. // {
  167. // "Invoke"
  168. // }
  169. // }
  170. // });
  171. // Assert.IsType<InvokeCommand>(cmd);
  172. }
  173. private void PrintResults(Dictionary<string, List<string>> results)
  174. {
  175. foreach (var key in results.Keys)
  176. {
  177. if (key.Length == 0)
  178. Console.Write("ANONYMOUS");
  179. else if (key.Length == 1)
  180. Console.Write("-");
  181. else
  182. Console.Write("--");
  183. Console.WriteLine(key);
  184. foreach (var value in results[key])
  185. {
  186. Console.WriteLine(" " + value);
  187. }
  188. }
  189. }
  190. }
  191. public class ArgumentAttribute : Attribute
  192. {
  193. public ArgumentAttribute(string desc)
  194. {
  195. Description = desc;
  196. Position = -1;
  197. }
  198. /// <summary>
  199. /// Long argument name.
  200. /// </summary>
  201. public string Name { get; set; }
  202. /// <summary>
  203. /// Abbreviated name that is friendly for the command line.
  204. /// </summary>
  205. public string ShortName { get; set; }
  206. /// <summary>
  207. /// Used in the syntax help text as the placeholder for the value.
  208. /// </summary>
  209. public string ValueName { get; set; }
  210. /// <summary>
  211. /// If the argument is not passed in with a name then it will
  212. /// be matched based on its position in the array of unnamed arguments.
  213. /// </summary>
  214. public int Position { get; set; }
  215. public string Description { get; set; }
  216. }
  217. public interface ICommandMetadata
  218. {
  219. string Name { get; }
  220. bool Default { get; }
  221. string Description { get; }
  222. }
  223. [MetadataAttribute]
  224. [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
  225. public class CommandAttribute : ExportAttribute, ICommandMetadata
  226. {
  227. public string Name { get; set; }
  228. public bool Default { get; set; }
  229. public string Description { get; set; }
  230. public CommandAttribute()
  231. : base(typeof(ICommand))
  232. { }
  233. }
  234. public interface ICommand
  235. {
  236. void Run();
  237. }
  238. [Command(Default = true)]
  239. public class InvokeCommand : ICommand
  240. {
  241. [Required()]
  242. [Argument("Name of the person running the sample.",
  243. Position = 1,
  244. ValueName = "persons_name")]
  245. public string ConfigFile { get; set; }
  246. public void Run()
  247. {
  248. }
  249. }
  250. public class TrunkMonkey
  251. {
  252. [ImportMany(typeof(ICommand))]
  253. public IList<Lazy<ICommand, ICommandMetadata>> Commands { get; set; }
  254. public TrunkMonkey()
  255. {
  256. var catalog = new AggregateCatalog();
  257. catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
  258. var container = new CompositionContainer(catalog);
  259. container.ComposeParts(this);
  260. }
  261. public Type GetCommandType(IEnumerable<string> args)
  262. {
  263. return null;
  264. }
  265. }
  266. }