2001-08-12 19:03:34 +00:00
|
|
|
|
;;;; getopt-long.test --- long options processing -*- scheme -*-
|
2001-08-02 10:13:03 +00:00
|
|
|
|
;;;;
|
2020-04-19 18:00:04 +01:00
|
|
|
|
;;;; Copyright (C) 2001, 2006, 2011 Free Software Foundation, Inc.
|
2001-08-02 10:13:03 +00:00
|
|
|
|
;;;;
|
2009-06-17 00:22:09 +01:00
|
|
|
|
;;;; This library is free software; you can redistribute it and/or
|
|
|
|
|
|
;;;; modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
|
;;;; License as published by the Free Software Foundation; either
|
|
|
|
|
|
;;;; version 3 of the License, or (at your option) any later version.
|
|
|
|
|
|
;;;;
|
|
|
|
|
|
;;;; This library is distributed in the hope that it will be useful,
|
2001-08-02 10:13:03 +00:00
|
|
|
|
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2009-06-17 00:22:09 +01:00
|
|
|
|
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
|
;;;; Lesser General Public License for more details.
|
|
|
|
|
|
;;;;
|
|
|
|
|
|
;;;; You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
|
;;;; License along with this library; if not, write to the Free Software
|
|
|
|
|
|
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
2001-08-02 10:13:03 +00:00
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
;;; Author: Thien-Thi Nguyen <ttn@gnu.org> --- August 2001
|
2020-04-19 18:00:04 +01:00
|
|
|
|
;;; Dale Mellor --- April 2020
|
2020-04-19 18:00:04 +01:00
|
|
|
|
|
|
|
|
|
|
|
2001-08-02 10:13:03 +00:00
|
|
|
|
(use-modules (test-suite lib)
|
|
|
|
|
|
(ice-9 getopt-long)
|
|
|
|
|
|
(ice-9 regex))
|
|
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
|
|
|
|
|
|
;;******** Test infrastructure *********************
|
|
|
|
|
|
|
2011-02-10 12:09:18 +01:00
|
|
|
|
(define-syntax pass-if-fatal-exception
|
|
|
|
|
|
(syntax-rules ()
|
|
|
|
|
|
((_ name exn exp)
|
|
|
|
|
|
(let ((port (open-output-string)))
|
|
|
|
|
|
(with-error-to-port port
|
|
|
|
|
|
(lambda ()
|
|
|
|
|
|
(run-test
|
|
|
|
|
|
name #t
|
|
|
|
|
|
(lambda ()
|
|
|
|
|
|
(catch (car exn)
|
|
|
|
|
|
(lambda () exp #f)
|
|
|
|
|
|
(lambda (k . args)
|
|
|
|
|
|
(let ((output (get-output-string port)))
|
|
|
|
|
|
(close-port port)
|
|
|
|
|
|
(if (string-match (cdr exn) output)
|
|
|
|
|
|
#t
|
|
|
|
|
|
(error "Unexpected output" output)))))))))))))
|
|
|
|
|
|
|
2001-08-12 18:31:10 +00:00
|
|
|
|
(defmacro deferr (name-frag re)
|
|
|
|
|
|
(let ((name (symbol-append 'exception: name-frag)))
|
2011-02-10 12:09:18 +01:00
|
|
|
|
`(define ,name (cons 'quit ,re))))
|
2001-08-12 18:31:10 +00:00
|
|
|
|
|
2011-02-10 12:09:18 +01:00
|
|
|
|
(deferr no-such-option "no such option")
|
|
|
|
|
|
(deferr option-predicate-failed "option predicate failed")
|
|
|
|
|
|
(deferr option-does-not-support-arg "option does not support argument")
|
|
|
|
|
|
(deferr option-must-be-specified "option must be specified")
|
|
|
|
|
|
(deferr option-must-have-arg "option must be specified with argument")
|
2001-08-12 18:31:10 +00:00
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
|
|
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
;;************* Newer test infrastructure ***********************
|
|
|
|
|
|
|
|
|
|
|
|
;; Many tests here are somewhat flakey as they depend on a precise
|
|
|
|
|
|
;; internal representation of the options analysis, which isn't really
|
|
|
|
|
|
;; defined or necessary. In the newer tests below we sort that
|
|
|
|
|
|
;; structure into alphabetical order, so we know exactly in advance how
|
|
|
|
|
|
;; to specify the expected results. We also make the test inputs
|
|
|
|
|
|
;; strings of command-line options, rather than lists, as these are
|
|
|
|
|
|
;; clearer and easier for us and closer to the real world.
|
2020-04-19 18:00:04 +01:00
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(define* (A-TEST args option-specs expectation
|
|
|
|
|
|
#:key stop-at-first-non-option)
|
2020-04-19 18:00:04 +01:00
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(define (symbol/>string a)
|
|
|
|
|
|
(if (symbol? a) (symbol->string a) ""))
|
|
|
|
|
|
|
|
|
|
|
|
(define (output-sort out)
|
|
|
|
|
|
(sort out (λ (a b) (string<? (symbol/>string (car a))
|
|
|
|
|
|
(symbol/>string (car b))))))
|
|
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(let ((answer
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(output-sort
|
|
|
|
|
|
(getopt-long
|
|
|
|
|
|
(cons "foo" (string-split args #\space))
|
|
|
|
|
|
option-specs
|
|
|
|
|
|
#:stop-at-first-non-option stop-at-first-non-option))))
|
|
|
|
|
|
(cond ((equal? answer (output-sort expectation)) #t)
|
|
|
|
|
|
(else (format (current-output-port)
|
|
|
|
|
|
"Test result was \n‘~s’ --VS-- \n‘~s’.\n"
|
|
|
|
|
|
answer (output-sort expectation))
|
|
|
|
|
|
#f))))
|
2020-04-19 18:00:04 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
;;************ The tests ******************************
|
|
|
|
|
|
|
2001-08-12 18:31:10 +00:00
|
|
|
|
(with-test-prefix "exported procs"
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(pass-if "`option-ref' defined" (defined? 'option-ref))
|
|
|
|
|
|
(pass-if "`getopt-long' defined" (defined? 'getopt-long)))
|
2001-08-02 10:13:03 +00:00
|
|
|
|
|
|
|
|
|
|
(with-test-prefix "specifying predicate"
|
|
|
|
|
|
|
|
|
|
|
|
(define (test1 . args)
|
2001-08-12 18:31:10 +00:00
|
|
|
|
(getopt-long args
|
|
|
|
|
|
`((test (value #t)
|
|
|
|
|
|
(predicate ,(lambda (x)
|
|
|
|
|
|
(string-match "^[0-9]+$" x)))))))
|
2001-08-02 10:13:03 +00:00
|
|
|
|
|
|
|
|
|
|
(pass-if "valid arg"
|
|
|
|
|
|
(equal? (test1 "foo" "bar" "--test=123")
|
|
|
|
|
|
'((() "bar") (test . "123"))))
|
|
|
|
|
|
|
2011-02-10 12:09:18 +01:00
|
|
|
|
(pass-if-fatal-exception "invalid arg"
|
2001-08-02 10:13:03 +00:00
|
|
|
|
exception:option-predicate-failed
|
|
|
|
|
|
(test1 "foo" "bar" "--test=foo"))
|
|
|
|
|
|
|
2011-02-10 12:09:18 +01:00
|
|
|
|
(pass-if-fatal-exception "option has no arg"
|
2001-08-12 19:03:34 +00:00
|
|
|
|
exception:option-must-have-arg
|
2001-08-12 18:31:10 +00:00
|
|
|
|
(test1 "foo" "bar" "--test"))
|
2001-08-02 10:13:03 +00:00
|
|
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
(with-test-prefix "not specifying predicate"
|
|
|
|
|
|
|
|
|
|
|
|
(define (test2 . args)
|
|
|
|
|
|
(getopt-long args `((test (value #t)))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "option has arg"
|
|
|
|
|
|
(equal? (test2 "foo" "bar" "--test=foo")
|
|
|
|
|
|
'((() "bar") (test . "foo"))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "option has no arg"
|
|
|
|
|
|
(equal? (test2 "foo" "bar")
|
|
|
|
|
|
'((() "bar"))))
|
|
|
|
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
(with-test-prefix "value optional"
|
|
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(define (test3 . args)
|
|
|
|
|
|
(getopt-long args '((foo (value optional) (single-char #\f))
|
|
|
|
|
|
(bar))))
|
2001-08-02 10:13:03 +00:00
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(pass-if "long option `foo' w/ arg, long option `bar'"
|
|
|
|
|
|
(equal? (test3 "prg" "--foo" "fooval" "--bar")
|
|
|
|
|
|
'((()) (bar . #t) (foo . "fooval"))))
|
2001-08-02 10:13:03 +00:00
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(pass-if "short option `foo' w/ arg, long option `bar'"
|
|
|
|
|
|
(equal? (test3 "prg" "-f" "fooval" "--bar")
|
|
|
|
|
|
'((()) (bar . #t) (foo . "fooval"))))
|
2001-08-02 10:13:03 +00:00
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(pass-if "short option `foo', long option `bar', no args"
|
|
|
|
|
|
(equal? (test3 "prg" "-f" "--bar")
|
|
|
|
|
|
'((()) (bar . #t) (foo . #t))))
|
2001-08-02 10:13:03 +00:00
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(pass-if "long option `foo', long option `bar', no args"
|
|
|
|
|
|
(equal? (test3 "prg" "--foo" "--bar")
|
|
|
|
|
|
'((()) (bar . #t) (foo . #t))))
|
2001-08-02 10:13:03 +00:00
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(pass-if "long option `bar', short option `foo', no args"
|
|
|
|
|
|
(equal? (test3 "prg" "--bar" "-f")
|
|
|
|
|
|
'((()) (foo . #t) (bar . #t))))
|
2001-08-02 10:13:03 +00:00
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(pass-if "long option `bar', long option `foo', no args"
|
|
|
|
|
|
(equal? (test3 "prg" "--bar" "--foo")
|
|
|
|
|
|
'((()) (foo . #t) (bar . #t))))
|
2020-04-19 18:00:33 +01:00
|
|
|
|
|
2020-05-18 12:48:19 +01:00
|
|
|
|
(pass-if "long option with equals and space"
|
|
|
|
|
|
(equal? (test3 "prg" "--foo=" "test")
|
|
|
|
|
|
'((() "test") (foo . #t))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "long option with equals and space, not allowed a value"
|
|
|
|
|
|
(equal? (test3 "prg" "--foo=" "test")
|
|
|
|
|
|
'((() "test") (foo . #t))))
|
|
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(pass-if "--="
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(equal? (test3 "prg" "--=")
|
|
|
|
|
|
'((() "--="))))
|
|
|
|
|
|
|
|
|
|
|
|
)
|
2001-08-12 18:31:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(with-test-prefix "option-ref"
|
|
|
|
|
|
|
|
|
|
|
|
(define (test4 option-arg . args)
|
|
|
|
|
|
(equal? option-arg (option-ref (getopt-long
|
|
|
|
|
|
(cons "prog" args)
|
|
|
|
|
|
'((foo
|
|
|
|
|
|
(value optional)
|
|
|
|
|
|
(single-char #\f))
|
|
|
|
|
|
(bar)))
|
|
|
|
|
|
'foo #f)))
|
|
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(pass-if "option-ref `--foo 4'"
|
2001-08-12 18:31:10 +00:00
|
|
|
|
(test4 "4" "--foo" "4"))
|
|
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(pass-if "option-ref `-f 4'"
|
2001-08-12 18:31:10 +00:00
|
|
|
|
(test4 "4" "-f" "4"))
|
|
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(pass-if "option-ref `-f4'"
|
2001-08-12 19:03:34 +00:00
|
|
|
|
(test4 "4" "-f4"))
|
2001-08-12 18:31:10 +00:00
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(pass-if "option-ref `--foo=4'"
|
2001-08-12 18:31:10 +00:00
|
|
|
|
(test4 "4" "--foo=4"))
|
|
|
|
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
(with-test-prefix "required"
|
|
|
|
|
|
|
|
|
|
|
|
(define (test5 args specs)
|
|
|
|
|
|
(getopt-long (cons "foo" args) specs))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "not mentioned, not given"
|
|
|
|
|
|
(equal? (test5 '() '())
|
|
|
|
|
|
'((()))))
|
|
|
|
|
|
|
2011-02-10 12:09:18 +01:00
|
|
|
|
(pass-if-fatal-exception "not mentioned, given"
|
2001-08-12 19:03:34 +00:00
|
|
|
|
exception:no-such-option
|
|
|
|
|
|
(test5 '("--req") '((something))))
|
2001-08-12 18:31:10 +00:00
|
|
|
|
|
|
|
|
|
|
(pass-if "not specified required, not given"
|
|
|
|
|
|
(equal? (test5 '() '((req (required? #f))))
|
|
|
|
|
|
'((()))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "not specified required, given anyway"
|
|
|
|
|
|
(equal? (test5 '("--req") '((req (required? #f))))
|
|
|
|
|
|
'((()) (req . #t))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "not specified required, but w/ value, given anyway w/ \"=\" val"
|
|
|
|
|
|
(equal? (test5 '("--req=7") '((req (required? #f) (value #t))))
|
|
|
|
|
|
'((()) (req . "7"))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "not specified required, but w/ value, given anyway w/ non-\"=\" val"
|
|
|
|
|
|
(equal? (test5 '("--req" "7") '((req (required? #f) (value #t))))
|
|
|
|
|
|
'((()) (req . "7"))))
|
|
|
|
|
|
|
2011-02-10 12:09:18 +01:00
|
|
|
|
(pass-if-fatal-exception "specified required, not given"
|
2001-08-12 18:31:10 +00:00
|
|
|
|
exception:option-must-be-specified
|
|
|
|
|
|
(test5 '() '((req (required? #t)))))
|
|
|
|
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
(with-test-prefix "specified no-value, given anyway"
|
|
|
|
|
|
|
|
|
|
|
|
(define (test6 args specs)
|
|
|
|
|
|
(getopt-long (cons "foo" args) specs))
|
|
|
|
|
|
|
2011-02-10 12:09:18 +01:00
|
|
|
|
(pass-if-fatal-exception "using \"=\" syntax"
|
2001-08-12 19:03:34 +00:00
|
|
|
|
exception:option-does-not-support-arg
|
|
|
|
|
|
(test6 '("--maybe=yes") '((maybe))))
|
2001-08-12 18:31:10 +00:00
|
|
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
(with-test-prefix "specified arg required"
|
|
|
|
|
|
|
|
|
|
|
|
(define (test7 args)
|
|
|
|
|
|
(getopt-long (cons "foo" args) '((hmm (value #t) (single-char #\H))
|
|
|
|
|
|
(ignore))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "short opt, arg given"
|
|
|
|
|
|
(equal? (test7 '("-H" "99"))
|
|
|
|
|
|
'((()) (hmm . "99"))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "long non-\"=\" opt, arg given"
|
|
|
|
|
|
(equal? (test7 '("--hmm" "100"))
|
|
|
|
|
|
'((()) (hmm . "100"))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "long \"=\" opt, arg given"
|
|
|
|
|
|
(equal? (test7 '("--hmm=101"))
|
|
|
|
|
|
'((()) (hmm . "101"))))
|
|
|
|
|
|
|
2011-02-10 12:09:18 +01:00
|
|
|
|
(pass-if-fatal-exception "short opt, arg not given"
|
2001-08-12 18:31:10 +00:00
|
|
|
|
exception:option-must-have-arg
|
|
|
|
|
|
(test7 '("-H")))
|
|
|
|
|
|
|
2011-02-10 12:09:18 +01:00
|
|
|
|
(pass-if-fatal-exception "long non-\"=\" opt, arg not given (next arg an option)"
|
2001-08-12 19:03:34 +00:00
|
|
|
|
exception:option-must-have-arg
|
|
|
|
|
|
(test7 '("--hmm" "--ignore")))
|
2001-08-12 18:31:10 +00:00
|
|
|
|
|
2011-02-10 12:09:18 +01:00
|
|
|
|
(pass-if-fatal-exception "long \"=\" opt, arg not given"
|
2001-08-12 19:03:34 +00:00
|
|
|
|
exception:option-must-have-arg
|
|
|
|
|
|
(test7 '("--hmm")))
|
2001-08-12 18:31:10 +00:00
|
|
|
|
|
2001-08-02 10:13:03 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
2001-09-08 02:33:30 +00:00
|
|
|
|
(with-test-prefix "apples-blimps-catalexis example"
|
|
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(define (test8 . args)
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(equal? (sort (getopt-long (cons "foo" args)
|
|
|
|
|
|
'((apples (single-char #\a))
|
|
|
|
|
|
(blimps (single-char #\b) (value #t))
|
|
|
|
|
|
(catalexis (single-char #\c) (value #t))))
|
2001-09-08 02:33:30 +00:00
|
|
|
|
(lambda (a b)
|
|
|
|
|
|
(cond ((null? (car a)) #t)
|
|
|
|
|
|
((null? (car b)) #f)
|
|
|
|
|
|
(else (string<? (symbol->string (car a))
|
|
|
|
|
|
(symbol->string (car b)))))))
|
|
|
|
|
|
'((())
|
|
|
|
|
|
(apples . #t)
|
|
|
|
|
|
(blimps . "bang")
|
|
|
|
|
|
(catalexis . "couth"))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "normal 1" (test8 "-a" "-b" "bang" "-c" "couth"))
|
|
|
|
|
|
(pass-if "normal 2" (test8 "-ab" "bang" "-c" "couth"))
|
|
|
|
|
|
(pass-if "normal 3" (test8 "-ac" "couth" "-b" "bang"))
|
|
|
|
|
|
|
2020-05-18 12:48:19 +01:00
|
|
|
|
|
|
|
|
|
|
;;;; Dale Mellor 2020-04-14
|
|
|
|
|
|
;;;;
|
|
|
|
|
|
;;;; I disagree with this test: to my mind 'c' is 'b's argument, and
|
|
|
|
|
|
;;;; the other two arguments are non-options which get passed
|
|
|
|
|
|
;;;; through; there should not be an exception.
|
|
|
|
|
|
|
|
|
|
|
|
;; (pass-if-fatal-exception "bad ordering causes missing option"
|
|
|
|
|
|
;; exception:option-must-have-arg
|
|
|
|
|
|
;; (test8 "-abc" "couth" "bang"))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "clumped options with trailing mandatory value"
|
|
|
|
|
|
(A-TEST "-abc couth bang"
|
|
|
|
|
|
'((apples (single-char #\a))
|
|
|
|
|
|
(blimps (single-char #\b) (value #t))
|
|
|
|
|
|
(catalexis (single-char #\c) (value #t)))
|
|
|
|
|
|
'((() "couth" "bang") (apples . #t) (blimps . "c"))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "clumped options with trailing optional value"
|
|
|
|
|
|
(A-TEST "-abc couth bang"
|
|
|
|
|
|
'((apples (single-char #\a))
|
|
|
|
|
|
(blimps (single-char #\b)
|
|
|
|
|
|
(value optional)))
|
|
|
|
|
|
'((() "couth" "bang") (apples . #t) (blimps . "c"))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "clumped options with trailing optional value"
|
|
|
|
|
|
(A-TEST "-abc couth bang"
|
|
|
|
|
|
'((apples (single-char #\a))
|
|
|
|
|
|
(blimps (single-char #\b)
|
|
|
|
|
|
(value optional))
|
|
|
|
|
|
(catalexis (single-char #\c)
|
|
|
|
|
|
(value #t)))
|
|
|
|
|
|
'((() "bang")
|
|
|
|
|
|
(apples . #t) (blimps . #t) (catalexis . "couth"))))
|
2001-09-08 02:33:30 +00:00
|
|
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2011-05-08 21:36:54 +01:00
|
|
|
|
(with-test-prefix "multiple occurrences"
|
2001-09-08 02:33:30 +00:00
|
|
|
|
|
|
|
|
|
|
(define (test9 . args)
|
|
|
|
|
|
(equal? (getopt-long (cons "foo" args)
|
|
|
|
|
|
'((inc (single-char #\I) (value #t))
|
|
|
|
|
|
(foo (single-char #\f))))
|
|
|
|
|
|
'((()) (inc . "2") (foo . #t) (inc . "1"))))
|
|
|
|
|
|
|
|
|
|
|
|
;; terminology:
|
|
|
|
|
|
;; sf -- single-char free
|
|
|
|
|
|
;; sa -- single-char abutted
|
|
|
|
|
|
;; lf -- long free
|
|
|
|
|
|
;; la -- long abutted (using "=")
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "sf/sf" (test9 "-I" "1" "-f" "-I" "2"))
|
|
|
|
|
|
(pass-if "sa/sa" (test9 "-I1" "-f" "-I2"))
|
|
|
|
|
|
(pass-if "sf/sa" (test9 "-I" "1" "-f" "-I2"))
|
|
|
|
|
|
(pass-if "sa/sf" (test9 "-I1" "-f" "-I" "2"))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "lf/lf" (test9 "--inc" "1" "-f" "--inc" "2"))
|
|
|
|
|
|
(pass-if "la/la" (test9 "--inc=1" "-f" "--inc=2"))
|
|
|
|
|
|
(pass-if "lf/la" (test9 "--inc" "1" "-f" "--inc=2"))
|
|
|
|
|
|
(pass-if "la/lf" (test9 "--inc=1" "-f" "--inc" "2"))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "sf/lf" (test9 "-I" "1" "-f" "--inc" "2"))
|
|
|
|
|
|
(pass-if "lf/sf" (test9 "--inc" "1" "-f" "-I" "2"))
|
|
|
|
|
|
(pass-if "sf/la" (test9 "-I" "1" "-f" "--inc=2"))
|
|
|
|
|
|
(pass-if "la/sf" (test9 "--inc=1" "-f" "-I" "2"))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "sa/lf" (test9 "-I1" "-f" "--inc" "2"))
|
|
|
|
|
|
(pass-if "lf/sa" (test9 "--inc" "1" "-f" "-I2"))
|
|
|
|
|
|
(pass-if "sa/la" (test9 "-I1" "-f" "--inc=2"))
|
|
|
|
|
|
(pass-if "la/sa" (test9 "--inc=1" "-f" "-I2"))
|
|
|
|
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2011-05-08 22:21:51 +01:00
|
|
|
|
(with-test-prefix "stop-at-first-non-option"
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "guile-tools compile example"
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(equal? (getopt-long '("guile-tools" "compile" "-Wformat" "eval.scm" "-o" "eval.go")
|
2011-05-08 22:21:51 +01:00
|
|
|
|
'((help (single-char #\h))
|
|
|
|
|
|
(version (single-char #\v)))
|
|
|
|
|
|
#:stop-at-first-non-option #t)
|
|
|
|
|
|
'((() "compile" "-Wformat" "eval.scm" "-o" "eval.go"))))
|
|
|
|
|
|
|
2020-05-18 12:48:19 +01:00
|
|
|
|
(pass-if "stop after option"
|
|
|
|
|
|
(equal? (getopt-long '("foo" "-a" "3" "4" "-b" "4")
|
|
|
|
|
|
'((about (single-char #\a) (value #t))
|
|
|
|
|
|
(breathe (single-char #\b) (value #t)))
|
|
|
|
|
|
#:stop-at-first-non-option #t)
|
|
|
|
|
|
'((() "4" "-b" "4") (about . "3"))))
|
2011-05-08 22:21:51 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(with-test-prefix "stop at end-of-options marker"
|
|
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(define* (test args expectation #:key stop-at-first-non-option)
|
|
|
|
|
|
(A-TEST args
|
|
|
|
|
|
'((abby) (ben) (charles))
|
|
|
|
|
|
expectation
|
|
|
|
|
|
#:stop-at-first-non-option stop-at-first-non-option))
|
2020-04-19 18:00:04 +01:00
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(pass-if "stop at start" (test "-- --abby" '((() "--abby"))))
|
2020-04-19 18:00:04 +01:00
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(pass-if "stop in middle" (test "--abby dave -- --ben"
|
|
|
|
|
|
'((() "dave" "--ben") (abby . #t))))
|
2020-04-19 18:00:04 +01:00
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(pass-if "stop at end" (test "--abby dave --ben --"
|
|
|
|
|
|
'((() "dave") (abby . #t) (ben . #t))))
|
2020-04-19 18:00:04 +01:00
|
|
|
|
|
|
|
|
|
|
(pass-if "marker before first non-option"
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(test "--abby -- --ben dave --charles"
|
|
|
|
|
|
'((() "--ben" "dave" "--charles") (abby . #t))
|
|
|
|
|
|
#:stop-at-first-non-option #t))
|
2020-04-19 18:00:33 +01:00
|
|
|
|
|
2020-05-18 12:48:19 +01:00
|
|
|
|
(pass-if "first non-option before marker"
|
|
|
|
|
|
(test "--abby dave --ben -- --charles"
|
|
|
|
|
|
'((() "dave" "--ben" "--" "--charles") (abby . #t))
|
|
|
|
|
|
#:stop-at-first-non-option #t))
|
|
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(pass-if "double end marker"
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(test "--abby -- -- --ben"
|
|
|
|
|
|
'((() "--" "--ben") (abby . #t))))
|
2020-04-19 18:00:04 +01:00
|
|
|
|
|
|
|
|
|
|
(pass-if "separated double end markers"
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(test "--abby dave -- --ben -- --charles"
|
|
|
|
|
|
'((() "dave" "--ben" "--" "--charles")
|
|
|
|
|
|
(abby . #t))))
|
2020-04-19 18:00:04 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(with-test-prefix "negative numbers for option values"
|
|
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(define (test args expectation)
|
|
|
|
|
|
(A-TEST args
|
|
|
|
|
|
`((arthur (single-char #\a) (value optional)
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(predicate ,string->number))
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(beth (single-char #\b) (value #t)
|
|
|
|
|
|
(predicate ,string->number))
|
|
|
|
|
|
(charles (single-char #\c) (value optional))
|
|
|
|
|
|
(dave (single-char #\d) (value #t)))
|
|
|
|
|
|
expectation))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "predicated --optional=-1"
|
|
|
|
|
|
(test "--arthur=-1" '((()) (arthur . "-1"))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "predicated -o-1"
|
|
|
|
|
|
(test "-a-1" '((()) (arthur . "-1"))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "predicated --optional -1"
|
|
|
|
|
|
(test "--arthur -1" '((()) (arthur . "-1"))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "predicated -o -1"
|
|
|
|
|
|
(test "-a -1" '((()) (arthur . "-1"))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "predicated --mandatory=-1"
|
|
|
|
|
|
(test "--beth=-1" '((()) (beth . "-1"))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "predicated -m-1"
|
|
|
|
|
|
(test "-b-1" '((()) (beth . "-1"))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "predicated --mandatory -1"
|
|
|
|
|
|
(test "--beth -1" '((()) (beth . "-1"))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "predicated -m -1"
|
|
|
|
|
|
(test "-b -1" '((()) (beth . "-1"))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "non-predicated --optional=-1"
|
|
|
|
|
|
(test "--charles=-1" '((()) (charles . "-1"))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "non-predicated -o-1"
|
|
|
|
|
|
(test "-c-1" '((()) (charles . "-1"))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "non-predicated --mandatory=-1"
|
|
|
|
|
|
(test "--dave=-1" '((()) (dave . "-1"))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "non-predicated -m-1"
|
|
|
|
|
|
(test "-d-1" '((()) (dave . "-1"))))
|
|
|
|
|
|
|
2020-05-18 12:48:19 +01:00
|
|
|
|
(pass-if-fatal-exception "non-predicated --optional -1"
|
|
|
|
|
|
exception:no-such-option
|
|
|
|
|
|
(test "--charles -1" '((()) (charles . "-1"))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if-fatal-exception "non-predicated -o -1"
|
|
|
|
|
|
exception:no-such-option
|
|
|
|
|
|
(test "-c -1" '((()) (charles . "-1"))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "non-predicated --mandatory=-1"
|
|
|
|
|
|
(test "--dave=-1" '((()) (dave . "-1"))))
|
|
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(pass-if "non-predicated --mandatory -1"
|
|
|
|
|
|
(test "--dave -1" '((()) (dave . "-1"))))
|
2020-05-18 12:48:19 +01:00
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(pass-if "non-predicated -m -1"
|
|
|
|
|
|
(test "-d -1" '((()) (dave . "-1"))))
|
2020-05-18 12:48:19 +01:00
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
|
|
|
|
|
|
|
2020-05-18 12:48:19 +01:00
|
|
|
|
(with-test-prefix "negative numbers as short options"
|
|
|
|
|
|
|
|
|
|
|
|
(define (test args expectation)
|
|
|
|
|
|
(A-TEST args
|
|
|
|
|
|
`((zero (single-char #\0) (value #f))
|
|
|
|
|
|
(one (single-char #\1) (value #t)
|
|
|
|
|
|
(predicate ,string->number))
|
|
|
|
|
|
(two (single-char #\2) (value optional)
|
|
|
|
|
|
(predicate ,string->number))
|
|
|
|
|
|
(three (single-char #\3) (value #t)
|
|
|
|
|
|
(predicate ,(λ (in) (not (string->number in)))))
|
|
|
|
|
|
(four (single-char #\4) (value optional)
|
|
|
|
|
|
(predicate ,(λ (in) (not (string->number in)))))
|
|
|
|
|
|
)
|
|
|
|
|
|
expectation))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "-0 -2" (test "-0 -2" '((()) (zero . #t) (two . #t))))
|
|
|
|
|
|
(pass-if "-1 -2" (test "-1 -2" '((()) (one . "-2"))))
|
|
|
|
|
|
(pass-if "-2 -3" (test "-2 -3" '((()) (two . "-3"))))
|
|
|
|
|
|
(pass-if "-0 -4 test" (test "-0 -4 test"
|
|
|
|
|
|
'((()) (zero . #t) (four . "test"))))
|
|
|
|
|
|
(pass-if "-4 -2" (test "-4 -2" '((()) (four . #t) (two . #t))))
|
|
|
|
|
|
(pass-if-fatal-exception "-4 -3" exception:option-must-have-arg
|
|
|
|
|
|
(test "-4 -3" '((()))))
|
|
|
|
|
|
(pass-if "-3a" (test "-3a" '((()) (three . "a"))))
|
|
|
|
|
|
(pass-if "-13" (test "-13" '((()) (one . "3"))))
|
|
|
|
|
|
(pass-if "-03a" (test "-03a" '((()) (zero . #t) (three . "a"))))
|
|
|
|
|
|
(pass-if "-023" (test "-023" '((()) (zero . #t) (two . "3"))))
|
|
|
|
|
|
(pass-if "-025" (test "-025" '((()) (zero . #t) (two . "5"))))
|
|
|
|
|
|
(pass-if-fatal-exception "-025a" exception:no-such-option
|
|
|
|
|
|
(test "-025a" '((()) (zero . #t) (two . "5"))))
|
|
|
|
|
|
(pass-if "-02 a" (test "-02 a" '((() "a") (zero . #t) (two . #t))))
|
|
|
|
|
|
(pass-if-fatal-exception "-02a" exception:no-such-option
|
|
|
|
|
|
(test "-02a" '((()))))
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(with-test-prefix "mcron backwards compatibility"
|
|
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(define (test args expectation)
|
|
|
|
|
|
(A-TEST args
|
|
|
|
|
|
`((daemon (single-char #\d) (value #f))
|
|
|
|
|
|
(stdin (single-char #\i) (value #t)
|
|
|
|
|
|
(predicate ,(λ (in) (or (string=? in "guile")
|
|
|
|
|
|
(string=? in "vixie")))))
|
|
|
|
|
|
(schedule (single-char #\s) (value optional)
|
|
|
|
|
|
(predicate ,(λ (in) (or (eq? in #t)
|
|
|
|
|
|
(and (string? in)
|
|
|
|
|
|
(string->number in))))))
|
|
|
|
|
|
(help (single-char #\?))
|
|
|
|
|
|
(version (single-char #\V)))
|
|
|
|
|
|
expectation))
|
2020-04-19 18:00:04 +01:00
|
|
|
|
|
|
|
|
|
|
(pass-if "-s8" (test "-s8 file" '((() "file") (schedule . "8"))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "-s 8" (test "-s 8 file" '((() "file") (schedule . "8"))))
|
|
|
|
|
|
|
2020-05-18 12:48:19 +01:00
|
|
|
|
(pass-if "-s file"
|
|
|
|
|
|
(test "-s file" '((() "file") (schedule . #t))))
|
|
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(pass-if "-sd file"
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(test "-sd file" '((() "file") (daemon . #t) (schedule . #t))))
|
2020-04-19 18:00:33 +01:00
|
|
|
|
|
2020-05-18 12:48:19 +01:00
|
|
|
|
(pass-if "-ds file"
|
|
|
|
|
|
(test "-ds file" '((() "file") (daemon . #t) (schedule . #t))))
|
|
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
(pass-if "--schedule=8" (test "--schedule=8 file"
|
|
|
|
|
|
'((() "file") (schedule . "8"))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "--schedule 8" (test "--schedule 8 file"
|
|
|
|
|
|
'((() "file") (schedule . "8"))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "-ds8" (test "-ds8 file"
|
|
|
|
|
|
'((() "file") (daemon . #t) (schedule . "8"))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "-ds 8" (test "-ds 8 file"
|
|
|
|
|
|
'((() "file") (daemon . #t) (schedule . "8"))))
|
|
|
|
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2020-04-19 18:00:04 +01:00
|
|
|
|
|
2001-08-02 10:13:03 +00:00
|
|
|
|
;;; getopt-long.test ends here
|