aboutsummaryrefslogblamecommitdiff
path: root/src/test/scala/ParserTest.scala
blob: 579ba959cdf5abed48ebbb7e9a0f1991d09f11f9 (plain) (tree)
1
2
3
4
5
6
7
8







                                              












                                                                                


     























                                               
       


























































































                                                                                                                        

     
 
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
      }
    }
  }
}