Documentation
¶
Overview ¶
Provides functionality for storing and analyzing test cases extracted from Go source files.
Index ¶
- func IsSelectorFuncCall(stmt ast.Stmt, owner, name string) bool
- func IsValidTestCase(funcDecl *ast.FuncDecl) (valid bool, badFormat bool)
- type Scenario
- type ScenarioDataStructure
- type ScenarioSet
- type TestCase
- func (tc *TestCase) Analyze()
- func (tc *TestCase) EncodeAsCSV() []string
- func (tc *TestCase) Fset() (*token.FileSet, bool)
- func (tc *TestCase) GetCSVHeaders() []string
- func (tc *TestCase) GetStatements() []ast.Stmt
- func (tc *TestCase) IdentifyScenarioSet(stmts []ast.Stmt)
- func (tc *TestCase) MarshalJSON() ([]byte, error)
- func (tc *TestCase) NumLines() int
- func (tc *TestCase) NumStatements() int
- func (tc *TestCase) SaveAsJSON(dir string) error
- func (tc *TestCase) String() string
- func (tc *TestCase) TypeOf(expr ast.Expr) types.Type
- func (tc *TestCase) UnmarshalJSON(data []byte) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func IsSelectorFuncCall ¶ added in v1.1.1
Returns a boolean indicating whether a statement is a function call expression of the form `owner.name(...)`.
func IsValidTestCase ¶
Determine if the given function declaration is a valid test case. Returns two booleans: `valid` indicating whether this is a valid test case, and `badFormat` indicating whether the test case has an incorrect (but acceptable) format. `badFormat` is false if the function is not valid.
The test case is validated using the following criteria: - The function name starts with "Test" followed by a capital letter - The function has `*testing.T` as its only formal parameter - The function does not have any receiver (i.e., it is not a method) - The function does not have any generic type parameters - The function does not return any values
Types ¶
type Scenario ¶ added in v1.1.1
type Scenario struct { Name string // the detected name of the scenario, either from a "name" or "desc" field, or the key of a map Expr ast.Expr }
Represents an individual scenario defined by a table-driven test todo LATER not implemented yet
type ScenarioDataStructure ¶ added in v1.1.1
type ScenarioDataStructure int
Represents the type of data structure used to store scenarios
const ( ScenarioNoDS ScenarioDataStructure = iota // no table-driven test structure detected ScenarioStructListDS // table-driven test using a slice or array of structs ScenarioMapDS // table-driven test using a map )
func (ScenarioDataStructure) MarshalJSON ¶ added in v1.1.1
func (sds ScenarioDataStructure) MarshalJSON() ([]byte, error)
func (ScenarioDataStructure) String ¶ added in v1.1.1
func (sds ScenarioDataStructure) String() string
func (*ScenarioDataStructure) UnmarshalJSON ¶ added in v1.1.1
func (sds *ScenarioDataStructure) UnmarshalJSON(data []byte) error
type ScenarioSet ¶ added in v1.1.1
type ScenarioSet struct { // Core data fields // todo LATER expand to support scenario definitions like `map[string]bool` without a struct template (probably by making changes to `DetectScenarioDataStructure`) ScenarioTemplate *types.Struct // the definition of the `struct` type that individual scenarios are based on DataStructure ScenarioDataStructure // describes the type of data structure used to store scenarios Scenarios []ast.Expr // the individual scenarios themselves //todo LATER convert to type `[]Scenario` Runner *ast.BlockStmt // the actual code that runs the subtest (which is the body of a loop) // Derived analysis results NameField string // the name of the field representing each scenario's name, or "map key" if the map key is used as the name ExpectedFields []string // the names of fields representing the expected results of each scenario HasFunctionFields bool // whether the scenario type has any fields whose type is a function UsesSubtest bool // whether the test calls `t.Run()` inside the loop body // contains filtered or unexported fields }
Represents the set of scenarios defined by a table-driven test
func (*ScenarioSet) Analyze ¶ added in v1.1.1
func (ss *ScenarioSet) Analyze()
Perform additional analysis based on the core data fields, populating the corresponding fields
func (*ScenarioSet) GetFields ¶ added in v1.1.1
func (ss *ScenarioSet) GetFields() iter.Seq[*types.Var]
Returns the fields of the scenario struct definition todo note that defining fields like `a, b int` counts as one `Field` element with multiple Names -- need to account for this
func (*ScenarioSet) MarshalJSON ¶ added in v1.1.1
func (ss *ScenarioSet) MarshalJSON() ([]byte, error)
Marshal the ScenarioSet for JSON output
func (*ScenarioSet) SaveScenariosIfMatching ¶ added in v1.1.1
func (ss *ScenarioSet) SaveScenariosIfMatching(expr ast.Expr, tc *TestCase) bool
Checks whether an expression has the same underlying type as the ScenarioTemplate, and if so, saves the scenarios from the expression. Returns whether the scenarios were saved successfully. Always returns `false` if the `ScenarioSet.DataStructure` is unknown. See https://go.dev/ref/spec#Type_identity for details of the `types.Identical` comparison method.
type TestCase ¶
type TestCase struct { // High-level identifiers for the test case Name string // the name of the test case Package string // the fully qualified package name where the test case is defined FilePath string // the path to the file where the test case is defined Project string // the overarching project directory that the test case's package is part of // Analysis results - only available after running `Analyze(testCase)` // todo maybe make this all into its own struct like AnalysisResults that references this struct? alternatively, store the struct in this object and call `Analyze()` by default unless a bool is passed to `CreateTestCase` ScenarioSet *ScenarioSet // the set of scenarios defined in this test case, if it is table-driven ParsedStatements []string // the parsed statements in the test case, as strings ImportedPackages []string // the list of imported packages in the test case's file // Actual syntax data FuncDecl *ast.FuncDecl // the actual declaration of the test case File *ast.File // the actual file where the test case is defined (for context, e.g. imports) }
Represents an individual test case defined at the top level of a Go source file. The fields of this struct should not be modified directly.
func CreateTestCase ¶
func CreateTestCase(funcDecl *ast.FuncDecl, file *ast.File, project string, fset *token.FileSet, typeInfo *types.Info) TestCase
Create a new TestCase struct for storage and analysis
func (*TestCase) Analyze ¶
func (tc *TestCase) Analyze()
Extract relevant information about this TestCase and save the results into its own corresponding fields
func (*TestCase) EncodeAsCSV ¶ added in v1.1.1
Encode TestCase as a CSV row, returning the encoded data corresponding to the headers in `GetCSVHeaders`.
func (*TestCase) Fset ¶ added in v1.1.1
Convenience method for getting the FileSet corresponding to this TestCase's project. The boolean result indicates whether the FileSet was successfully retrieved.
func (*TestCase) GetCSVHeaders ¶ added in v1.1.1
Return the headers for the CSV representation of the TestCase Complex or large fields are excluded for the sake of brevity.
func (*TestCase) GetStatements ¶
Return the list of statements in this test case
func (*TestCase) IdentifyScenarioSet ¶ added in v1.1.1
Populates the TestCase's ScenarioSet field using the information extracted from from the test's statements
func (*TestCase) MarshalJSON ¶
Marshal the TestCase for JSON output
func (*TestCase) NumLines ¶
Return the number of individual lines (not statements) that the test case spans
func (*TestCase) NumStatements ¶
Return the number of statements in the test case
func (*TestCase) SaveAsJSON ¶
Save the TestCase as JSON to a file named like `<project>/<project>_<package>_<testcase>.json` in the specified directory (or the output directory if not specified).
func (*TestCase) String ¶
Return a string representation of the TestCase for logging and debugging purposes
func (*TestCase) TypeOf ¶ added in v1.1.1
Convenience method for getting the type of an expression (including identifiers) within the current TestCase's project. Returns `nil` if the type information for the project is not available, or if the expression is not found.
func (*TestCase) UnmarshalJSON ¶
Unmarshal the TestCase from JSON todo maybe remove this because it probably doesn't decode properly