Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ The config file is a json file with the following structure:
}
}
```
As output formats, you can choose between `cobertura` and `textfmt`. The first is described in the cobertura section and
As output formats, you can choose between `cobertura` and `textfmt`. The first is described in the cobertura section and
the second is the default go coverage format.
Complexity only apply for the `cobertura` format. The complexity type can be either `cognitive` or `cyclomatic`.
The difference between these metrics is described in the cobertura section.
Complexity only applies for the `cobertura` format. The complexity type can be either `cognitive` or `cyclomatic`.
The difference between these metrics is described in the cobertura section.

The `SourcePath` is given relative to the working directory (starting with a `./`) or as absolute path.
The `SourcePath` is given relative to the working directory (starting with a `./`) or as absolute path.
The `ExcludePaths` are paths that should be excluded from the coverage report. If a directory is in the exclude list, all files in this directory or subdirectory are excluded.
They are given relative to the `SourcePath`. There are no white card or regex matching here. Thus, If you want to execlude more than one directory, you have to add them all to the list.
The example above would exclude all files in the `vendor` directory in the working directory.
Expand All @@ -57,7 +57,7 @@ The `Cleaner` part contains the filters that should be applied to the source cod

## The accuracy of `go test -coverprofile`
The `go test -coverprofile` command is a great tool to get coverage information about your project.
However, it measures the coverage on a bock level. This means that if you function contains empty lines, only comments,
However, it measures the coverage on a block level. This means that if you function contains empty lines, only comments,
or lines with only a closing bracket, they will be counted in line metrics.

This project tries to solve this problem by using the `go/ast` package to determine the actual lines of code from the source.
Expand All @@ -71,7 +71,7 @@ Thus, we add branch coverage on method and file level. Where such multi conditio
There are parts of the source code that may not be included in the coverage report.
At the moment, the following parts can be excluded:
* Generated files
* Files that fellows [this convention](https://go.dev/s/generatedcode) are excluded
* Files that follow [this convention](https://go.dev/s/generatedcode) are excluded
* None code lines
* Empty lines
* Lines that only contain a comment
Expand All @@ -85,7 +85,7 @@ You can activate these filters by using the corresponding config values.

# Cobertura Format
The cobertura format is a widely used format for coverage reports. It is supported by many tools like Jenkins.
It is an XML format that contains the coverage information for each file and package.
It is an XML format that contains the coverage information for each file and package.
Besides the coverage information, it also contains the complexity metrics for each function.
The format is described [here](https://github.com/cobertura/cobertura/blob/master/cobertura/src/site/htdocs/xml/coverage-04.dtd).
## Cyclomatic Complexity vs Cognitive Complexity
Expand All @@ -110,7 +110,7 @@ Cognitive Complexity aims to produce a measurement that will correlate more clos

### Summary

In summary, while Cyclomatic Complexity is a measure of the structural complexity of a program, Cognitive Complexity is a measure of how difficult a program is to understand by a human reader.
In summary, while Cyclomatic Complexity is a measure of the structural complexity of a program, Cognitive Complexity is a measure of how difficult a program is to understand by a human reader.
Both are useful, but they serve different purposes and can lead to different conclusions about the code's quality.

## Others
Expand All @@ -119,4 +119,4 @@ So far we are aware about two other projects that do something similar:
* [gocover-cobertura](https://github.com/boumenot/gocover-cobertura)

However, both of them focus on the coverage part and take over a big downsides of the `go test -coverprofile` command.
Further this project adds complexity metrics, more options to determine coverage, and branch coverage.
Further this project adds complexity metrics, more options to determine coverage, and branch coverage.
33 changes: 33 additions & 0 deletions pkg/source/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"path/filepath"
"strings"

"go/token"
"golang.org/x/tools/go/packages"

"github.com/Fabianexe/gocoverageplus/pkg/entity"
Expand Down Expand Up @@ -73,6 +74,38 @@ func LoadSources(path string, excludePaths []string) (*entity.Project, error) {
countMethods++
className := getClassName(fun)
methodsMap[className] = append(methodsMap[className], method)
} else if gen, ok := decl.(*ast.GenDecl); ok && gen.Tok == token.VAR {
for _, spec := range gen.Specs {
if valueSpec, ok := spec.(*ast.ValueSpec); ok {
for _, value := range valueSpec.Values {
if funcLit, ok := value.(*ast.FuncLit); ok && len(valueSpec.Names) > 0 {
method := &entity.Method{
Name: valueSpec.Names[0].Name,
Body: funcLit.Body,
File: pkg.Fset.File(value.Pos()),
}

// start after the function declaration
startLine := pkg.Fset.Position(funcLit.Body.Lbrace).Line + 1
endLine := pkg.Fset.Position(funcLit.End()).Line
if startLine >= endLine {
continue
}

bV := &branchVisitor{
fset: pkg.Fset,
}

ast.Walk(bV, valueSpec)

method.Tree = bV.getTree()

countMethods++
methodsMap["-"] = append(methodsMap["-"], method)
}
}
}
}
}
}

Expand Down