package commando
import utest._
object ParserTest extends TestSuite {
implicit class EliteCommando(line: String) {
def parse(command: Command): Unit = {
val args = line.split(" ").tail
commando.parse(args, command, (c, err) => throw new ParseException(err))
}
def fail(command: Command, message: String): Unit = {
val args = line.split(" ").tail
try {
commando.parse(args, command, (c, err) => throw new ParseException(err))
sys.error("parsing succeeded but was expected to fail")
} catch {
case err: ParseException if err.getMessage.contains(message) =>
case err: ParseException =>
sys.error(s"parsing failed for the wrong reason: ${err.getMessage}")
}
}
}
def cbx(asserts: Command.Arguments => Unit) =
cmd("cbx")(
opt("server", 's', "name" -> true)
).sub(
cmd("version")(
opt("verbose", 'v', "k=v" -> false)
).run(asserts),
cmd("login")(
pos("server_url"),
pos("username", false),
pos("password", false)
).run(asserts),
cmd("run")(
opt("file", 'f', "file_name" -> true),
opt("force"),
pos("pipeline", false)
).run(asserts),
cmd("level1")().sub(
cmd("level2-1")(
pos("p2")
).sub(
cmd("level3")(pos("p3")).run(asserts)
),
cmd("level2-2")().run(asserts)
)
)
val tests = Tests {
"print usage" - {
cbx(_ => ()).usage
}
"simple" - {
"cbx version" parse cbx { args =>
args ==> Map.empty
}
}
"empty allowed optional" - {
"cbx version -v" parse cbx { args =>
args ==> Map("verbose" -> Seq(""))
}
"cbx version --verbose" parse cbx { args =>
args ==> Map("verbose" -> Seq(""))
}
}
"set allowed optional" - {
"cbx version -v x" parse cbx { args =>
args ==> Map("verbose" -> Seq("x"))
}
"cbx version --verbose x" parse cbx { args =>
args ==> Map("verbose" -> Seq("x"))
}
"cbx version --verbose=x" parse cbx { args =>
args ==> Map("verbose" -> Seq("x"))
}
"cbx version --verbose=x=y" parse cbx { args =>
args ==> Map("verbose" -> Seq("x=y"))
}
"cbx version --verbose=x=y,z=w" parse cbx { args =>
args ==> Map("verbose" -> Seq("x=y,z=w"))
}
"cbx version --verbose x=y" parse cbx { args =>
args ==> Map("verbose" -> Seq("x=y"))
}
"cbx version --verbose x=y z=w".fail(cbx(_ => ()), "too many arguments")
}
"required argument optional" - {
"cbx run" parse cbx { _ ==> Map.empty } // make sure it works first
"cbx run -f x" parse cbx { _ ==> Map("file" -> Seq("x")) }
"cbx run --file x" parse cbx { _ ==> Map("file" -> Seq("x")) }
"cbx run --file=x" parse cbx { _ ==> Map("file" -> Seq("x")) }
"cbx run --file=x=y,z=w" parse cbx { _ ==> Map("file" -> Seq("x=y,z=w")) }
"cbx run --file".fail(cbx(_ => ()), "requires")
"cbx run --file --".fail(cbx(_ => ()), "requires")
}
"no argument optional" - {
"cbx run --force=x".fail(cbx(_ => ()), "no argument allowed")
"cbx run --force x" parse cbx { _ ==> Map("force" -> Seq(""), "pipeline" -> Seq("x")) }
}
"global optional" - {
"cbx --server run run" parse cbx {_ ==> Map("server" -> Seq("run"))}
"cbx -s run run" parse cbx {_ ==> Map("server" -> Seq("run"))}
"cbx --server=run run" parse cbx {_ ==> Map("server" -> Seq("run"))}
"cbx -x run".fail(cbx(_ => ()), "unknown option")
"cbx --x run".fail(cbx(_ => ()), "unknown option")
}
"positional" - {
"cbx login x" parse cbx { _ ==> Map("server_url" -> Seq("x"))}
"cbx login x y" parse cbx { _ ==> Map("server_url" -> Seq("x"), "username" -> Seq("y"))}
"cbx login x y z" parse cbx { _ ==> Map("server_url" -> Seq("x"), "username" -> Seq("y"), "password" -> Seq("z"))}
"cbx login - x y z".fail(cbx(_ => ()), "too many")
"cbx login - y" parse cbx { _ ==> Map("server_url" -> Seq("-"), "username" -> Seq("y"))}
}
"out of order options" - {
"cbx run --force pipelinename -f x" parse cbx {
_ ==> Map("force" -> Seq(""), "pipeline" -> Seq("pipelinename"), "file" -> Seq("x"))
}
"cbx run --force -- -f" parse cbx {
_ ==> Map("force" -> Seq(""), "pipeline" -> Seq("-f"))
}
"cbx run --force -- --file" parse cbx {
_ ==> Map("force" -> Seq(""), "pipeline" -> Seq("--file"))
}
"cbx run --force -- --" parse cbx {
_ ==> Map("force" -> Seq(""), "pipeline" -> Seq("--"))
}
"cbx run --force -- -f x".fail(cbx(_ => ()), "too many")
}
"nested1" - {
"cbx level1 level2-1 x=y level3 z" parse cbx {
_ ==> Map("p2" -> Seq("x=y"), "p3" -> Seq("z"))
}
}
"nested2" - {
"cbx level1 level2-2 --" parse cbx {
_ ==> Map.empty
}
}
}
}