rillig / gobco

Measure branch coverage of golang tests
BSD 2-Clause "Simplified" License
68 stars 13 forks source link

Finding original package path in directory with `_test` package may fails #33

Open 1st-vil opened 7 months ago

1st-vil commented 7 months ago

Overview

In a directory with multiple package (Maybe they are something and something_test), it tries to find the package's path of something. It is performed by looking for its direct import import "github.com/org/repo/something" in the directory. here: https://github.com/rillig/gobco/blob/master/instrumenter.go#L623-L643

Maybe it expects there is such import in a file with something_test package. But, in some cases like it uses another package as helper, the import may not be in the directory. So there are need to provide secure way to determine the package's path.

Example

it can't find the path

something/something.go

package something

type SomeInterface interface {
    Add(a, b int) int
}

type SomeStruct struct {
}

func (s *SomeStruct) Add(a, b int) int {
    return a + b
}

something/something_test.go

package something_test

import (
    "awesomeProject/helper"
    "testing"
)

func Test_Add(t *testing.T) {
    h := helper.TestHelper{}
    s := h.SomeHelperMethod()

    if s.Add(1, 1) != 2 {
        t.Error("error")
    }
}

helper/helper.go

package helper

import "awesomeProject/something"

type TestHelper struct {
}

func (h *TestHelper) SomeHelperMethod() something.SomeInterface {
    return &something.SomeStruct{}
}

For above files, error like below occurred.

% gobco
/private/var/folders/p9/_rh78g8d2clbbn1gk1qd6s6r0000gq/T/gobco-30bfe6a8ee2bdbbc/module-ade35ebcc7c72727/something/gobco_bridge_test.go:3:9: invalid import path: 
go test .: exit status 1

It find incorrect path with same package name

interface/something/something.go

package something

type SomeInterface interface {
    Add(a, b int) int
}

something/factory.go

package something

import "awesomeProject/interface/something"

func NewSomething() something.SomeInterface {
    return &SomeStruct{}
}

something/something.go

package something

type SomeStruct struct {
}

func (s *SomeStruct) Add(a, b int) int {
    return a + b
}

something/something_test.go

package something_test

import (
    "awesomeProject/helper"
    "testing"
)

func Test_Add(t *testing.T) {
    h := helper.TestHelper{}
    s := h.SomeHelperMethod()

    if s.Add(1, 1) != 2 {
        t.Error("error")
    }
}

helper/helper.go

package helper

import (
    somethingInterface "awesomeProject/interface/something"
    "awesomeProject/something"
)

type TestHelper struct {
}

func (h *TestHelper) SomeHelperMethod() somethingInterface.SomeInterface {
    return &something.SomeStruct{}
}

For above files, error like below occurred.

% gobco
# awesomeProject/something_test [awesomeProject/something.test]
./gobco_bridge_test.go:6:19: undefined: something.GobcoCover
FAIL    awesomeProject/something [build failed]
FAIL
go test .: exit status 1
1st-vil commented 7 months ago

@rillig Hello. Thank you for developing this useful tool 🙇‍♂️

I'd like to contribute gobco and create PR on this issue to resolve it sooner. Is it good for you? and could you tell me some points of caution on contributing this repo if there is it?

rillig commented 7 months ago

Hello @1st-vil, you found pretty nice use cases, and you explanation is easy to follow. If you have an idea on how to reliably determine the import path of the current package, I'm welcoming a pull request of yours. My idea would be to search for a go.mod file in the current directory and its parent directories. The code in writeGobcoBlackBox may be a good starting point.

There are no points of caution, just go ahead. :)

1st-vil commented 7 months ago

Hi @rillig. I created a PR on this issue. So I'd like you to review it 🙇‍♂️

1st-vil commented 7 months ago

@rillig If we merge the PR, I'd like you to publish next release including it after fix. It's because I'd like to use this in fixed version that is ensured not to change. Is it ok?

1st-vil commented 6 months ago

@rillig Hello. I'd appreciate it if you could see my PR 🙇

rillig commented 6 months ago

@1st-vil Sorry that it took me so long to reply.

Thank you for the PR showing that the module can be found.

Right now, gobco does not have any external dependencies, and I'd like to keep this property.

For just finding the module path, there is no need to verify the hashes, so I'd like to omit these dependencies. Another point I don't understand is why the PR adds dependencies for 5 different versions of golang.org/x/mod; I'd think that a single version should be enough.

1st-vil commented 5 months ago

@rillig Sorry that it took me so long to reply too...

I'm also not sure about why the PR adds dependencies for 5 different versions of golang.org/x/mod. I just used golang.org/x/mod/modfile. But I found that we can use exec.Command("go", "list", "-m") instead to get a module name. By doing this, There will not be those dependencies.

Could you check my changes again?

1st-vil commented 4 months ago

@rillig Hi. Could you see my PR again 🙇