github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/gnovm/pkg/doc/dirs_test.go (about)

     1  package doc
     2  
     3  import (
     4  	"bytes"
     5  	"log"
     6  	"os"
     7  	"path/filepath"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  func getwd(t *testing.T) string {
    16  	t.Helper()
    17  	wd, err := os.Getwd()
    18  	require.NoError(t, err)
    19  	return wd
    20  }
    21  
    22  func wdJoin(t *testing.T, arg string) string {
    23  	t.Helper()
    24  	return filepath.Join(getwd(t), arg)
    25  }
    26  
    27  func TestNewDirs_nonExisting(t *testing.T) {
    28  	old := log.Default().Writer()
    29  	var buf bytes.Buffer
    30  	log.Default().SetOutput(&buf)
    31  	defer func() { log.Default().SetOutput(old) }() // in case of panic
    32  
    33  	// git doesn't track empty directories; so need to create this one on our own.
    34  	de := wdJoin(t, "testdata/dirsempty")
    35  	require.NoError(t, os.MkdirAll(de, 0o755))
    36  
    37  	d := newDirs([]string{wdJoin(t, "non/existing/dir"), de}, []string{wdJoin(t, "and/this/one/neither")})
    38  	for _, ok := d.Next(); ok; _, ok = d.Next() { //nolint:revive
    39  	}
    40  	log.Default().SetOutput(old)
    41  	assert.Empty(t, d.hist, "hist should be empty")
    42  	assert.Equal(t, strings.Count(buf.String(), "\n"), 2, "output should contain 2 lines")
    43  	assert.Contains(t, buf.String(), "non/existing/dir: no such file or directory")
    44  	assert.Contains(t, buf.String(), "this/one/neither/gno.mod: no such file or directory")
    45  	assert.NotContains(t, buf.String(), "dirsempty: no such file or directory")
    46  }
    47  
    48  func TestNewDirs_invalidModDir(t *testing.T) {
    49  	old := log.Default().Writer()
    50  	var buf bytes.Buffer
    51  	log.Default().SetOutput(&buf)
    52  	defer func() { log.Default().SetOutput(old) }() // in case of panic
    53  
    54  	d := newDirs(nil, []string{wdJoin(t, "testdata/dirs")})
    55  	for _, ok := d.Next(); ok; _, ok = d.Next() { //nolint:revive
    56  	}
    57  	log.Default().SetOutput(old)
    58  	assert.Empty(t, d.hist, "hist should be len 0 (testdata/dirs is not a valid mod dir)")
    59  	assert.Equal(t, strings.Count(buf.String(), "\n"), 1, "output should contain 1 line")
    60  	assert.Contains(t, buf.String(), "gno.mod: no such file or directory")
    61  }
    62  
    63  func tNewDirs(t *testing.T) (string, *bfsDirs) {
    64  	t.Helper()
    65  
    66  	// modify GNO_HOME to testdata/dirsdep -- this allows us to test
    67  	// dependency lookup by dirs.
    68  	old, ex := os.LookupEnv("GNO_HOME")
    69  	os.Setenv("GNO_HOME", wdJoin(t, "testdata/dirsdep"))
    70  
    71  	t.Cleanup(func() {
    72  		if ex {
    73  			os.Setenv("GNO_HOME", old)
    74  		} else {
    75  			os.Unsetenv("GNO_HOME")
    76  		}
    77  	})
    78  
    79  	return wdJoin(t, "testdata"),
    80  		newDirs([]string{wdJoin(t, "testdata/dirs")}, []string{wdJoin(t, "testdata/dirsmod")})
    81  }
    82  
    83  func TestDirs_findPackage(t *testing.T) {
    84  	td, d := tNewDirs(t)
    85  	tt := []struct {
    86  		name string
    87  		res  []bfsDir
    88  	}{
    89  		{"rand", []bfsDir{
    90  			{importPath: "rand", dir: filepath.Join(td, "dirs/rand")},
    91  			{importPath: "crypto/rand", dir: filepath.Join(td, "dirs/crypto/rand")},
    92  			{importPath: "math/rand", dir: filepath.Join(td, "dirs/math/rand")},
    93  			{importPath: "dirs.mod/prefix/math/rand", dir: filepath.Join(td, "dirsmod/math/rand")},
    94  		}},
    95  		{"crypto/rand", []bfsDir{
    96  			{importPath: "crypto/rand", dir: filepath.Join(td, "dirs/crypto/rand")},
    97  		}},
    98  		{"dep", []bfsDir{
    99  			{importPath: "dirs.mod/dep", dir: filepath.Join(td, "dirsdep/pkg/mod/dirs.mod/dep")},
   100  		}},
   101  		{"alpha", []bfsDir{
   102  			{importPath: "dirs.mod/dep/alpha", dir: filepath.Join(td, "dirsdep/pkg/mod/dirs.mod/dep/alpha")},
   103  			// no gnoland-data/module/alpha as it is inside a module
   104  		}},
   105  		{"math", []bfsDir{
   106  			{importPath: "math", dir: filepath.Join(td, "dirs/math")},
   107  		}},
   108  		{"ath", []bfsDir{}},
   109  		{"/math", []bfsDir{}},
   110  		{"", []bfsDir{}},
   111  	}
   112  	for _, tc := range tt {
   113  		tc := tc
   114  		t.Run("name_"+strings.Replace(tc.name, "/", "_", -1), func(t *testing.T) {
   115  			res := d.findPackage(tc.name)
   116  			assert.Equal(t, tc.res, res, "dirs returned should be the equal")
   117  		})
   118  	}
   119  }
   120  
   121  func TestDirs_findDir(t *testing.T) {
   122  	td, d := tNewDirs(t)
   123  	tt := []struct {
   124  		name string
   125  		in   string
   126  		res  []bfsDir
   127  	}{
   128  		{"rand", filepath.Join(td, "dirs/rand"), []bfsDir{
   129  			{importPath: "rand", dir: filepath.Join(td, "dirs/rand")},
   130  		}},
   131  		{"crypto/rand", filepath.Join(td, "dirs/crypto/rand"), []bfsDir{
   132  			{importPath: "crypto/rand", dir: filepath.Join(td, "dirs/crypto/rand")},
   133  		}},
   134  		// ignored (dir name testdata), so should not return anything.
   135  		{"crypto/testdata/rand", filepath.Join(td, "dirs/crypto/testdata/rand"), nil},
   136  		{"xx", filepath.Join(td, "dirs/xx"), nil},
   137  		{"xx2", "/xx2", nil},
   138  		{"2xx", "/2xx", nil},
   139  	}
   140  	for _, tc := range tt {
   141  		tc := tc
   142  		t.Run(strings.Replace(tc.name, "/", "_", -1), func(t *testing.T) {
   143  			res := d.findDir(tc.in)
   144  			assert.Equal(t, tc.res, res, "dirs returned should be the equal")
   145  		})
   146  	}
   147  }