Skip to content

Commit 36a50f8

Browse files
committed
Add spy and fake implementation to improve testability
1 parent 0e4b44a commit 36a50f8

26 files changed

+8437
-103
lines changed

.github/workflows/quality.yml

Lines changed: 5 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,17 @@ on:
55
branches: ["main"]
66
pull_request:
77
branches: ["main"]
8+
env:
9+
GITHUB_COM_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
810
jobs:
911
check-quality:
1012
permissions:
1113
actions: "write"
1214
runs-on: "ubuntu-latest"
1315
steps:
14-
# setup
1516
- uses: "nixbuild/nix-quick-install-action@5bb6a3b3abe66fd09bbf250dce8ada94f856a703" # v30
1617
- uses: "actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683" # v4
17-
- uses: "nix-community/cache-nix-action@c448f065ba14308da81de769632ca67a3ce67cf5" # v6
18+
- uses: "nix-community/cache-nix-action@135667ec418502fa5a3598af6fb9eb733888ce6a" # v6
1819
with:
1920
primary-key: "cache-nix-store-${{ runner.os }}-${{ hashFiles('flake.nix', 'flake.lock') }}"
2021
restore-prefixes-first-match: "cache-nix-store-${{ runner.os }}-"
@@ -33,38 +34,5 @@ jobs:
3334
run: "nix flake metadata"
3435
- name: "Setup shell"
3536
run: "nix develop --command true"
36-
37-
# tests
38-
- uses: "DeterminateSystems/flake-checker-action@078f5f7f47ee188aa6cb472527ca5984e195222d" # v9
39-
with:
40-
fail-mode: true
41-
ignore-missing-flake-lock: false
42-
nixpkgs-keys: "nixpkgs"
43-
send-statistics: false
44-
45-
- name: "Flake check"
46-
run: "nix flake check --all-systems --print-build-logs"
47-
48-
- name: "Files respect Editorconfig configuration"
49-
run: "nix develop --command lint-editorconfig"
50-
51-
- name: "Files respect treefmt format"
52-
run: "nix develop --command treefmt --no-cache --fail-on-change"
53-
54-
- name: "Lint Github Actions"
55-
run: "nix develop --command lint-ghaction"
56-
57-
- name: "Lint Shell scripts"
58-
run: "nix develop --command lint-sh"
59-
60-
- name: "Lint YAML configurations files"
61-
run: "nix develop --command lint-yaml"
62-
63-
- name: "Lint Go code"
64-
run: "nix develop --command lint-go"
65-
66-
- name: "Lint Nix code"
67-
run: "nix develop --command lint-nix"
68-
69-
- name: "Run go unit tests"
70-
run: "nix develop --command go test -v -race -count 10 -failfast -timeout 45s -shuffle on ./..."
37+
- name: "Just CI"
38+
run: "nix develop --command just ci"

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
/result
33

44
# nixago: ignore-linked-files
5-
/.idea/watcherTasks.xml
65
/.editorconfig
6+
/.idea/watcherTasks.xml
7+
/.justfile

double/fake_generated.go

Lines changed: 123 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

