Documentation ¶
Overview ¶
Package testcases contains files with recorded or imagined inputs and expected outputs / errors.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var CommentAfterPostcondition = Case{
ID: "comment_after_postcondition",
Text: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * x > 0
// * x < 100
// * some condition: y > 3
//
// SomeFunc ensures:
// * strings.HasPrefix(result, "hello")
//
// Some text here.
func SomeFunc(x int, y int) (result string, err error) {
// Post-condition
defer func() {
if !(strings.HasPrefix(result, "hello")) {
panic("Violated: strings.HasPrefix(result, \"hello\")")
}
}(); // some comment here
return
}
`,
Expected: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * x > 0
// * x < 100
// * some condition: y > 3
//
// SomeFunc ensures:
// * strings.HasPrefix(result, "hello")
//
// Some text here.
func SomeFunc(x int, y int) (result string, err error) {
// Pre-conditions
switch {
case !(x > 0):
panic("Violated: x > 0")
case !(x < 100):
panic("Violated: x < 100")
case !(y > 3):
panic("Violated: some condition: y > 3")
default:
// Pass
}
// Post-condition
defer func() {
if !(strings.HasPrefix(result, "hello")) {
panic("Violated: strings.HasPrefix(result, \"hello\")")
}
}(); // some comment here
return
}
`}
CommentAfterPostcondition tests that we correctly handle a function whose body contains a comment following the post-condition.
var ConditionsRemovedInComment = Case{
ID: "conditions_removed_in_comment",
Text: `package somepkg
// SomeFunc does something.
func SomeFunc(x int, y int) (result string, err error) {
// Pre-condition
if !(y > 4) {
panic("Violated: y > 4")
}
// do something
return
}
`,
Expected: `package somepkg
// SomeFunc does something.
func SomeFunc(x int, y int) (result string, err error) {
// do something
return
}
`}
ConditionsRemovedInComment tests that non-empty functions without conditions in the documentation are stripped of the condition checking code.
var ConditionsRemovedInCommentOfEmptyFunction = Case{
ID: "conditions_removed_in_comment_of_empty_function",
Text: `package somepkg
// SomeFunc does something.
func SomeFunc(x int, y int) () {
// Pre-condition
if !(y > 4) {
panic("Violated: y > 4")
}
}
`,
Expected: `package somepkg
// SomeFunc does something.
func SomeFunc(x int, y int) () {}
`}
ConditionsRemovedInCommentOfEmptyFunction tests that empty functions without conditions in the documentation are stripped of the condition checking code.
var CurlyBracketsOnSameLine = Case{
ID: "curly_brackets_on_same_line",
Text: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * x > 0
// * x < 100
// * some condition: y > 3
//
// SomeFunc ensures:
// * strings.HasPrefix(result, "hello")
//
// Some text here.
func SomeFunc(x int, y int) (result string, err error) {}
`,
Expected: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * x > 0
// * x < 100
// * some condition: y > 3
//
// SomeFunc ensures:
// * strings.HasPrefix(result, "hello")
//
// Some text here.
func SomeFunc(x int, y int) (result string, err error) {
// Pre-conditions
switch {
case !(x > 0):
panic("Violated: x > 0")
case !(x < 100):
panic("Violated: x < 100")
case !(y > 3):
panic("Violated: some condition: y > 3")
default:
// Pass
}
// Post-condition
defer func() {
if !(strings.HasPrefix(result, "hello")) {
panic("Violated: strings.HasPrefix(result, \"hello\")")
}
}()
}
`}
CurlyBracketsOnSameLine tests that condition checks are correctly generated in an empty function where curly brackets are written on the same line.
var DoubleNegation = Case{
ID: "double_negation",
Text: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * !strings.HasPrefix(x, "something")
//
// SomeFunc ensures:
// * !strings.HasSuffix(result, "smth else")
func SomeFunc(x string) (result string, err error) {}
`,
Expected: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * !strings.HasPrefix(x, "something")
//
// SomeFunc ensures:
// * !strings.HasSuffix(result, "smth else")
func SomeFunc(x string) (result string, err error) {
// Pre-condition
if strings.HasPrefix(x, "something") {
panic("Violated: !strings.HasPrefix(x, \"something\")")
}
// Post-condition
defer func() {
if strings.HasSuffix(result, "smth else") {
panic("Violated: !strings.HasSuffix(result, \"smth else\")")
}
}()
}
`}
DoubleNegation tests that condition expressions are correctly checked in If statement with double negation.
var DoubleNegations = Case{
ID: "double_negations",
Text: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * !strings.HasPrefix(x, "something")
// * !strings.HasPrefix(x, "another")
//
// SomeFunc ensures:
// * !strings.HasSuffix(result, "smth else")
// * !strings.HasSuffix(result, "yet another")
func SomeFunc(x string) (result string, err error) {}
`,
Expected: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * !strings.HasPrefix(x, "something")
// * !strings.HasPrefix(x, "another")
//
// SomeFunc ensures:
// * !strings.HasSuffix(result, "smth else")
// * !strings.HasSuffix(result, "yet another")
func SomeFunc(x string) (result string, err error) {
// Pre-conditions
switch {
case strings.HasPrefix(x, "something"):
panic("Violated: !strings.HasPrefix(x, \"something\")")
case strings.HasPrefix(x, "another"):
panic("Violated: !strings.HasPrefix(x, \"another\")")
default:
// Pass
}
// Post-conditions
defer func() {
switch {
case strings.HasSuffix(result, "smth else"):
panic("Violated: !strings.HasSuffix(result, \"smth else\")")
case strings.HasSuffix(result, "yet another"):
panic("Violated: !strings.HasSuffix(result, \"yet another\")")
default:
// Pass
}
}()
}
`}
DoubleNegations tests that conditions are correctly checked in Switch statement when the conditions contain a negation which is then double-negated in the case expression.
var FailureNoDeferInPostcondition = Failure{
ID: "no_defer_in_postcondition",
Text: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * x > 0
//
// SomeFunc ensures:
// * result == "oi"
//
// Some text here.
func SomeFunc(x int, y int) (result string, err error) {
// Pre-condition
if !(x > 0) {
panic("Violated: x > 0")
}
// Post-condition
panic("hello")
return
}
`,
Error: "expected a defer statement after the comment \"Post-condition\" in function SomeFunc on line 19"}
FailureNoDeferInPostcondition tests that we correctly detect when post-condition comment is not followed by a defer statement in the function body.
var FailureNoIfInPrecondition = Failure{
ID: "no_if_in_precondition",
Text: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * x > 0
//
// SomeFunc ensures:
// * result == "oi"
//
// Some text here.
func SomeFunc(x int, y int) (result string, err error) {
// Pre-condition
panic("hello")
return
}
`,
Error: "expected an 'if' statement after the comment \"Pre-condition\" in function SomeFunc on line 14"}
FailureNoIfInPrecondition tests that we correctly detect when pre-condition comment is not followed by an If statement in the function body.
var FailureNoStatementAfterPostcondtion = Failure{
ID: "no_statement_after_postcondition",
Text: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * x > 0
//
// SomeFunc ensures:
// * result == "oi"
//
// Some text here.
func SomeFunc(x int, y int) (result string, err error) {
// Pre-condition
if !(x > 0) {
panic("Violated: x > 0")
}
// Post-condition
}
`,
Error: "found no statement after the comment \"Post-condition\" in function SomeFunc on line 18"}
FailureNoStatementAfterPostcondtion tests that we correctly detect when post-condition comment is not followed by a statement in the function body.
var FailureNoStatementAfterPrecondtion = Failure{
ID: "no_statement_after_precondition",
Text: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * x > 0
//
// SomeFunc ensures:
// * result == "oi"
//
// Some text here.
func SomeFunc(x int, y int) (result string, err error) {
// Pre-condition
}
`,
Error: "found no statement after the comment Pre-condition in function SomeFunc on line 13"}
FailureNoStatementAfterPrecondtion tests that we correctly detect when pre-condition comment is not followed by a statement in the function body.
var FailureNoSwitchInPrecondition = Failure{
ID: "no_switch_in_preconditions",
Text: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * x > 0
//
// SomeFunc ensures:
// * result == "oi"
//
// Some text here.
func SomeFunc(x int, y int) (result string, err error) {
// Pre-conditions
panic("hello")
return
}
`,
Error: "expected a 'switch' statement after the comment \"Pre-conditions\" in function SomeFunc on line 14"}
FailureNoSwitchInPrecondition tests that we correctly detect when comment implying pre-conditions is not followed by a switch statement in the function body.
var FailureStatementBefore = Failure{
ID: "statement_before",
Text: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * x > 0
//
// SomeFunc ensures:
// * result == "oi"
//
// Some text here.
func SomeFunc(x int, y int) (result string, err error) {
panic("hello")
// Pre-condition
if !(x > 0) {
panic("Violated: x > 0")
}
// Post-condition
defer func() {
if !(result == "oi") {
panic("Violated: result == \"oi\"")
}
}();
return
}
`,
Error: "unexpected statement before the comment \"Pre-condition\" in function SomeFunc on line 13"}
FailureStatementBefore tests that we detect when there is a statement preceding the condition checks.
var FailureStatementInBetween = Failure{
ID: "statement_in_between",
Text: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * x > 0
//
// SomeFunc ensures:
// * result == "oi"
//
// Some text here.
func SomeFunc(x int, y int) (result string, err error) {
// Pre-condition
if !(x > 0) {
panic("Violated: x > 0")
}
panic("hello")
// Post-condition
defer func() {
if !(result == "oi") {
panic("Violated: result == \"oi\"")
}
}();
return
}
`,
Error: "unexpected statement between the pre- and post-condition blocks in function SomeFunc on line 18"}
FailureStatementInBetween tests that we detect when there is a statement between the pre- and post-condition blocks.
var FailureUnmatchedFunctionInPostcondition = Failure{
ID: "unmatched_function_in_postcondition",
Text: `package somepkg
// SomeFunc does something.
//
// UnexpectedFunc ensures:
// * x > 0
func SomeFunc(x int, y int) (result string, err error) {
return
}
`,
Error: "failed to parse comments of the function SomeFunc on line 3: expected \"SomeFunc\" in \"ensures\" line, " +
"but got \"UnexpectedFunc\""}
FailureUnmatchedFunctionInPostcondition tests that we detect when the function name in the post-condition documentation differs from the actual function name.
var FailureUnmatchedFunctionInPrecondition = Failure{
ID: "unmatched_function_in_precondition",
Text: `package somepkg
// SomeFunc does something.
//
// UnexpectedFunc requires:
// * x > 0
func SomeFunc(x int, y int) (result string, err error) {
return
}
`,
Error: "failed to parse comments of the function SomeFunc on line 3: expected \"SomeFunc\" " +
"in \"requires\" line, but got \"UnexpectedFunc\""}
FailureUnmatchedFunctionInPrecondition tests that we detect when the function name in the pre-condition documentation differs from the actual function name.
var HasOnlyComment = Case{
ID: "has_only_comment",
Text: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * x > 0
// * x < 100
// * some condition: y > 3
//
// SomeFunc ensures:
// * strings.HasPrefix(result, "hello")
//
// Some text here.
func SomeFunc(x int, y int) (result string, err error) {
// Some comment
}
`,
Expected: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * x > 0
// * x < 100
// * some condition: y > 3
//
// SomeFunc ensures:
// * strings.HasPrefix(result, "hello")
//
// Some text here.
func SomeFunc(x int, y int) (result string, err error) {
// Pre-conditions
switch {
case !(x > 0):
panic("Violated: x > 0")
case !(x < 100):
panic("Violated: x < 100")
case !(y > 3):
panic("Violated: some condition: y > 3")
default:
// Pass
}
// Post-condition
defer func() {
if !(strings.HasPrefix(result, "hello")) {
panic("Violated: strings.HasPrefix(result, \"hello\")")
}
}()
// Some comment
}
`}
HasOnlyComment tests that conditions are correctly generated in a function whose body contains only a comment.
var HasPostcondition = Case{
ID: "has_postcondition",
Text: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * x > 0
// * x < 100
// * some condition: y > 3
//
// SomeFunc ensures:
// * strings.HasPrefix(result, "hello")
//
// Some text here.
func SomeFunc(x int, y int) (result string, err error) {
// Post-condition
defer func() {
if !(strings.HasPrefix(result, "hello")) {
panic("Violated: strings.HasPrefix(result, \"hello\")")
}
}()
// do something
return
}
`,
Expected: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * x > 0
// * x < 100
// * some condition: y > 3
//
// SomeFunc ensures:
// * strings.HasPrefix(result, "hello")
//
// Some text here.
func SomeFunc(x int, y int) (result string, err error) {
// Pre-conditions
switch {
case !(x > 0):
panic("Violated: x > 0")
case !(x < 100):
panic("Violated: x < 100")
case !(y > 3):
panic("Violated: some condition: y > 3")
default:
// Pass
}
// Post-condition
defer func() {
if !(strings.HasPrefix(result, "hello")) {
panic("Violated: strings.HasPrefix(result, \"hello\")")
}
}()
// do something
return
}
`}
HasPostcondition tests that conditions are correctly generated in a function whose body already contains a post-condition.
var HasPrecondition = Case{
ID: "has_precondition",
Text: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * x > 0
// * x < 100
// * some condition: y > 3
//
// SomeFunc ensures:
// * strings.HasPrefix(result, "hello")
//
// Some text here.
func SomeFunc(x int, y int) (result string, err error) {
// Pre-condition
if !(y > 4) {
panic("Violated: y > 4")
}
// do something
return
}
`,
Expected: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * x > 0
// * x < 100
// * some condition: y > 3
//
// SomeFunc ensures:
// * strings.HasPrefix(result, "hello")
//
// Some text here.
func SomeFunc(x int, y int) (result string, err error) {
// Pre-conditions
switch {
case !(x > 0):
panic("Violated: x > 0")
case !(x < 100):
panic("Violated: x < 100")
case !(y > 3):
panic("Violated: some condition: y > 3")
default:
// Pass
}
// Post-condition
defer func() {
if !(strings.HasPrefix(result, "hello")) {
panic("Violated: strings.HasPrefix(result, \"hello\")")
}
}()
// do something
return
}
`}
HasPrecondition tests that conditions are correctly generated in a function whose body already contains a pre-condition.
var MultipleFunctions = Case{
ID: "multiple_functions",
Text: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * x > 0
//
// Some text here.
func SomeFunc(x int, y int) (result string, err error) {
// do something
return
}
// AnotherFunc does something.
//
// AnotherFunc requires:
// * x > 0
//
// Some text here.
func AnotherFunc(x int, y int) (result string, err error) {
// do something
return
}
`,
Expected: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * x > 0
//
// Some text here.
func SomeFunc(x int, y int) (result string, err error) {
// Pre-condition
if !(x > 0) {
panic("Violated: x > 0")
}
// do something
return
}
// AnotherFunc does something.
//
// AnotherFunc requires:
// * x > 0
//
// Some text here.
func AnotherFunc(x int, y int) (result string, err error) {
// Pre-condition
if !(x > 0) {
panic("Violated: x > 0")
}
// do something
return
}
`}
MultipleFunctions tests that conditions are correctly generated in a file containing more than one function.
var NoConditions = Case{
ID: "no_conditions",
Text: `package somepkg
// SomeFunc does something.
func SomeFunc(x int, y int) (result string, err error) {
// do something
return
}
`,
Expected: `package somepkg
// SomeFunc does something.
func SomeFunc(x int, y int) (result string, err error) {
// do something
return
}
`}
NoConditions tests that functions without conditions are left unchanged.
var NoFunction = Case{
ID: "no_function",
Text: `package somepkg
`,
Expected: `package somepkg
`}
NoFunction tests that files without functions are left unchanged.
var NoPreviousConditions = Case{
ID: "no_previous_conditions",
Text: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * x > 0
// * x < 100
// * some condition: y > 3
//
// SomeFunc ensures:
// * strings.HasPrefix(result, "hello")
//
// Some text here.
func SomeFunc(x int, y int) (result string, err error) {
// do something
return
}
`,
Expected: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * x > 0
// * x < 100
// * some condition: y > 3
//
// SomeFunc ensures:
// * strings.HasPrefix(result, "hello")
//
// Some text here.
func SomeFunc(x int, y int) (result string, err error) {
// Pre-conditions
switch {
case !(x > 0):
panic("Violated: x > 0")
case !(x < 100):
panic("Violated: x < 100")
case !(y > 3):
panic("Violated: some condition: y > 3")
default:
// Pass
}
// Post-condition
defer func() {
if !(strings.HasPrefix(result, "hello")) {
panic("Violated: strings.HasPrefix(result, \"hello\")")
}
}()
// do something
return
}
`}
NoPreviousConditions tests handling of functions with conditions defined in the documentation, but not yet generated in the function body.
var RemoveInCode = Case{ ID: "remove_in_code", Remove: true, Text: `package somepkg // SomeFunc does something. // // SomeFunc ensures: // * strings.HasPrefix(result, "hello") // // Some text here. func SomeFunc(x int, y int) (result string, err error) { // Post-condition defer func() { if !(strings.HasPrefix(result, "hello")) { panic("Violated: strings.HasPrefix(result, \"hello\")") } }() // do something return } `, Expected: `package somepkg // SomeFunc does something. // // SomeFunc ensures: // * strings.HasPrefix(result, "hello") // // Some text here. func SomeFunc(x int, y int) (result string, err error) { // do something return } `}
RemoveInCode tests the case when pre and postconditions are left in the documentation, but removed from code.
var RemoveInCodeOfEmptyFunction = Case{ ID: "remove_in_code_of_empty_function", Remove: true, Text: `package somepkg // SomeFunc does something. // // SomeFunc ensures: // * strings.HasPrefix(result, "hello") // // Some text here. func SomeFunc(x int, y int) (result string, err error) { // Post-condition defer func() { if !(strings.HasPrefix(result, "hello")) { panic("Violated: strings.HasPrefix(result, \"hello\")") } }() } `, Expected: `package somepkg // SomeFunc does something. // // SomeFunc ensures: // * strings.HasPrefix(result, "hello") // // Some text here. func SomeFunc(x int, y int) (result string, err error) {} `}
RemoveInCodeOfEmptyFunction tests the case when pre and postconditions are left in the documentation, but are removed from code of a function whose body is empty.
var RemoveInCodeWithSemicolon = Case{ ID: "remove_in_code_with_semicolon", Remove: true, Text: `package somepkg // SomeFunc does something. // // SomeFunc ensures: // * strings.HasPrefix(result, "hello") // // Some text here. func SomeFunc(x int, y int) (result string, err error) { // Post-condition defer func() { if !(strings.HasPrefix(result, "hello")) { panic("Violated: strings.HasPrefix(result, \"hello\")") } }(); return // do something } `, Expected: `package somepkg // SomeFunc does something. // // SomeFunc ensures: // * strings.HasPrefix(result, "hello") // // Some text here. func SomeFunc(x int, y int) (result string, err error) {; return // do something } `}
RemoveInCodeWithSemicolon tests the case when pre and postconditions are left in the documentation, but removed from code in a function whose body continues with a semi-colon just after the conditions.
var SemicolonAfterPostcondition = Case{
ID: "semicolon_after_postcondition",
Text: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * x > 0
// * x < 100
// * some condition: y > 3
//
// SomeFunc ensures:
// * strings.HasPrefix(result, "hello")
//
// Some text here.
func SomeFunc(x int, y int) (result string, err error) {
// Post-condition
defer func() {
if !(strings.HasPrefix(result, "hello")) {
panic("Violated: strings.HasPrefix(result, \"hello\")")
}
}(); return // return here
}
`,
Expected: `package somepkg
// SomeFunc does something.
//
// SomeFunc requires:
// * x > 0
// * x < 100
// * some condition: y > 3
//
// SomeFunc ensures:
// * strings.HasPrefix(result, "hello")
//
// Some text here.
func SomeFunc(x int, y int) (result string, err error) {
// Pre-conditions
switch {
case !(x > 0):
panic("Violated: x > 0")
case !(x < 100):
panic("Violated: x < 100")
case !(y > 3):
panic("Violated: some condition: y > 3")
default:
// Pass
}
// Post-condition
defer func() {
if !(strings.HasPrefix(result, "hello")) {
panic("Violated: strings.HasPrefix(result, \"hello\")")
}
}(); return // return here
}
`}
SemicolonAfterPostcondition tests that remainder of the code is handled correctly when it is separated by a semicolon from the post-condition.
var TypeDeclaration = Case{
ID: "type_declaration",
Text: `package somepkg
// SomeStruct defines a struct.
//
// SomeStruct requires:
// * x > 3
type SomeStruct struct {
int x
}
`,
Expected: `package somepkg
// SomeStruct defines a struct.
//
// SomeStruct requires:
// * x > 3
type SomeStruct struct {
int x
}
`}
TypeDeclaration tests that type declarations are left unchanged even though they might contain contract conditions in the description.
Functions ¶
This section is empty.
Types ¶
Source Files ¶
- case_comment_after_postcondition.go
- case_conditions_removed_empty_function.go
- case_conditions_removed_in_comment.go
- case_curly_brackets_on_same_line.go
- case_double_negation.go
- case_double_negations.go
- case_has_only_comment.go
- case_has_postcondition.go
- case_has_precondition.go
- case_multiple_functions.go
- case_no_conditions.go
- case_no_function.go
- case_no_previous_conditions.go
- case_remove_in_code.go
- case_remove_in_code_of_empty_function.go
- case_remove_in_code_with_semicolon.go
- case_semicolon_after_postcondition.go
- case_type_declaration.go
- doc.go
- failure_no_defer_in_postcondition.go
- failure_no_if_in_precondition.go
- failure_no_statement_after_postcondition.go
- failure_no_statement_after_precondition.go
- failure_no_switch_in_preconditions.go
- failure_statement_before.go
- failure_statement_in_between.go
- failure_unmatched_function_in_postcondition.go
- failure_unmatched_function_in_precondition.go
- types.go