1package sh_test
2
3import (
4	"bytes"
5	"fmt"
6	"io/ioutil"
7	"os"
8	"path/filepath"
9	"testing"
10
11	"github.com/magefile/mage/sh"
12)
13
14// compareFiles checks that two files are identical for testing purposes. That means they have the same length,
15// the same contents, and the same permissions. It does NOT mean they have the same timestamp, as that is expected
16// to change in normal Mage sh.Copy operation.
17func compareFiles(file1 string, file2 string) error {
18	s1, err := os.Stat(file1)
19	if err != nil {
20		return fmt.Errorf("can't stat %s: %v", file1, err)
21	}
22	s2, err := os.Stat(file2)
23	if err != nil {
24		return fmt.Errorf("can't stat %s: %v", file2, err)
25	}
26	if s1.Size() != s2.Size() {
27		return fmt.Errorf("files %s and %s have different sizes: %d vs %d", file1, file2, s1.Size(), s2.Size())
28	}
29	if s1.Mode() != s2.Mode() {
30		return fmt.Errorf("files %s and %s have different permissions: %#4o vs %#4o", file1, file2, s1.Mode(), s2.Mode())
31	}
32	f1bytes, err := ioutil.ReadFile(file1)
33	if err != nil {
34		return fmt.Errorf("can't read %s: %v", file1, err)
35	}
36	f2bytes, err := ioutil.ReadFile(file2)
37	if err != nil {
38		return fmt.Errorf("can't read %s: %v", file2, err)
39	}
40	if !bytes.Equal(f1bytes, f2bytes) {
41		return fmt.Errorf("files %s and %s have different contents", file1, file2)
42	}
43	return nil
44}
45
46func TestHelpers(t *testing.T) {
47
48	mytmpdir, err := ioutil.TempDir("", "mage")
49	if err != nil {
50		t.Fatalf("can't create test directory: %v", err)
51	}
52	defer func() {
53		derr := os.RemoveAll(mytmpdir)
54		if derr != nil {
55			fmt.Printf("error cleaning up after TestHelpers: %v", derr)
56		}
57	}()
58	srcname := filepath.Join(mytmpdir, "test1.txt")
59	err = ioutil.WriteFile(srcname, []byte("All work and no play makes Jack a dull boy."), 0644)
60	if err != nil {
61		t.Fatalf("can't create test file %s: %v", srcname, err)
62	}
63	destname := filepath.Join(mytmpdir, "test2.txt")
64
65	t.Run("sh/copy", func(t *testing.T) {
66		cerr := sh.Copy(destname, srcname)
67		if cerr != nil {
68			t.Errorf("test file copy from %s to %s failed: %v", srcname, destname, cerr)
69		}
70		cerr = compareFiles(srcname, destname)
71		if cerr != nil {
72			t.Errorf("test file copy verification failed: %v", cerr)
73		}
74	})
75
76	// While we've got a temporary directory, test how forgiving sh.Rm is
77	t.Run("sh/rm/ne", func(t *testing.T) {
78		nef := filepath.Join(mytmpdir, "file_not_exist.txt")
79		rerr := sh.Rm(nef)
80		if rerr != nil {
81			t.Errorf("sh.Rm complained when removing nonexistent file %s: %v", nef, rerr)
82		}
83	})
84
85	t.Run("sh/copy/ne", func(t *testing.T) {
86		nef := filepath.Join(mytmpdir, "file_not_exist.txt")
87		nedf := filepath.Join(mytmpdir, "file_not_exist2.txt")
88		cerr := sh.Copy(nedf, nef)
89		if cerr == nil {
90			t.Errorf("sh.Copy succeeded copying nonexistent file %s", nef)
91		}
92	})
93
94	// We test sh.Rm by clearing up our own test files and directories
95	t.Run("sh/rm", func(t *testing.T) {
96		rerr := sh.Rm(destname)
97		if rerr != nil {
98			t.Errorf("failed to remove file %s: %v", destname, rerr)
99		}
100		rerr = sh.Rm(srcname)
101		if rerr != nil {
102			t.Errorf("failed to remove file %s: %v", srcname, rerr)
103		}
104		rerr = sh.Rm(mytmpdir)
105		if rerr != nil {
106			t.Errorf("failed to remove dir %s: %v", mytmpdir, rerr)
107		}
108		_, rerr = os.Stat(mytmpdir)
109		if rerr == nil {
110			t.Errorf("removed dir %s but it's still there?", mytmpdir)
111		}
112	})
113
114	t.Run("sh/rm/nedir", func(t *testing.T) {
115		rerr := sh.Rm(mytmpdir)
116		if rerr != nil {
117			t.Errorf("sh.Rm complained removing nonexistent dir %s", mytmpdir)
118		}
119	})
120
121}
122