Skip to content

Commit 4ac8bef

Browse files
committed
test: cmd
1 parent 6efdeac commit 4ac8bef

30 files changed

+1071
-157
lines changed

cmd/assets_test.go

Lines changed: 331 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,331 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"path/filepath"
7+
"reflect"
8+
"runtime"
9+
"testing"
10+
11+
"sqlpkg.org/cli/assets"
12+
"sqlpkg.org/cli/fileio"
13+
"sqlpkg.org/cli/httpx"
14+
"sqlpkg.org/cli/spec"
15+
)
16+
17+
func TestBuildAssetPath(t *testing.T) {
18+
httpx.Mock()
19+
t.Run("exists", func(t *testing.T) {
20+
pkg := &spec.Package{
21+
Owner: "nalgeon", Name: "example", Version: "0.1.0",
22+
Assets: spec.Assets{
23+
Path: &spec.AssetPath{Value: "https://antonz.org", IsRemote: true},
24+
Files: map[string]string{
25+
"darwin-arm64": "example-darwin.zip",
26+
"linux-amd64": "example-linux.zip",
27+
},
28+
},
29+
}
30+
31+
path, err := BuildAssetPath(pkg)
32+
if err != nil {
33+
t.Fatalf("BuildAssetPath: unexpected error %v", err)
34+
}
35+
want := fmt.Sprintf("https://antonz.org/example-%s.zip", runtime.GOOS)
36+
if path.Value != want {
37+
t.Errorf("BuildAssetPath: unexpected Value %q", path.Value)
38+
}
39+
if !path.IsRemote {
40+
t.Errorf("BuildAssetPath: unexpected IsRemote %v", path.IsRemote)
41+
}
42+
})
43+
t.Run("unsupported platform", func(t *testing.T) {
44+
pkg := &spec.Package{
45+
Owner: "nalgeon", Name: "example", Version: "0.1.0",
46+
}
47+
48+
_, err := BuildAssetPath(pkg)
49+
if err == nil {
50+
t.Fatal("BuildAssetPath: expected error, got nil")
51+
}
52+
})
53+
}
54+
55+
func TestDownloadAsset(t *testing.T) {
56+
httpx.Mock()
57+
t.Run("http", func(t *testing.T) {
58+
pkg := &spec.Package{
59+
Owner: "nalgeon", Name: "example", Version: "0.1.0",
60+
Assets: spec.Assets{
61+
Path: &spec.AssetPath{Value: "https://antonz.org", IsRemote: true},
62+
Files: map[string]string{
63+
"darwin-arm64": "example-darwin.zip",
64+
"linux-amd64": "example-linux.zip",
65+
},
66+
},
67+
}
68+
path := &spec.AssetPath{
69+
Value: fmt.Sprintf("%s/example-%s.zip", pkg.Assets.Path, runtime.GOOS),
70+
IsRemote: true,
71+
}
72+
73+
asset, err := DownloadAsset(pkg, path)
74+
if err != nil {
75+
t.Fatalf("DownloadAsset: unexpected error %v", err)
76+
}
77+
if asset.Name != fmt.Sprintf("example-%s.zip", runtime.GOOS) {
78+
t.Errorf("DownloadAsset: unexpected Name %v", asset.Name)
79+
}
80+
if filepath.Base(asset.Path) != asset.Name {
81+
t.Errorf("DownloadAsset: unexpected Path %v", asset.Path)
82+
}
83+
if !fileio.Exists(asset.Path) {
84+
t.Error("DownloadAsset: file does not exist")
85+
}
86+
if asset.Size != 128 && asset.Size != 137 {
87+
t.Errorf("DownloadAsset: unexpected asset size %v", asset.Size)
88+
}
89+
if !reflect.DeepEqual(asset.Checksum[:6], []byte{0x17, 0xe2, 0xf2, 0xf9, 0x71, 0x93}) && !reflect.DeepEqual(asset.Checksum[:6], []byte{0x58, 0x38, 0x10, 0x0a, 0x12, 0x9a}) {
90+
t.Errorf("DownloadAsset: unexpected asset checksum %v", asset.Checksum[:6])
91+
}
92+
})
93+
t.Run("file", func(t *testing.T) {
94+
pkg := &spec.Package{
95+
Owner: "nalgeon", Name: "example", Version: "0.1.0",
96+
Assets: spec.Assets{
97+
Path: &spec.AssetPath{Value: "./testdata", IsRemote: false},
98+
Files: map[string]string{
99+
"darwin-arm64": "example-darwin.zip",
100+
"linux-amd64": "example-linux.zip",
101+
},
102+
},
103+
}
104+
path := &spec.AssetPath{
105+
Value: fmt.Sprintf("%s/example-%s.zip", pkg.Assets.Path, runtime.GOOS),
106+
IsRemote: true,
107+
}
108+
109+
asset, err := DownloadAsset(pkg, path)
110+
if err != nil {
111+
t.Fatalf("DownloadAsset: unexpected error %v", err)
112+
}
113+
if asset.Name != fmt.Sprintf("example-%s.zip", runtime.GOOS) {
114+
t.Errorf("DownloadAsset: unexpected Name %v", asset.Name)
115+
}
116+
if filepath.Base(asset.Path) != asset.Name {
117+
t.Errorf("DownloadAsset: unexpected Path %v", asset.Path)
118+
}
119+
if !fileio.Exists(asset.Path) {
120+
t.Error("DownloadAsset: file does not exist")
121+
}
122+
if asset.Size != 128 && asset.Size != 137 {
123+
t.Errorf("DownloadAsset: unexpected asset size %v", asset.Size)
124+
}
125+
if !reflect.DeepEqual(asset.Checksum[:6], []byte{0x17, 0xe2, 0xf2, 0xf9, 0x71, 0x93}) && !reflect.DeepEqual(asset.Checksum[:6], []byte{0x58, 0x38, 0x10, 0x0a, 0x12, 0x9a}) {
126+
t.Errorf("DownloadAsset: unexpected asset checksum %v", asset.Checksum[:6])
127+
}
128+
})
129+
t.Run("not found", func(t *testing.T) {
130+
pkg := &spec.Package{
131+
Owner: "nalgeon", Name: "other", Version: "0.1.0",
132+
Assets: spec.Assets{
133+
Path: &spec.AssetPath{Value: "https://antonz.org", IsRemote: true},
134+
Files: map[string]string{
135+
"darwin-arm64": "other-darwin.zip",
136+
"linux-amd64": "other-linux.zip",
137+
},
138+
},
139+
}
140+
path := &spec.AssetPath{
141+
Value: fmt.Sprintf("%s/other-%s.zip", pkg.Assets.Path, runtime.GOOS),
142+
IsRemote: true,
143+
}
144+
145+
_, err := DownloadAsset(pkg, path)
146+
if err == nil {
147+
t.Fatal("DownloadAsset: expected error, got nil")
148+
}
149+
})
150+
}
151+
152+
func TestValidateAsset(t *testing.T) {
153+
t.Run("valid", func(t *testing.T) {
154+
pkg := &spec.Package{
155+
Owner: "nalgeon", Name: "example", Version: "0.1.0",
156+
Assets: spec.Assets{
157+
Path: &spec.AssetPath{Value: "https://antonz.org", IsRemote: true},
158+
Files: map[string]string{
159+
"darwin-arm64": "example-darwin.zip",
160+
"linux-amd64": "example-linux.zip",
161+
},
162+
Checksums: map[string]string{
163+
"example-darwin.zip": "sha256-17e2f2f97193",
164+
"example-linux.zip": "sha256-5838100a129a",
165+
},
166+
},
167+
}
168+
asset := &assets.Asset{
169+
Name: "example-darwin.zip",
170+
Path: "./testdata/example-darwin.zip",
171+
Size: 137,
172+
Checksum: []byte{0x17, 0xe2, 0xf2, 0xf9, 0x71, 0x93},
173+
}
174+
175+
err := ValidateAsset(pkg, asset)
176+
if err != nil {
177+
t.Errorf("ValidateAsset: unexpected error %v", err)
178+
}
179+
})
180+
t.Run("missing", func(t *testing.T) {
181+
pkg := &spec.Package{
182+
Owner: "nalgeon", Name: "example", Version: "0.1.0",
183+
Assets: spec.Assets{
184+
Path: &spec.AssetPath{Value: "https://antonz.org", IsRemote: true},
185+
Files: map[string]string{
186+
"darwin-arm64": "example-darwin.zip",
187+
"linux-amd64": "example-linux.zip",
188+
},
189+
},
190+
}
191+
asset := &assets.Asset{
192+
Name: "example-darwin.zip",
193+
Path: "./testdata/example-darwin.zip",
194+
Size: 137,
195+
Checksum: []byte{0x17, 0xe2, 0xf2, 0xf9, 0x71, 0x93},
196+
}
197+
198+
err := ValidateAsset(pkg, asset)
199+
if err != nil {
200+
t.Errorf("ValidateAsset: unexpected error %v", err)
201+
}
202+
})
203+
t.Run("invalid", func(t *testing.T) {
204+
pkg := &spec.Package{
205+
Owner: "nalgeon", Name: "example", Version: "0.1.0",
206+
Assets: spec.Assets{
207+
Path: &spec.AssetPath{Value: "https://antonz.org", IsRemote: true},
208+
Files: map[string]string{
209+
"darwin-arm64": "example-darwin.zip",
210+
"linux-amd64": "example-linux.zip",
211+
},
212+
Checksums: map[string]string{
213+
"example-darwin.zip": "sha256-17e2f2f97193",
214+
"example-linux.zip": "sha256-5838100a129a",
215+
},
216+
},
217+
}
218+
asset := &assets.Asset{
219+
Name: "example-darwin.zip",
220+
Path: "./testdata/example-darwin.zip",
221+
Size: 137,
222+
Checksum: []byte{0x51, 0x52, 0x53, 0x54, 0x55, 0x56},
223+
}
224+
225+
err := ValidateAsset(pkg, asset)
226+
if err == nil {
227+
t.Fatal("ValidateAsset: expected error, got nil")
228+
}
229+
})
230+
}
231+
232+
func TestUnpackAsset(t *testing.T) {
233+
t.Run("archived", func(t *testing.T) {
234+
dir := t.TempDir()
235+
path := filepath.Join(dir, "example-darwin.zip")
236+
_, err := fileio.CopyFile(filepath.Join("testdata", "example-darwin.zip"), path)
237+
if err != nil {
238+
t.Fatalf("fileio.CopyFile: unexpected error %v", err)
239+
}
240+
241+
pkg := &spec.Package{
242+
Owner: "nalgeon", Name: "example", Version: "0.1.0",
243+
}
244+
asset := &assets.Asset{
245+
Name: "example-darwin.zip", Path: path,
246+
}
247+
248+
err = UnpackAsset(pkg, asset)
249+
if err != nil {
250+
t.Fatalf("UnpackAsset: unexpected error %v", err)
251+
}
252+
253+
if fileio.Exists(filepath.Join(dir, asset.Name)) {
254+
t.Fatal("UnpackAsset: asset archive is not deleted")
255+
}
256+
257+
if !fileio.Exists(filepath.Join(dir, "example.dylib")) {
258+
t.Fatal("UnpackAsset: unpacked asset does not exit")
259+
}
260+
data, err := os.ReadFile(filepath.Join(dir, "example.dylib"))
261+
if err != nil {
262+
t.Fatalf("os.ReadFile: unexpected error %v", err)
263+
}
264+
if string(data) != "example.dylib" {
265+
t.Errorf("UnpackAsset: unexpected unpacked contents: %q", string(data))
266+
}
267+
})
268+
t.Run("unpacked", func(t *testing.T) {
269+
dir := t.TempDir()
270+
path := filepath.Join(dir, "example.dylib")
271+
_, err := fileio.CopyFile(filepath.Join("testdata", "example.dylib"), path)
272+
if err != nil {
273+
t.Fatalf("fileio.CopyFile: unexpected error %v", err)
274+
}
275+
276+
pkg := &spec.Package{
277+
Owner: "nalgeon", Name: "example", Version: "0.1.0",
278+
}
279+
asset := &assets.Asset{
280+
Name: "example.dylib", Path: path,
281+
}
282+
283+
err = UnpackAsset(pkg, asset)
284+
if err != nil {
285+
t.Fatalf("UnpackAsset: unexpected error %v", err)
286+
}
287+
288+
if !fileio.Exists(filepath.Join(dir, asset.Name)) {
289+
t.Fatal("UnpackAsset: asset does not exit")
290+
}
291+
292+
data, err := os.ReadFile(filepath.Join(dir, asset.Name))
293+
if err != nil {
294+
t.Fatalf("os.ReadFile: unexpected error %v", err)
295+
}
296+
if string(data) != "example.dylib" {
297+
t.Errorf("UnpackAsset: unexpected contents: %q", string(data))
298+
}
299+
})
300+
}
301+
302+
func TestInstallFiles(t *testing.T) {
303+
SetupTestRepo(t)
304+
defer TeardownTestRepo(t)
305+
306+
dir := t.TempDir()
307+
path := filepath.Join(dir, "example.dylib")
308+
_, err := fileio.CopyFile(filepath.Join("testdata", "example.dylib"), path)
309+
if err != nil {
310+
t.Fatalf("fileio.CopyFile: unexpected error %v", err)
311+
}
312+
313+
pkg := &spec.Package{
314+
Owner: "nalgeon", Name: "example", Version: "0.1.0",
315+
}
316+
asset := &assets.Asset{
317+
Name: "example.dylib", Path: path,
318+
}
319+
320+
err = InstallFiles(pkg, asset)
321+
if err != nil {
322+
t.Fatalf("InstallFiles: unexpected error %v", err)
323+
}
324+
if !fileio.Exists(spec.Path(WorkDir, pkg.Owner, pkg.Name)) {
325+
t.Errorf("InstallFiles: package spec is not installed")
326+
}
327+
installedPath := filepath.Join(spec.Dir(WorkDir, pkg.Owner, pkg.Name), asset.Name)
328+
if !fileio.Exists(installedPath) {
329+
t.Errorf("InstallFiles: package asset is not installed")
330+
}
331+
}

