test(processor): whole-file golden driver + seed python cases
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
# Task 1 Report — Inject `cfg` into file-mutating methods
|
||||
|
||||
## Files changed
|
||||
|
||||
- `internal/processor/processor.go`
|
||||
- `Process()`: now loads `cfg` once (`config.Load()` / fallback `config.Default()`) for the non-git path and threads it into `processDirectory` and `processFile`.
|
||||
- `processDirectory(dirPath string, cfg *config.Config) error` — new `cfg` param, forwarded to `processFile`.
|
||||
- `processFile(filename string, cfg *config.Config) error` — new `cfg` param, forwarded to `processFileInMemory`.
|
||||
- `processFileInMemory(filename string, language types.Language, cfg *config.Config) error` — removed internal `config.Load()` block; `cfg` now supplied by caller.
|
||||
- `internal/processor/git_processor.go`
|
||||
- `processGitChanges()`: now loads `cfg` once (`cfg, _, cfgErr := config.Load()` / fallback `config.Default()`) right before `totals := &GitTotals{}`, and passes it into `processFileWithLineRanges` on the non-dry-run path.
|
||||
- `processFileWithLineRanges(filename string, lineRanges []git.LineRange, cfg *config.Config) error` — removed internal `config.Load()` block; `cfg` now supplied by caller.
|
||||
- `internal/ignore/ignore.go` — incidental: `go fmt` (run as part of `make check`) stripped trailing whitespace on 3 blank lines. No syntactic change (`jj diff` confirms "No syntactic changes"); not part of the planned refactor scope.
|
||||
|
||||
`showPreview` and `showGitPreviewWithTotals` were left untouched — both keep their own `config.Load()` calls per the plan.
|
||||
|
||||
Used the `cfgErr` variant in `processGitChanges` (per the plan's fallback note) since `err` was already declared earlier in that function via the `switch` block.
|
||||
|
||||
## `go test ./...` output (after refactor)
|
||||
|
||||
```
|
||||
ok github.com/carlosarraes/shush/cmd/shush (cached)
|
||||
? github.com/carlosarraes/shush/internal/cli [no test files]
|
||||
? github.com/carlosarraes/shush/internal/commands [no test files]
|
||||
? github.com/carlosarraes/shush/internal/config [no test files]
|
||||
ok github.com/carlosarraes/shush/internal/git (cached)
|
||||
? github.com/carlosarraes/shush/internal/guide [no test files]
|
||||
? github.com/carlosarraes/shush/internal/hooks [no test files]
|
||||
? github.com/carlosarraes/shush/internal/ignore [no test files]
|
||||
ok github.com/carlosarraes/shush/internal/processor (cached)
|
||||
? github.com/carlosarraes/shush/internal/types [no test files]
|
||||
```
|
||||
|
||||
## `make check` result
|
||||
|
||||
Ran `go fmt ./...` (reformatted `internal/ignore/ignore.go`, whitespace-only), `go vet ./...` (clean, no output), `go test -v ./...` — all suites passed:
|
||||
- `cmd/shush`: `TestGitFlagValidation` and all 10 subtests — PASS
|
||||
- `internal/git`: `TestParseGitDiffUnified` (6 subtests), `TestIsInLineRanges` (13 subtests), `TestIsInLineRangesEmptyRanges` — PASS
|
||||
- `internal/processor`: `TestRemoveCommentsFromLine` (8 subtests), `TestFindCommentIndex` (7 subtests), `TestLineHasComment` (5 subtests) — PASS
|
||||
|
||||
Overall: `make check` exited clean — zero failures, zero vet warnings.
|
||||
|
||||
## New method signatures
|
||||
|
||||
```go
|
||||
func (p *Processor) processFileInMemory(filename string, language types.Language, cfg *config.Config) error
|
||||
func (p *Processor) processFileWithLineRanges(filename string, lineRanges []git.LineRange, cfg *config.Config) error
|
||||
```
|
||||
|
||||
## jj commit
|
||||
|
||||
```
|
||||
jj describe -m "refactor(processor): inject cfg into file-mutating methods"
|
||||
jj new
|
||||
```
|
||||
|
||||
Result:
|
||||
```
|
||||
lyzxvysr e01678cb refactor(processor): inject cfg into file-mutating methods
|
||||
```
|
||||
@@ -0,0 +1,3 @@
|
||||
# header comment
|
||||
x = 1
|
||||
print(x)
|
||||
@@ -0,0 +1,2 @@
|
||||
x = 1
|
||||
print(x)
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
x = 1 # set x
|
||||
print(x) # show
|
||||
@@ -0,0 +1,2 @@
|
||||
x = 1
|
||||
print(x)
|
||||
@@ -0,0 +1,102 @@
|
||||
package processor
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/carlosarraes/shush/internal/config"
|
||||
"github.com/carlosarraes/shush/internal/git"
|
||||
"github.com/carlosarraes/shush/internal/types"
|
||||
)
|
||||
|
||||
var update = flag.Bool("update", false, "update golden files")
|
||||
|
||||
type wholeFileCase struct {
|
||||
name string
|
||||
file string // fixture under testdata/, e.g. "py_inline.py"
|
||||
cli types.CLI
|
||||
cfg *config.Config // nil => config.Default()
|
||||
gitMode bool // true => processFileWithLineRanges (surgical git path)
|
||||
ranges []git.LineRange // used only when gitMode; nil => whole file
|
||||
wantBackup bool
|
||||
}
|
||||
|
||||
func runWholeFileCase(t *testing.T, tc wholeFileCase) {
|
||||
t.Helper()
|
||||
|
||||
src := filepath.Join("testdata", tc.file)
|
||||
in, err := os.ReadFile(src)
|
||||
if err != nil {
|
||||
t.Fatalf("read input %s: %v", src, err)
|
||||
}
|
||||
|
||||
tmp := t.TempDir()
|
||||
work := filepath.Join(tmp, tc.file)
|
||||
if err := os.WriteFile(work, in, 0644); err != nil {
|
||||
t.Fatalf("write work copy: %v", err)
|
||||
}
|
||||
|
||||
cfg := tc.cfg
|
||||
if cfg == nil {
|
||||
cfg = config.Default()
|
||||
}
|
||||
|
||||
p := &Processor{cli: tc.cli}
|
||||
if tc.gitMode {
|
||||
err = p.processFileWithLineRanges(work, tc.ranges, cfg)
|
||||
} else {
|
||||
lang, derr := DetectLanguage(work)
|
||||
if derr != nil {
|
||||
t.Fatalf("detect language for %s: %v", work, derr)
|
||||
}
|
||||
err = p.processFileInMemory(work, lang, cfg)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("process: %v", err)
|
||||
}
|
||||
|
||||
got, err := os.ReadFile(work)
|
||||
if err != nil {
|
||||
t.Fatalf("read result: %v", err)
|
||||
}
|
||||
|
||||
golden := src + ".golden"
|
||||
if *update {
|
||||
if err := os.WriteFile(golden, got, 0644); err != nil {
|
||||
t.Fatalf("update golden: %v", err)
|
||||
}
|
||||
}
|
||||
want, err := os.ReadFile(golden)
|
||||
if err != nil {
|
||||
t.Fatalf("read golden %s: %v", golden, err)
|
||||
}
|
||||
if !bytes.Equal(got, want) {
|
||||
t.Errorf("output mismatch:\n--- got ---\n%q\n--- want ---\n%q", got, want)
|
||||
}
|
||||
|
||||
if tc.wantBackup {
|
||||
bakData, err := os.ReadFile(work + ".bak")
|
||||
if err != nil {
|
||||
t.Fatalf("read backup: %v", err)
|
||||
}
|
||||
if !bytes.Equal(bakData, in) {
|
||||
t.Errorf("backup mismatch:\n--- got ---\n%q\n--- want ---\n%q", bakData, in)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestWholeFile(t *testing.T) {
|
||||
cases := []wholeFileCase{
|
||||
{name: "python comment-only line removed", file: "py_comment_only.py"},
|
||||
{name: "python inline comment stripped", file: "py_inline.py"},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
runWholeFileCase(t, tc)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user