[Style] testing, comments, some reorg; Vincent's comments

This commit is contained in:
Matthias Felleisen 2011-08-05 16:56:59 -04:00 committed by Eli Barzilay
parent b99f7151a2
commit 4bf1a63d56
8 changed files with 142 additions and 86 deletions

View File

@ -30,7 +30,9 @@ act in this context.
Write meaningful commit messages. The first line (say 80 chars) should
provide a concise summary of the commit. If the message must be longer,
edit the rest of the message in your text editor and leave a blank line
between the summary line and the rest of the message.
between the summary line and the rest of the message. The message for bug
report fixes should contain ``Close PR NNNNN'' so that bug reports are
automatically closed.
To avoid 'merge commits', update your repository with @tt{git --rebase pull}.

View File

@ -20,12 +20,35 @@ Seasoned Schemers, not necessarily Racketeers, also use triple and
quadruple semicolons. This is considered a courtesy to distinguish file
headers from section headers.
In addition to ``;'', we have two other mechanisms for commenting code:
``#|...|#'' for blocks and ``#;'' to comment out an expression.
In rare cases there might be a more substantial piece of text or code, and
in that case the block comment style can be more convenient than
semicolons. Another use of block comments is for code samples to be
copied and pasted into a file. Either way, block comments are not used
for single-line comments.
Expression comments---``#;''---apply to the following S-expression. This
makes them a useful tool for debugging. They can even be composed in
interesting ways with other comments, for example, ``#;#;'' will comment
two expressions, and a line with just ``;#;'' gives you a single-character
``toggle'' for the expression that starts on the next line. But on the
flip side, lots tools don't process them properly---treating them instead
as a ``#'' followed by a commented line. For example, in DrRacket
S-expression comments are ignored when it comes to syntax coloring, which
makes it easy to miss them. In Emacs, the commented text is colored like a
comment and treated as text, which makes it difficult to edit as code.
The bottom line here is that ``#;'' comments are useful for debugging, but
try to avoid leaving them in committed code. If you really want to use
``#;'', clarify their use with a line comment (``;'').
@; -----------------------------------------------------------------------------
@section{Definitions}
Racket comes with quite a few definitional constructs, including
@scheme[let], @scheme[let*], @scheme[letrec], and @scheme[define]. Except
for the last one, definitional construct increase the indentation level.
for the last one, definitional constructs increase the indentation level.
Therefore, favor @scheme[define] when feasible.
@compare[
@ -90,11 +113,12 @@ prefer them over @scheme[if].
racket
(cond
[(empty? l) true]
[(empty? l) #false]
[else
(define f (fir l))
(define r (rest l))
(and (flat-rate f)
(if (discounted? f)
(discount-rate f)
(curved f (chk r)))])
]
@racketmod[#:file
@ -102,10 +126,11 @@ racket
racket
(if (empty? l)
true
#false
(let ([f (fir l)]
[r (rest l)])
(and (flat-rate f)
(if (discounted? f)
(discount-rate f)
(curved f (chk r)))))
]
]
@ -198,7 +223,7 @@ Even a curried function does not need @racket[lambda].
@tt{good}
racket
(define ((staged-image-composition fixed-image) variable-image)
(define ((cut fx-image) image2)
...)
]
@; -----------------------------------------------------------------------------
@ -206,8 +231,8 @@ racket
@tt{acceptable}
racket
(define (staged-image-composition fixed-image)
(lambda (variable-image)
(define (cut fx-image)
(lambda (image2)
...))
]
]
@ -233,7 +258,7 @@ The identity function is @racket[values]:
@section{Traversals}
With the availability of @racket[for/fold], @racket[for/list],
@racket[for/vector], and friends, programming with for @racket[for] loops
@racket[for/vector], and friends, programming with @racket[for] loops
has become just as functional as programming with @racket[map] and
@racket[foldr]. With @racket[for*] loops, filter, and termination clauses
in the iteration specification, these loops are also far more concise than
@ -270,8 +295,11 @@ racket
racket
;; [Listof X] -> Number
(define (sum-up s)
(foldr (lambda (x sum) (+ sum x)) 0 s))
(define (sum-up alist)
(foldr (lambda (x sum)
(+ sum x))
0
alist))
;; example:
(sum-up '(1 2 3))

View File

@ -23,7 +23,7 @@ This section explains these three points as far as the Racket code base is
code base.
@; -----------------------------------------------------------------------------
@section[#:tag "correctness"]{Correctness}
@section[#:tag "correctness"]{Correctness and Testing}
@nested[#:style 'inset]{@italic{I have bug reports, therefore I exist.} -- Matthias,
watching Matthew, Robby, Shriram and others create the original code base}
@ -45,54 +45,8 @@ We ensure this basic level of correctness with large test suites. Our test
DrRacket comes with an automatic GUI player that explores its
functionality.
Most tests suites live in @tt{collects/tests/} in the PLT
repository. @margin-note*{Due to historical reasons, a few collections
come with their own local test suites.} These test suites suggest a
culture of testing per tool or language. If you add a new collection,
create a new test suite in the @tt{tests} collection.
Run the test suites before you commit. After you commit, watch for and
read(!) @hyperlink["http://drdr.racket-lang.org/"]{DrDr}'s emails. Do
@emph{not} ignore them. If you have a tests that regularly fails, consider
splitting your test directory into two parts: @tt{success} and
@tt{failure}. The former is for tests that should succeed now, and the
latter is for tests that are currently intended to fail. See the
@hyperlink["https://github.com/plt/racket/tree/master/collects/tests/typed-scheme"]{Typed
Racket testing arrangement} for an example.
When you debug an existing piece of code, formulate a test case first. Put
it into the test suite for the component so the mistake will never be
accidentally re-introduced and add a note that points to the problem
report. Second, modify the code to fix the mistake. Do this second to be
sure you didn't introduce a mistake in your tests; it is all too easy to
think you have fixed a mistake when in reality your new test just doesn't
properly reveal the old mistake. Third, re-run the test suite to ensure
that the mistake is fixed and no existing tests fail.
If there is no test suite and you aren't sure how to build one, then ask on
the developer mailing list. Perhaps people will explain why there isn't
one or they will sketch how to create one. Please don't ignore the
problem. If you cannot build a test suite, you have a few options:
@itemlist[#:style 'ordered
@item{Add functionality to the library to enable testing. Of course,
adding functionality means adding external documentation. Robby and
Matthew have done so for the GUI library, and there is now a large
automated test suite for DrRacket. So even GUI programs can come with
extended test suites.}
@item{Add an end-to-end test that may have to be verified by a human.
For example, it might be hard to test Slideshow, so you could create a
slide set and describe what it should look like so future maintainers to
verify when @emph{they} make changes. Consider this the @emph{last and
least desirable} option, however.}
]
@;
The lack of tests for some collection will not disappear overnight. But if
we all contribute a little bit, we will eventually expand the test suites
to cover the entire code base, and future generations of maintainers will
be grateful.
For details on testing in the context of the Racket code base, see
@secref{testing}.
@; -----------------------------------------------------------------------------
@section{Maintenance}

View File

@ -56,10 +56,11 @@ Also, look over the commit messages. If you see problems with the code
@; -----------------------------------------------------------------------------
@include-section{correct-maintain-speed.scrbl}
@include-section{some-performance.scrbl}
@include-section{testing.scrbl}
@include-section{unit.scrbl}
@include-section{constructs.scrbl}
@include-section{textual.scrbl}
@include-section{some-performance.scrbl}
@include-section{branch-and-commit.scrbl}
@include-section{acknowledgment.scrbl}

View File

@ -0,0 +1,71 @@
#lang scribble/base
@(require "shared.rkt")
@title[#:tag "testing"]{Testing}
@; -----------------------------------------------------------------------------
@section[#:tag "test-suite"]{Test Suites}
Most of our collections come with test suites. These tests suites tend to
live in @tt{collects/tests/} in the PLT repository, though due to
historical reasons, a few collections come with their own local test
suites. If you add a new collection, create a new test suite in the
@tt{tests} collection.
Run the test suites before you commit. To facilitate testing, we urge you
to add a @tt{TESTME.txt} file to your collections. Ideally, you may also
wish to have a file in this directory that runs the basic tests. See the
@hyperlink["https://github.com/plt/racket/tree/master/collects/2htdp/"]{2htdp},
which is one of the collections with own testing style. The file should
describe where the tests are located, how to run thee tests, and what to
look for in terms of successes and failures. These files are necessary
because different collections have different needs for testing, and
testing evolved in many different ways in our history.
After you commit, watch for and read(!)
@hyperlink["http://drdr.racket-lang.org/"]{DrDr}'s emails. Do @emph{not}
ignore them. If you have tests that are known to fail and fixing this
requires a lot of work, consider splitting your test directory into two
parts: @tt{success} and @tt{failure}. The former is for tests that should
succeed now, and the latter is for tests that are currently expected to
fail. See the
@hyperlink["https://github.com/plt/racket/tree/master/collects/tests/typed-scheme"]{Typed
Racket testing arrangement} for an example.
@; -----------------------------------------------------------------------------
@section[#:tag "test-bang"]{Always Test!}
When you debug an existing piece of code, formulate a test case first. Put
it into the test suite for the component so the mistake will never be
accidentally re-introduced and add a note that points to the problem
report. Second, modify the code to fix the mistake. Do this second to be
sure you didn't introduce a mistake in your tests; it is all too easy to
think you have fixed a mistake when in reality your new test just doesn't
properly reveal the old mistake. Third, re-run the test suite to ensure
that the mistake is fixed and no existing tests fail.
If there is no test suite and you aren't sure how to build one, then ask on
the developer mailing list. Perhaps people will explain why there isn't
one or they will sketch how to create one. Please don't ignore the
problem. If you cannot build a test suite, you have a few options:
@itemlist[#:style 'ordered
@item{Add functionality to the library to enable testing. Of course,
adding functionality means adding external documentation. Robby and
Matthew have done so for the GUI library, and there is now a large
automated test suite for DrRacket. So even GUI programs can come with
extended test suites.}
@item{Add an end-to-end test that may have to be verified by a human.
For example, it might be hard to test Slideshow, so you could create a
slide set and describe what it should look like so future maintainers to
verify when @emph{they} make changes. Consider this the @emph{last and
least desirable} option, however.}
]
@;
The lack of tests for some collection will not disappear overnight. But if
we all contribute a little bit, we will eventually expand the test suites
to cover the entire code base, and future generations of maintainers will
be grateful.

View File

@ -120,6 +120,17 @@ patient and use the existing indentation tool anyway.
@bold{Caveat 2}: This rule does not apply to scribble code.
@; -----------------------------------------------------------------------------
@section{Tabs}
Do not use tab characters in your code. Tabs make it hard to use textual
tools like git or diff effectively. To disable tabs,
@itemlist[
@item{in DrRacket: you are all set. It doesn't insert tabs.}
@item{in Emacs: add (setq indent-tabs-mode nil) to your emacs initialization file.}
@item{in vi: set expandtab.}
]
@; -----------------------------------------------------------------------------
@section{Line Breaks}
@ -192,18 +203,17 @@ racket
(code:comment #, @t{and})
(composition img
(above img
(- width hdelta)
(- height vdelta)
bg)
]
@racketmod[#:file
@tt{bad}
racket
(composition ufo
(above ufo
10 v-delta bg)
]]
@ -281,7 +291,8 @@ traverse_forest
]
@;
Note that _ (the underline character) is also classified as bad
Racketeering.
Racketeering within names. It is an acceptable placeholder in syntax
patterns, match patterns, and parameters that don't matter.
Another widely used convention is to @emph{prefix} a function name with the data
type of the main argument. This convention generalizes the selector-style
@ -331,7 +342,7 @@ Finally, in addition to regular alphanumeric characters, Racketeers use a
@row[<%> "interfaces" dc<%>]
@row[^ "unit signatures" game-context^]
@row["@" "units" testing-context@]
@row["#%" "kernel identifiers" #:app]
@row["#%" "kernel identifiers" #%app]
]
The use of ``#%'' to prefix names from the kernel language warns readers
that these identifiers are extremely special and they need to watch out
@ -350,7 +361,7 @@ may relax this constraint.
@section{Spaces}
Don't pollute your code with spaces and extraneous blank lines.
Don't pollute your code with spaces at the end of lines and extraneous blank lines.
@; -----------------------------------------------------------------------------
@section{End of File}

View File

@ -8,12 +8,6 @@
@item{Write a section on when macros, when functions.}
@item{Write a section on how to organize test suites --
Robby: please review the "correctness" section (1.1) and determine what we
need to add. It turns out that the point showed up in several feedback
messages so a hand-wavy thing is probably not enough.}
@item{Write a section on how to design test cases.}
@item{Write a section on how to check the stressability of your software.}
@ -22,9 +16,4 @@ messages so a hand-wavy thing is probably not enough.}
@item{Do we need a discussion of life cycles that start in @tt{unstable}?}
@item{The section on comments (constructs) should be expanded to cover
S-expression comments etc. --
Eli: you seem to have good ideas. Please write up an explanation.}
]

View File

@ -138,7 +138,7 @@ Avoid @racket[(provide (all-defined-out))] except for general-purpose
libraries.
A test suite section---if located within the module---should come at the
every end, including its specific dependencies, i.e., @racket[require]
very end, including its specific dependencies, i.e., @racket[require]
specifications.
@; -----------------------------------------------------------------------------