Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wip: refactor Golden to a interface, improve testability of main impl… #3

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
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
56 changes: 22 additions & 34 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,47 +7,39 @@ jobs:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.18"
cache: false
- name: golangci-lint
uses: golangci/golangci-lint-action@v2
uses: golangci/golangci-lint-action@v4
with:
version: v1.42
version: v1.56
env:
VERBOSE: "true"

tidy:
name: Tidy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
with:
go-version: 1.15
- uses: actions/cache@v2
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
go-version: "1.18"
- name: Check if mods are tidy
run: make check-tidy

cov:
name: Coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: 1.15
- uses: actions/cache@v2
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
go-version: "1.18"
- name: Publish coverage
uses: paambaati/codeclimate-action@v2.7.4
uses: paambaati/codeclimate-action@v5.0.0
env:
VERBOSE: "true"
GOMAXPROCS: 4
Expand All @@ -68,20 +60,16 @@ jobs:
- macos-latest
- windows-latest
go_version:
- "1.15"
- "1.16"
- "1.17"
- "1.18"
- "1.19"
- "1.20"
- "1.21"
- "1.22"
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go_version }}
- uses: actions/cache@v2
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
go-version: "1.22"
- name: Run tests
run: go test -v -count=1 -race ./...
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
bin/*
coverage.out

testdata/*
!testdata/TestExample*
testdata/TestFile*
testdata/TestGet*
testdata/TestSet*
4 changes: 0 additions & 4 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ linters:
- asciicheck
- bodyclose
- deadcode
- depguard
- durationcheck
- errcheck
- errorlint
Expand Down Expand Up @@ -69,9 +68,6 @@ linters:
- whitespace

issues:
exclude:
- Using the variable on range scope `tt` in function literal
- Using the variable on range scope `tc` in function literal
exclude-rules:
- path: "_test\\.go"
linters:
Expand Down
18 changes: 7 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,23 +34,19 @@ SHELL := env \
# Tools
#

TOOLS += $(TOOLDIR)/gobin
$(TOOLDIR)/gobin:
GO111MODULE=off go get -u github.com/myitcv/gobin

# external tool
define tool # 1: binary-name, 2: go-import-path
TOOLS += $(TOOLDIR)/$(1)

$(TOOLDIR)/$(1): $(TOOLDIR)/gobin Makefile
gobin $(V) "$(2)"
$(TOOLDIR)/$(1): Makefile
GOBIN="$(CURDIR)/$(TOOLDIR)" go install "$(2)"
endef

$(eval $(call tool,godoc,golang.org/x/tools/cmd/godoc))
$(eval $(call tool,gofumpt,mvdan.cc/gofumpt))
$(eval $(call tool,goimports,golang.org/x/tools/cmd/goimports))
$(eval $(call tool,golangci-lint,github.com/golangci/golangci-lint/cmd/golangci-lint@v1.42))
$(eval $(call tool,gomod,github.com/Helcaraxan/gomod))
$(eval $(call tool,godoc,golang.org/x/tools/cmd/godoc@latest))
$(eval $(call tool,gofumpt,mvdan.cc/gofumpt@latest))
$(eval $(call tool,goimports,golang.org/x/tools/cmd/goimports@latest))
$(eval $(call tool,golangci-lint,github.com/golangci/golangci-lint/cmd/golangci-lint@v1.56))
$(eval $(call tool,gomod,github.com/Helcaraxan/gomod@latest))

.PHONY: tools
tools: $(TOOLS)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,4 @@ for documentation and examples.

## License

[MIT](https://github.com/jimeh/go-golden/blob/master/LICENSE)
[MIT](https://github.com/jimeh/go-golden/blob/main/LICENSE)
46 changes: 46 additions & 0 deletions fs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package golden

import "os"

type FS interface {
// MkdirAll creates a directory named path, along with any necessary
// parents, and returns nil, or else returns an error. The permission bits
// perm (before umask) are used for all directories that MkdirAll creates.
MkdirAll(path string, perm os.FileMode) error

// ReadFile reads the named file and returns the contents. A successful call
// returns err == nil, not err == EOF. Because ReadFile reads the whole
// file, it does not treat an EOF from Read as an error to be reported.
ReadFile(filename string) ([]byte, error)

// WriteFile writes data to a file named by filename. If the file does not
// exist, WriteFile creates it with permissions perm; otherwise WriteFile
// truncates it before writing, without changing permissions.
WriteFile(name string, data []byte, perm os.FileMode) error
}

type fsImpl struct{}

var _ FS = fsImpl{}

// NewFS returns a new FS instance which operates against the host file system
// via calls to functions in the os package.
func NewFS() FS {
return fsImpl{}
}

// DefaultFS is the default FS instance used by all top-level package functions,
// including the Default Golden instance, and also the New function.
var DefaultFS = NewFS()

func (fsImpl) MkdirAll(path string, perm os.FileMode) error {
return os.MkdirAll(path, perm)
}

func (fsImpl) ReadFile(filename string) ([]byte, error) {
return os.ReadFile(filename)
}

func (fsImpl) WriteFile(filename string, data []byte, perm os.FileMode) error {
return os.WriteFile(filename, data, perm)
}
131 changes: 131 additions & 0 deletions fs_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package golden

import (
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestMkdirAll(t *testing.T) {
tempDir := t.TempDir()

tests := []struct {
name string
path string
perm os.FileMode
wantErr bool
}{
{"create new dir", "newdir", 0o755, false},
{"create nested dirs", "nested/dir/structure", 0o755, false},
{"invalid path", string([]byte{0, 0}), 0o755, true},
}

fs := NewFS()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
path := filepath.Join(tempDir, tt.path)
err := fs.MkdirAll(path, tt.perm)

if tt.wantErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
_, err := os.Stat(path)
assert.NoError(t, err)
}
})
}
}

func TestReadFile(t *testing.T) {
tempDir := t.TempDir()

sampleFilePath := filepath.Join(tempDir, "sample.txt")
sampleContent := []byte("Hello, world!")
err := os.WriteFile(sampleFilePath, sampleContent, 0o600)
require.NoError(t, err)

tests := []struct {
name string
filename string
want []byte
wantErr bool
}{
{"read existing file", sampleFilePath, sampleContent, false},
{"file does not exist", "nonexistent.txt", nil, true},
}

fs := NewFS()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := fs.ReadFile(tt.filename)

if tt.wantErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.Equal(t, string(tt.want), string(got))
}
})
}
}

func TestWriteFile(t *testing.T) {
tempDir := t.TempDir()

tests := []struct {
name string
filename string
data []byte
perm os.FileMode
wantErr bool
}{
{
"write to new file",
"newfile.txt",
[]byte("new content"),
0o644,
false,
},
{
"overwrite existing file",
"existing.txt",
[]byte("overwritten content"),
0o644,
false,
},
{
"invalid filename",
string([]byte{0, 0}),
[]byte("invalid filename"),
0o644,
true,
},
{
"non-existent directory",
"nonexistentdir/newfile.txt",
[]byte("this will fail"),
0o644,
true,
},
}

fs := NewFS()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
filePath := filepath.Join(tempDir, tt.filename)
err := fs.WriteFile(filePath, tt.data, tt.perm)
if tt.wantErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
content, err := os.ReadFile(filePath)
assert.NoError(t, err)
assert.Equal(t, tt.data, content)
}
})
}
}
10 changes: 8 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
module github.com/jimeh/go-golden

go 1.15
go 1.18

require (
github.com/jimeh/envctl v0.1.0
github.com/stretchr/testify v1.7.0
github.com/stretchr/testify v1.9.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
10 changes: 6 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/jimeh/envctl v0.1.0 h1:KTv3D+pi5M4/PgFVE/W8ssWqiZP3pDJ8Cga50L+1avo=
github.com/jimeh/envctl v0.1.0/go.mod h1:aM27ffBbO1yUBKUzgJGCUorS4z+wyh+qhQe1ruxXZZo=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Loading
Loading