diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 56d697b..cf06f0e 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -2,9 +2,9 @@ name: Go on: push: - branches: [ "master" ] + branches: [ "main" ] pull_request: - branches: [ "master" ] + branches: [ "main" ] jobs: @@ -21,19 +21,8 @@ jobs: - name: Build run: go build -v ./... + - name: Set up gomock + run: go install go.uber.org/mock/mockgen@latest + - name: Test run: go test -v ./... - - end-to-end-tests: - runs-on: ubuntu-latest - needs: build - steps: - - uses: actions/checkout@v4 - - - name: Set up Go - uses: actions/setup-go@v4 - with: - go-version: '1.24' - - - name: Run End-to-End Tests - run: go test -v -run TestEndToEnd diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0c63fef..af6b37d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,7 +16,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: '1.22' + go-version: '1.24' - name: Build binaries run: | diff --git a/README.md b/README.md index f54186f..a8b3791 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,33 @@ -# fixturec -Tool for generate test fixtures in golang +# Fixturec + +`fixturec` is a command-line utility that automatically generates test fixtures and mocks for Go structs. + +🚀 Installation +``` +go install github.com/Vypolor/fixturec@latest +``` + +🧠 How It Works + +In the Go file containing your struct, add a go:generate directive: + +``` +// go:generate fixturec -t Impl +``` + + +where Impl is the name of the struct for which you want to generate a fixture. + +The tool performs the following steps: +- analyzes the specified struct and finds fields that are interfaces defined within the same module; +- checks for a //go:generate mockgen ... directive in the interface’s file and adds it if missing; +- runs go generate to create mocks using mockgen; +- generates a fixture_test.go file in the same package as the original struct. + +⚙️ Flags + +| Flag | Description | +|------|------------------------------------------------------------------------------------------------------| +| `-t` | **(required)** — name of the struct to generate the fixture for. Example: `-t Impl`. | +| `-g` | *(planned)* — disables automatic mock generation. Enabled by default. Currently **not implemented**. | +| `-e` | *(planned)* — enables mock generation for **external packages**. Currently **not implemented**. | diff --git a/internal/generator/fixture/generator_test.go b/internal/generator/fixture/generator_test.go new file mode 100644 index 0000000..abbf810 --- /dev/null +++ b/internal/generator/fixture/generator_test.go @@ -0,0 +1,51 @@ +package fixture + +import ( + "os" + "path/filepath" + "testing" + + "github.com/Vypolor/fixturec/internal/generator/dto" + "github.com/stretchr/testify/require" +) + +func TestGenerateFixtureFile(t *testing.T) { + t.Parallel() + + pkgName := "gen" + structName := "ToGen" + + dir, err := os.MkdirTemp("", "fixturec") + if err != nil { + t.Fatal(err) + } + + fields := []dto.FieldInfo{ + { + FieldName: "myType1", + TypeName: "github.com/Vypolor/without_external/mypackage1.MyType1", + PkgPath: "github.com/Vypolor/without_external/mypackage1", + }, + { + FieldName: "myType2", + TypeName: "github.com/Vypolor/without_external/mypackage2.MyType2", + PkgPath: "github.com/Vypolor/without_external/mypackage2", + }, + } + + require.NoError(t, GenerateFixtureFile(dir, pkgName, structName, fields)) + + // read golden file + golden, err := os.ReadFile(filepath.Join("testdata", "gen.golden")) + require.NoError(t, err) + + // read generated file + genFilePath := filepath.Join(dir, "fixture_test.go") + generated, err := os.ReadFile(genFilePath) + require.NoError(t, err) + + require.Equal(t, golden, generated) + + // delete temp dir + require.NoError(t, os.RemoveAll(dir)) +} diff --git a/internal/generator/fixture/testdata/gen.golden b/internal/generator/fixture/testdata/gen.golden new file mode 100644 index 0000000..117e095 --- /dev/null +++ b/internal/generator/fixture/testdata/gen.golden @@ -0,0 +1,41 @@ +package gen + +import ( + "context" + "testing" + + mypackage1_mock "github.com/Vypolor/without_external/mypackage1/mock" + mypackage2_mock "github.com/Vypolor/without_external/mypackage2/mock" + ctrl_mock "go.uber.org/mock/gomock" +) + +type fixture struct { + ctrl *ctrl_mock.Controller + ctx context.Context + + myType1 *mypackage1_mock.MockMyType1 + myType2 *mypackage2_mock.MockMyType2 + + toGen *ToGen +} + +func setUp(t *testing.T) *fixture { + f := &fixture{ + ctrl: ctrl_mock.NewController(t), + ctx: context.Background(), + + myType1: mypackage1_mock.NewMockMyType1(ctrl_mock.NewController(t)), + myType2: mypackage2_mock.NewMockMyType2(ctrl_mock.NewController(t)), + } + + f.toGen = &ToGen{ + myType1: f.myType1, + myType2: f.myType2, + } + + return f +} + +func (f *fixture) tearDown() { + f.ctrl.Finish() +} diff --git a/internal/generator/fixture/testdata/with_external/fixture_test.golden b/internal/generator/fixture/testdata/with_external/fixture_test.golden deleted file mode 100644 index e69de29..0000000 diff --git a/internal/generator/fixture/testdata/without_external/fixture_test.golden b/internal/generator/fixture/testdata/without_external/fixture_test.golden deleted file mode 100644 index e69de29..0000000 diff --git a/internal/generator/mock/mock.go b/internal/generator/mock/mock.go index 54db777..7e3cdb5 100644 --- a/internal/generator/mock/mock.go +++ b/internal/generator/mock/mock.go @@ -58,7 +58,10 @@ func GenerateMocks(pkgDir string, fields []dto.FieldInfo) error { } dirLine := fmt.Sprintf("//go:generate mockgen -destination=mock/mock_gen.go -package=mock -source=./%s\n", filepath.Base(filename)) - _ = os.WriteFile(filename, append([]byte(dirLine), b...), utils.FilePerm0644) + + if err = os.WriteFile(filename, append([]byte(dirLine), b...), utils.FilePerm0644); err != nil { + return fmt.Errorf("failed to write file %s: %w", filename, err) + } fmt.Printf("Inserted mockgen directive into %s\n", filename) }