github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/dockerignore/ignore_test.go (about)

     1  package dockerignore_test
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  
     9  	"github.com/tilt-dev/tilt/internal/dockerignore"
    10  	"github.com/tilt-dev/tilt/internal/testutils/tempdir"
    11  	"github.com/tilt-dev/tilt/pkg/model"
    12  )
    13  
    14  func TestMatches(t *testing.T) {
    15  	tf := newTestFixture(t, "node_modules")
    16  	tf.AssertResult(tf.JoinPath("node_modules", "foo"), true)
    17  	tf.AssertResult(tf.JoinPath("node_modules", "foo", "bar", "baz"), true)
    18  	tf.AssertResultEntireDir(tf.JoinPath("node_modules"), true)
    19  	tf.AssertResult(tf.JoinPath("foo", "bar"), false)
    20  	tf.AssertResultEntireDir(tf.JoinPath("foo"), false)
    21  }
    22  
    23  func TestComment(t *testing.T) {
    24  	tf := newTestFixture(t, "# generated code")
    25  	tf.AssertResult(tf.JoinPath("node_modules", "foo"), false)
    26  	tf.AssertResult(tf.JoinPath("foo", "bar"), false)
    27  }
    28  
    29  func TestGlob(t *testing.T) {
    30  	tf := newTestFixture(t, "*/temp*")
    31  	tf.AssertResult(tf.JoinPath("somedir", "temporary.txt"), true)
    32  	tf.AssertResult(tf.JoinPath("somedir", "temp"), true)
    33  }
    34  
    35  func TestCurrentDirDoubleGlob(t *testing.T) {
    36  	tf := newTestFixture(t, "**/temp*")
    37  	tf.AssertResult(tf.JoinPath("a", "temporary.txt"), true)
    38  	tf.AssertResult(tf.JoinPath("a", "b", "temporary.txt"), true)
    39  	tf.AssertResult(tf.JoinPath("a", "b", "c", "temporary.txt"), true)
    40  	tf.AssertResult(tf.JoinPath("b", "c", "temporary.txt"), true)
    41  	tf.AssertResult(tf.JoinPath("..", "a", "b", "temporary.txt"), false)
    42  }
    43  
    44  func TestInnerDirDoubleGlob(t *testing.T) {
    45  	tf := newTestFixture(t, "a/**/temp*")
    46  	tf.AssertResult(tf.JoinPath("a", "temporary.txt"), true)
    47  	tf.AssertResult(tf.JoinPath("a", "b", "temporary.txt"), true)
    48  	tf.AssertResult(tf.JoinPath("a", "b", "c", "temporary.txt"), true)
    49  	tf.AssertResult(tf.JoinPath("b", "c", "temporary.txt"), false)
    50  	tf.AssertResult(tf.JoinPath("..", "a", "b", "temporary.txt"), false)
    51  }
    52  
    53  func TestUplevel(t *testing.T) {
    54  	tf := newTestFixture(t, "../a/b.txt")
    55  	tf.AssertResult(tf.JoinPath("..", "a", "b.txt"), true)
    56  	tf.AssertResult(tf.JoinPath("a", "b.txt"), false)
    57  }
    58  
    59  func TestUplevelDoubleGlob(t *testing.T) {
    60  	tf := newTestFixture(t, "../**/b.txt")
    61  	tf.AssertResult(tf.JoinPath("..", "a", "b.txt"), true)
    62  	tf.AssertResult(tf.JoinPath("a", "b.txt"), true)
    63  }
    64  
    65  func TestUplevelMatchDirDoubleGlob(t *testing.T) {
    66  	tf := newTestFixture(t, "../**/b")
    67  	tf.AssertResult(tf.JoinPath("a", "temporary.txt"), false)
    68  	tf.AssertResult(tf.JoinPath("a", "b"), true)
    69  	tf.AssertResult(tf.JoinPath("a", "b", "temporary.txt"), true)
    70  	tf.AssertResult(tf.JoinPath("a", "b", "c", "temporary.txt"), true)
    71  	tf.AssertResult(tf.JoinPath("a", "b", "c", "d", "temporary.txt"), true)
    72  	tf.AssertResult(tf.JoinPath("a", "b2", "c", "d", "temporary.txt"), false)
    73  }
    74  
    75  func TestOneCharacterExtension(t *testing.T) {
    76  	tf := newTestFixture(t, "temp?")
    77  	tf.AssertResult(tf.JoinPath("tempa"), true)
    78  	tf.AssertResult(tf.JoinPath("tempeh"), false)
    79  	tf.AssertResult(tf.JoinPath("temp"), false)
    80  }
    81  
    82  func TestException(t *testing.T) {
    83  	tf := newTestFixture(t, "docs", "!docs/README.md")
    84  	tf.AssertResult(tf.JoinPath("docs", "stuff.md"), true)
    85  	tf.AssertResult(tf.JoinPath("docs", "README.md"), false)
    86  	tf.AssertResultEntireDir(tf.JoinPath("docs"), false)
    87  }
    88  
    89  func TestNestedException(t *testing.T) {
    90  	tf := newTestFixture(t, "a", "!a/b", "a/b/c")
    91  	tf.AssertResultEntireDir(tf.JoinPath("a"), false)
    92  	tf.AssertResultEntireDir(tf.JoinPath("a", "b"), false)
    93  	tf.AssertResultEntireDir(tf.JoinPath("a", "b", "c"), true)
    94  }
    95  
    96  func TestOrthogonalException(t *testing.T) {
    97  	tf := newTestFixture(t, "a", "b", "!b/README.md")
    98  	tf.AssertResultEntireDir(tf.JoinPath("a"), true)
    99  	tf.AssertResultEntireDir(tf.JoinPath("b"), false)
   100  }
   101  
   102  func TestOnlyGoFiles(t *testing.T) {
   103  	tf := newTestFixture(t, "*", "!pkg/**/*.go", "!go.mod", "!go.sum")
   104  	tf.AssertResult(tf.JoinPath("pkg", "hello.txt"), true)
   105  	tf.AssertResult(tf.JoinPath("pkg", "internal", "hello.txt"), true)
   106  	tf.AssertResult(tf.JoinPath("pkg", "internal", "module", "hello.txt"), true)
   107  	tf.AssertResult(tf.JoinPath("pkg", "hello.go"), false)
   108  	tf.AssertResult(tf.JoinPath("pkg", "internal", "hello.go"), false)
   109  	tf.AssertResult(tf.JoinPath("pkg", "internal", "module", "hello.go"), false)
   110  	tf.AssertResultEntireDir(tf.JoinPath("pkg"), false)
   111  	tf.AssertResultEntireDir(tf.JoinPath("pkg", "internal"), false)
   112  	tf.AssertResultEntireDir(tf.JoinPath("pkg", "internal", "module"), false)
   113  }
   114  
   115  func TestNoDockerignoreFile(t *testing.T) {
   116  	tf := newTestFixture(t)
   117  	tf.AssertResult(tf.JoinPath("hi"), false)
   118  	tf.AssertResult(tf.JoinPath("hi", "hello"), false)
   119  	tf.AssertResultEntireDir(tf.JoinPath("hi"), false)
   120  }
   121  
   122  type testFixture struct {
   123  	repoRoot *tempdir.TempDirFixture
   124  	t        *testing.T
   125  	tester   model.PathMatcher
   126  }
   127  
   128  func newTestFixture(t *testing.T, dockerignores ...string) *testFixture {
   129  	tf := testFixture{}
   130  	tempDir := tempdir.NewTempDirFixture(t)
   131  	tf.repoRoot = tempDir
   132  	ignoreText := strings.Builder{}
   133  	for _, rule := range dockerignores {
   134  		ignoreText.WriteString(rule + "\n")
   135  	}
   136  	if ignoreText.Len() > 0 {
   137  		tempDir.WriteFile(".dockerignore", ignoreText.String())
   138  	}
   139  
   140  	tester, err := dockerignore.NewDockerIgnoreTester(tempDir.Path())
   141  	if err != nil {
   142  		t.Fatal(err)
   143  	}
   144  	tf.tester = tester
   145  
   146  	tf.t = t
   147  	return &tf
   148  }
   149  
   150  func (tf *testFixture) JoinPath(path ...string) string {
   151  	return tf.repoRoot.JoinPath(path...)
   152  }
   153  
   154  func (tf *testFixture) AssertResult(path string, expectedMatches bool) {
   155  	tf.t.Helper()
   156  	isIgnored, err := tf.tester.Matches(path)
   157  	if err != nil {
   158  		tf.t.Fatal(err)
   159  	} else if assert.NoError(tf.t, err) {
   160  		assert.Equalf(tf.t, expectedMatches, isIgnored, "Expected isIgnored to be %t for file %s, got %t", expectedMatches, path, isIgnored)
   161  	}
   162  }
   163  
   164  func (tf *testFixture) AssertResultEntireDir(path string, expectedMatches bool) {
   165  	isIgnored, err := tf.tester.MatchesEntireDir(path)
   166  	if err != nil {
   167  		tf.t.Fatal(err)
   168  	} else if assert.NoError(tf.t, err) {
   169  		assert.Equalf(tf.t, expectedMatches, isIgnored, "Expected isIgnored to be %t for file %s, got %t", expectedMatches, path, isIgnored)
   170  	}
   171  }