double/fake_test.go

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package double
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/krostar/test"
8+
"github.com/krostar/test/check"
9+
10+
"github.com/krostar/cli"
11+
)
12+
13+
func Test_Fake(t *testing.T) {
14+
t.Run("default only implements Execute", func(t *testing.T) {
15+
f := NewFake()
16+
17+
test.Assert(check.Not(check.Panics(t, func() {
18+
test.Assert(t, f.Execute(t.Context(), []string{}, []string{}) == nil)
19+
}, nil)))
20+
21+
_, okContext := f.(cli.CommandContext)
22+
_, okDescription := f.(cli.CommandDescription)
23+
_, okExamples := f.(cli.CommandExamples)
24+
_, okFlags := f.(cli.CommandFlags)
25+
_, okHook := f.(cli.CommandHook)
26+
_, okPersistentFlags := f.(cli.CommandPersistentFlags)
27+
_, okPersistentHook := f.(cli.CommandPersistentHook)
28+
_, okUsage := f.(cli.CommandUsage)
29+
30+
test.Assert(t, !okContext && !okDescription && !okExamples && !okFlags && !okHook && !okPersistentFlags && !okPersistentHook && !okUsage)
31+
})
32+
33+
t.Run("FakeWithContext", func(t *testing.T) {
34+
ctx := t.Context()
35+
36+
f := NewFake(FakeWithContext(func(context.Context) context.Context { return ctx }))
37+
38+
fContext, okContext := f.(cli.CommandContext)
39+
test.Assert(t, okContext && fContext.Context(t.Context()) == ctx)
40+
})
41+
42+
t.Run("FakeWithDescription", func(t *testing.T) {
43+
description := "hello world"
44+
45+
f := NewFake(FakeWithDescription(func() string { return description }))
46+
47+
fDescription, okDescription := f.(cli.CommandDescription)
48+
test.Assert(t, okDescription && fDescription.Description() == description)
49+
})
50+
51+
t.Run("FakeWithExamples", func(t *testing.T) {
52+
examples := []string{"hello", "world"}
53+
54+
f := NewFake(FakeWithExamples(func() []string { return examples }))
55+
56+
fExamples, okExamples := f.(cli.CommandExamples)
57+
test.Assert(t, okExamples)
58+
test.Assert(check.Compare(t, fExamples.Examples(), examples))
59+
})
60+
61+
t.Run("FakeWithFlags", func(t *testing.T) {
62+
flags := []cli.Flag{cli.NewBuiltinFlag("long", "s", new(int), "description")}
63+
64+
f := NewFake(FakeWithFlags(func() []cli.Flag { return flags }))
65+
66+
fFlags, okFlags := f.(cli.CommandFlags)
67+
test.Assert(t, okFlags && len(fFlags.Flags()) == len(flags))
68+
})
69+
70+
t.Run("FakeWithHook", func(t *testing.T) {
71+
hook := &cli.Hook{BeforeCommandExecution: func(context.Context) error { return nil }}
72+
73+
f := NewFake(FakeWithHook(func() *cli.Hook { return hook }))
74+
75+
fHook, okHook := f.(cli.CommandHook)
76+
test.Assert(t, okHook && fHook.Hook() == hook)
77+
})
78+
79+
t.Run("FakeWithPersistentFlags", func(t *testing.T) {
80+
flags := []cli.Flag{cli.NewBuiltinFlag("long", "s", new(int), "description")}
81+
82+
f := NewFake(FakeWithPersistentFlags(func() []cli.Flag { return flags }))
83+
84+
fPersistentFlags, okPersistentFlags := f.(cli.CommandPersistentFlags)
85+
test.Assert(t, okPersistentFlags && len(fPersistentFlags.PersistentFlags()) == len(flags))
86+
})
87+
88+
t.Run("FakeWithPersistentHook", func(t *testing.T) {
89+
hook := &cli.PersistentHook{BeforeCommandExecution: func(context.Context) error { return nil }}
90+
91+
f := NewFake(FakeWithPersistentHook(func() *cli.PersistentHook { return hook }))
92+
93+
fPersistentHook, okPersistentHook := f.(cli.CommandPersistentHook)
94+
test.Assert(t, okPersistentHook && fPersistentHook.PersistentHook() == hook)
95+
})
96+
97+
t.Run("FakeWithUsage", func(t *testing.T) {
98+
usage := "hello world"
99+
100+
f := NewFake(FakeWithUsage(func() string { return usage }))
101+
102+
fUsage, okUsage := f.(cli.CommandUsage)
103+
test.Assert(t, okUsage && fUsage.Usage() == usage)
104+
})
105+
}

0 commit comments

Comments
 (0)