Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/babashka/cli.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,10 @@
(when-not (if (set? f) (contains? f v) (f v))
(let [ex-msg-fn (or (:ex-msg vf)
(fn [{:keys [flag value]}]
(str "Invalid value for option " flag ": " value)))
(str "Invalid value for option " flag ": " value
(when (set? f)
(str ". Expected one of: "
(str/join ", " (sort (map #(if (keyword? %) (kw->str %) (str %)) f))))))))
flag (get opt->flag k)]
(error-fn (cond-> {:cause :validate
:msg (ex-msg-fn {:option k :value v :flag (flag-for k)})
Expand Down
8 changes: 8 additions & 0 deletions test/babashka/cli/completion_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,14 @@
(is (= #{"a" "b"}
(set (complete-options {:spec {:mode {:coerce :keyword :validate #{:a :b}}}}
["--mode" ""])))))
(testing "set-valued :validate auto-completes strings"
(is (= #{"production" "staging"}
(set (complete-options {:spec {:env {:validate #{"production" "staging"}}}}
["--env" ""])))))
(testing "set-valued :validate auto-completes numbers"
(is (= #{"1" "2" "3"}
(set (complete-options {:spec {:n {:coerce :long :validate #{1 2 3}}}}
["--n" ""])))))
(testing ":complete-fn receives :to-complete and parsed :opts (dependent completion)"
(let [spec {:from {:coerce :string :complete ["x" "y"]}
:to {:coerce :string
Expand Down
20 changes: 20 additions & 0 deletions test/babashka/cli_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,26 @@
(is (str/includes? help "Custom"))
(is (not (str/includes? help "Does a thing")))))))

(deftest set-validate-test
(testing "a set :validate of strings validates, and lists the values on error"
(is (submap? {:env "staging"}
(cli/parse-opts ["--env" "staging"]
{:spec {:env {:validate #{"production" "staging"}}}})))
(is (thrown-with-msg?
#?(:cljd Object :default Exception)
#"Invalid value for option --env: foo\. Expected one of: production, staging"
(cli/parse-opts ["--env" "foo"]
{:spec {:env {:validate #{"production" "staging"}}}}))))
(testing "a set :validate of numbers (coerced) validates, and lists the values on error"
(is (submap? {:n 2}
(cli/parse-opts ["--n" "2"]
{:spec {:n {:coerce :long :validate #{1 2 3}}}})))
(is (thrown-with-msg?
#?(:cljd Object :default Exception)
#"Invalid value for option --n: 5\. Expected one of: 1, 2, 3"
(cli/parse-opts ["--n" "5"]
{:spec {:n {:coerce :long :validate #{1 2 3}}}})))))

(defn- listed-command-names
"Command names from the `Commands:` section of help/error output, in order."
[s]
Expand Down
Loading