cmd/cmd.go

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,39 +17,27 @@ var WorkDir string
1717
// userHomeDir is the user's home directory.
1818
var userHomeDir string
1919

20-
// init determines the working directory.
21-
// It is either the .sqlpkg directory (if present) or ~/.sqlpkg otherwise.
2220
func init() {
23-
if fileio.Exists(spec.DirName) {
24-
WorkDir = "."
25-
return
26-
}
27-
var err error
28-
userHomeDir, err = os.UserHomeDir()
29-
if err != nil {
30-
WorkDir = "."
31-
return
32-
}
33-
WorkDir = userHomeDir
21+
inferWorkDir()
3422
}
3523

36-
// getPathFullName expands an owner-name package pair to a full sqlpkg.json path.
37-
func GetPathByFullName(fullName string) (string, error) {
24+
// GetDirByFullName expands an owner-name package pair to a full package dir.
25+
func GetDirByFullName(fullName string) (string, error) {
3826
parts := strings.Split(fullName, "/")
3927
if len(parts) != 2 {
4028
return "", errors.New("invalid package name")
4129
}
42-
path := spec.Path(WorkDir, parts[0], parts[1])
30+
path := spec.Dir(WorkDir, parts[0], parts[1])
4331
return path, nil
4432
}
4533

46-
// GetDirByFullName expands an owner-name package pair to a full package dir.
47-
func GetDirByFullName(fullName string) (string, error) {
34+
// GetPathByFullName expands an owner-name package pair to a full sqlpkg.json path.
35+
func GetPathByFullName(fullName string) (string, error) {
4836
parts := strings.Split(fullName, "/")
4937
if len(parts) != 2 {
5038
return "", errors.New("invalid package name")
5139
}
52-
path := spec.Dir(WorkDir, parts[0], parts[1])
40+
path := spec.Path(WorkDir, parts[0], parts[1])
5341
return path, nil
5442
}
5543

@@ -59,3 +47,19 @@ func PrintLocalRepo() {
5947
logx.Log("(local repository)")
6048
}
6149
}
50+
51+
// inferWorkDir determines the working directory.
52+
// It is either the .sqlpkg directory (if present) or ~/.sqlpkg otherwise.
53+
func inferWorkDir() {
54+
if fileio.Exists(spec.DirName) {
55+
WorkDir = "."
56+
return
57+
}
58+
var err error
59+
userHomeDir, err = os.UserHomeDir()
60+
if err != nil {
61+
WorkDir = "."
62+
return
63+
}
64+
WorkDir = userHomeDir
65+
}

0 commit comments

Comments
 (0)