1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519 |
- /*
- 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/ioutil"
- "os"
- "reflect"
- "regexp"
- "strings"
- "testing"
- )
- var testParser = &Parser{HelpHandler: NoHelpHandler}
- 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 := testParser.ParseArgs("Usage: prog add", []string{"add"}, ""); reflect.DeepEqual(v, Opts{"add": true}) != true {
- t.Error(err)
- }
- if v, err := testParser.ParseArgs("Usage: prog [add]", []string{}, ""); reflect.DeepEqual(v, Opts{"add": false}) != true {
- t.Error(err)
- }
- if v, err := testParser.ParseArgs("Usage: prog [add]", []string{"add"}, ""); reflect.DeepEqual(v, Opts{"add": true}) != true {
- t.Error(err)
- }
- if v, err := testParser.ParseArgs("Usage: prog (add|rm)", []string{"add"}, ""); reflect.DeepEqual(v, Opts{"add": true, "rm": false}) != true {
- t.Error(err)
- }
- if v, err := testParser.ParseArgs("Usage: prog (add|rm)", []string{"rm"}, ""); reflect.DeepEqual(v, Opts{"add": false, "rm": true}) != true {
- t.Error(err)
- }
- if v, err := testParser.ParseArgs("Usage: prog a b", []string{"a", "b"}, ""); reflect.DeepEqual(v, Opts{"a": true, "b": true}) != true {
- t.Error(err)
- }
- _, err := testParser.ParseArgs("Usage: prog a b", []string{"b", "a"}, "")
- 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 := testParser.ParseArgs("Usage: prog", []string{"--non-existent"}, "")
- if _, ok := err.(*UserError); !ok {
- t.Error(fmt.Sprintf("(%s) %s", reflect.TypeOf(err), err))
- }
- _, err = testParser.ParseArgs("Usage: prog [--version --verbose]\nOptions: --version\n --verbose", []string{"--ver"}, "")
- if _, ok := err.(*UserError); !ok {
- t.Error(err)
- }
- _, err = testParser.ParseArgs("Usage: prog --long\nOptions: --long ARG", []string{}, "")
- if _, ok := err.(*LanguageError); !ok {
- t.Error(err)
- }
- _, err = testParser.ParseArgs("Usage: prog --long ARG\nOptions: --long ARG", []string{"--long"}, "")
- if _, ok := err.(*UserError); !ok {
- t.Error(fmt.Sprintf("(%s) %s", reflect.TypeOf(err), err))
- }
- _, err = testParser.ParseArgs("Usage: prog --long=ARG\nOptions: --long", []string{}, "")
- if _, ok := err.(*LanguageError); !ok {
- t.Error(err)
- }
- _, err = testParser.ParseArgs("Usage: prog --long\nOptions: --long", []string{}, "--long=ARG")
- if _, ok := err.(*UserError); !ok {
- t.Error(err)
- }
- }
- func TestShortOptionsErrorHandling(t *testing.T) {
- _, err := testParser.ParseArgs("Usage: prog -x\nOptions: -x this\n -x that", []string{}, "")
- if _, ok := err.(*LanguageError); !ok {
- t.Error(fmt.Sprintf("(%s) %s", reflect.TypeOf(err), err))
- }
- _, err = testParser.ParseArgs("Usage: prog", []string{"-x"}, "")
- if _, ok := err.(*UserError); !ok {
- t.Error(err)
- }
- _, err = testParser.ParseArgs("Usage: prog -o\nOptions: -o ARG", []string{}, "")
- if _, ok := err.(*LanguageError); !ok {
- t.Error(err)
- }
- _, err = testParser.ParseArgs("Usage: prog -o ARG\nOptions: -o ARG", []string{"-o"}, "")
- if _, ok := err.(*UserError); !ok {
- t.Error(err)
- }
- }
- func TestMatchingParen(t *testing.T) {
- _, err := testParser.ParseArgs("Usage: prog [a [b]", []string{}, "")
- if _, ok := err.(*LanguageError); !ok {
- t.Error(err)
- }
- _, err = testParser.ParseArgs("Usage: prog [a [b] ] c )", []string{}, "")
- if _, ok := err.(*LanguageError); !ok {
- t.Error(err)
- }
- }
- func TestAllowDoubleDash(t *testing.T) {
- if v, err := testParser.ParseArgs("usage: prog [-o] [--] <arg>\noptions: -o", []string{"--", "-o"}, ""); reflect.DeepEqual(v, Opts{"-o": false, "<arg>": "-o", "--": true}) != true {
- t.Error(err)
- }
- if v, err := testParser.ParseArgs("usage: prog [-o] [--] <arg>\noptions: -o", []string{"-o", "1"}, ""); reflect.DeepEqual(v, Opts{"-o": true, "<arg>": "1", "--": false}) != true {
- t.Error(err)
- }
- _, err := testParser.ParseArgs("usage: prog [-o] <arg>\noptions:-o", []string{"-o"}, "")
- 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 := testParser.ParseArgs(doc, []string{"arg"}, ""); reflect.DeepEqual(v, Opts{"-v": false, "A": "arg"}) != true {
- t.Error(err)
- }
- if v, err := testParser.ParseArgs(doc, []string{"-v", "arg"}, ""); reflect.DeepEqual(v, Opts{"-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 := testParser.ParseArgs(doc, []string{"-v", "file.py"}, ""); reflect.DeepEqual(v, Opts{"-v": true, "-q": false, "-r": false, "--help": false, "FILE": "file.py", "INPUT": nil, "OUTPUT": nil}) != true {
- t.Error(err)
- }
- if v, err := testParser.ParseArgs(doc, []string{"-v"}, ""); reflect.DeepEqual(v, Opts{"-v": true, "-q": false, "-r": false, "--help": false, "FILE": nil, "INPUT": nil, "OUTPUT": nil}) != true {
- t.Error(err)
- }
- _, err := testParser.ParseArgs(doc, []string{"-v", "input.py", "output.py"}, "") // does not match
- if _, ok := err.(*UserError); !ok {
- t.Error(err)
- }
- _, err = testParser.ParseArgs(doc, []string{"--fake"}, "")
- 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 := testParser.ParseArgs("no usage with colon here", []string{}, "")
- if _, ok := err.(*LanguageError); !ok {
- t.Error(err)
- }
- _, err = testParser.ParseArgs("usage: here \n\n and again usage: here", []string{}, "")
- 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 := testParser.ParseArgs("usage: prog --aabb | --aa", []string{"--aa"}, ""); reflect.DeepEqual(v, Opts{"--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 := testParser.ParseArgs("usage: prog [-v]", []string{"-v"}, ""); reflect.DeepEqual(v, Opts{"-v": true}) != true {
- t.Error(err)
- }
- if v, err := testParser.ParseArgs("usage: prog [-vv]", []string{}, ""); reflect.DeepEqual(v, Opts{"-v": 0}) != true {
- t.Error(err)
- }
- if v, err := testParser.ParseArgs("usage: prog [-vv]", []string{"-v"}, ""); reflect.DeepEqual(v, Opts{"-v": 1}) != true {
- t.Error(err)
- }
- if v, err := testParser.ParseArgs("usage: prog [-vv]", []string{"-vv"}, ""); reflect.DeepEqual(v, Opts{"-v": 2}) != true {
- t.Error(err)
- }
- _, err := testParser.ParseArgs("usage: prog [-vv]", []string{"-vvv"}, "")
- if _, ok := err.(*UserError); !ok {
- t.Error(err)
- }
- if v, err := testParser.ParseArgs("usage: prog [-v | -vv | -vvv]", []string{"-vvv"}, ""); reflect.DeepEqual(v, Opts{"-v": 3}) != true {
- t.Error(err)
- }
- if v, err := testParser.ParseArgs("usage: prog [-v...]", []string{"-vvvvvv"}, ""); reflect.DeepEqual(v, Opts{"-v": 6}) != true {
- t.Error(err)
- }
- if v, err := testParser.ParseArgs("usage: prog [--ver --ver]", []string{"--ver", "--ver"}, ""); reflect.DeepEqual(v, Opts{"--ver": 2}) != true {
- t.Error(err)
- }
- }
- func TestAnyOptionsParameter(t *testing.T) {
- _, err := testParser.ParseArgs("usage: prog [options]", []string{"-foo", "--bar", "--spam=eggs"}, "")
- if _, ok := err.(*UserError); !ok {
- t.Fail()
- }
- _, err = testParser.ParseArgs("usage: prog [options]", []string{"--foo", "--bar", "--bar"}, "")
- if _, ok := err.(*UserError); !ok {
- t.Fail()
- }
- _, err = testParser.ParseArgs("usage: prog [options]", []string{"--bar", "--bar", "--bar", "-ffff"}, "")
- if _, ok := err.(*UserError); !ok {
- t.Fail()
- }
- _, err = testParser.ParseArgs("usage: prog [options]", []string{"--long=arg", "--long=another"}, "")
- 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 := testParser.ParseArgs(doc, []string{}, ""); reflect.DeepEqual(v, Opts{"--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 := testParser.ParseArgs(doc, []string{}, ""); reflect.DeepEqual(v, Opts{"--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 := testParser.ParseArgs(doc, []string{"--data=this"}, ""); reflect.DeepEqual(v, Opts{"--data": []string{"this"}}) != true {
- t.Error(err)
- }
- }
- func TestIssue59(t *testing.T) {
- if v, err := testParser.ParseArgs("usage: prog --long=<a>", []string{"--long="}, ""); reflect.DeepEqual(v, Opts{"--long": ""}) != true {
- t.Error(err)
- }
- if v, err := testParser.ParseArgs("usage: prog -l <a>\noptions: -l <a>", []string{"-l", ""}, ""); reflect.DeepEqual(v, Opts{"-l": ""}) != true {
- t.Error(err)
- }
- }
- func TestOptionsFirst(t *testing.T) {
- if v, err := testParser.ParseArgs("usage: prog [--opt] [<args>...]", []string{"--opt", "this", "that"}, ""); reflect.DeepEqual(v, Opts{"--opt": true, "<args>": []string{"this", "that"}}) != true {
- t.Error(err)
- }
- if v, err := testParser.ParseArgs("usage: prog [--opt] [<args>...]", []string{"this", "that", "--opt"}, ""); reflect.DeepEqual(v, Opts{"--opt": true, "<args>": []string{"this", "that"}}) != true {
- t.Error(err)
- }
- optFirstParser := &Parser{HelpHandler: PrintHelpOnly, OptionsFirst: true}
- if v, err := optFirstParser.ParseArgs("usage: prog [--opt] [<args>...]", []string{"this", "that", "--opt"}, ""); reflect.DeepEqual(v, Opts{"--opt": false, "<args>": []string{"this", "that", "--opt"}}) != true {
- t.Error(err)
- }
- }
- func TestIssue68OptionsShortcutDoesNotIncludeOptionsInUsagePattern(t *testing.T) {
- args, err := testParser.ParseArgs("usage: prog [-ab] [options]\noptions: -x\n -y", []string{"-ax"}, "")
- 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 := testParser.ParseArgs("usage: prog [-ab]", nil, "")
- w := Opts{"-a": true, "-b": false}
- if reflect.DeepEqual(v, w) != true {
- t.Error(err)
- }
- os.Args = strings.Fields("prog -b")
- v, err = testParser.ParseArgs("usage: prog [-ab]", nil, "")
- w = Opts{"-a": false, "-b": true}
- if reflect.DeepEqual(v, w) != true {
- t.Error(err)
- }
- }
- func TestIssue71DoubleDashIsNotAValidOptionArgument(t *testing.T) {
- _, err := testParser.ParseArgs("usage: prog [--log=LEVEL] [--] <args>...", []string{"--log", "--", "1", "2"}, "")
- if _, ok := err.(*UserError); !ok {
- t.Fail()
- }
- _, err = testParser.ParseArgs(`usage: prog [-l LEVEL] [--] <args>...
- options: -l LEVEL`, []string{"-l", "--", "1", "2"}, "")
- 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 := testParser.ParseArgs(c.doc, c.argv, "")
- 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 Opts
- 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 uses a custom parser which also returns the output
- func parseOutput(doc string, argv []string, help bool, version string, optionsFirst bool) (Opts, string, error) {
- var output string
- p := &Parser{
- HelpHandler: func(err error, usage string) { output = usage },
- OptionsFirst: optionsFirst,
- SkipHelpFlags: !help,
- }
- args, err := p.ParseArgs(doc, argv, version)
- 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...)
- }
- }
|