tests: remove tests from the vendored paths module.

This commit is contained in:
Alexandre Pujol 2024-10-19 22:55:17 +01:00
parent c59086311b
commit 081399a160
Failed to generate hash of commit
40 changed files with 0 additions and 1082 deletions

View file

@ -1,169 +0,0 @@
/*
* This file is part of PathsHelper library.
*
* Copyright 2018 Arduino AG (http://www.arduino.cc/)
*
* PathsHelper library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package paths
import (
"fmt"
"testing"
"github.com/stretchr/testify/require"
)
func TestListConstructors(t *testing.T) {
list0 := NewPathList()
require.Len(t, list0, 0)
list1 := NewPathList("test")
require.Len(t, list1, 1)
require.Equal(t, "[test]", fmt.Sprintf("%s", list1))
list3 := NewPathList("a", "b", "c")
require.Len(t, list3, 3)
require.Equal(t, "[a b c]", fmt.Sprintf("%s", list3))
require.False(t, list3.Contains(New("d")))
require.True(t, list3.Contains(New("a")))
require.False(t, list3.Contains(New("d/../a")))
require.False(t, list3.ContainsEquivalentTo(New("d")))
require.True(t, list3.ContainsEquivalentTo(New("a")))
require.True(t, list3.ContainsEquivalentTo(New("d/../a")))
list4 := list3.Clone()
require.Equal(t, "[a b c]", fmt.Sprintf("%s", list4))
list4.AddIfMissing(New("d"))
require.Equal(t, "[a b c d]", fmt.Sprintf("%s", list4))
list4.AddIfMissing(New("b"))
require.Equal(t, "[a b c d]", fmt.Sprintf("%s", list4))
list4.AddAllMissing(NewPathList("a", "e", "i", "o", "u"))
require.Equal(t, "[a b c d e i o u]", fmt.Sprintf("%s", list4))
}
func TestListSorting(t *testing.T) {
list := NewPathList(
"pointless",
"spare",
"carve",
"unwieldy",
"empty",
"bow",
"tub",
"grease",
"error",
"energetic",
"depend",
"property")
require.Equal(t, "[pointless spare carve unwieldy empty bow tub grease error energetic depend property]", fmt.Sprintf("%s", list))
list.Sort()
require.Equal(t, "[bow carve depend empty energetic error grease pointless property spare tub unwieldy]", fmt.Sprintf("%s", list))
}
func TestListFilters(t *testing.T) {
list := NewPathList(
"aaaa",
"bbbb",
"cccc",
"dddd",
"eeff",
"aaaa/bbbb",
"eeee/ffff",
"gggg/hhhh",
)
l1 := list.Clone()
l1.FilterPrefix("a")
require.Equal(t, "[aaaa]", fmt.Sprintf("%s", l1))
l2 := list.Clone()
l2.FilterPrefix("b")
require.Equal(t, "[bbbb aaaa/bbbb]", fmt.Sprintf("%s", l2))
l3 := list.Clone()
l3.FilterOutPrefix("b")
require.Equal(t, "[aaaa cccc dddd eeff eeee/ffff gggg/hhhh]", fmt.Sprintf("%s", l3))
l4 := list.Clone()
l4.FilterPrefix("a", "b")
require.Equal(t, "[aaaa bbbb aaaa/bbbb]", fmt.Sprintf("%s", l4))
l5 := list.Clone()
l5.FilterPrefix("test")
require.Equal(t, "[]", fmt.Sprintf("%s", l5))
l6 := list.Clone()
l6.FilterOutPrefix("b", "c", "h")
require.Equal(t, "[aaaa dddd eeff eeee/ffff]", fmt.Sprintf("%s", l6))
l7 := list.Clone()
l7.FilterSuffix("a")
require.Equal(t, "[aaaa]", fmt.Sprintf("%s", l7))
l8 := list.Clone()
l8.FilterSuffix("a", "h")
require.Equal(t, "[aaaa gggg/hhhh]", fmt.Sprintf("%s", l8))
l9 := list.Clone()
l9.FilterSuffix("test")
require.Equal(t, "[]", fmt.Sprintf("%s", l9))
l10 := list.Clone()
l10.FilterOutSuffix("a")
require.Equal(t, "[bbbb cccc dddd eeff aaaa/bbbb eeee/ffff gggg/hhhh]", fmt.Sprintf("%s", l10))
l11 := list.Clone()
l11.FilterOutSuffix("a", "h")
require.Equal(t, "[bbbb cccc dddd eeff aaaa/bbbb eeee/ffff]", fmt.Sprintf("%s", l11))
l12 := list.Clone()
l12.FilterOutSuffix("test")
require.Equal(t, "[aaaa bbbb cccc dddd eeff aaaa/bbbb eeee/ffff gggg/hhhh]", fmt.Sprintf("%s", l12))
l13 := list.Clone()
l13.FilterOutSuffix()
require.Equal(t, "[aaaa bbbb cccc dddd eeff aaaa/bbbb eeee/ffff gggg/hhhh]", fmt.Sprintf("%s", l13))
l14 := list.Clone()
l14.FilterSuffix()
require.Equal(t, "[]", fmt.Sprintf("%s", l14))
l15 := list.Clone()
l15.FilterOutPrefix()
require.Equal(t, "[aaaa bbbb cccc dddd eeff aaaa/bbbb eeee/ffff gggg/hhhh]", fmt.Sprintf("%s", l15))
l16 := list.Clone()
l16.FilterPrefix()
require.Equal(t, "[]", fmt.Sprintf("%s", l16))
l17 := list.Clone()
l17.Filter(func(p *Path) bool {
return p.Base() == "bbbb"
})
require.Equal(t, "[bbbb aaaa/bbbb]", fmt.Sprintf("%s", l17))
}

View file

@ -1,432 +0,0 @@
/*
* This file is part of PathsHelper library.
*
* Copyright 2018 Arduino AG (http://www.arduino.cc/)
*
* PathsHelper library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package paths
import (
"path/filepath"
"runtime"
"strings"
"testing"
"github.com/stretchr/testify/require"
)
func pathEqualsTo(t *testing.T, expected string, actual *Path) {
require.Equal(t, expected, filepath.ToSlash(actual.String()))
}
func TestPathNew(t *testing.T) {
test1 := New("path")
require.Equal(t, "path", test1.String())
test2 := New("path", "path")
require.Equal(t, filepath.Join("path", "path"), test2.String())
test3 := New()
require.Nil(t, test3)
test4 := New("")
require.Nil(t, test4)
}
func TestPath(t *testing.T) {
testPath := New("testdata", "fileset")
pathEqualsTo(t, "testdata/fileset", testPath)
isDir, err := testPath.IsDirCheck()
require.True(t, isDir)
require.NoError(t, err)
require.True(t, testPath.IsDir())
require.False(t, testPath.IsNotDir())
exist, err := testPath.ExistCheck()
require.True(t, exist)
require.NoError(t, err)
require.True(t, testPath.Exist())
require.False(t, testPath.NotExist())
folderPath := testPath.Join("folder")
pathEqualsTo(t, "testdata/fileset/folder", folderPath)
isDir, err = folderPath.IsDirCheck()
require.True(t, isDir)
require.NoError(t, err)
require.True(t, folderPath.IsDir())
require.False(t, folderPath.IsNotDir())
exist, err = folderPath.ExistCheck()
require.True(t, exist)
require.NoError(t, err)
require.True(t, folderPath.Exist())
require.False(t, folderPath.NotExist())
filePath := testPath.Join("file")
pathEqualsTo(t, "testdata/fileset/file", filePath)
isDir, err = filePath.IsDirCheck()
require.False(t, isDir)
require.NoError(t, err)
require.False(t, filePath.IsDir())
require.True(t, filePath.IsNotDir())
exist, err = filePath.ExistCheck()
require.True(t, exist)
require.NoError(t, err)
require.True(t, filePath.Exist())
require.False(t, filePath.NotExist())
anotherFilePath := filePath.Join("notexistent")
pathEqualsTo(t, "testdata/fileset/file/notexistent", anotherFilePath)
isDir, err = anotherFilePath.IsDirCheck()
require.False(t, isDir)
require.Error(t, err)
require.False(t, anotherFilePath.IsDir())
require.False(t, anotherFilePath.IsNotDir())
exist, err = anotherFilePath.ExistCheck()
require.False(t, exist)
require.NoError(t, err)
require.False(t, anotherFilePath.Exist())
require.True(t, anotherFilePath.NotExist())
list, err := folderPath.ReadDir()
require.NoError(t, err)
require.Len(t, list, 4)
pathEqualsTo(t, "testdata/fileset/folder/.hidden", list[0])
pathEqualsTo(t, "testdata/fileset/folder/file2", list[1])
pathEqualsTo(t, "testdata/fileset/folder/file3", list[2])
pathEqualsTo(t, "testdata/fileset/folder/subfolder", list[3])
list2 := list.Clone()
list2.FilterDirs()
require.Len(t, list2, 1)
pathEqualsTo(t, "testdata/fileset/folder/subfolder", list2[0])
list2 = list.Clone()
list2.FilterOutHiddenFiles()
require.Len(t, list2, 3)
pathEqualsTo(t, "testdata/fileset/folder/file2", list2[0])
pathEqualsTo(t, "testdata/fileset/folder/file3", list2[1])
pathEqualsTo(t, "testdata/fileset/folder/subfolder", list2[2])
list2 = list.Clone()
list2.FilterOutPrefix("file")
require.Len(t, list2, 2)
pathEqualsTo(t, "testdata/fileset/folder/.hidden", list2[0])
pathEqualsTo(t, "testdata/fileset/folder/subfolder", list2[1])
}
func TestResetStatCacheWhenFollowingSymlink(t *testing.T) {
testdata := New("testdata", "fileset")
files, err := testdata.ReadDir()
require.NoError(t, err)
for _, file := range files {
if file.Base() == "symlinktofolder" {
err = file.FollowSymLink()
require.NoError(t, err)
isDir, err := file.IsDirCheck()
require.NoError(t, err)
require.True(t, isDir)
break
}
}
}
func TestIsInsideDir(t *testing.T) {
notInside := func(a, b *Path) {
isInside, err := a.IsInsideDir(b)
require.NoError(t, err)
require.False(t, isInside, "%s is inside %s", a, b)
}
inside := func(a, b *Path) {
isInside, err := a.IsInsideDir(b)
require.NoError(t, err)
require.True(t, isInside, "%s is inside %s", a, b)
notInside(b, a)
}
f1 := New("/a/b/c")
f2 := New("/a/b/c/d")
f3 := New("/a/b/c/d/e")
notInside(f1, f1)
notInside(f1, f2)
inside(f2, f1)
notInside(f1, f3)
inside(f3, f1)
r1 := New("a/b/c")
r2 := New("a/b/c/d")
r3 := New("a/b/c/d/e")
r4 := New("f/../a/b/c/d/e")
r5 := New("a/b/c/d/e/f/..")
notInside(r1, r1)
notInside(r1, r2)
inside(r2, r1)
notInside(r1, r3)
inside(r3, r1)
inside(r4, r1)
notInside(r1, r4)
inside(r5, r1)
notInside(r1, r5)
f4 := New("/home/megabug/aide/arduino-1.8.6/hardware/arduino/avr")
f5 := New("/home/megabug/a15/packages")
notInside(f5, f4)
notInside(f4, f5)
if runtime.GOOS == "windows" {
f6 := New("C:\\", "A")
f7 := New("C:\\", "A", "B", "C")
f8 := New("E:\\", "A", "B", "C")
inside(f7, f6)
notInside(f8, f6)
}
}
func TestReadFileAsLines(t *testing.T) {
lines, err := New("testdata/fileset/anotherFile").ReadFileAsLines()
require.NoError(t, err)
require.Len(t, lines, 4)
require.Equal(t, "line 1", lines[0])
require.Equal(t, "line 2", lines[1])
require.Equal(t, "", lines[2])
require.Equal(t, "line 3", lines[3])
}
func TestCanonicaTempDir(t *testing.T) {
require.Equal(t, TempDir().String(), TempDir().Canonical().String())
}
func TestCopyDir(t *testing.T) {
tmp, err := MkTempDir("", "")
require.NoError(t, err)
defer tmp.RemoveAll()
src := New("testdata", "fileset")
err = src.CopyDirTo(tmp.Join("dest"))
require.NoError(t, err, "copying dir")
exist, err := tmp.Join("dest", "folder", "subfolder", "file4").ExistCheck()
require.True(t, exist)
require.NoError(t, err)
isdir, err := tmp.Join("dest", "folder", "subfolder", "file4").IsDirCheck()
require.False(t, isdir)
require.NoError(t, err)
err = src.CopyDirTo(tmp.Join("dest"))
require.Error(t, err, "copying dir to already existing")
err = src.Join("file").CopyDirTo(tmp.Join("dest2"))
require.Error(t, err, "copying file as dir")
}
func TestParents(t *testing.T) {
parents := New("/a/very/long/path").Parents()
require.Len(t, parents, 5)
pathEqualsTo(t, "/a/very/long/path", parents[0])
pathEqualsTo(t, "/a/very/long", parents[1])
pathEqualsTo(t, "/a/very", parents[2])
pathEqualsTo(t, "/a", parents[3])
pathEqualsTo(t, "/", parents[4])
parents2 := New("a/very/relative/path").Parents()
require.Len(t, parents, 5)
pathEqualsTo(t, "a/very/relative/path", parents2[0])
pathEqualsTo(t, "a/very/relative", parents2[1])
pathEqualsTo(t, "a/very", parents2[2])
pathEqualsTo(t, "a", parents2[3])
pathEqualsTo(t, ".", parents2[4])
}
func TestFilterDirs(t *testing.T) {
testPath := New("testdata", "fileset")
list, err := testPath.ReadDir()
require.NoError(t, err)
require.Len(t, list, 6)
pathEqualsTo(t, "testdata/fileset/anotherFile", list[0])
pathEqualsTo(t, "testdata/fileset/file", list[1])
pathEqualsTo(t, "testdata/fileset/folder", list[2])
pathEqualsTo(t, "testdata/fileset/symlinktofolder", list[3])
pathEqualsTo(t, "testdata/fileset/test.txt", list[4])
pathEqualsTo(t, "testdata/fileset/test.txt.gz", list[5])
list.FilterDirs()
require.Len(t, list, 2)
pathEqualsTo(t, "testdata/fileset/folder", list[0])
pathEqualsTo(t, "testdata/fileset/symlinktofolder", list[1])
}
func TestFilterOutDirs(t *testing.T) {
{
testPath := New("testdata", "fileset")
list, err := testPath.ReadDir()
require.NoError(t, err)
require.Len(t, list, 6)
pathEqualsTo(t, "testdata/fileset/anotherFile", list[0])
pathEqualsTo(t, "testdata/fileset/file", list[1])
pathEqualsTo(t, "testdata/fileset/folder", list[2])
pathEqualsTo(t, "testdata/fileset/symlinktofolder", list[3])
pathEqualsTo(t, "testdata/fileset/test.txt", list[4])
pathEqualsTo(t, "testdata/fileset/test.txt.gz", list[5])
list.FilterOutDirs()
require.Len(t, list, 4)
pathEqualsTo(t, "testdata/fileset/anotherFile", list[0])
pathEqualsTo(t, "testdata/fileset/file", list[1])
pathEqualsTo(t, "testdata/fileset/test.txt", list[2])
pathEqualsTo(t, "testdata/fileset/test.txt.gz", list[3])
}
{
list, err := New("testdata", "broken_symlink", "dir_1").ReadDirRecursive()
require.NoError(t, err)
require.Len(t, list, 7)
pathEqualsTo(t, "testdata/broken_symlink/dir_1/broken_link", list[0])
pathEqualsTo(t, "testdata/broken_symlink/dir_1/file2", list[1])
pathEqualsTo(t, "testdata/broken_symlink/dir_1/linked_dir", list[2])
pathEqualsTo(t, "testdata/broken_symlink/dir_1/linked_dir/file1", list[3])
pathEqualsTo(t, "testdata/broken_symlink/dir_1/linked_file", list[4])
pathEqualsTo(t, "testdata/broken_symlink/dir_1/real_dir", list[5])
pathEqualsTo(t, "testdata/broken_symlink/dir_1/real_dir/file1", list[6])
list.FilterOutDirs()
require.Len(t, list, 5)
pathEqualsTo(t, "testdata/broken_symlink/dir_1/broken_link", list[0])
pathEqualsTo(t, "testdata/broken_symlink/dir_1/file2", list[1])
pathEqualsTo(t, "testdata/broken_symlink/dir_1/linked_dir/file1", list[2])
pathEqualsTo(t, "testdata/broken_symlink/dir_1/linked_file", list[3])
pathEqualsTo(t, "testdata/broken_symlink/dir_1/real_dir/file1", list[4])
}
}
func TestEquivalentPaths(t *testing.T) {
wd, err := Getwd()
require.NoError(t, err)
require.True(t, New("file1").EquivalentTo(New("file1", "somethingelse", "..")))
require.True(t, New("file1", "abc").EquivalentTo(New("file1", "abc", "def", "..")))
require.True(t, wd.Join("file1").EquivalentTo(New("file1")))
require.True(t, wd.Join("file1").EquivalentTo(New("file1", "abc", "..")))
if runtime.GOOS == "windows" {
q := New("testdata", "fileset", "anotherFile")
r := New("testdata", "fileset", "ANOTHE~1")
require.True(t, q.EquivalentTo(r))
require.True(t, r.EquivalentTo(q))
}
}
func TestCanonicalize(t *testing.T) {
wd, err := Getwd()
require.NoError(t, err)
p := New("testdata", "fileset", "anotherFile").Canonical()
require.Equal(t, wd.Join("testdata", "fileset", "anotherFile").String(), p.String())
p = New("testdata", "fileset", "nonexistentFile").Canonical()
require.Equal(t, wd.Join("testdata", "fileset", "nonexistentFile").String(), p.String())
if runtime.GOOS == "windows" {
q := New("testdata", "fileset", "ANOTHE~1").Canonical()
require.Equal(t, wd.Join("testdata", "fileset", "anotherFile").String(), q.String())
r := New("c:\\").Canonical()
require.Equal(t, "C:\\", r.String())
tmp, err := MkTempDir("", "pref")
require.NoError(t, err)
require.Equal(t, tmp.String(), tmp.Canonical().String())
}
}
func TestRelativeTo(t *testing.T) {
res, err := New("/my/abs/path/123/456").RelTo(New("/my/abs/path"))
require.NoError(t, err)
pathEqualsTo(t, "../..", res)
res, err = New("/my/abs/path").RelTo(New("/my/abs/path/123/456"))
require.NoError(t, err)
pathEqualsTo(t, "123/456", res)
res, err = New("my/path").RelTo(New("/other/path"))
require.Error(t, err)
require.Nil(t, res)
res, err = New("/my/abs/path/123/456").RelFrom(New("/my/abs/path"))
pathEqualsTo(t, "123/456", res)
require.NoError(t, err)
res, err = New("/my/abs/path").RelFrom(New("/my/abs/path/123/456"))
require.NoError(t, err)
pathEqualsTo(t, "../..", res)
res, err = New("my/path").RelFrom(New("/other/path"))
require.Error(t, err)
require.Nil(t, res)
}
func TestWriteToTempFile(t *testing.T) {
tmpDir := New("testdata", "fileset", "tmp")
err := tmpDir.MkdirAll()
require.NoError(t, err)
defer tmpDir.RemoveAll()
tmpData := []byte("test")
tmp, err := WriteToTempFile(tmpData, tmpDir, "prefix")
defer tmp.Remove()
require.NoError(t, err)
require.True(t, strings.HasPrefix(tmp.Base(), "prefix"))
isInside, err := tmp.IsInsideDir(tmpDir)
require.NoError(t, err)
require.True(t, isInside)
data, err := tmp.ReadFile()
require.NoError(t, err)
require.Equal(t, tmpData, data)
}
func TestCopyToSamePath(t *testing.T) {
tmpDir := New(t.TempDir())
srcFile := tmpDir.Join("test_file")
dstFile := srcFile
// create the source file in tmp dir
err := srcFile.WriteFile([]byte("hello"))
require.NoError(t, err)
content, err := srcFile.ReadFile()
require.NoError(t, err)
require.Equal(t, []byte("hello"), content)
// cannot copy the same file
err = srcFile.CopyTo(dstFile)
require.Error(t, err)
require.Contains(t, err.Error(), "are the same file")
}

View file

@ -1,56 +0,0 @@
//
// This file is part of PathsHelper library.
//
// Copyright 2023 Arduino AG (http://www.arduino.cc/)
//
// PathsHelper library is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
//
package paths
import (
"context"
"testing"
"time"
"github.com/stretchr/testify/require"
)
func TestProcessWithinContext(t *testing.T) {
// Build `delay` helper inside testdata/delay
builder, err := NewProcess(nil, "go", "build")
require.NoError(t, err)
builder.SetDir("testdata/delay")
require.NoError(t, builder.Run())
// Run delay and test if the process is terminated correctly due to context
process, err := NewProcess(nil, "testdata/delay/delay")
require.NoError(t, err)
start := time.Now()
ctx, cancel := context.WithTimeout(context.Background(), 250*time.Millisecond)
err = process.RunWithinContext(ctx)
require.Error(t, err)
require.Less(t, time.Since(start), 500*time.Millisecond)
cancel()
}

View file

@ -1,343 +0,0 @@
/*
* This file is part of PathsHelper library.
*
* Copyright 2018-2022 Arduino AG (http://www.arduino.cc/)
*
* PathsHelper library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package paths
import (
"fmt"
"io/fs"
"os"
"runtime"
"testing"
"time"
"github.com/stretchr/testify/require"
)
func TestReadDirRecursive(t *testing.T) {
testPath := New("testdata", "fileset")
list, err := testPath.ReadDirRecursive()
require.NoError(t, err)
require.Len(t, list, 16)
pathEqualsTo(t, "testdata/fileset/anotherFile", list[0])
pathEqualsTo(t, "testdata/fileset/file", list[1])
pathEqualsTo(t, "testdata/fileset/folder", list[2])
pathEqualsTo(t, "testdata/fileset/folder/.hidden", list[3])
pathEqualsTo(t, "testdata/fileset/folder/file2", list[4])
pathEqualsTo(t, "testdata/fileset/folder/file3", list[5])
pathEqualsTo(t, "testdata/fileset/folder/subfolder", list[6])
pathEqualsTo(t, "testdata/fileset/folder/subfolder/file4", list[7])
pathEqualsTo(t, "testdata/fileset/symlinktofolder", list[8])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/.hidden", list[9])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/file2", list[10])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/file3", list[11])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/subfolder", list[12])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/subfolder/file4", list[13])
pathEqualsTo(t, "testdata/fileset/test.txt", list[14])
pathEqualsTo(t, "testdata/fileset/test.txt.gz", list[15])
}
func TestReadDirRecursiveSymLinkLoop(t *testing.T) {
// Test symlink loop
tmp, err := MkTempDir("", "")
require.NoError(t, err)
defer tmp.RemoveAll()
folder := tmp.Join("folder")
err = os.Symlink(tmp.String(), folder.String())
require.NoError(t, err)
l, err := tmp.ReadDirRecursive()
require.Error(t, err)
fmt.Println(err)
require.Nil(t, l)
l, err = tmp.ReadDirRecursiveFiltered(nil)
require.Error(t, err)
fmt.Println(err)
require.Nil(t, l)
}
func TestReadDirFiltered(t *testing.T) {
folderPath := New("testdata/fileset/folder")
list, err := folderPath.ReadDir()
require.NoError(t, err)
require.Len(t, list, 4)
pathEqualsTo(t, "testdata/fileset/folder/.hidden", list[0])
pathEqualsTo(t, "testdata/fileset/folder/file2", list[1])
pathEqualsTo(t, "testdata/fileset/folder/file3", list[2])
pathEqualsTo(t, "testdata/fileset/folder/subfolder", list[3])
list, err = folderPath.ReadDir(FilterDirectories())
require.NoError(t, err)
require.Len(t, list, 1)
pathEqualsTo(t, "testdata/fileset/folder/subfolder", list[0])
list, err = folderPath.ReadDir(FilterOutPrefixes("file"))
require.NoError(t, err)
require.Len(t, list, 2)
pathEqualsTo(t, "testdata/fileset/folder/.hidden", list[0])
pathEqualsTo(t, "testdata/fileset/folder/subfolder", list[1])
}
func TestReadDirRecursiveFiltered(t *testing.T) {
testdata := New("testdata", "fileset")
l, err := testdata.ReadDirRecursiveFiltered(nil)
require.NoError(t, err)
l.Sort()
require.Len(t, l, 16)
pathEqualsTo(t, "testdata/fileset/anotherFile", l[0])
pathEqualsTo(t, "testdata/fileset/file", l[1])
pathEqualsTo(t, "testdata/fileset/folder", l[2])
pathEqualsTo(t, "testdata/fileset/folder/.hidden", l[3])
pathEqualsTo(t, "testdata/fileset/folder/file2", l[4])
pathEqualsTo(t, "testdata/fileset/folder/file3", l[5])
pathEqualsTo(t, "testdata/fileset/folder/subfolder", l[6])
pathEqualsTo(t, "testdata/fileset/folder/subfolder/file4", l[7])
pathEqualsTo(t, "testdata/fileset/symlinktofolder", l[8])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/.hidden", l[9])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/file2", l[10])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/file3", l[11])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/subfolder", l[12])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/subfolder/file4", l[13])
pathEqualsTo(t, "testdata/fileset/test.txt", l[14])
pathEqualsTo(t, "testdata/fileset/test.txt.gz", l[15])
l, err = testdata.ReadDirRecursiveFiltered(FilterOutDirectories())
require.NoError(t, err)
l.Sort()
require.Len(t, l, 6)
pathEqualsTo(t, "testdata/fileset/anotherFile", l[0])
pathEqualsTo(t, "testdata/fileset/file", l[1])
pathEqualsTo(t, "testdata/fileset/folder", l[2]) // <- this is listed but not traversed
pathEqualsTo(t, "testdata/fileset/symlinktofolder", l[3]) // <- this is listed but not traversed
pathEqualsTo(t, "testdata/fileset/test.txt", l[4])
pathEqualsTo(t, "testdata/fileset/test.txt.gz", l[5])
l, err = testdata.ReadDirRecursiveFiltered(nil, FilterOutDirectories())
require.NoError(t, err)
l.Sort()
require.Len(t, l, 12)
pathEqualsTo(t, "testdata/fileset/anotherFile", l[0])
pathEqualsTo(t, "testdata/fileset/file", l[1])
pathEqualsTo(t, "testdata/fileset/folder/.hidden", l[2])
pathEqualsTo(t, "testdata/fileset/folder/file2", l[3])
pathEqualsTo(t, "testdata/fileset/folder/file3", l[4])
pathEqualsTo(t, "testdata/fileset/folder/subfolder/file4", l[5])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/.hidden", l[6])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/file2", l[7])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/file3", l[8])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/subfolder/file4", l[9])
pathEqualsTo(t, "testdata/fileset/test.txt", l[10])
pathEqualsTo(t, "testdata/fileset/test.txt.gz", l[11])
l, err = testdata.ReadDirRecursiveFiltered(FilterOutDirectories(), FilterOutDirectories())
require.NoError(t, err)
l.Sort()
require.Len(t, l, 4)
pathEqualsTo(t, "testdata/fileset/anotherFile", l[0])
pathEqualsTo(t, "testdata/fileset/file", l[1])
pathEqualsTo(t, "testdata/fileset/test.txt", l[2])
pathEqualsTo(t, "testdata/fileset/test.txt.gz", l[3])
l, err = testdata.ReadDirRecursiveFiltered(FilterOutPrefixes("sub"), FilterOutSuffixes("3"))
require.NoError(t, err)
l.Sort()
require.Len(t, l, 12)
pathEqualsTo(t, "testdata/fileset/anotherFile", l[0])
pathEqualsTo(t, "testdata/fileset/file", l[1])
pathEqualsTo(t, "testdata/fileset/folder", l[2])
pathEqualsTo(t, "testdata/fileset/folder/.hidden", l[3])
pathEqualsTo(t, "testdata/fileset/folder/file2", l[4])
pathEqualsTo(t, "testdata/fileset/folder/subfolder", l[5]) // <- subfolder skipped by Prefix("sub")
pathEqualsTo(t, "testdata/fileset/symlinktofolder", l[6])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/.hidden", l[7])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/file2", l[8])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/subfolder", l[9]) // <- subfolder skipped by Prefix("sub")
pathEqualsTo(t, "testdata/fileset/test.txt", l[10])
pathEqualsTo(t, "testdata/fileset/test.txt.gz", l[11])
l, err = testdata.ReadDirRecursiveFiltered(FilterOutPrefixes("sub"), AndFilter(FilterOutSuffixes("3"), FilterOutPrefixes("fil")))
require.NoError(t, err)
l.Sort()
require.Len(t, l, 9)
pathEqualsTo(t, "testdata/fileset/anotherFile", l[0])
pathEqualsTo(t, "testdata/fileset/folder", l[1])
pathEqualsTo(t, "testdata/fileset/folder/.hidden", l[2])
pathEqualsTo(t, "testdata/fileset/folder/subfolder", l[3])
pathEqualsTo(t, "testdata/fileset/symlinktofolder", l[4])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/.hidden", l[5])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/subfolder", l[6])
pathEqualsTo(t, "testdata/fileset/test.txt", l[7])
pathEqualsTo(t, "testdata/fileset/test.txt.gz", l[8])
l, err = testdata.ReadDirRecursiveFiltered(FilterOutPrefixes("sub"), AndFilter(FilterOutSuffixes("3"), FilterOutPrefixes("fil"), FilterOutSuffixes(".gz")))
require.NoError(t, err)
l.Sort()
require.Len(t, l, 8)
pathEqualsTo(t, "testdata/fileset/anotherFile", l[0])
pathEqualsTo(t, "testdata/fileset/folder", l[1])
pathEqualsTo(t, "testdata/fileset/folder/.hidden", l[2])
pathEqualsTo(t, "testdata/fileset/folder/subfolder", l[3])
pathEqualsTo(t, "testdata/fileset/symlinktofolder", l[4])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/.hidden", l[5])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/subfolder", l[6])
pathEqualsTo(t, "testdata/fileset/test.txt", l[7])
l, err = testdata.ReadDirRecursiveFiltered(OrFilter(FilterPrefixes("sub"), FilterSuffixes("tofolder")))
require.NoError(t, err)
l.Sort()
require.Len(t, l, 11)
pathEqualsTo(t, "testdata/fileset/anotherFile", l[0])
pathEqualsTo(t, "testdata/fileset/file", l[1])
pathEqualsTo(t, "testdata/fileset/folder", l[2])
pathEqualsTo(t, "testdata/fileset/symlinktofolder", l[3])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/.hidden", l[4])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/file2", l[5])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/file3", l[6])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/subfolder", l[7])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/subfolder/file4", l[8])
pathEqualsTo(t, "testdata/fileset/test.txt", l[9])
pathEqualsTo(t, "testdata/fileset/test.txt.gz", l[10])
l, err = testdata.ReadDirRecursiveFiltered(nil, FilterNames("folder"))
require.NoError(t, err)
l.Sort()
require.Len(t, l, 1)
pathEqualsTo(t, "testdata/fileset/folder", l[0])
l, err = testdata.ReadDirRecursiveFiltered(FilterNames("symlinktofolder"), FilterOutNames(".hidden"))
require.NoError(t, err)
require.Len(t, l, 9)
l.Sort()
pathEqualsTo(t, "testdata/fileset/anotherFile", l[0])
pathEqualsTo(t, "testdata/fileset/file", l[1])
pathEqualsTo(t, "testdata/fileset/folder", l[2])
pathEqualsTo(t, "testdata/fileset/symlinktofolder", l[3])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/file2", l[4])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/file3", l[5])
pathEqualsTo(t, "testdata/fileset/symlinktofolder/subfolder", l[6])
pathEqualsTo(t, "testdata/fileset/test.txt", l[7])
pathEqualsTo(t, "testdata/fileset/test.txt.gz", l[8])
}
func TestReadDirRecursiveLoopDetection(t *testing.T) {
loopsPath := New("testdata", "loops")
unbuondedReaddir := func(testdir string) (PathList, error) {
var files PathList
var err error
done := make(chan bool)
go func() {
files, err = loopsPath.Join(testdir).ReadDirRecursive()
done <- true
}()
require.Eventually(
t,
func() bool {
select {
case <-done:
return true
default:
return false
}
},
5*time.Second,
10*time.Millisecond,
"Infinite symlink loop while loading sketch",
)
return files, err
}
for _, dir := range []string{"loop_1", "loop_2", "loop_3", "loop_4"} {
l, err := unbuondedReaddir(dir)
require.EqualError(t, err, "directories symlink loop detected", "loop not detected in %s", dir)
require.Nil(t, l)
}
{
l, err := unbuondedReaddir("regular_1")
require.NoError(t, err)
require.Len(t, l, 4)
l.Sort()
pathEqualsTo(t, "testdata/loops/regular_1/dir1", l[0])
pathEqualsTo(t, "testdata/loops/regular_1/dir1/file1", l[1])
pathEqualsTo(t, "testdata/loops/regular_1/dir2", l[2])
pathEqualsTo(t, "testdata/loops/regular_1/dir2/file1", l[3])
}
{
l, err := unbuondedReaddir("regular_2")
require.NoError(t, err)
require.Len(t, l, 6)
l.Sort()
pathEqualsTo(t, "testdata/loops/regular_2/dir1", l[0])
pathEqualsTo(t, "testdata/loops/regular_2/dir1/file1", l[1])
pathEqualsTo(t, "testdata/loops/regular_2/dir2", l[2])
pathEqualsTo(t, "testdata/loops/regular_2/dir2/dir1", l[3])
pathEqualsTo(t, "testdata/loops/regular_2/dir2/dir1/file1", l[4])
pathEqualsTo(t, "testdata/loops/regular_2/dir2/file2", l[5])
}
{
l, err := unbuondedReaddir("regular_3")
require.NoError(t, err)
require.Len(t, l, 7)
l.Sort()
pathEqualsTo(t, "testdata/loops/regular_3/dir1", l[0])
pathEqualsTo(t, "testdata/loops/regular_3/dir1/file1", l[1])
pathEqualsTo(t, "testdata/loops/regular_3/dir2", l[2])
pathEqualsTo(t, "testdata/loops/regular_3/dir2/dir1", l[3])
pathEqualsTo(t, "testdata/loops/regular_3/dir2/dir1/file1", l[4])
pathEqualsTo(t, "testdata/loops/regular_3/dir2/file2", l[5])
pathEqualsTo(t, "testdata/loops/regular_3/link", l[6]) // broken symlink is reported in files
}
if runtime.GOOS != "windows" {
dir1 := loopsPath.Join("regular_4_with_permission_error", "dir1")
l, err := unbuondedReaddir("regular_4_with_permission_error")
require.NoError(t, err)
require.NotEmpty(t, l)
dir1Stat, err := dir1.Stat()
require.NoError(t, err)
err = dir1.Chmod(fs.FileMode(0)) // Enforce permission error
require.NoError(t, err)
t.Cleanup(func() {
// Restore normal permission after the test
dir1.Chmod(dir1Stat.Mode())
})
l, err = unbuondedReaddir("regular_4_with_permission_error")
require.Error(t, err)
require.Nil(t, l)
}
}

View file

@ -1 +0,0 @@
broken

View file

@ -1 +0,0 @@
real_dir

View file

@ -1 +0,0 @@
file2

View file

@ -1 +0,0 @@
delay*

View file

@ -1,40 +0,0 @@
/*
* This file is part of PathsHelper library.
*
* Copyright 2023 Arduino AG (http://www.arduino.cc/)
*
* PathsHelper library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package main
import (
"fmt"
"time"
)
func main() {
time.Sleep(3 * time.Second)
fmt.Println("Elapsed!")
}

View file

@ -1,4 +0,0 @@
line 1
line 2
line 3

View file

View file

@ -1 +0,0 @@
folder

View file

@ -1,20 +0,0 @@
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

Binary file not shown.

View file

@ -1 +0,0 @@
../dir1

View file

@ -1 +0,0 @@
../dir2

View file

@ -1 +0,0 @@
../dir1

View file

@ -1 +0,0 @@
../dir2

View file

@ -1 +0,0 @@
../../dir1/

View file

@ -1 +0,0 @@
../dir3

View file

@ -1 +0,0 @@
../../../dir1

View file

@ -1 +0,0 @@
dir1

View file

@ -1 +0,0 @@
../dir1

View file

@ -1 +0,0 @@
../dir1

View file

@ -1 +0,0 @@
broken

View file

@ -1 +0,0 @@
../dir1

View file

@ -1 +0,0 @@
broken