testcases

package
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 28, 2018 License: MIT Imports: 0 Imported by: 0

Documentation

Overview

Package testcases contains files with recorded or imagined inputs and expected outputs / errors.

Index

Constants

This section is empty.

Variables

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
var NoFunction = Case{
	ID: "no_function",
	Text: `package somepkg
`,
	Expected: `package somepkg
`}

NoFunction tests that files without functions are left unchanged.

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
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

type Case

type Case struct {
	ID string

	// Input
	Text string

	// The value of remove argument to Process
	Remove bool

	// Expected code after the Text was processed
	Expected string
}

Case defines a use case and the expected output.

type Failure

type Failure struct {
	ID    string
	Text  string
	Error string
}

Failure defines a case when gocontracts should fail and the expected error.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL