//
using System;
+using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using Mono.Options;
#endif
+using Cadenza.Collections.Tests;
+
using NUnit.Framework;
#if NDESK_OPTIONS
public override string ToString () {return s;}
}
+ class TestArgumentSource : ArgumentSource, IEnumerable {
+ string[] names;
+ string desc;
+
+ public TestArgumentSource (string[] names, string desc)
+ {
+ this.names = names;
+ this.desc = desc;
+ }
+
+ Dictionary<string, string[]> args = new Dictionary<string, string[]>();
+
+ public void Add (string key, params string[] values)
+ {
+ args.Add (key, values);
+ }
+
+ public override string[] GetNames ()
+ {
+ return names;
+ }
+
+ public override string Description {
+ get {return desc;}
+ }
+
+ public override bool GetArguments (string value, out IEnumerable<string> replacement)
+ {
+ replacement = null;
+
+ string[] values;
+ if (args.TryGetValue (value, out values)) {
+ replacement = values;
+ return true;
+ }
+
+ return false;
+ }
+
+
+ IEnumerator IEnumerable.GetEnumerator ()
+ {
+ return args.GetEnumerator ();
+ }
+ }
+
[TestFixture]
- public class OptionSetTest {
+ public class OptionSetTest : ListContract<Option> {
+
+ protected override ICollection<Option> CreateCollection (IEnumerable<Option> values)
+ {
+ OptionSet set = new OptionSet();
+ foreach (Option value in values)
+ set.Add (value);
+ return set;
+ }
+
+ protected override Option CreateValueA ()
+ {
+ return new CustomOption ("A", null, 0, null);
+ }
+
+ protected override Option CreateValueB ()
+ {
+ return new CustomOption ("B", null, 0, null);
+ }
+
+ protected override Option CreateValueC ()
+ {
+ return new CustomOption ("C", null, 0, null);
+ }
+
static IEnumerable<string> _ (params string[] a)
{
return a;
[Test]
public void BundledValues ()
+ {
+ BundledValues (_("-DNAME", "-D", "NAME2", "-Debug", "-L/foo", "-L", "/bar", "-EDNAME3"));
+ BundledValues (_("@s1", "-D", "@s2", "-L/foo", "@s4"));
+ }
+
+ public void BundledValues (IEnumerable<string> args)
{
var defines = new List<string> ();
var libs = new List<string> ();
{ "L|library:", v => libs.Add (v) },
{ "Debug", v => debug = v != null },
{ "E", v => { /* ignore */ } },
+ new TestArgumentSource (null, null) {
+ { "@s1", "-DNAME" },
+ { "@s2", "NAME2", "@s3" },
+ { "@s3", "-Debug" },
+ { "@s4", "-L", "/bar", "-EDNAME3" },
+ },
};
- p.Parse (_("-DNAME", "-D", "NAME2", "-Debug", "-L/foo", "-L", "/bar", "-EDNAME3"));
+ p.Parse (args);
Assert.AreEqual (defines.Count, 3);
Assert.AreEqual (defines [0], "NAME");
Assert.AreEqual (defines [1], "NAME2");
Assert.AreEqual (libs [1], null);
Utils.AssertException (typeof(OptionException),
- "Cannot bundle unregistered option '-V'.",
+ "Cannot use unregistered option 'V' in bundle '-EVALUENOTSUP'.",
p, v => { v.Parse (_("-EVALUENOTSUP")); });
}
[Test]
public void RequiredValues ()
+ {
+ RequiredValues (_("a", "-a", "s", "-n=42", "n"));
+ RequiredValues (_("@s1", "s", "@s2", "n"));
+ }
+
+ void RequiredValues (IEnumerable<string> args)
{
string a = null;
int n = 0;
OptionSet p = new OptionSet () {
{ "a=", v => a = v },
{ "n=", (int v) => n = v },
+ new TestArgumentSource (null, null) {
+ { "@s1", "a", "-a" },
+ { "@s2", "-n=42" },
+ },
};
- List<string> extra = p.Parse (_("a", "-a", "s", "-n=42", "n"));
+ List<string> extra = p.Parse (args);
Assert.AreEqual (extra.Count, 2);
Assert.AreEqual (extra [0], "a");
Assert.AreEqual (extra [1], "n");
[Test]
public void CombinationPlatter ()
+ {
+ CombinationPlatter (new string[]{"foo", "-v", "-a=42", "/b-",
+ "-a", "64", "bar", "--f", "B", "/h", "-?", "--help", "-v"});
+ CombinationPlatter (_("@s1", "-a=42", "@s3", "-a", "64", "bar", "@s4"));
+ }
+
+ void CombinationPlatter (IEnumerable<string> args)
{
int a = -1, b = -1;
string av = null, bv = null;
case "?": help |= 0x2; break;
case "help": help |= 0x4; break;
} } },
+ new TestArgumentSource (null, null) {
+ { "@s1", "foo", "-v", "@s2" },
+ { "@s2" },
+ { "@s3", "/b-" },
+ { "@s4", "--f", "B", "/h", "-?", "--help", "-v" },
+ },
};
- List<string> e = p.Parse (new string[]{"foo", "-v", "-a=42", "/b-",
- "-a", "64", "bar", "--f", "B", "/h", "-?", "--help", "-v"});
+ List<string> e = p.Parse (args);
Assert.AreEqual (e.Count, 2);
Assert.AreEqual (e[0], "foo");
Assert.AreEqual (a, "-b");
Utils.AssertException (typeof(ArgumentNullException),
"Argument cannot be null.\nParameter name: option",
- p, v => { v.Add (null); });
+ p, v => { v.Add ((Option) null); });
+ Utils.AssertException (typeof(ArgumentNullException),
+ "Argument cannot be null.\nParameter name: header",
+ p, v => { v.Add ((string) null); });
// bad type
Utils.AssertException (typeof(OptionException),
// try to bundle with an option requiring a value
Utils.AssertException (typeof(OptionException),
- "Cannot bundle unregistered option '-z'.",
+ "Cannot use unregistered option 'z' in bundle '-cz'.",
p, v => { v.Parse (_("-cz", "extra")); });
Utils.AssertException (typeof(ArgumentNullException),
public void WriteOptionDescriptions ()
{
var p = new OptionSet () {
+ "\n:Category 1:",
+ { "hidden", "hidden option, invisible in help", v => {}, true },
+ { "hidden2=", "hidden option, invisible in help", (k, v) => {}, true },
{ "p|indicator-style=", "append / indicator to directories", v => {} },
{ "color:", "controls color info", v => {} },
{ "color2:", "set {color}", v => {} },
" item 2",
v => {} },
{ "long-desc2",
- "IWantThisDescriptionToBreakInsideAWordGeneratingAutoWordHyphenation.",
+ "IWantThisDescriptionToBreakInsideAWordGeneratingAutoWordHyphenation. ",
v => {} },
{ "long-desc3",
"OnlyOnePeriod.AndNoWhitespaceShouldBeSupportedEvenWithLongDescriptions",
{ "long-desc5",
"Lots of spaces in the middle - . - . - . - . - . - . - . - and more until the end.",
v => {} },
+ "",
+ "==This is a really long category name which will involve line wrapping, just because...==",
{ "o|out=",
"The {DIRECTORY} to place the generated files and directories.\n\n" +
"If not specified, defaults to\n`dirname FILE`/cache/`basename FILE .tree`.",
v => {} },
+ "",
+ "Category 3:",
{ "h|?|help", "show help text", v => {} },
{ "version", "output version information and exit", v => {} },
{ "<>", v => {} },
+ new TestArgumentSource (new[]{"@s1", "@s2"}, "Read Response File for More Options"),
};
StringWriter expected = new StringWriter ();
+ expected.WriteLine ("");
+ expected.WriteLine (":Category 1:");
expected.WriteLine (" -p, --indicator-style=VALUE");
expected.WriteLine (" append / indicator to directories");
expected.WriteLine (" --color[=VALUE] controls color info");
expected.WriteLine (" 2 3 4 5 and more until the end.");
expected.WriteLine (" --long-desc5 Lots of spaces in the middle - . - . - . - . - . -");
expected.WriteLine (" . - . - and more until the end.");
+ expected.WriteLine ("");
+ expected.WriteLine ("==This is a really long category name which will involve line wrapping, just");
+ expected.WriteLine ("because...==");
expected.WriteLine (" -o, --out=DIRECTORY The DIRECTORY to place the generated files and");
expected.WriteLine (" directories.");
expected.WriteLine (" ");
expected.WriteLine (" If not specified, defaults to");
expected.WriteLine (" `dirname FILE`/cache/`basename FILE .tree`.");
+ expected.WriteLine ("");
+ expected.WriteLine ("Category 3:");
expected.WriteLine (" -h, -?, --help show help text");
expected.WriteLine (" --version output version information and exit");
+ expected.WriteLine (" @s1, @s2 Read Response File for More Options");
StringWriter actual = new StringWriter ();
p.WriteOptionDescriptions (actual);
[Test]
public void OptionBundling ()
+ {
+ OptionBundling (_ ("-abcf", "foo", "bar"));
+ OptionBundling (_ ("@s1", "foo", "bar"));
+ }
+
+ void OptionBundling (IEnumerable<string> args)
{
string a, b, c, f;
a = b = c = f = null;
{ "b", v => b = "b" },
{ "c", v => c = "c" },
{ "f=", v => f = v },
+ new TestArgumentSource (null, null) {
+ { "@s1", "-abcf" },
+ },
};
- List<string> extra = p.Parse (_ ("-abcf", "foo", "bar"));
+ List<string> extra = p.Parse (args);
Assert.AreEqual (extra.Count, 1);
Assert.AreEqual (extra [0], "bar");
Assert.AreEqual (a, "a");
var p = new OptionSet () {
{ "a", v => {} },
{ "b", v => {} },
+ new TestArgumentSource (null, null) {
+ { "@s1", "-a", "-b" },
+ },
};
List<string> e = p.Parse (_ ("-a", "-b", "--", "-a", "-b"));
Assert.AreEqual (e.Count, 2);
Assert.AreEqual (e [0], "-a");
Assert.AreEqual (e [1], "-b");
+
+ e = p.Parse (_ ("@s1", "--", "@s1"));
+ Assert.AreEqual (e.Count, 1);
+ Assert.AreEqual (e [0], "@s1");
}
[Test]
{ "d={=>}{-->}", (k, v) => a.Add (k, v) },
{ "e={}", (k, v) => a.Add (k, v) },
{ "f=+/", (k, v) => a.Add (k, v) },
+ new TestArgumentSource (null, null) {
+ { "@s1", "-a", "A" },
+ { "@s2", @"C:\tmp", "-a" },
+ { "@s3", "C=D", @"-a=E=F:\tmp" },
+ { "@s4", "-a:G:H", "-aI=J" },
+ { "@s5", "-b", "1" },
+ { "@s6", "a", "-b" },
+ { "@s7", "2", "b" },
+ { "@s8", "-dA=>B", "-d" },
+ { "@s9", "C-->D", "-d:E" },
+ { "@s10", "F", "-d" },
+ { "@s11", "G", "H" },
+ { "@s12", "-dJ-->K" }
+ },
};
- p.Parse (_("-a", "A", "B", "-a", "C", "D", "-a=E=F", "-a:G:H", "-aI=J", "-b", "1", "a", "-b", "2", "b"));
- AssertDictionary (a,
- "A", "B",
- "C", "D",
- "E", "F",
- "G", "H",
- "I", "J");
- AssertDictionary (b,
- "1", "a",
- "2", "b");
+ p.Parse (_("-a", "A", @"C:\tmp", "-a", "C=D", @"-a=E=F:\tmp", "-a:G:H", "-aI=J", "-b", "1", "a", "-b", "2", "b"));
+ Action assert = () => {
+ AssertDictionary (a,
+ "A", @"C:\tmp",
+ "C", "D",
+ "E", @"F:\tmp",
+ "G", "H",
+ "I", "J");
+ AssertDictionary (b,
+ "1", "a",
+ "2", "b");
+ };
+ assert ();
+ a.Clear ();
+ b.Clear ();
+ p.Parse (_("@s1", "@s2", "@s3", "@s4", "@s5", "@s6", "@s7"));
+ assert ();
a.Clear ();
+ b.Clear ();
+
p.Parse (_("-c"));
Assert.AreEqual (a.Count, 0);
p.Parse (_("-c", "a"));
a.Clear ();
p.Parse (_("-dA=>B", "-d", "C-->D", "-d:E", "F", "-d", "G", "H", "-dJ-->K"));
- AssertDictionary (a,
- "A", "B",
- "C", "D",
- "E", "F",
- "G", "H",
- "J", "K");
+ assert = () => {
+ AssertDictionary (a,
+ "A", "B",
+ "C", "D",
+ "E", "F",
+ "G", "H",
+ "J", "K");
+ };
+ assert ();
+ a.Clear ();
+ p.Parse (_("@s8", "@s9", "@s10", "@s11", "@s12"));
+ assert ();
a.Clear ();
+
p.Parse (_("-eA=B", "-eC=D", "-eE", "F", "-e:G", "H"));
AssertDictionary (a,
"A=B", "-eC=D",
new CustomOption ("a==:", null, 2, v => a.Add (v [0], v [1])),
new CustomOption ("b==:", null, 3, v => b.Add (v [0], new string[]{v [1], v [2]})),
};
- p.Parse (_("-a=b=c", "-a=d", "e", "-a:f=g", "-a:h:i", "-a", "j=k", "-a", "l:m"));
+ p.Parse (_(@"-a=b=C:\tmp", "-a=d", @"C:\e", @"-a:f=C:\g", @"-a:h:C:\i", "-a", @"j=C:\k", "-a", @"l:C:\m"));
Assert.AreEqual (a.Count, 6);
- Assert.AreEqual (a ["b"], "c");
- Assert.AreEqual (a ["d"], "e");
- Assert.AreEqual (a ["f"], "g");
- Assert.AreEqual (a ["h"], "i");
- Assert.AreEqual (a ["j"], "k");
- Assert.AreEqual (a ["l"], "m");
+ Assert.AreEqual (a ["b"], @"C:\tmp");
+ Assert.AreEqual (a ["d"], @"C:\e");
+ Assert.AreEqual (a ["f"], @"C:\g");
+ Assert.AreEqual (a ["h"], @"C:\i");
+ Assert.AreEqual (a ["j"], @"C:\k");
+ Assert.AreEqual (a ["l"], @"C:\m");
Utils.AssertException (typeof(OptionException),
"Missing required value for option '-a'.",
p, v => {v.Parse (_("-a=b"));});
- p.Parse (_("-b", "a", "b", "c", "-b:d:e:f", "-b=g=h:i", "-b:j=k:l"));
+ p.Parse (_("-b", "a", "b", @"C:\tmp", @"-b:d:e:F:\tmp", @"-b=g=h:i:\tmp", @"-b:j=k:l:\tmp"));
Assert.AreEqual (b.Count, 4);
Assert.AreEqual (b ["a"][0], "b");
- Assert.AreEqual (b ["a"][1], "c");
+ Assert.AreEqual (b ["a"][1], @"C:\tmp");
Assert.AreEqual (b ["d"][0], "e");
- Assert.AreEqual (b ["d"][1], "f");
+ Assert.AreEqual (b ["d"][1], @"F:\tmp");
Assert.AreEqual (b ["g"][0], "h");
- Assert.AreEqual (b ["g"][1], "i");
+ Assert.AreEqual (b ["g"][1], @"i:\tmp");
Assert.AreEqual (b ["j"][0], "k");
- Assert.AreEqual (b ["j"][1], "l");
+ Assert.AreEqual (b ["j"][1], @"l:\tmp");
}
[Test]
Assert.AreEqual (formats ["baz"][0], "e");
Assert.AreEqual (formats ["baz"][1], "f");
}
+
+ [Test]
+ public void ReportInvalidDuplication ()
+ {
+ int verbosity = 0;
+ var p = new OptionSet () {
+ { "v", v => verbosity = v != null ? verbosity + 1 : verbosity },
+ };
+ try {
+ p.Parse (new []{"-v-v-v"});
+ Assert.Fail ("Should not be reached.");
+ } catch (OptionException e) {
+ Assert.AreEqual (null, e.OptionName);
+ Assert.AreEqual ("Cannot use unregistered option '-' in bundle '-v-v-v'.", e.Message);
+ }
+ }
}
}