123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536 |
- /*
- Based of off docopt.py: https://github.com/docopt/docopt
- Licensed under terms of MIT license (see LICENSE-MIT)
- Copyright (c) 2013 Keith Batten, kbatten@gmail.com
- */
- package docopt
- import (
- "bytes"
- "encoding/json"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "reflect"
- "regexp"
- "strings"
- "testing"
- )
- func TestPatternFlat(t *testing.T) {
- q := patternList{
- newArgument("N", nil),
- newOption("-a", "", 0, false),
- newArgument("M", nil)}
- p, err := newRequired(
- newOneOrMore(newArgument("N", nil)),
- newOption("-a", "", 0, false),
- newArgument("M", nil)).flat(patternDefault)
- if reflect.DeepEqual(p, q) != true {
- t.Error(err)
- }
- q = patternList{newOptionsShortcut()}
- p, err = newRequired(
- newOptional(newOptionsShortcut()),
- newOptional(newOption("-a", "", 0, false))).flat(patternOptionSSHORTCUT)
- if reflect.DeepEqual(p, q) != true {
- t.Error(err)
- }
- return
- }
- func TestOption(t *testing.T) {
- if !parseOption("-h").eq(newOption("-h", "", 0, false)) {
- t.Fail()
- }
- if !parseOption("--help").eq(newOption("", "--help", 0, false)) {
- t.Fail()
- }
- if !parseOption("-h --help").eq(newOption("-h", "--help", 0, false)) {
- t.Fail()
- }
- if !parseOption("-h, --help").eq(newOption("-h", "--help", 0, false)) {
- t.Fail()
- }
- if !parseOption("-h TOPIC").eq(newOption("-h", "", 1, false)) {
- t.Fail()
- }
- if !parseOption("--help TOPIC").eq(newOption("", "--help", 1, false)) {
- t.Fail()
- }
- if !parseOption("-h TOPIC --help TOPIC").eq(newOption("-h", "--help", 1, false)) {
- t.Fail()
- }
- if !parseOption("-h TOPIC, --help TOPIC").eq(newOption("-h", "--help", 1, false)) {
- t.Fail()
- }
- if !parseOption("-h TOPIC, --help=TOPIC").eq(newOption("-h", "--help", 1, false)) {
- t.Fail()
- }
- if !parseOption("-h Description...").eq(newOption("-h", "", 0, false)) {
- t.Fail()
- }
- if !parseOption("-h --help Description...").eq(newOption("-h", "--help", 0, false)) {
- t.Fail()
- }
- if !parseOption("-h TOPIC Description...").eq(newOption("-h", "", 1, false)) {
- t.Fail()
- }
- if !parseOption(" -h").eq(newOption("-h", "", 0, false)) {
- t.Fail()
- }
- if !parseOption("-h TOPIC Description... [default: 2]").eq(newOption("-h", "", 1, "2")) {
- t.Fail()
- }
- if !parseOption("-h TOPIC Descripton... [default: topic-1]").eq(newOption("-h", "", 1, "topic-1")) {
- t.Fail()
- }
- if !parseOption("--help=TOPIC ... [default: 3.14]").eq(newOption("", "--help", 1, "3.14")) {
- t.Fail()
- }
- if !parseOption("-h, --help=DIR ... [default: ./]").eq(newOption("-h", "--help", 1, "./")) {
- t.Fail()
- }
- if !parseOption("-h TOPIC Descripton... [dEfAuLt: 2]").eq(newOption("-h", "", 1, "2")) {
- t.Fail()
- }
- return
- }
- func TestOptionName(t *testing.T) {
- if newOption("-h", "", 0, false).name != "-h" {
- t.Fail()
- }
- if newOption("-h", "--help", 0, false).name != "--help" {
- t.Fail()
- }
- if newOption("", "--help", 0, false).name != "--help" {
- t.Fail()
- }
- return
- }
- func TestCommands(t *testing.T) {
- if v, err := Parse("Usage: prog add", []string{"add"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"add": true}) != true {
- t.Error(err)
- }
- if v, err := Parse("Usage: prog [add]", []string{}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"add": false}) != true {
- t.Error(err)
- }
- if v, err := Parse("Usage: prog [add]", []string{"add"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"add": true}) != true {
- t.Error(err)
- }
- if v, err := Parse("Usage: prog (add|rm)", []string{"add"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"add": true, "rm": false}) != true {
- t.Error(err)
- }
- if v, err := Parse("Usage: prog (add|rm)", []string{"rm"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"add": false, "rm": true}) != true {
- t.Error(err)
- }
- if v, err := Parse("Usage: prog a b", []string{"a", "b"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"a": true, "b": true}) != true {
- t.Error(err)
- }
- _, err := Parse("Usage: prog a b", []string{"b", "a"}, true, "", false, false)
- if _, ok := err.(*UserError); !ok {
- t.Error(err)
- }
- return
- }
- func TestFormalUsage(t *testing.T) {
- doc := `
- Usage: prog [-hv] ARG
- prog N M
- prog is a program`
- usage := parseSection("usage:", doc)[0]
- if usage != "Usage: prog [-hv] ARG\n prog N M" {
- t.FailNow()
- }
- formal, err := formalUsage(usage)
- if err != nil {
- t.Fatal(err)
- }
- if formal != "( [-hv] ARG ) | ( N M )" {
- t.Fail()
- }
- return
- }
- func TestParseArgv(t *testing.T) {
- o := patternList{
- newOption("-h", "", 0, false),
- newOption("-v", "--verbose", 0, false),
- newOption("-f", "--file", 1, false),
- }
- p, err := parseArgv(tokenListFromString(""), &o, false)
- q := patternList{}
- if reflect.DeepEqual(p, q) != true {
- t.Error(err)
- }
- p, err = parseArgv(tokenListFromString("-h"), &o, false)
- q = patternList{newOption("-h", "", 0, true)}
- if reflect.DeepEqual(p, q) != true {
- t.Error(err)
- }
- p, err = parseArgv(tokenListFromString("-h --verbose"), &o, false)
- q = patternList{
- newOption("-h", "", 0, true),
- newOption("-v", "--verbose", 0, true),
- }
- if reflect.DeepEqual(p, q) != true {
- t.Error(err)
- }
- p, err = parseArgv(tokenListFromString("-h --file f.txt"), &o, false)
- q = patternList{
- newOption("-h", "", 0, true),
- newOption("-f", "--file", 1, "f.txt"),
- }
- if reflect.DeepEqual(p, q) != true {
- t.Error(err)
- }
- p, err = parseArgv(tokenListFromString("-h --file f.txt arg"), &o, false)
- q = patternList{
- newOption("-h", "", 0, true),
- newOption("-f", "--file", 1, "f.txt"),
- newArgument("", "arg"),
- }
- if reflect.DeepEqual(p, q) != true {
- t.Error(err)
- }
- p, err = parseArgv(tokenListFromString("-h --file f.txt arg arg2"), &o, false)
- q = patternList{
- newOption("-h", "", 0, true),
- newOption("-f", "--file", 1, "f.txt"),
- newArgument("", "arg"),
- newArgument("", "arg2"),
- }
- if reflect.DeepEqual(p, q) != true {
- t.Error(err)
- }
- p, err = parseArgv(tokenListFromString("-h arg -- -v"), &o, false)
- q = patternList{
- newOption("-h", "", 0, true),
- newArgument("", "arg"),
- newArgument("", "--"),
- newArgument("", "-v"),
- }
- if reflect.DeepEqual(p, q) != true {
- t.Error(err)
- }
- }
- func TestParsePattern(t *testing.T) {
- o := patternList{
- newOption("-h", "", 0, false),
- newOption("-v", "--verbose", 0, false),
- newOption("-f", "--file", 1, false),
- }
- p, err := parsePattern("[ -h ]", &o)
- q := newRequired(newOptional(newOption("-h", "", 0, false)))
- if p.eq(q) != true {
- t.Error(err)
- }
- p, err = parsePattern("[ ARG ... ]", &o)
- q = newRequired(newOptional(
- newOneOrMore(
- newArgument("ARG", nil))))
- if p.eq(q) != true {
- t.Error(err)
- }
- p, err = parsePattern("[ -h | -v ]", &o)
- q = newRequired(
- newOptional(
- newEither(
- newOption("-h", "", 0, false),
- newOption("-v", "--verbose", 0, false))))
- if p.eq(q) != true {
- t.Error(err)
- }
- p, err = parsePattern("( -h | -v [ --file <f> ] )", &o)
- q = newRequired(
- newRequired(
- newEither(
- newOption("-h", "", 0, false),
- newRequired(
- newOption("-v", "--verbose", 0, false),
- newOptional(
- newOption("-f", "--file", 1, nil))))))
- if p.eq(q) != true {
- t.Error(err)
- }
- p, err = parsePattern("(-h|-v[--file=<f>]N...)", &o)
- q = newRequired(
- newRequired(
- newEither(
- newOption("-h", "", 0, false),
- newRequired(
- newOption("-v", "--verbose", 0, false),
- newOptional(
- newOption("-f", "--file", 1, nil)),
- newOneOrMore(
- newArgument("N", nil))))))
- if p.eq(q) != true {
- t.Error(err)
- }
- p, err = parsePattern("(N [M | (K | L)] | O P)", &o)
- q = newRequired(
- newRequired(
- newEither(
- newRequired(
- newArgument("N", nil),
- newOptional(
- newEither(
- newArgument("M", nil),
- newRequired(
- newEither(
- newArgument("K", nil),
- newArgument("L", nil)))))),
- newRequired(
- newArgument("O", nil),
- newArgument("P", nil)))))
- if p.eq(q) != true {
- t.Error(err)
- }
- p, err = parsePattern("[ -h ] [N]", &o)
- q = newRequired(
- newOptional(
- newOption("-h", "", 0, false)),
- newOptional(
- newArgument("N", nil)))
- if p.eq(q) != true {
- t.Error(err)
- }
- p, err = parsePattern("[options]", &o)
- q = newRequired(
- newOptional(
- newOptionsShortcut()))
- if p.eq(q) != true {
- t.Error(err)
- }
- p, err = parsePattern("[options] A", &o)
- q = newRequired(
- newOptional(
- newOptionsShortcut()),
- newArgument("A", nil))
- if p.eq(q) != true {
- t.Error(err)
- }
- p, err = parsePattern("-v [options]", &o)
- q = newRequired(
- newOption("-v", "--verbose", 0, false),
- newOptional(
- newOptionsShortcut()))
- if p.eq(q) != true {
- t.Error(err)
- }
- p, err = parsePattern("ADD", &o)
- q = newRequired(newArgument("ADD", nil))
- if p.eq(q) != true {
- t.Error(err)
- }
- p, err = parsePattern("<add>", &o)
- q = newRequired(newArgument("<add>", nil))
- if p.eq(q) != true {
- t.Error(err)
- }
- p, err = parsePattern("add", &o)
- q = newRequired(newCommand("add", false))
- if p.eq(q) != true {
- t.Error(err)
- }
- }
- func TestOptionMatch(t *testing.T) {
- v, w, x := newOption("-a", "", 0, false).match(
- &patternList{newOption("-a", "", 0, true)}, nil)
- y := patternList{newOption("-a", "", 0, true)}
- if v != true ||
- reflect.DeepEqual(*w, patternList{}) != true ||
- reflect.DeepEqual(*x, y) != true {
- t.Fail()
- }
- v, w, x = newOption("-a", "", 0, false).match(
- &patternList{newOption("-x", "", 0, false)}, nil)
- y = patternList{newOption("-x", "", 0, false)}
- if v != false ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, patternList{}) != true {
- t.Fail()
- }
- v, w, x = newOption("-a", "", 0, false).match(
- &patternList{newOption("-x", "", 0, false)}, nil)
- y = patternList{newOption("-x", "", 0, false)}
- if v != false ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, patternList{}) != true {
- t.Fail()
- }
- v, w, x = newOption("-a", "", 0, false).match(
- &patternList{newArgument("N", nil)}, nil)
- y = patternList{newArgument("N", nil)}
- if v != false ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, patternList{}) != true {
- t.Fail()
- }
- v, w, x = newOption("-a", "", 0, false).match(
- &patternList{
- newOption("-x", "", 0, false),
- newOption("-a", "", 0, false),
- newArgument("N", nil)}, nil)
- y = patternList{
- newOption("-x", "", 0, false),
- newArgument("N", nil)}
- z := patternList{newOption("-a", "", 0, false)}
- if v != true ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, z) != true {
- t.Fail()
- }
- v, w, x = newOption("-a", "", 0, false).match(
- &patternList{
- newOption("-a", "", 0, true),
- newOption("-a", "", 0, false)}, nil)
- y = patternList{newOption("-a", "", 0, false)}
- z = patternList{newOption("-a", "", 0, true)}
- if v != true ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, z) != true {
- t.Fail()
- }
- }
- func TestArgumentMatch(t *testing.T) {
- v, w, x := newArgument("N", nil).match(
- &patternList{newArgument("N", 9)}, nil)
- y := patternList{newArgument("N", 9)}
- if v != true ||
- reflect.DeepEqual(*w, patternList{}) != true ||
- reflect.DeepEqual(*x, y) != true {
- t.Fail()
- }
- v, w, x = newArgument("N", nil).match(
- &patternList{newOption("-x", "", 0, false)}, nil)
- y = patternList{newOption("-x", "", 0, false)}
- if v != false ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, patternList{}) != true {
- t.Fail()
- }
- v, w, x = newArgument("N", nil).match(
- &patternList{newOption("-x", "", 0, false),
- newOption("-a", "", 0, false),
- newArgument("", 5)}, nil)
- y = patternList{newOption("-x", "", 0, false),
- newOption("-a", "", 0, false)}
- z := patternList{newArgument("N", 5)}
- if v != true ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, z) != true {
- t.Fail()
- }
- v, w, x = newArgument("N", nil).match(
- &patternList{newArgument("", 9),
- newArgument("", 0)}, nil)
- y = patternList{newArgument("", 0)}
- z = patternList{newArgument("N", 9)}
- if v != true ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, z) != true {
- t.Fail()
- }
- }
- func TestCommandMatch(t *testing.T) {
- v, w, x := newCommand("c", false).match(
- &patternList{newArgument("", "c")}, nil)
- y := patternList{newCommand("c", true)}
- if v != true ||
- reflect.DeepEqual(*w, patternList{}) != true ||
- reflect.DeepEqual(*x, y) != true {
- t.Fail()
- }
- v, w, x = newCommand("c", false).match(
- &patternList{newOption("-x", "", 0, false)}, nil)
- y = patternList{newOption("-x", "", 0, false)}
- if v != false ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, patternList{}) != true {
- t.Fail()
- }
- v, w, x = newCommand("c", false).match(
- &patternList{
- newOption("-x", "", 0, false),
- newOption("-a", "", 0, false),
- newArgument("", "c")}, nil)
- y = patternList{newOption("-x", "", 0, false),
- newOption("-a", "", 0, false)}
- z := patternList{newCommand("c", true)}
- if v != true ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, z) != true {
- t.Fail()
- }
- v, w, x = newEither(
- newCommand("add", false),
- newCommand("rm", false)).match(
- &patternList{newArgument("", "rm")}, nil)
- y = patternList{newCommand("rm", true)}
- if v != true ||
- reflect.DeepEqual(*w, patternList{}) != true ||
- reflect.DeepEqual(*x, y) != true {
- t.Fail()
- }
- }
- func TestOptionalMatch(t *testing.T) {
- v, w, x := newOptional(newOption("-a", "", 0, false)).match(
- &patternList{newOption("-a", "", 0, false)}, nil)
- y := patternList{newOption("-a", "", 0, false)}
- if v != true ||
- reflect.DeepEqual(*w, patternList{}) != true ||
- reflect.DeepEqual(*x, y) != true {
- t.Fail()
- }
- v, w, x = newOptional(newOption("-a", "", 0, false)).match(
- &patternList{}, nil)
- if v != true ||
- reflect.DeepEqual(*w, patternList{}) != true ||
- reflect.DeepEqual(*x, patternList{}) != true {
- t.Fail()
- }
- v, w, x = newOptional(newOption("-a", "", 0, false)).match(
- &patternList{newOption("-x", "", 0, false)}, nil)
- y = patternList{newOption("-x", "", 0, false)}
- if v != true ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, patternList{}) != true {
- t.Fail()
- }
- v, w, x = newOptional(newOption("-a", "", 0, false),
- newOption("-b", "", 0, false)).match(
- &patternList{newOption("-a", "", 0, false)}, nil)
- y = patternList{newOption("-a", "", 0, false)}
- if v != true ||
- reflect.DeepEqual(*w, patternList{}) != true ||
- reflect.DeepEqual(*x, y) != true {
- t.Fail()
- }
- v, w, x = newOptional(newOption("-a", "", 0, false),
- newOption("-b", "", 0, false)).match(
- &patternList{newOption("-b", "", 0, false)}, nil)
- y = patternList{newOption("-b", "", 0, false)}
- if v != true ||
- reflect.DeepEqual(*w, patternList{}) != true ||
- reflect.DeepEqual(*x, y) != true {
- t.Fail()
- }
- v, w, x = newOptional(newOption("-a", "", 0, false),
- newOption("-b", "", 0, false)).match(
- &patternList{newOption("-x", "", 0, false)}, nil)
- y = patternList{newOption("-x", "", 0, false)}
- if v != true ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, patternList{}) != true {
- t.Fail()
- }
- v, w, x = newOptional(newArgument("N", nil)).match(
- &patternList{newArgument("", 9)}, nil)
- y = patternList{newArgument("N", 9)}
- if v != true ||
- reflect.DeepEqual(*w, patternList{}) != true ||
- reflect.DeepEqual(*x, y) != true {
- t.Fail()
- }
- v, w, x = newOptional(newOption("-a", "", 0, false),
- newOption("-b", "", 0, false)).match(
- &patternList{newOption("-b", "", 0, false),
- newOption("-x", "", 0, false),
- newOption("-a", "", 0, false)}, nil)
- y = patternList{newOption("-x", "", 0, false)}
- z := patternList{newOption("-a", "", 0, false),
- newOption("-b", "", 0, false)}
- if v != true ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, z) != true {
- t.Fail()
- }
- }
- func TestRequiredMatch(t *testing.T) {
- v, w, x := newRequired(newOption("-a", "", 0, false)).match(
- &patternList{newOption("-a", "", 0, false)}, nil)
- y := patternList{newOption("-a", "", 0, false)}
- if v != true ||
- reflect.DeepEqual(*w, patternList{}) != true ||
- reflect.DeepEqual(*x, y) != true {
- t.Fail()
- }
- v, w, x = newRequired(newOption("-a", "", 0, false)).match(&patternList{}, nil)
- if v != false ||
- reflect.DeepEqual(*w, patternList{}) != true ||
- reflect.DeepEqual(*x, patternList{}) != true {
- t.Fail()
- }
- v, w, x = newRequired(newOption("-a", "", 0, false)).match(
- &patternList{newOption("-x", "", 0, false)}, nil)
- y = patternList{newOption("-x", "", 0, false)}
- if v != false ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, patternList{}) != true {
- t.Fail()
- }
- v, w, x = newRequired(newOption("-a", "", 0, false),
- newOption("-b", "", 0, false)).match(
- &patternList{newOption("-a", "", 0, false)}, nil)
- y = patternList{newOption("-a", "", 0, false)}
- if v != false ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, patternList{}) != true {
- t.Fail()
- }
- }
- func TestEitherMatch(t *testing.T) {
- v, w, x := newEither(
- newOption("-a", "", 0, false),
- newOption("-b", "", 0, false)).match(
- &patternList{newOption("-a", "", 0, false)}, nil)
- y := patternList{newOption("-a", "", 0, false)}
- if v != true ||
- reflect.DeepEqual(*w, patternList{}) != true ||
- reflect.DeepEqual(*x, y) != true {
- t.Fail()
- }
- v, w, x = newEither(
- newOption("-a", "", 0, false),
- newOption("-b", "", 0, false)).match(&patternList{
- newOption("-a", "", 0, false),
- newOption("-b", "", 0, false)}, nil)
- y = patternList{newOption("-b", "", 0, false)}
- z := patternList{newOption("-a", "", 0, false)}
- if v != true ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, z) != true {
- t.Fail()
- }
- v, w, x = newEither(
- newOption("-a", "", 0, false),
- newOption("-b", "", 0, false)).match(&patternList{
- newOption("-x", "", 0, false)}, nil)
- y = patternList{newOption("-x", "", 0, false)}
- z = patternList{}
- if v != false ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, z) != true {
- t.Fail()
- }
- v, w, x = newEither(
- newOption("-a", "", 0, false),
- newOption("-b", "", 0, false),
- newOption("-c", "", 0, false)).match(&patternList{
- newOption("-x", "", 0, false),
- newOption("-b", "", 0, false)}, nil)
- y = patternList{newOption("-x", "", 0, false)}
- z = patternList{newOption("-b", "", 0, false)}
- if v != true ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, z) != true {
- t.Fail()
- }
- v, w, x = newEither(
- newArgument("M", nil),
- newRequired(newArgument("N", nil),
- newArgument("M", nil))).match(&patternList{
- newArgument("", 1),
- newArgument("", 2)}, nil)
- y = patternList{}
- z = patternList{newArgument("N", 1), newArgument("M", 2)}
- if v != true ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, z) != true {
- t.Fail()
- }
- }
- func TestOneOrMoreMatch(t *testing.T) {
- v, w, x := newOneOrMore(newArgument("N", nil)).match(
- &patternList{newArgument("", 9)}, nil)
- y := patternList{newArgument("N", 9)}
- if v != true ||
- reflect.DeepEqual(*w, patternList{}) != true ||
- reflect.DeepEqual(*x, y) != true {
- t.Fail()
- }
- v, w, x = newOneOrMore(newArgument("N", nil)).match(
- &patternList{}, nil)
- y = patternList{}
- z := patternList{}
- if v != false ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, z) != true {
- t.Fail()
- }
- v, w, x = newOneOrMore(newArgument("N", nil)).match(
- &patternList{newOption("-x", "", 0, false)}, nil)
- y = patternList{newOption("-x", "", 0, false)}
- z = patternList{}
- if v != false ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, z) != true {
- t.Fail()
- }
- v, w, x = newOneOrMore(newArgument("N", nil)).match(
- &patternList{newArgument("", 9), newArgument("", 8)}, nil)
- y = patternList{}
- z = patternList{newArgument("N", 9), newArgument("N", 8)}
- if v != true ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, z) != true {
- t.Fail()
- }
- v, w, x = newOneOrMore(newArgument("N", nil)).match(&patternList{
- newArgument("", 9),
- newOption("-x", "", 0, false),
- newArgument("", 8)}, nil)
- y = patternList{newOption("-x", "", 0, false)}
- z = patternList{newArgument("N", 9), newArgument("N", 8)}
- if v != true ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, z) != true {
- t.Fail()
- }
- v, w, x = newOneOrMore(newOption("-a", "", 0, false)).match(&patternList{
- newOption("-a", "", 0, false),
- newArgument("", 8),
- newOption("-a", "", 0, false)}, nil)
- y = patternList{newArgument("", 8)}
- z = patternList{newOption("-a", "", 0, false), newOption("-a", "", 0, false)}
- if v != true ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, z) != true {
- t.Fail()
- }
- v, w, x = newOneOrMore(newOption("-a", "", 0, false)).match(&patternList{
- newArgument("", 8),
- newOption("-x", "", 0, false)}, nil)
- y = patternList{newArgument("", 8), newOption("-x", "", 0, false)}
- z = patternList{}
- if v != false ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, z) != true {
- t.Fail()
- }
- v, w, x = newOneOrMore(newRequired(newOption("-a", "", 0, false),
- newArgument("N", nil))).match(&patternList{
- newOption("-a", "", 0, false),
- newArgument("", 1),
- newOption("-x", "", 0, false),
- newOption("-a", "", 0, false),
- newArgument("", 2)}, nil)
- y = patternList{newOption("-x", "", 0, false)}
- z = patternList{newOption("-a", "", 0, false),
- newArgument("N", 1),
- newOption("-a", "", 0, false),
- newArgument("N", 2)}
- if v != true ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, z) != true {
- t.Fail()
- }
- v, w, x = newOneOrMore(newOptional(newArgument("N", nil))).match(
- &patternList{newArgument("", 9)}, nil)
- y = patternList{}
- z = patternList{newArgument("N", 9)}
- if v != true ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, z) != true {
- t.Fail()
- }
- }
- func TestListArgumentMatch(t *testing.T) {
- p := newRequired(
- newArgument("N", nil),
- newArgument("N", nil))
- p.fix()
- v, w, x := p.match(&patternList{newArgument("", "1"),
- newArgument("", "2")}, nil)
- y := patternList{newArgument("N", []string{"1", "2"})}
- if v != true ||
- reflect.DeepEqual(*w, patternList{}) != true ||
- reflect.DeepEqual(*x, y) != true {
- t.Fail()
- }
- p = newOneOrMore(newArgument("N", nil))
- p.fix()
- v, w, x = p.match(&patternList{newArgument("", "1"),
- newArgument("", "2"), newArgument("", "3")}, nil)
- y = patternList{newArgument("N", []string{"1", "2", "3"})}
- if v != true ||
- reflect.DeepEqual(*w, patternList{}) != true ||
- reflect.DeepEqual(*x, y) != true {
- t.Fail()
- }
- p = newRequired(newArgument("N", nil),
- newOneOrMore(newArgument("N", nil)))
- p.fix()
- v, w, x = p.match(&patternList{
- newArgument("", "1"),
- newArgument("", "2"),
- newArgument("", "3")}, nil)
- y = patternList{newArgument("N", []string{"1", "2", "3"})}
- if v != true ||
- reflect.DeepEqual(*w, patternList{}) != true ||
- reflect.DeepEqual(*x, y) != true {
- t.Fail()
- }
- p = newRequired(newArgument("N", nil),
- newRequired(newArgument("N", nil)))
- p.fix()
- v, w, x = p.match(&patternList{
- newArgument("", "1"),
- newArgument("", "2")}, nil)
- y = patternList{newArgument("N", []string{"1", "2"})}
- if v != true ||
- reflect.DeepEqual(*w, patternList{}) != true ||
- reflect.DeepEqual(*x, y) != true {
- t.Fail()
- }
- }
- func TestBasicPatternMatching(t *testing.T) {
- // ( -a N [ -x Z ] )
- p := newRequired(
- newOption("-a", "", 0, false),
- newArgument("N", nil),
- newOptional(
- newOption("-x", "", 0, false),
- newArgument("Z", nil)))
- // -a N
- q := patternList{newOption("-a", "", 0, false), newArgument("", 9)}
- y := patternList{newOption("-a", "", 0, false), newArgument("N", 9)}
- v, w, x := p.match(&q, nil)
- if v != true ||
- reflect.DeepEqual(*w, patternList{}) != true ||
- reflect.DeepEqual(*x, y) != true {
- t.Fail()
- }
- // -a -x N Z
- q = patternList{newOption("-a", "", 0, false),
- newOption("-x", "", 0, false),
- newArgument("", 9), newArgument("", 5)}
- y = patternList{}
- z := patternList{newOption("-a", "", 0, false), newArgument("N", 9),
- newOption("-x", "", 0, false), newArgument("Z", 5)}
- v, w, x = p.match(&q, nil)
- if v != true ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, z) != true {
- t.Fail()
- }
- // -x N Z # BZZ!
- q = patternList{newOption("-x", "", 0, false),
- newArgument("", 9), newArgument("", 5)}
- y = patternList{newOption("-x", "", 0, false),
- newArgument("", 9), newArgument("", 5)}
- z = patternList{}
- v, w, x = p.match(&q, nil)
- if v != false ||
- reflect.DeepEqual(*w, y) != true ||
- reflect.DeepEqual(*x, z) != true {
- t.Fail()
- }
- }
- func TestPatternEither(t *testing.T) {
- p := newOption("-a", "", 0, false).transform()
- q := newEither(newRequired(
- newOption("-a", "", 0, false)))
- if p.eq(q) != true {
- t.Fail()
- }
- p = newArgument("A", nil).transform()
- q = newEither(newRequired(
- newArgument("A", nil)))
- if p.eq(q) != true {
- t.Fail()
- }
- p = newRequired(
- newEither(
- newOption("-a", "", 0, false),
- newOption("-b", "", 0, false)),
- newOption("-c", "", 0, false)).transform()
- q = newEither(
- newRequired(
- newOption("-a", "", 0, false),
- newOption("-c", "", 0, false)),
- newRequired(
- newOption("-b", "", 0, false),
- newOption("-c", "", 0, false)))
- if p.eq(q) != true {
- t.Fail()
- }
- p = newOptional(newOption("-a", "", 0, false),
- newEither(newOption("-b", "", 0, false),
- newOption("-c", "", 0, false))).transform()
- q = newEither(
- newRequired(
- newOption("-b", "", 0, false), newOption("-a", "", 0, false)),
- newRequired(
- newOption("-c", "", 0, false), newOption("-a", "", 0, false)))
- if p.eq(q) != true {
- t.Fail()
- }
- p = newEither(newOption("-x", "", 0, false),
- newEither(newOption("-y", "", 0, false),
- newOption("-z", "", 0, false))).transform()
- q = newEither(
- newRequired(newOption("-x", "", 0, false)),
- newRequired(newOption("-y", "", 0, false)),
- newRequired(newOption("-z", "", 0, false)))
- if p.eq(q) != true {
- t.Fail()
- }
- p = newOneOrMore(newArgument("N", nil),
- newArgument("M", nil)).transform()
- q = newEither(
- newRequired(newArgument("N", nil), newArgument("M", nil),
- newArgument("N", nil), newArgument("M", nil)))
- if p.eq(q) != true {
- t.Fail()
- }
- }
- func TestPatternFixRepeatingArguments(t *testing.T) {
- p := newOption("-a", "", 0, false)
- p.fixRepeatingArguments()
- if p.eq(newOption("-a", "", 0, false)) != true {
- t.Fail()
- }
- p = newArgument("N", nil)
- p.fixRepeatingArguments()
- if p.eq(newArgument("N", nil)) != true {
- t.Fail()
- }
- p = newRequired(
- newArgument("N", nil),
- newArgument("N", nil))
- q := newRequired(
- newArgument("N", []string{}),
- newArgument("N", []string{}))
- p.fixRepeatingArguments()
- if p.eq(q) != true {
- t.Fail()
- }
- p = newEither(
- newArgument("N", nil),
- newOneOrMore(newArgument("N", nil)))
- q = newEither(
- newArgument("N", []string{}),
- newOneOrMore(newArgument("N", []string{})))
- p.fix()
- if p.eq(q) != true {
- t.Fail()
- }
- }
- func TestSet(t *testing.T) {
- p := newArgument("N", nil)
- q := newArgument("N", nil)
- if reflect.DeepEqual(p, q) != true {
- t.Fail()
- }
- pl := patternList{newArgument("N", nil), newArgument("N", nil)}
- ql := patternList{newArgument("N", nil)}
- if reflect.DeepEqual(pl.unique(), ql.unique()) != true {
- t.Fail()
- }
- }
- func TestPatternFixIdentities1(t *testing.T) {
- p := newRequired(
- newArgument("N", nil),
- newArgument("N", nil))
- if len(p.children) < 2 {
- t.FailNow()
- }
- if p.children[0].eq(p.children[1]) != true {
- t.Fail()
- }
- if p.children[0] == p.children[1] {
- t.Fail()
- }
- p.fixIdentities(nil)
- if p.children[0] != p.children[1] {
- t.Fail()
- }
- }
- func TestPatternFixIdentities2(t *testing.T) {
- p := newRequired(
- newOptional(
- newArgument("X", nil),
- newArgument("N", nil)),
- newArgument("N", nil))
- if len(p.children) < 2 {
- t.FailNow()
- }
- if len(p.children[0].children) < 2 {
- t.FailNow()
- }
- if p.children[0].children[1].eq(p.children[1]) != true {
- t.Fail()
- }
- if p.children[0].children[1] == p.children[1] {
- t.Fail()
- }
- p.fixIdentities(nil)
- if p.children[0].children[1] != p.children[1] {
- t.Fail()
- }
- }
- func TestLongOptionsErrorHandling(t *testing.T) {
- _, err := Parse("Usage: prog", []string{"--non-existent"}, true, "", false, false)
- if _, ok := err.(*UserError); !ok {
- t.Error(fmt.Sprintf("(%s) %s", reflect.TypeOf(err), err))
- }
- _, err = Parse("Usage: prog [--version --verbose]\nOptions: --version\n --verbose",
- []string{"--ver"}, true, "", false, false)
- if _, ok := err.(*UserError); !ok {
- t.Error(err)
- }
- _, err = Parse("Usage: prog --long\nOptions: --long ARG", []string{}, true, "", false, false)
- if _, ok := err.(*LanguageError); !ok {
- t.Error(err)
- }
- _, err = Parse("Usage: prog --long ARG\nOptions: --long ARG",
- []string{"--long"}, true, "", false, false)
- if _, ok := err.(*UserError); !ok {
- t.Error(fmt.Sprintf("(%s) %s", reflect.TypeOf(err), err))
- }
- _, err = Parse("Usage: prog --long=ARG\nOptions: --long", []string{}, true, "", false, false)
- if _, ok := err.(*LanguageError); !ok {
- t.Error(err)
- }
- _, err = Parse("Usage: prog --long\nOptions: --long",
- []string{}, true, "--long=ARG", false, false)
- if _, ok := err.(*UserError); !ok {
- t.Error(err)
- }
- }
- func TestShortOptionsErrorHandling(t *testing.T) {
- _, err := Parse("Usage: prog -x\nOptions: -x this\n -x that", []string{}, true, "", false, false)
- if _, ok := err.(*LanguageError); !ok {
- t.Error(fmt.Sprintf("(%s) %s", reflect.TypeOf(err), err))
- }
- _, err = Parse("Usage: prog", []string{"-x"}, true, "", false, false)
- if _, ok := err.(*UserError); !ok {
- t.Error(err)
- }
- _, err = Parse("Usage: prog -o\nOptions: -o ARG", []string{}, true, "", false, false)
- if _, ok := err.(*LanguageError); !ok {
- t.Error(err)
- }
- _, err = Parse("Usage: prog -o ARG\nOptions: -o ARG", []string{"-o"}, true, "", false, false)
- if _, ok := err.(*UserError); !ok {
- t.Error(err)
- }
- }
- func TestMatchingParen(t *testing.T) {
- _, err := Parse("Usage: prog [a [b]", []string{}, true, "", false, false)
- if _, ok := err.(*LanguageError); !ok {
- t.Error(err)
- }
- _, err = Parse("Usage: prog [a [b] ] c )", []string{}, true, "", false, false)
- if _, ok := err.(*LanguageError); !ok {
- t.Error(err)
- }
- }
- func TestAllowDoubleDash(t *testing.T) {
- if v, err := Parse("usage: prog [-o] [--] <arg>\noptions: -o", []string{"--", "-o"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-o": false, "<arg>": "-o", "--": true}) != true {
- t.Error(err)
- }
- if v, err := Parse("usage: prog [-o] [--] <arg>\noptions: -o", []string{"-o", "1"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-o": true, "<arg>": "1", "--": false}) != true {
- t.Error(err)
- }
- _, err := Parse("usage: prog [-o] <arg>\noptions:-o", []string{"-o"}, true, "", false, false)
- if _, ok := err.(*UserError); !ok { //"--" is not allowed; FIXME?
- t.Error(err)
- }
- }
- func TestDocopt(t *testing.T) {
- doc := `Usage: prog [-v] A
- Options: -v Be verbose.`
- if v, err := Parse(doc, []string{"arg"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-v": false, "A": "arg"}) != true {
- t.Error(err)
- }
- if v, err := Parse(doc, []string{"-v", "arg"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-v": true, "A": "arg"}) != true {
- t.Error(err)
- }
- doc = `Usage: prog [-vqr] [FILE]
- prog INPUT OUTPUT
- prog --help
- Options:
- -v print status messages
- -q report only file names
- -r show all occurrences of the same error
- --help
- `
- if v, err := Parse(doc, []string{"-v", "file.py"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-v": true, "-q": false, "-r": false, "--help": false, "FILE": "file.py", "INPUT": nil, "OUTPUT": nil}) != true {
- t.Error(err)
- }
- if v, err := Parse(doc, []string{"-v"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-v": true, "-q": false, "-r": false, "--help": false, "FILE": nil, "INPUT": nil, "OUTPUT": nil}) != true {
- t.Error(err)
- }
- _, err := Parse(doc, []string{"-v", "input.py", "output.py"}, true, "", false, false) // does not match
- if _, ok := err.(*UserError); !ok {
- t.Error(err)
- }
- _, err = Parse(doc, []string{"--fake"}, true, "", false, false)
- if _, ok := err.(*UserError); !ok {
- t.Error(err)
- }
- _, output, err := parseOutput(doc, []string{"--hel"}, true, "", false)
- if err != nil || len(output) == 0 {
- t.Error(err)
- }
- }
- func TestLanguageErrors(t *testing.T) {
- _, err := Parse("no usage with colon here", []string{}, true, "", false, false)
- if _, ok := err.(*LanguageError); !ok {
- t.Error(err)
- }
- _, err = Parse("usage: here \n\n and again usage: here", []string{}, true, "", false, false)
- if _, ok := err.(*LanguageError); !ok {
- t.Error(err)
- }
- }
- func TestIssue40(t *testing.T) {
- _, output, err := parseOutput("usage: prog --help-commands | --help", []string{"--help"}, true, "", false)
- if err != nil || len(output) == 0 {
- t.Error(err)
- }
- if v, err := Parse("usage: prog --aabb | --aa", []string{"--aa"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"--aabb": false, "--aa": true}) != true {
- t.Error(err)
- }
- }
- func TestIssue34UnicodeStrings(t *testing.T) {
- // TODO: see if applicable
- }
- func TestCountMultipleFlags(t *testing.T) {
- if v, err := Parse("usage: prog [-v]", []string{"-v"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-v": true}) != true {
- t.Error(err)
- }
- if v, err := Parse("usage: prog [-vv]", []string{}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-v": 0}) != true {
- t.Error(err)
- }
- if v, err := Parse("usage: prog [-vv]", []string{"-v"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-v": 1}) != true {
- t.Error(err)
- }
- if v, err := Parse("usage: prog [-vv]", []string{"-vv"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-v": 2}) != true {
- t.Error(err)
- }
- _, err := Parse("usage: prog [-vv]", []string{"-vvv"}, true, "", false, false)
- if _, ok := err.(*UserError); !ok {
- t.Error(err)
- }
- if v, err := Parse("usage: prog [-v | -vv | -vvv]", []string{"-vvv"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-v": 3}) != true {
- t.Error(err)
- }
- if v, err := Parse("usage: prog [-v...]", []string{"-vvvvvv"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-v": 6}) != true {
- t.Error(err)
- }
- if v, err := Parse("usage: prog [--ver --ver]", []string{"--ver", "--ver"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"--ver": 2}) != true {
- t.Error(err)
- }
- }
- func TestAnyOptionsParameter(t *testing.T) {
- _, err := Parse("usage: prog [options]",
- []string{"-foo", "--bar", "--spam=eggs"}, true, "", false, false)
- if _, ok := err.(*UserError); !ok {
- t.Fail()
- }
- _, err = Parse("usage: prog [options]",
- []string{"--foo", "--bar", "--bar"}, true, "", false, false)
- if _, ok := err.(*UserError); !ok {
- t.Fail()
- }
- _, err = Parse("usage: prog [options]",
- []string{"--bar", "--bar", "--bar", "-ffff"}, true, "", false, false)
- if _, ok := err.(*UserError); !ok {
- t.Fail()
- }
- _, err = Parse("usage: prog [options]",
- []string{"--long=arg", "--long=another"}, true, "", false, false)
- if _, ok := err.(*UserError); !ok {
- t.Fail()
- }
- }
- func TestDefaultValueForPositionalArguments(t *testing.T) {
- doc := "Usage: prog [--data=<data>...]\nOptions:\n\t-d --data=<arg> Input data [default: x]"
- if v, err := Parse(doc, []string{}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"--data": []string{"x"}}) != true {
- t.Error(err)
- }
- doc = "Usage: prog [--data=<data>...]\nOptions:\n\t-d --data=<arg> Input data [default: x y]"
- if v, err := Parse(doc, []string{}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"--data": []string{"x", "y"}}) != true {
- t.Error(err)
- }
- doc = "Usage: prog [--data=<data>...]\nOptions:\n\t-d --data=<arg> Input data [default: x y]"
- if v, err := Parse(doc, []string{"--data=this"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"--data": []string{"this"}}) != true {
- t.Error(err)
- }
- }
- func TestIssue59(t *testing.T) {
- if v, err := Parse("usage: prog --long=<a>", []string{"--long="}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"--long": ""}) != true {
- t.Error(err)
- }
- if v, err := Parse("usage: prog -l <a>\noptions: -l <a>", []string{"-l", ""}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-l": ""}) != true {
- t.Error(err)
- }
- }
- func TestOptionsFirst(t *testing.T) {
- if v, err := Parse("usage: prog [--opt] [<args>...]", []string{"--opt", "this", "that"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"--opt": true, "<args>": []string{"this", "that"}}) != true {
- t.Error(err)
- }
- if v, err := Parse("usage: prog [--opt] [<args>...]", []string{"this", "that", "--opt"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"--opt": true, "<args>": []string{"this", "that"}}) != true {
- t.Error(err)
- }
- if v, err := Parse("usage: prog [--opt] [<args>...]", []string{"this", "that", "--opt"}, true, "", true, false); reflect.DeepEqual(v, map[string]interface{}{"--opt": false, "<args>": []string{"this", "that", "--opt"}}) != true {
- t.Error(err)
- }
- }
- func TestIssue68OptionsShortcutDoesNotIncludeOptionsInUsagePattern(t *testing.T) {
- args, err := Parse("usage: prog [-ab] [options]\noptions: -x\n -y", []string{"-ax"}, true, "", false, false)
- if args["-a"] != true {
- t.Error(err)
- }
- if args["-b"] != false {
- t.Error(err)
- }
- if args["-x"] != true {
- t.Error(err)
- }
- if args["-y"] != false {
- t.Error(err)
- }
- }
- func TestIssue65EvaluateArgvWhenCalledNotWhenImported(t *testing.T) {
- os.Args = strings.Fields("prog -a")
- v, err := Parse("usage: prog [-ab]", nil, true, "", false, false)
- w := map[string]interface{}{"-a": true, "-b": false}
- if reflect.DeepEqual(v, w) != true {
- t.Error(err)
- }
- os.Args = strings.Fields("prog -b")
- v, err = Parse("usage: prog [-ab]", nil, true, "", false, false)
- w = map[string]interface{}{"-a": false, "-b": true}
- if reflect.DeepEqual(v, w) != true {
- t.Error(err)
- }
- }
- func TestIssue71DoubleDashIsNotAValidOptionArgument(t *testing.T) {
- _, err := Parse("usage: prog [--log=LEVEL] [--] <args>...",
- []string{"--log", "--", "1", "2"}, true, "", false, false)
- if _, ok := err.(*UserError); !ok {
- t.Fail()
- }
- _, err = Parse(`usage: prog [-l LEVEL] [--] <args>...
- options: -l LEVEL`, []string{"-l", "--", "1", "2"}, true, "", false, false)
- if _, ok := err.(*UserError); !ok {
- t.Fail()
- }
- }
- func TestParseSection(t *testing.T) {
- v := parseSection("usage:", "foo bar fizz buzz")
- w := []string{}
- if reflect.DeepEqual(v, w) != true {
- t.Fail()
- }
- v = parseSection("usage:", "usage: prog")
- w = []string{"usage: prog"}
- if reflect.DeepEqual(v, w) != true {
- t.Fail()
- }
- v = parseSection("usage:", "usage: -x\n -y")
- w = []string{"usage: -x\n -y"}
- if reflect.DeepEqual(v, w) != true {
- t.Fail()
- }
- usage := `usage: this
- usage:hai
- usage: this that
- usage: foo
- bar
- PROGRAM USAGE:
- foo
- bar
- usage:
- ` + "\t" + `too
- ` + "\t" + `tar
- Usage: eggs spam
- BAZZ
- usage: pit stop`
- v = parseSection("usage:", usage)
- w = []string{"usage: this",
- "usage:hai",
- "usage: this that",
- "usage: foo\n bar",
- "PROGRAM USAGE:\n foo\n bar",
- "usage:\n\ttoo\n\ttar",
- "Usage: eggs spam",
- "usage: pit stop",
- }
- if reflect.DeepEqual(v, w) != true {
- t.Fail()
- }
- }
- func TestIssue126DefaultsNotParsedCorrectlyWhenTabs(t *testing.T) {
- section := "Options:\n\t--foo=<arg> [default: bar]"
- v := patternList{newOption("", "--foo", 1, "bar")}
- if reflect.DeepEqual(parseDefaults(section), v) != true {
- t.Fail()
- }
- }
- // conf file based test cases
- func TestFileTestcases(t *testing.T) {
- filenames := []string{"testcases.docopt", "test_golang.docopt"}
- for _, filename := range filenames {
- raw, err := ioutil.ReadFile(filename)
- if err != nil {
- t.Fatal(err)
- }
- tests, err := parseTest(raw)
- if err != nil {
- t.Fatal(err)
- }
- for _, c := range tests {
- result, err := Parse(c.doc, c.argv, true, "", false, false)
- if _, ok := err.(*UserError); c.userError && !ok {
- // expected a user-error
- t.Error("testcase:", c.id, "result:", result)
- } else if _, ok := err.(*UserError); !c.userError && ok {
- // unexpected user-error
- t.Error("testcase:", c.id, "error:", err, "result:", result)
- } else if reflect.DeepEqual(c.expect, result) != true {
- t.Error("testcase:", c.id, "result:", result, "expect:", c.expect)
- }
- }
- }
- }
- type testcase struct {
- id int
- doc string
- prog string
- argv []string
- expect map[string]interface{}
- userError bool
- }
- func parseTest(raw []byte) ([]testcase, error) {
- var res []testcase
- commentPattern := regexp.MustCompile("#.*")
- raw = commentPattern.ReplaceAll(raw, []byte(""))
- raw = bytes.TrimSpace(raw)
- if bytes.HasPrefix(raw, []byte(`"""`)) {
- raw = raw[3:]
- }
- id := 0
- for _, fixture := range bytes.Split(raw, []byte(`r"""`)) {
- doc, _, body := stringPartition(string(fixture), `"""`)
- for _, cas := range strings.Split(body, "$")[1:] {
- argvString, _, expectString := stringPartition(strings.TrimSpace(cas), "\n")
- prog, _, argvString := stringPartition(strings.TrimSpace(argvString), " ")
- argv := []string{}
- if len(argvString) > 0 {
- argv = strings.Fields(argvString)
- }
- var expectUntyped interface{}
- err := json.Unmarshal([]byte(expectString), &expectUntyped)
- if err != nil {
- return nil, err
- }
- switch expect := expectUntyped.(type) {
- case string: // user-error
- res = append(res, testcase{id, doc, prog, argv, nil, true})
- case map[string]interface{}:
- // convert []interface{} values to []string
- // convert float64 values to int
- for k, vUntyped := range expect {
- switch v := vUntyped.(type) {
- case []interface{}:
- itemList := make([]string, len(v))
- for i, itemUntyped := range v {
- if item, ok := itemUntyped.(string); ok {
- itemList[i] = item
- }
- }
- expect[k] = itemList
- case float64:
- expect[k] = int(v)
- }
- }
- res = append(res, testcase{id, doc, prog, argv, expect, false})
- default:
- return nil, fmt.Errorf("unhandled json data type")
- }
- id++
- }
- }
- return res, nil
- }
- // parseOutput wraps the Parse() function to also return stdout
- func parseOutput(doc string, argv []string, help bool, version string,
- optionsFirst bool) (map[string]interface{}, string, error) {
- stdout := os.Stdout
- r, w, _ := os.Pipe()
- os.Stdout = w
- args, err := Parse(doc, argv, help, version, optionsFirst, false)
- outChan := make(chan string)
- go func() {
- var buf bytes.Buffer
- io.Copy(&buf, r)
- outChan <- buf.String()
- }()
- w.Close()
- os.Stdout = stdout
- output := <-outChan
- return args, output, err
- }
- var debugEnabled = false
- func debugOn(l ...interface{}) {
- debugEnabled = true
- debug(l...)
- }
- func debugOff(l ...interface{}) {
- debug(l...)
- debugEnabled = false
- }
- func debug(l ...interface{}) {
- if debugEnabled {
- fmt.Println(l...)
- }
- }
|