ported the documentation for the framework's test library -- also extended srcdoc.ss a little bit
svn: r9499
This commit is contained in:
parent
6ffcad639c
commit
6a53f96e06
|
@ -821,84 +821,10 @@
|
||||||
(define test:mouse-click mouse-click)
|
(define test:mouse-click mouse-click)
|
||||||
(define test:new-window new-window)
|
(define test:new-window new-window)
|
||||||
|
|
||||||
#;
|
|
||||||
(provide/doc
|
(provide/doc
|
||||||
(proc-doc
|
(proc-doc/names
|
||||||
test:number-pending-actions
|
test:button-push
|
||||||
(-> number?)
|
(-> (or/c (λ (str)
|
||||||
@{Returns the number of pending events (those that haven't completed yet)}))
|
|
||||||
|
|
||||||
(provide/contract/docs
|
|
||||||
(test:number-pending-actions
|
|
||||||
(-> number?)
|
|
||||||
()
|
|
||||||
"Returns the number of pending events (those that haven't completed yet)")
|
|
||||||
|
|
||||||
(test:run-interval
|
|
||||||
(case->
|
|
||||||
(number? . -> . void?)
|
|
||||||
(-> number?))
|
|
||||||
((msec) ())
|
|
||||||
"See also"
|
|
||||||
"\\hyperref{Actions and completeness}{Actions and completeness, section~}{}{fw:actions-completeness}."
|
|
||||||
"The first case in the case-lambda sets"
|
|
||||||
"the run interval to \\var{msec} milliseconds and the second"
|
|
||||||
"returns the current setting.")
|
|
||||||
|
|
||||||
(test:reraise-error
|
|
||||||
(-> void?)
|
|
||||||
()
|
|
||||||
"See also"
|
|
||||||
"\\hyperref{Errors}{Errors, section~}{}{fw:test:errors}.")
|
|
||||||
|
|
||||||
(test:run-one
|
|
||||||
((-> void?) . -> . void?)
|
|
||||||
(f)
|
|
||||||
"Runs the function \\var{f} as if it was a simulated event. See also"
|
|
||||||
"\\hyperref{the test section}{section ~}{}{fw:test}.")
|
|
||||||
|
|
||||||
(test:current-get-eventspaces
|
|
||||||
(case->
|
|
||||||
((-> (listof eventspace?)) . -> . void?)
|
|
||||||
(-> (-> (listof eventspace?))))
|
|
||||||
((func) ())
|
|
||||||
|
|
||||||
"This parameter that specifies which "
|
|
||||||
"\\hyperref{eventspaces}{eventspace (see section~}{)}{eventspaceinfo}"
|
|
||||||
"are considered when finding the frontmost frame."
|
|
||||||
|
|
||||||
"The first case"
|
|
||||||
"sets the parameter to \\var{func}. The procedure \\var{func} will be"
|
|
||||||
"invoked with no arguments to determine the eventspaces to consider"
|
|
||||||
"when finding the frontmost frame for simulated user events."
|
|
||||||
|
|
||||||
"The second case"
|
|
||||||
"returns the current value of the parameter. This will be a procedure"
|
|
||||||
"which, when invoked, returns a list of eventspaces.")
|
|
||||||
(test:close-top-level-window
|
|
||||||
((is-a?/c top-level-window<%>) . -> . void?)
|
|
||||||
(tlw)
|
|
||||||
"Use this function to simulate clicking on the close box of a frame."
|
|
||||||
"Closes \\var{tlw} with this expression:"
|
|
||||||
""
|
|
||||||
"\\begin{schemedisplay}"
|
|
||||||
"(when (send tlw can-close?)"
|
|
||||||
" (send tlw on-close)"
|
|
||||||
" (send tlw show #f))"
|
|
||||||
"\\end{schemedisplay}")
|
|
||||||
|
|
||||||
(test:top-level-focus-window-has?
|
|
||||||
(((is-a?/c area<%>) . -> . boolean?) . -> . boolean?)
|
|
||||||
(test)
|
|
||||||
"Calls \\var{test} for each child of the top-level-focus-frame"
|
|
||||||
"and returns \\scheme|#t| if \\var{test} ever does, otherwise"
|
|
||||||
"returns \\scheme|#f|. If there"
|
|
||||||
"is no top-level-focus-window, returns \\scheme|#f|.")
|
|
||||||
|
|
||||||
;; ((frame-has? p) f) =
|
|
||||||
;; f is a frame and it has a child (in it or a subpanel) that responds #t to p
|
|
||||||
(test:button-push
|
|
||||||
((or/c (λ (str)
|
|
||||||
(and (string? str)
|
(and (string? str)
|
||||||
(test:top-level-focus-window-has?
|
(test:top-level-focus-window-has?
|
||||||
(λ (c)
|
(λ (c)
|
||||||
|
@ -914,94 +840,102 @@
|
||||||
(λ (btn)
|
(λ (btn)
|
||||||
(test:top-level-focus-window-has?
|
(test:top-level-focus-window-has?
|
||||||
(λ (c) (eq? c btn))))))
|
(λ (c) (eq? c btn))))))
|
||||||
. -> .
|
|
||||||
void?)
|
void?)
|
||||||
(button)
|
(button)
|
||||||
"Simulates pushing \\var{button}. If a string is supplied, the"
|
@{Simulates pushing @scheme[button]. If a string is supplied, the
|
||||||
"primitive searches for a button labelled with that string in the"
|
primitive searches for a button labelled with that string in the
|
||||||
"active frame. Otherwise, it pushes the button argument.")
|
active frame. Otherwise, it pushes the button argument.})
|
||||||
|
|
||||||
(test:set-radio-box!
|
(proc-doc/names
|
||||||
((or/c string? (is-a?/c radio-box%)) (or/c string? number?) . -> . void?)
|
test:set-radio-box!
|
||||||
|
(-> (or/c string? (is-a?/c radio-box%)) (or/c string? number?) void?)
|
||||||
(radio-box state)
|
(radio-box state)
|
||||||
"Sets the radio-box to \\var{state}. If \\var{state} is a"
|
@{Sets the radio-box to @scheme[state]. If @scheme[state] is a
|
||||||
"string, this function finds the choice with that label and"
|
string, this function finds the choice with that label and
|
||||||
"if it is a number, it uses the number as an index into the"
|
if it is a number, it uses the number as an index into the
|
||||||
"state. If the number is out of range or if the label isn't"
|
state. If the number is out of range or if the label isn't
|
||||||
"in the radio box, an exception is raised."
|
in the radio box, an exception is raised.
|
||||||
""
|
|
||||||
"If \\var{radio-box} is a string, this function searches for a"
|
|
||||||
"\\iscmclass{radio-box} with a label matching that string,"
|
|
||||||
"otherwise it uses \\var{radio-box} itself.")
|
|
||||||
|
|
||||||
(test:set-radio-box-item!
|
If @scheme[radio-box] is a string, this function searches for a
|
||||||
(string? . -> . void?)
|
@scheme[radio-box%] object with a label matching that string,
|
||||||
|
otherwise it uses @scheme[radio-box] itself.})
|
||||||
|
|
||||||
|
(proc-doc/names
|
||||||
|
test:set-radio-box-item!
|
||||||
|
(-> string? void?)
|
||||||
(entry)
|
(entry)
|
||||||
"Finds a \\iscmclass{radio-box} that has a label \\var{entry}"
|
@{Finds a @scheme[radio-box%] that has a label @scheme[entry]
|
||||||
"and sets the radio-box to \\var{entry}.")
|
and sets the radio-box to @scheme[entry].})
|
||||||
(test:set-check-box!
|
|
||||||
((or/c string? (is-a?/c check-box%)) boolean? . -> . void?)
|
(proc-doc/names
|
||||||
|
test:set-check-box!
|
||||||
|
(-> (or/c string? (is-a?/c check-box%)) boolean? void?)
|
||||||
(check-box state)
|
(check-box state)
|
||||||
"Clears the \\iscmclass{check-box} item if \\var{state} is \\rawscm{\\#f}, and sets it"
|
@{Clears the @scheme[check-box%] item if @scheme[state] is @scheme[#f], and sets it
|
||||||
"otherwise."
|
otherwise.
|
||||||
""
|
|
||||||
"If \\var{check-box} is a string,"
|
|
||||||
"this function searches for a \\iscmclass{check-box} with a label matching that string,"
|
|
||||||
"otherwise it uses \\var{check-box} itself.")
|
|
||||||
|
|
||||||
(test:set-choice!
|
If @scheme[check-box] is a string,
|
||||||
((or/c string? (is-a?/c choice%)) (or/c string? (and/c number? exact? integer? positive?)) . -> . void?)
|
this function searches for a @scheme[check-box%] with a label matching that string,
|
||||||
|
otherwise it uses @scheme[check-box] itself.})
|
||||||
|
|
||||||
|
(proc-doc/names
|
||||||
|
test:set-choice!
|
||||||
|
(-> (or/c string? (is-a?/c choice%)) (or/c string? (and/c number? exact? integer? positive?))
|
||||||
|
void?)
|
||||||
(choice str)
|
(choice str)
|
||||||
"Selects \\var{choice}'s item \\var{str}. If \\var{choice} is a string,"
|
@{Selects @scheme[choice]'s item @scheme[str]. If @scheme[choice] is a string,
|
||||||
"this function searches for a \\iscmclass{choice} with a label matching"
|
this function searches for a @scheme[choice%] with a label matching
|
||||||
"that string, otherwise it uses \\var{choice} itself.")
|
that string, otherwise it uses @scheme[choice] itself.})
|
||||||
|
|
||||||
(test:set-list-box!
|
(proc-doc/names
|
||||||
((or/c string? (is-a?/c list-box%)) (or/c string? (and/c number? exact? integer? positive?)) . -> . void?)
|
test:set-list-box!
|
||||||
|
(-> (or/c string? (is-a?/c list-box%)) (or/c string? (and/c number? exact? integer? positive?))
|
||||||
|
void?)
|
||||||
(choice str)
|
(choice str)
|
||||||
"Selects \\var{list-box}'s item \\var{str}. If \\var{list-box} is a string,"
|
@{Selects @scheme[list-box]'s item @scheme[str]. If @scheme[list-box] is a string,
|
||||||
"this function searches for a \\iscmclass{list-box} with a label matching"
|
this function searches for a @scheme[list-box%] with a label matching
|
||||||
"that string, otherwise it uses \\var{list-box} itself.")
|
that string, otherwise it uses @scheme[list-box] itself.})
|
||||||
|
|
||||||
(test:keystroke
|
(proc-doc/names
|
||||||
|
test:keystroke
|
||||||
(->* ((or/c char? symbol?))
|
(->* ((or/c char? symbol?))
|
||||||
((listof (symbols 'alt 'control 'meta 'shift 'noalt 'nocontrol 'nometea 'noshift)))
|
((listof (symbols 'alt 'control 'meta 'shift 'noalt 'nocontrol 'nometea 'noshift)))
|
||||||
void?)
|
void?)
|
||||||
((key)
|
((key)
|
||||||
((modifier-list null)))
|
((modifier-list null)))
|
||||||
"This function simulates a user pressing a key. The argument, \\var{key},"
|
@{This function simulates a user pressing a key. The argument, @scheme[key],
|
||||||
"is just like the argument to the"
|
is just like the argument to the
|
||||||
"@link key-event get-key-code"
|
@method[key-event% get-key-code]
|
||||||
"method of the"
|
method of the @scheme[key-event%] class.
|
||||||
"@link key-event"
|
|
||||||
"class. "
|
|
||||||
""
|
|
||||||
"{\\it Note:}"
|
|
||||||
"To send the ``Enter'' key, use \\verb|#\return|,"
|
|
||||||
"not \\verb|#\newline|."
|
|
||||||
""
|
|
||||||
"The \\rawscm{'shift} or \\rawscm{'noshift} modifier is implicitly set from \\var{key},"
|
|
||||||
"but is overridden by the argument list. The \\rawscm{'shift} modifier is"
|
|
||||||
"set for any capitol alpha-numeric letters and any of the following characters:"
|
|
||||||
"\\begin{schemedisplay}"
|
|
||||||
"#\\? #\\: #\\~ #\\\\ #\\|"
|
|
||||||
"#\\< #\\> #\\{ #\\} #\\[ #\\] #\\( #\\)"
|
|
||||||
"#\\! #\\@ #\\# #\\$ #\\% #\\^ #\\& #\\* #\\_ #\\+"
|
|
||||||
"\\end{schemedisplay}"
|
|
||||||
""
|
|
||||||
"If conflicting modifiers are provided, the ones later in the list are used.")
|
|
||||||
|
|
||||||
(test:menu-select
|
@italic{Note:}
|
||||||
|
To send the ``Enter'' key, use @scheme[#\return],
|
||||||
|
not @scheme[#\newline].
|
||||||
|
|
||||||
|
The @scheme['shift] or @scheme['noshift] modifier is implicitly set from @scheme[key],
|
||||||
|
but is overridden by the argument list. The @scheme['shift] modifier is
|
||||||
|
set for any capitol alpha-numeric letters and any of the following characters:
|
||||||
|
@schemeblock[
|
||||||
|
#\? #\: #\~ #\\ #\|
|
||||||
|
#\< #\> #\{ #\} #\[ #\] #\( #\)
|
||||||
|
#\! #\@ #\# #\$ #\% #\^ #\& #\* #\_ #\+
|
||||||
|
]
|
||||||
|
|
||||||
|
If conflicting modifiers are provided, the ones later in the list are used.})
|
||||||
|
|
||||||
|
(proc-doc/names
|
||||||
|
test:menu-select
|
||||||
(string? string? . -> . void?)
|
(string? string? . -> . void?)
|
||||||
(menu item)
|
(menu item)
|
||||||
"Selects the menu-item named \\var{item} in the menu named \\var{menu}."
|
@{Selects the menu-item named @scheme[item] in the menu named @scheme[menu].
|
||||||
""
|
|
||||||
"{\\it Note:}"
|
|
||||||
"The string for the menu item does not include its keyboard equivalent."
|
|
||||||
"For example, to select ``New'' from the ``File'' menu, "
|
|
||||||
"use ``New'', not ``New Ctrl+m n''.")
|
|
||||||
|
|
||||||
(test:mouse-click
|
@italic{Note:}
|
||||||
|
The string for the menu item does not include its keyboard equivalent.
|
||||||
|
For example, to select ``New'' from the ``File'' menu,
|
||||||
|
use ``New'', not ``New Ctrl+m n''.})
|
||||||
|
|
||||||
|
(proc-doc/names
|
||||||
|
test:mouse-click
|
||||||
(->*
|
(->*
|
||||||
((symbols 'left 'middle 'right)
|
((symbols 'left 'middle 'right)
|
||||||
(and/c exact? integer?)
|
(and/c exact? integer?)
|
||||||
|
@ -1010,27 +944,90 @@
|
||||||
void?)
|
void?)
|
||||||
((button x y)
|
((button x y)
|
||||||
((modifiers null)))
|
((modifiers null)))
|
||||||
"Simulates a mouse click at the coordinate: $(x,y)$ in the currently"
|
@{Simulates a mouse click at the coordinate (x,y) in the currently
|
||||||
"focused \\iscmintf{window}, assuming that it supports the "
|
focused @scheme[window], assuming that it supports the
|
||||||
"@ilink canvas on-event"
|
@method[canvas<%> on-event] method.
|
||||||
"method."
|
Use @scheme[test:button-push] to click on a button.
|
||||||
"Use"
|
|
||||||
"@flink test:button-push"
|
|
||||||
"to click on a button."
|
|
||||||
""
|
|
||||||
"On the Macintosh, \\rawscm{'right} corresponds to holding down the command"
|
|
||||||
"modifier key while clicking and \\rawscm{'middle} cannot be generated."
|
|
||||||
""
|
|
||||||
"Under Windows, \\rawscm{'middle} can only be generated if the user has a"
|
|
||||||
"three button mouse."
|
|
||||||
""
|
|
||||||
"The modifiers later in the list \\var{modifiers} take precedence over"
|
|
||||||
"ones that appear earlier.")
|
|
||||||
|
|
||||||
(test:new-window
|
On the Macintosh, @scheme['right] corresponds to holding down the command
|
||||||
((is-a?/c window<%>) . -> . void?)
|
modifier key while clicking and @scheme['middle] cannot be generated.
|
||||||
|
|
||||||
|
Under Windows, @scheme['middle] can only be generated if the user has a
|
||||||
|
three button mouse.
|
||||||
|
|
||||||
|
The modifiers later in the list @scheme[modifiers] take precedence over
|
||||||
|
ones that appear earlier.})
|
||||||
|
|
||||||
|
(proc-doc/names
|
||||||
|
test:run-interval
|
||||||
|
(case->
|
||||||
|
(number? . -> . void?)
|
||||||
|
(-> number?))
|
||||||
|
((msec) ())
|
||||||
|
@{See also @secref{test:actions-completeness}.
|
||||||
|
The first case in the case-lambda sets
|
||||||
|
the run interval to @scheme[msec] milliseconds and the second
|
||||||
|
returns the current setting.})
|
||||||
|
|
||||||
|
(parameter-doc
|
||||||
|
test:current-get-eventspaces
|
||||||
|
(parameter/c (-> (listof eventspace?)))
|
||||||
|
func
|
||||||
|
|
||||||
|
@{This parameter that specifies which
|
||||||
|
\\hyperref{eventspaces}{eventspace see section~}{}{eventspaceinfo}
|
||||||
|
are considered when finding the frontmost frame.
|
||||||
|
The first case
|
||||||
|
sets the parameter to @scheme[func]. The procedure @scheme[func] will be
|
||||||
|
invoked with no arguments to determine the eventspaces to consider
|
||||||
|
when finding the frontmost frame for simulated user events.
|
||||||
|
The second case
|
||||||
|
returns the current value of the parameter. This will be a procedure
|
||||||
|
which, when invoked, returns a list of eventspaces.})
|
||||||
|
|
||||||
|
(proc-doc/names
|
||||||
|
test:new-window
|
||||||
|
(-> (is-a?/c window<%>) void?)
|
||||||
(window)
|
(window)
|
||||||
"Moves the keyboard focus to a new window within the currently active"
|
@{Moves the keyboard focus to a new window within the currently active
|
||||||
"frame. Unfortunately, neither this function nor any other function in"
|
frame. Unfortunately, neither this function nor any other function in
|
||||||
"the test engine can cause the focus to move from the top-most (active)"
|
the test engine can cause the focus to move from the top-most (active) frame.})
|
||||||
"frame. "))
|
|
||||||
|
(proc-doc/names
|
||||||
|
test:close-top-level-window
|
||||||
|
(-> (is-a?/c top-level-window<%>) void?)
|
||||||
|
(tlw)
|
||||||
|
@{Use this function to simulate clicking on the close box of a frame.
|
||||||
|
Closes @scheme[tlw] with this expression:
|
||||||
|
@schemeblock[
|
||||||
|
(when (send tlw can-close?)
|
||||||
|
(send tlw on-close)
|
||||||
|
(send tlw show #f))]})
|
||||||
|
|
||||||
|
(proc-doc/names
|
||||||
|
test:top-level-focus-window-has?
|
||||||
|
(-> (-> (is-a?/c area<%>) boolean?) boolean?)
|
||||||
|
(test)
|
||||||
|
@{Calls @scheme[test] for each child of the top-level-focus-frame
|
||||||
|
and returns @scheme[#t] if @scheme[test] ever does, otherwise
|
||||||
|
returns @scheme[#f]. If there
|
||||||
|
is no top-level-focus-window, returns @scheme[#f].})
|
||||||
|
|
||||||
|
|
||||||
|
(proc-doc
|
||||||
|
test:number-pending-actions
|
||||||
|
(-> number?)
|
||||||
|
@{Returns the number of pending events (those that haven't completed yet)})
|
||||||
|
|
||||||
|
(proc-doc
|
||||||
|
test:reraise-error
|
||||||
|
(-> void?)
|
||||||
|
@{See also @secref{test:errors}.})
|
||||||
|
|
||||||
|
(proc-doc/names
|
||||||
|
test:run-one
|
||||||
|
(-> (-> void?) void?)
|
||||||
|
(f)
|
||||||
|
@{Runs the function @scheme[f] as if it was a simulated event.}))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
|
|
||||||
(provide require/doc
|
(provide require/doc
|
||||||
provide/doc
|
provide/doc
|
||||||
proc-doc)
|
parameter-doc
|
||||||
|
proc-doc
|
||||||
|
proc-doc/names)
|
||||||
|
|
||||||
(define-syntax-rule (require/doc spec ...)
|
(define-syntax-rule (require/doc spec ...)
|
||||||
(void (quote-syntax (require/doc spec ...))))
|
(void (quote-syntax (require/doc spec ...))))
|
||||||
|
@ -53,26 +55,18 @@
|
||||||
(lambda (stx)
|
(lambda (stx)
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
[(_ id contract desc)
|
[(_ id contract desc)
|
||||||
(with-syntax ([(arg ...)
|
(with-syntax ([((arg ...) result)
|
||||||
(syntax-case #'contract (->d)
|
(syntax-case #'contract (->d -> values)
|
||||||
[(->d (req ...) () result)
|
[(->d (req ...) () (values [name res] ...))
|
||||||
#'(req ...)]
|
#'((req ...) (values res ...))]
|
||||||
|
[(->d (req ...) () [name res])
|
||||||
|
#'((req ...) res)]
|
||||||
|
[(-> result)
|
||||||
|
#'(() result)]
|
||||||
[else
|
[else
|
||||||
(raise-syntax-error
|
(raise-syntax-error
|
||||||
#f
|
#f
|
||||||
"unsupported procedure contract form (arguments)"
|
"unsupported procedure contract form (no argument names)"
|
||||||
stx
|
|
||||||
#'contract)])]
|
|
||||||
[result
|
|
||||||
(syntax-case #'contract (->d)
|
|
||||||
[(->d reqs opts (values [name res] ...))
|
|
||||||
#'(values res ...)]
|
|
||||||
[(->d reqs opts [name res])
|
|
||||||
#'res]
|
|
||||||
[else
|
|
||||||
(raise-syntax-error
|
|
||||||
#f
|
|
||||||
"unsupported procedure contract form (arguments)"
|
|
||||||
stx
|
stx
|
||||||
#'contract)])])
|
#'contract)])])
|
||||||
(values
|
(values
|
||||||
|
@ -80,4 +74,58 @@
|
||||||
#'(defproc (id arg ...) result . desc)
|
#'(defproc (id arg ...) result . desc)
|
||||||
#'(scribble/manual)))])))
|
#'(scribble/manual)))])))
|
||||||
|
|
||||||
|
(define-provide/doc-transformer proc-doc/names
|
||||||
|
(lambda (stx)
|
||||||
|
(syntax-case stx ()
|
||||||
|
[(_ id contract names desc)
|
||||||
|
(with-syntax ([header
|
||||||
|
(syntax-case #'(contract names) (->d -> values)
|
||||||
|
[((-> ctcs ... result) (arg-names ...))
|
||||||
|
(begin
|
||||||
|
(unless (= (length (syntax->list #'(ctcs ...)))
|
||||||
|
(length (syntax->list #'(arg-names ...))))
|
||||||
|
(raise-syntax-error #f "mismatched argument list and domain contract count" stx))
|
||||||
|
#'([(id (arg-names ctcs) ...) result]))]
|
||||||
|
|
||||||
|
[((->* (mandatory ...) (optional ...) result)
|
||||||
|
((mandatory-names ...)
|
||||||
|
((optional-names optional-default) ...)))
|
||||||
|
(begin
|
||||||
|
(unless (= (length (syntax->list #'(mandatory-names ...)))
|
||||||
|
(length (syntax->list #'(mandatory ...))))
|
||||||
|
(raise-syntax-error #f "mismatched mandatory argument list and domain contract count" stx))
|
||||||
|
(unless (= (length (syntax->list #'(optional-names ...)))
|
||||||
|
(length (syntax->list #'(optional ...))))
|
||||||
|
(raise-syntax-error #f "mismatched mandatory argument list and domain contract count" stx))
|
||||||
|
#'([(id (mandatory-names mandatory) ... (optional-names optional optional-default) ...)
|
||||||
|
result]))]
|
||||||
|
[((case-> (-> doms ... rng) ...)
|
||||||
|
((args ...) ...))
|
||||||
|
(begin
|
||||||
|
(for-each
|
||||||
|
(λ (doms args)
|
||||||
|
(unless (= (length (syntax->list doms))
|
||||||
|
(length (syntax->list args)))
|
||||||
|
(raise-syntax-error #f "mismatched case argument list and domain contract" stx)))
|
||||||
|
(syntax->list #'((doms ...) ...))
|
||||||
|
(syntax->list #'((args ...) ...)))
|
||||||
|
#'([(id (args doms) ...) rng] ...))]
|
||||||
|
[else
|
||||||
|
(raise-syntax-error
|
||||||
|
#f
|
||||||
|
"unsupported procedure contract form (no argument names)"
|
||||||
|
stx
|
||||||
|
#'contract)])])
|
||||||
|
(values
|
||||||
|
#'[id contract]
|
||||||
|
#'(defproc* header . desc)
|
||||||
|
#'(scribble/manual)))])))
|
||||||
|
|
||||||
|
(define-provide/doc-transformer parameter-doc
|
||||||
|
(lambda (stx)
|
||||||
|
(syntax-case stx (parameter/c)
|
||||||
|
[(_ id (parameter/c contract) arg-id desc)
|
||||||
|
(values
|
||||||
|
#'[id (parameter/c contract)]
|
||||||
|
#'(defparam id arg-id contract . desc)
|
||||||
|
#'(scribble/manual))])))
|
||||||
|
|
|
@ -1,8 +1,118 @@
|
||||||
#lang scribble/doc
|
#lang scribble/doc
|
||||||
@(require scribble/manual)
|
@(require scribble/manual scribble/extract)
|
||||||
@(require (for-label framework/framework))
|
@(require (for-label framework/framework))
|
||||||
@(require (for-label scheme/gui))
|
@(require (for-label scheme/gui))
|
||||||
@title{Test}
|
@title{Test}
|
||||||
|
|
||||||
@(require framework/framework-docs)
|
@(require framework/framework-docs)
|
||||||
|
@(defmodule framework/test)
|
||||||
|
|
||||||
|
The framework provides several new primitive functions that simulate
|
||||||
|
user actions, which may be used to test applications. You use these
|
||||||
|
primitives and combine them just as regular MzScheme functions. For
|
||||||
|
example,
|
||||||
|
@schemeblock[
|
||||||
|
(test:keystroke #\A)
|
||||||
|
(test:menu-select "File" "Save")
|
||||||
|
]
|
||||||
|
sends a keystroke event to the window with the keyboard focus and invokes
|
||||||
|
the callback function for the ``Save'' menu item from the ``File'' menu.
|
||||||
|
This has the same effect as if the user typed the key ``A'', pulled
|
||||||
|
down the ``File'' menu and selected ``Save''.
|
||||||
|
|
||||||
|
It is possible to load this portion of the framework without loading
|
||||||
|
the rest of the framework. Use
|
||||||
|
@scheme[(require framework/test)].
|
||||||
|
|
||||||
|
Currently, the test engine has primitives for pushing
|
||||||
|
buttons, setting check-boxes and choices, sending keystrokes,
|
||||||
|
selecting menu items and clicking the mouse. Many functions
|
||||||
|
that are also useful in application testing, such as
|
||||||
|
traversing a tree of panels, getting the text from a canvas,
|
||||||
|
determining if a window is shown, and so on, exist in MrEd.
|
||||||
|
|
||||||
|
@section[#:tag "test:actions-completeness"]{Actions and completeness}
|
||||||
|
|
||||||
|
The actions associated with a testing primitive may not have finished
|
||||||
|
when the primitive returns to its caller.
|
||||||
|
Some actions may yield control before they can complete.
|
||||||
|
For example, selecting ``Save As...'' from the ``File'' menu
|
||||||
|
opens a dialog box and will not complete until the ``OK''
|
||||||
|
or ``Cancel'' button is pushed.
|
||||||
|
|
||||||
|
However, all testing functions wait at least a minimum interval
|
||||||
|
before returning to give the action a chance to finish.
|
||||||
|
This interval controls the speed at which the test suite runs,
|
||||||
|
and gives some slack time for events to complete.
|
||||||
|
The default interval is 100 milliseconds. The interval can be queried
|
||||||
|
or set with @scheme[test:run-interval].
|
||||||
|
|
||||||
|
A primitive action will not return until the run-interval has
|
||||||
|
expired and the action has finished, raised an error, or yielded.
|
||||||
|
The number of incomplete actions is given by
|
||||||
|
@scheme[test:number-pending-actions].
|
||||||
|
|
||||||
|
@italic{Note:}
|
||||||
|
Once a primitive action is started, it is not possible to undo it
|
||||||
|
or kill its remaining effect.
|
||||||
|
Thus, it is not possible to write a utility that flushes the
|
||||||
|
incomplete actions and resets number-pending-actions to zero.
|
||||||
|
|
||||||
|
However, actions which do not complete right away often provide a
|
||||||
|
way to cancel themselves.
|
||||||
|
For example, many dialog boxes have a ``Cancel'' button which will
|
||||||
|
terminate the action with no further effect.
|
||||||
|
But this is accomplished by sending an additional action
|
||||||
|
(the button push), not by undoing the original action.
|
||||||
|
|
||||||
|
@section[#:tag "test:errors"]{Errors}
|
||||||
|
|
||||||
|
Errors in the primitive actions (which necessarily run in the
|
||||||
|
handler thread) are caught and reraised in the calling thread.
|
||||||
|
|
||||||
|
However, the primitive actions can only guarantee that the action
|
||||||
|
has started, and they may return before the action has completed.
|
||||||
|
As a consequence, an action may raise an error long after the
|
||||||
|
function that started it has returned.
|
||||||
|
In this case, the error is saved and reraised at the first opportunity
|
||||||
|
(the next primitive action).
|
||||||
|
|
||||||
|
The test engine keeps a buffer for one error, saving only the
|
||||||
|
first error. Any subsequent errors are discarded.
|
||||||
|
Reraising an error empties the buffer, allowing the next error
|
||||||
|
to be saved.
|
||||||
|
|
||||||
|
The function @scheme[test:reraise-error]
|
||||||
|
reraises any pending errors.
|
||||||
|
|
||||||
|
@section{Technical Issues}
|
||||||
|
|
||||||
|
@subsection{Active Frame}
|
||||||
|
|
||||||
|
The Self Test primitive actions all implicitly apply to the
|
||||||
|
top-most (active) frame.
|
||||||
|
|
||||||
|
@subsection{Thread Issues}
|
||||||
|
|
||||||
|
The code started by the primitive actions must run in the handler
|
||||||
|
thread of the eventspace where the event takes place. As a result,
|
||||||
|
the test suite that invokes the primitive actions must @italic{not} run
|
||||||
|
in that handler thread (or else some actions will deadlock). See
|
||||||
|
\Mrhyperref{the eventspace section}{see section~}{}{eventspaceinfo}
|
||||||
|
for more info.
|
||||||
|
|
||||||
|
@subsection{Window Manager (Unix only)}
|
||||||
|
|
||||||
|
In order for the Self Tester to work correctly, the window manager
|
||||||
|
must set the keyboard focus to follow the active frame.
|
||||||
|
This is the default behavior in Microsoft Windows and MacOS,
|
||||||
|
but not in X windows.
|
||||||
|
|
||||||
|
In X windows, you must explicitly tell your window manager to set the
|
||||||
|
keyboard focus to the top-most frame, regardless of the position of the
|
||||||
|
actual mouse.
|
||||||
|
|
||||||
|
@section{Test Functions}
|
||||||
|
|
||||||
@(def-fw-procs test)
|
@(def-fw-procs test)
|
||||||
|
@(include-extracted (lib "test.ss" "framework"))
|
||||||
|
|
|
@ -74,121 +74,6 @@ The precise set of exported names is:
|
||||||
@scheme[preferences:restore-defaults].
|
@scheme[preferences:restore-defaults].
|
||||||
}}
|
}}
|
||||||
|
|
||||||
@section{GUI Test Suite Utilities}
|
|
||||||
|
|
||||||
The framework provides several new primitive functions that simulate
|
|
||||||
user actions, which may be used to test applications. You use these
|
|
||||||
primitives and combine them just as regular MzScheme functions. For
|
|
||||||
example,
|
|
||||||
@schemeblock[
|
|
||||||
(test:keystroke #\A)
|
|
||||||
(test:menu-select "File" "Save")
|
|
||||||
]
|
|
||||||
sends a keystroke event to the window with the keyboard focus and invokes
|
|
||||||
the callback function for the ``Save'' menu item from the ``File'' menu.
|
|
||||||
This has the same effect as if the user typed the key ``A'', pulled
|
|
||||||
down the ``File'' menu and selected ``Save''.
|
|
||||||
|
|
||||||
It is possible to load this portion of the framework without loading
|
|
||||||
the rest of the framework. Use
|
|
||||||
@scheme[(require framework/test)].
|
|
||||||
|
|
||||||
Currently, the test engine has primitives for pushing
|
|
||||||
buttons, setting check-boxes and choices, sending keystrokes,
|
|
||||||
selecting menu items and clicking the mouse. Many functions
|
|
||||||
that are also useful in application testing, such as
|
|
||||||
traversing a tree of panels, getting the text from a canvas,
|
|
||||||
determining if a window is shown, and so on, exist in MrEd.
|
|
||||||
|
|
||||||
@subsection{Actions and completeness}
|
|
||||||
|
|
||||||
The actions associated with a testing primitive may not have finished
|
|
||||||
when the primitive returns to its caller.
|
|
||||||
Some actions may yield control before they can complete.
|
|
||||||
For example, selecting ``Save As...'' from the ``File'' menu
|
|
||||||
opens a dialog box and will not complete until the ``OK''
|
|
||||||
or ``Cancel'' button is pushed.
|
|
||||||
|
|
||||||
However, all testing functions wait at least a minimum interval
|
|
||||||
before returning to give the action a chance to finish.
|
|
||||||
This interval controls the speed at which the test suite runs,
|
|
||||||
and gives some slack time for events to complete.
|
|
||||||
The default interval is 100 milliseconds. The interval can be queried
|
|
||||||
or set with \iscmprocedure{test:run-interval}.
|
|
||||||
|
|
||||||
A primitive action will not return until the run-interval has
|
|
||||||
expired and the action has finished, raised an error, or yielded.
|
|
||||||
The number of incomplete actions is given by
|
|
||||||
\iscmprocedure{test:number-pending-actions}.
|
|
||||||
|
|
||||||
{\it Note:}
|
|
||||||
Once a primitive action is started, it is not possible to undo it
|
|
||||||
or kill its remaining effect.
|
|
||||||
Thus, it is not possible to write a utility that flushes the
|
|
||||||
incomplete actions and resets number-pending-actions to zero.
|
|
||||||
|
|
||||||
However, actions which do not complete right away often provide a
|
|
||||||
way to cancel themselves.
|
|
||||||
For example, many dialog boxes have a ``Cancel'' button which will
|
|
||||||
terminate the action with no further effect.
|
|
||||||
But this is accomplished by sending an additional action
|
|
||||||
(the button push), not by undoing the original action.
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
\subsection{Errors}
|
|
||||||
\label{fw:test:errors}
|
|
||||||
|
|
||||||
Errors in the primitive actions (which necessarily run in the
|
|
||||||
handler thread) are caught and reraised in the calling thread.
|
|
||||||
|
|
||||||
However, the primitive actions can only guarantee that the action
|
|
||||||
has started, and they may return before the action has completed.
|
|
||||||
As a consequence, an action may raise an error long after the
|
|
||||||
function that started it has returned.
|
|
||||||
In this case, the error is saved and reraised at the first opportunity
|
|
||||||
(the next primitive action).
|
|
||||||
|
|
||||||
The test engine keeps a buffer for one error, saving only the
|
|
||||||
first error. Any subsequent errors are discarded.
|
|
||||||
Reraising an error empties the buffer, allowing the next error
|
|
||||||
to be saved.
|
|
||||||
|
|
||||||
The function
|
|
||||||
\iscmprocedure{test:reraise-error}
|
|
||||||
reraises any pending errors.
|
|
||||||
|
|
||||||
\subsection{Technical Issues}
|
|
||||||
|
|
||||||
{\bf Active Frame}
|
|
||||||
|
|
||||||
The Self Test primitive actions all implicitly apply to the
|
|
||||||
top-most (active) frame.
|
|
||||||
|
|
||||||
{\bf Thread Issues}
|
|
||||||
|
|
||||||
The code started by the primitive actions must run in the handler
|
|
||||||
thread of the eventspace where the event takes place. As a result,
|
|
||||||
the test suite that invokes the primitive actions must {\it not} run
|
|
||||||
in that handler thread (or else some actions will deadlock). See
|
|
||||||
\Mrhyperref{the eventspace section}{see section~}{}{eventspaceinfo}
|
|
||||||
for more info.
|
|
||||||
|
|
||||||
{\bf Window Manager (Unix only)}
|
|
||||||
|
|
||||||
In order for the Self Tester to work correctly, the window manager
|
|
||||||
must set the keyboard focus to follow the active frame.
|
|
||||||
This is the default behavior in Microsoft Windows and MacOS,
|
|
||||||
but not in X windows.
|
|
||||||
|
|
||||||
In X windows, you must explicitly tell your window manager to set the
|
|
||||||
keyboard focus to the top-most frame, regardless of the position of the
|
|
||||||
actual mouse. Some window managers may not implement such functionality.
|
|
||||||
You can obtain such an effect in Fvwm and Fvwm95 by using the option:
|
|
||||||
\begin{verbatim}
|
|
||||||
Style "*" ClickToFocus
|
|
||||||
\end{verbatim}
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
@section{Thanks}
|
@section{Thanks}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user