Skip to content

Commit 687d39b

Browse files
authored
test: Add unit tests for init command (#303)
* Add unit tests for init command * Tidy up go mod * Update internal/init/init.go Co-authored-by: Qiao Han <qiao@supabase.io>
1 parent 4f20937 commit 687d39b

File tree

7 files changed

+83
-80
lines changed

7 files changed

+83
-80
lines changed

cmd/init.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package cmd
33
import (
44
"fmt"
55

6+
"github.com/spf13/afero"
67
"github.com/spf13/cobra"
78
_init "github.com/supabase/cli/internal/init"
89
"github.com/supabase/cli/internal/utils"
@@ -12,7 +13,8 @@ var initCmd = &cobra.Command{
1213
Use: "init",
1314
Short: "Initialize a project to use Supabase CLI.",
1415
RunE: func(cmd *cobra.Command, args []string) error {
15-
if err := _init.Run(); err != nil {
16+
fsys := afero.NewOsFs()
17+
if err := _init.Run(fsys); err != nil {
1618
return err
1719
}
1820

go.mod

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ require (
1919
github.com/withfig/autocomplete-tools/packages/cobra v1.1.3
2020
)
2121

22+
require (
23+
github.com/davecgh/go-spew v1.1.1 // indirect
24+
github.com/pmezard/go-difflib v1.0.0 // indirect
25+
gopkg.in/yaml.v3 v3.0.1 // indirect
26+
)
27+
2228
require (
2329
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
2430
github.com/Microsoft/go-winio v0.5.2 // indirect
@@ -60,10 +66,11 @@ require (
6066
github.com/pkg/errors v0.9.1 // indirect
6167
github.com/rivo/uniseg v0.2.0 // indirect
6268
github.com/sirupsen/logrus v1.8.1 // indirect
63-
github.com/spf13/afero v1.8.2 // indirect
69+
github.com/spf13/afero v1.8.2
6470
github.com/spf13/cast v1.4.1 // indirect
6571
github.com/spf13/jwalterweatherman v1.1.0 // indirect
6672
github.com/spf13/pflag v1.0.5 // indirect
73+
github.com/stretchr/testify v1.8.0
6774
github.com/subosito/gotenv v1.2.0 // indirect
6875
github.com/yuin/goldmark v1.4.11 // indirect
6976
github.com/yuin/goldmark-emoji v1.0.1 // indirect

go.sum

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,12 +348,15 @@ github.com/spf13/viper v1.10.1/go.mod h1:IGlFPqhNAPKRxohIzWpI5QEy4kuI7tcl5WvR+8q
348348
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
349349
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
350350
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
351+
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
351352
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
352353
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
353354
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
354355
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
355-
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
356356
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
357+
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
358+
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
359+
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
357360
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
358361
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
359362
github.com/withfig/autocomplete-tools/packages/cobra v1.1.3 h1:toi+jQYY7SG/DRYZxP2U2VkFeCY+6FYLXEr8QR8VXzY=
@@ -730,7 +733,8 @@ gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
730733
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
731734
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
732735
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
733-
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
736+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
737+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
734738
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
735739
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
736740
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

internal/init/init.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"errors"
77
"os"
88

9+
"github.com/spf13/afero"
910
"github.com/supabase/cli/internal/utils"
1011
)
1112

@@ -21,33 +22,33 @@ var (
2122
errAlreadyInitialized = errors.New("Project already initialized. Remove " + utils.Bold("supabase") + " to reinitialize.")
2223
)
2324

24-
func Run() error {
25-
if err := run(); errors.Is(err, errAlreadyInitialized) {
25+
func Run(fsys afero.Fs) error {
26+
if err := run(fsys); errors.Is(err, errAlreadyInitialized) {
2627
return err
2728
} else if err != nil {
28-
_ = os.RemoveAll("supabase")
29+
_ = fsys.RemoveAll("supabase")
2930
return err
3031
}
3132

3233
return nil
3334
}
3435

35-
func run() error {
36+
func run(fsys afero.Fs) error {
3637
// Sanity checks.
3738
{
38-
if _, err := os.ReadFile("supabase/config.toml"); err == nil {
39+
if _, err := afero.ReadFile(fsys, "supabase/config.toml"); err == nil {
3940
return errAlreadyInitialized
4041
} else if !errors.Is(err, os.ErrNotExist) {
4142
return err
4243
}
4344
}
4445

45-
if err := utils.MkdirIfNotExist("supabase"); err != nil {
46+
if err := fsys.Mkdir("supabase", 0755); err != nil && !errors.Is(err, os.ErrExist) {
4647
return err
4748
}
4849

4950
// 1. Write `config.toml`.
50-
if err := utils.WriteConfig(false); err != nil {
51+
if err := utils.WriteConfig(fsys, false); err != nil {
5152
return err
5253
}
5354

@@ -60,17 +61,17 @@ func run() error {
6061
// skip
6162
} else {
6263
gitignorePath := *gitRoot + "/.gitignore"
63-
gitignore, err := os.ReadFile(gitignorePath)
64+
gitignore, err := afero.ReadFile(fsys, gitignorePath)
6465
if errors.Is(err, os.ErrNotExist) {
65-
if err := os.WriteFile(gitignorePath, initGitignore, 0644); err != nil {
66+
if err := afero.WriteFile(fsys, gitignorePath, initGitignore, 0644); err != nil {
6667
return err
6768
}
6869
} else if err != nil {
6970
return err
7071
} else if bytes.Contains(gitignore, initGitignore) {
7172
// skip
7273
} else {
73-
f, err := os.OpenFile(gitignorePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
74+
f, err := fsys.OpenFile(gitignorePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
7475
if err != nil {
7576
return err
7677
}

internal/init/init_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package init
2+
3+
import (
4+
"testing"
5+
6+
"github.com/spf13/afero"
7+
"github.com/stretchr/testify/assert"
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
func TestInitCommand(t *testing.T) {
12+
t.Run("creates config file", func(t *testing.T) {
13+
fsys := &afero.MemMapFs{}
14+
assert.NoError(t, Run(fsys))
15+
// TODO: verify .gitignore
16+
exists, err := afero.Exists(fsys, "supabase/config.toml")
17+
assert.NoError(t, err)
18+
assert.True(t, exists)
19+
})
20+
21+
t.Run("errors when config file exists", func(t *testing.T) {
22+
// Test setup
23+
fsys := &afero.MemMapFs{}
24+
_, err := fsys.Create("supabase/config.toml")
25+
require.NoError(t, err)
26+
// Actual test
27+
assert.Error(t, Run(fsys))
28+
})
29+
}

internal/utils/config.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"text/template"
1313

1414
"github.com/BurntSushi/toml"
15+
"github.com/spf13/afero"
1516
"github.com/spf13/viper"
1617
)
1718

@@ -125,7 +126,12 @@ type (
125126
)
126127

127128
func LoadConfig() error {
128-
if _, err := toml.DecodeFile("supabase/config.toml", &Config); err == nil {
129+
return loadConfig(afero.NewOsFs())
130+
}
131+
132+
func loadConfig(fsys afero.Fs) error {
133+
// TODO: remove this helper once all sub commands pass in fsys
134+
if _, err := toml.DecodeFS(afero.NewIOFS(fsys), "supabase/config.toml", &Config); err == nil {
129135
// skip
130136
} else if errors.Is(err, os.ErrNotExist) {
131137
_, _err := os.Stat("supabase/config.json")
@@ -388,7 +394,8 @@ secret = ""
388394
return nil
389395
}
390396

391-
func WriteConfig(test bool) error {
397+
func WriteConfig(fsys afero.Fs, test bool) error {
398+
// Using current directory name as project id
392399
cwd, err := os.Getwd()
393400
if err != nil {
394401
return err
@@ -410,7 +417,7 @@ func WriteConfig(test bool) error {
410417
return err
411418
}
412419

413-
if err := os.WriteFile("supabase/config.toml", initConfigBuf.Bytes(), 0644); err != nil {
420+
if err := afero.WriteFile(fsys, "supabase/config.toml", initConfigBuf.Bytes(), 0644); err != nil {
414421
return err
415422
}
416423

internal/utils/config_test.go

Lines changed: 16 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,36 @@
11
package utils
22

33
import (
4-
"os"
54
"testing"
5+
6+
"github.com/spf13/afero"
7+
"github.com/stretchr/testify/assert"
68
)
79

810
func TestConfigParsing(t *testing.T) {
9-
t.Cleanup(func() {
10-
if err := os.Remove("supabase/config.toml"); err != nil {
11-
if !os.IsNotExist(err) {
12-
t.Error(err)
13-
}
14-
}
15-
if err := os.Remove("supabase"); err != nil {
16-
if !os.IsNotExist(err) {
17-
t.Error(err)
18-
}
19-
}
20-
})
21-
22-
if err := os.Mkdir("supabase", 0755); err != nil {
23-
t.Error(err)
24-
t.FailNow()
25-
}
26-
2711
t.Run("classic config file", func(t *testing.T) {
28-
if err := WriteConfig(false); err != nil {
29-
t.Error(err)
30-
t.FailNow()
31-
}
32-
if err := LoadConfig(); err != nil {
33-
t.Error(err)
34-
t.FailNow()
35-
}
12+
fsys := afero.NewMemMapFs()
13+
assert.NoError(t, WriteConfig(fsys, false))
14+
assert.NoError(t, loadConfig(fsys))
3615
})
3716

3817
t.Run("config file with environment variables", func(t *testing.T) {
39-
if err := WriteConfig(true); err != nil {
40-
t.Error(err)
41-
t.FailNow()
42-
}
18+
fsys := afero.NewMemMapFs()
19+
assert.NoError(t, WriteConfig(fsys, true))
4320

4421
t.Setenv("AZURE_CLIENT_ID", "hello")
4522
t.Setenv("AZURE_SECRET", "this is cool")
46-
if err := LoadConfig(); err != nil {
47-
t.Error(err)
48-
t.FailNow()
49-
}
50-
if err := InterpolateEnvInConfig(); err != nil {
51-
t.Error(err)
52-
t.FailNow()
53-
}
54-
t.Setenv("AZURE_CLIENT_ID", "hello")
55-
t.Setenv("AZURE_SECRET", "this is cool")
23+
assert.NoError(t, loadConfig(fsys))
24+
assert.NoError(t, InterpolateEnvInConfig())
5625

57-
if Config.Auth.External["azure"].ClientId != "hello" {
58-
t.Errorf("unexpected value for key [ClientId]: %+v", Config.Auth.External["azure"])
59-
t.FailNow()
60-
}
61-
62-
if Config.Auth.External["azure"].Secret != "this is cool" {
63-
t.Errorf("unexpected value for key [Secret]: %+v", Config.Auth.External["azure"])
64-
t.FailNow()
65-
}
26+
assert.Equal(t, "hello", Config.Auth.External["azure"].ClientId)
27+
assert.Equal(t, "this is cool", Config.Auth.External["azure"].Secret)
6628
})
6729

6830
t.Run("config file with environment variables fails when unset", func(t *testing.T) {
69-
if err := WriteConfig(true); err != nil {
70-
t.Error(err)
71-
t.FailNow()
72-
}
73-
74-
if err := LoadConfig(); err != nil {
75-
t.Error(err)
76-
t.FailNow()
77-
}
78-
if err := InterpolateEnvInConfig(); err == nil {
79-
t.Error("expected to fail")
80-
t.FailNow()
81-
}
31+
fsys := afero.NewMemMapFs()
32+
assert.NoError(t, WriteConfig(fsys, true))
33+
assert.NoError(t, loadConfig(fsys))
34+
assert.Error(t, InterpolateEnvInConfig())
8235
})
8336
}

0 commit comments

Comments
 (0)