added custom format plugins (Issue #11)

This commit is contained in:
Spencer Florence 2015-01-09 09:37:31 -05:00
parent 4cadfeab5f
commit 15bfa15225
6 changed files with 69 additions and 9 deletions

View File

@ -12,3 +12,7 @@
(define scribblings '(("scribblings/cover.scrbl" (multi-page))))
(define test-omit-paths (list "tests/error-file.rkt"))
(define cover-formats '(("html" cover generate-html-coverage)
("coveralls" cover generate-coveralls-coverage)
("raw" cover generate-raw-coverage)))

View File

@ -13,6 +13,6 @@
(->* (exact-positive-integer?)
(#:byte? boolean?)
(or/c 'yes 'no 'missing)))]
[generate-coveralls-coverage (->* (coverage/c) (path-string?) any)]
[generate-html-coverage (->* (coverage/c) (path-string?) any)]
[generate-raw-coverage (->* (coverage/c) (path-string?) any)]))
[generate-coveralls-coverage coverage-gen/c]
[generate-html-coverage coverage-gen/c]
[generate-raw-coverage coverage-gen/c]))

View File

@ -1,7 +1,8 @@
#lang racket/base
(provide coverage/c file-coverage/c)
(provide coverage/c file-coverage/c coverage-gen/c)
(require racket/contract)
(define file-coverage/c (listof (list/c boolean? srcloc?)))
(define coverage/c (hash/c (and/c path-string? absolute-path?)
file-coverage/c))
(define coverage-gen/c (->* (coverage/c) (path-string?) any))

View File

@ -1,6 +1,11 @@
#lang racket/base
(require racket/list racket/cmdline raco/command-name
setup/getinfo
racket/match
racket/contract/base
racket/function
"main.rkt"
(only-in "private/contracts.rkt" coverage-gen/c)
"private/shared.rkt")
(module+ test
@ -44,11 +49,8 @@
(cons file files)))
(define files (expand-directories args include-exts))
(define generate-coverage
(case output-format
[("html") generate-html-coverage]
[("coveralls") generate-coveralls-coverage]
[("raw") generate-raw-coverage]
[else (error 'cover "given unknown coverage output format: ~s" output-format)]))
(hash-ref (get-formats) output-format
(lambda _ (error 'cover "given unknown coverage output format: ~s" output-format))))
(printf "generating test coverage for ~s\n" files)
(define passed (keyword-apply test-files! '(#:submod) (list submod) files))
(define coverage (remove-excluded-paths (get-test-coverage) exclude-paths))
@ -148,3 +150,37 @@
(build-path "a"))
(check-equal? (->relative "/test/a/b")
(build-path "a" "b"))))
(define (get-formats)
(define dirs (find-relevant-directories '(cover-formats) 'all-available))
(for*/hash ([d (in-list dirs)]
[f (in-value (get-info/full/skip d))]
#:when f
[v (in-value (f 'cover-formats (const #f)))]
#:when v
[l (in-list v)])
(with-handlers ([exn:misc:match? (make-cover-load-error d l)])
(match-define (list (? string? name) (? module-path? path) (? symbol? ident)) l)
(define f (dynamic-require path ident (make-cover-require-error ident path)))
(values
name
(contract coverage-gen/c f 'cover ident ident #f)))))
(define ((make-cover-load-error dir v) . _)
(error 'cover "unable to load coverage format from ~s. Found unusable value ~s"
dir v))
(define ((make-cover-require-error ident path))
(error 'cover "unable to load symbol ~s from ~s" ident path))
(define (get-info/full/skip dir)
(with-handlers ([exn:fail? (const #f)])
(get-info/full dir)))
(module+ test
(test-begin
;; we expect that a standard install has "html", "coveralls", and "raw"
(define h (get-formats))
(check-true (hash-has-key? h "html"))
(check-true (hash-has-key? h "coveralls"))
(check-true (hash-has-key? h "raw"))))

View File

@ -11,5 +11,6 @@ Cover is a test coverage tool. It is designed to be used in addition to raco tes
@include-section["basics.scrbl"]
@include-section["api.scrbl"]
@include-section["plugins.scrbl"]
@index-section[]

18
scribblings/plugins.scrbl Normal file
View File

@ -0,0 +1,18 @@
#lang scribble/doc
@(require "base.rkt")
@title[#:tag "plugin"]{Creating Custom Output Formats}
Any package may add an output format to cover. A format is, roughly, a function that takes
coverage information and transforms it into some other format. To add a format
put a definition for @racket[cover-formats] into a packages @filepath["info.rkt"]. This should be a
@racket[(listof (list _command-name _module-path _function-name))]:
@itemize{
@item{@racket[_command-name] is a string which will be used as the argument to @exec{-c} to
use this format.}
@item{@racket[_module-path] should be the path to a racket file providing this format.}
@item{@@racket[_function-name] should be a symbol that is
bound to a function in @racket[_module-math]. It should match the contract
@racket[(->* (coverage/c) (path-string?) any)], and is the implementation of
the format.}
}