Пример #1
0
func Test_FinderNode_Expand_single_include(t *testing.T) {
	cleanup := testutils.Chtemp()
	defer cleanup()

	testutils.TouchFiles(
		"lib1/foo.c", "lib1/sub/blah.c", "include/bop.h", "include/bip.h")

	finder := NewFinderNode("*/*.c")
	assertExpand(t, nil, []string{"lib1/foo.c"}, finder)

	finder = NewFinderNode("**/*.c")
	assertExpand(t, nil, []string{"lib1/foo.c", "lib1/sub/blah.c"}, finder)

	finder = NewFinderNode("l?b?/**/*.c")
	assertExpand(t, nil, []string{"lib1/foo.c", "lib1/sub/blah.c"}, finder)

	finder = NewFinderNode("in?lu?e/*.h")
	assertExpand(t, nil, []string{"include/bip.h", "include/bop.h"}, finder)

	finder = NewFinderNode("inc*/?i*.h")
	assertExpand(t, nil, []string{"include/bip.h"}, finder)

	// adding new files changes nothing, because FinderNode caches the
	// result of Expand()
	testutils.TouchFiles("include/mip.h", "include/fibbb.h")
	assertExpand(t, nil, []string{"include/bip.h"}, finder)

	// but a new FileFinder instance will see them
	finder = NewFinderNode("inc*/?i*.h")
	assertExpand(t,
		nil,
		[]string{"include/bip.h", "include/fibbb.h", "include/mip.h"},
		finder)
}
Пример #2
0
func Test_FinderNode_Expand_vars(t *testing.T) {
	// imagine code like this:
	//   srcdir = "src/stuff"
	//   files = <$srcdir/*.c>
	//   "myapp": "$srcdir/main.c" {
	//       "cc -c $files"
	//   }
	// ...i.e. a FinderNode that is not in the DAG, so variable
	// references do not get expanded by DAG.ExpandNodes(). This is
	// clearly a bogus build script, but that's beside the point. We
	// need to ensure that the wildcard expanded is not "$srcdir/*.c"
	// but "src/stuff/*.c".

	cleanup := testutils.Chtemp()
	defer cleanup()

	testutils.TouchFiles(
		"lib1/foo.c", "lib1/sub/blah.c", "include/bop.h", "include/bip.h")

	ns := types.NewValueMap()
	ns.Assign("libsrc", types.MakeFuString("lib1"))
	finder := NewFinderNode("$libsrc/**/*.c")
	expect := []string{
		"lib1/foo.c",
		"lib1/sub/blah.c",
	}
	assertExpand(t, ns, expect, finder)
}
Пример #3
0
func Test_remove(t *testing.T) {
	cleanup := testutils.Chtemp()
	defer cleanup()

	args := RuntimeArgs{
		BasicArgs: types.MakeBasicArgs(nil, []types.FuObject{}, nil),
	}

	// remove() doesn't care about empty arg list (same reason as mkdir())
	result, errs := fn_remove(args)
	assert.Nil(t, result)
	assert.Equal(t, 0, len(errs))

	// remove() ignores non-existent files
	args.SetArgs(types.MakeStringList("foo", "bar/bleep/meep", "qux").List())
	result, errs = fn_remove(args)
	assert.Nil(t, result)
	assert.Equal(t, 0, len(errs))

	// remove() removes regular files
	testutils.TouchFiles("foo", "bar/bleep/meep", "bar/bleep/feep", "qux")
	args.SetArgs(types.MakeStringList("foo", "bar/bleep/meep", "bogus").List())
	result, errs = fn_remove(args)
	assert.Nil(t, result)
	assert.Equal(t, 0, len(errs))
	assert.Equal(t, []string{"bar", "qux"}, dirContents("."))
	assert.Equal(t, []string{"bleep"}, dirContents("bar"))
	assert.Equal(t, []string{"feep"}, dirContents("bar/bleep"))

	// remove() removes files and directories too
	testutils.TouchFiles("foo", "bar/bleep/meep", "qux")
	args.SetArgs(types.MakeStringList("bogus", "bar", "morebogus", "qux").List())
	result, errs = fn_remove(args)
	assert.Nil(t, result)
	assert.Equal(t, 0, len(errs))
	assert.Equal(t, []string{"foo"}, dirContents("."))

	// remove() fails if it tries to delete from an unwriteable directory
	testutils.TouchFiles("bar/bong", "qux/bip")
	testutils.ChmodRO("bar")
	defer testutils.ChmodOwnerAll("bar")

	args.SetArgs(types.MakeStringList("bar", "qux").List())
	result, errs = fn_remove(args)
	assert.Nil(t, result)
	assert.Equal(t, "remove bar/bong: permission denied", errs[0].Error())
}
Пример #4
0
func Test_findScripts(t *testing.T) {
	cleanup := testutils.Chtemp()
	defer cleanup()

	var script string
	var err error

	// case 1: user specifies the script to run, regardless of whether
	// it exists or not
	script, err = findScript("foo")
	assert.Equal(t, "foo", script)
	assert.Nil(t, err)

	// case 2: no *.fubsy files in current dir
	script, err = findScript("")
	assert.Equal(t,
		"main.fubsy not found (and no other *.fubsy files found)",
		err.Error())

	// case 3: only main.fubsy exists
	testutils.TouchFiles("main.fubsy")
	script, err = findScript("")
	assert.Equal(t, "main.fubsy", script)
	assert.Nil(t, err)

	// case 4: multiple *.fubsy files exist, including main.fubsy
	testutils.TouchFiles("a.fubsy", "b.fubsy")
	script, err = findScript("")
	assert.Equal(t, "main.fubsy", script)
	assert.Nil(t, err)

	// case 5: multiple *.fubsy files exist, not including main.fubsy
	remove("main.fubsy")
	script, err = findScript("")
	assert.Equal(t, "", script)
	assert.True(t,
		strings.HasPrefix(
			err.Error(),
			"main.fubsy not found, and multiple *.fubsy files exist",
		))

	// case 6: exactly one *.fubsy file exists, and it's not main.fubsy
	remove("a.fubsy")
	script, err = findScript("")
	assert.Equal(t, "b.fubsy", script)
	assert.Nil(t, err)
}
Пример #5
0
func Test_FinderNode_FindFiles_prune(t *testing.T) {
	cleanup := testutils.Chtemp()
	defer cleanup()

	testutils.TouchFiles(
		"src/a/1.c", "src/a/2.c", "src/a/2.h", "src/a/3.h",
		"src/b/1.c", "src/b/2.c", "src/b/2.h", "src/b/3.h",
		"src/b/b/1.c", "src/b/b/2.c", "src/b/b/2.h",
		"lib/x.c", "lib/sub/x.c")

	var finder *FinderNode
	var expect []string

	test := func(expect []string) {
		actual, err := finder.FindFiles()
		assert.Nil(t, err)
		if !reflect.DeepEqual(expect, actual) {
			t.Errorf("includes = %v, prune = %v:\nexpected:\n%#v\nbut got:\n%#v",
				finder.includes, finder.prune, expect, actual)
		}
		// wipe the cache so this finder can be used again
		finder.matches = nil
	}

	finder = NewFinderNode("src/**/*.c", "src/b/**/*.h")
	finder.Prune("src/a")
	expect = []string{
		"src/b/1.c", "src/b/2.c", "src/b/b/1.c", "src/b/b/2.c",
		"src/b/2.h", "src/b/3.h", "src/b/b/2.h"}
	test(expect)

	// successive calls to Prune() build up the prune set
	finder = NewFinderNode("*/*.c")
	finder.Prune("src")
	expect = []string{"lib/x.c"}
	test(expect)
	finder.Prune("lib")
	expect = []string{}
	test(expect)

	finder = NewFinderNode("*/*/?.c")
	expect = []string{
		"lib/sub/x.c", "src/a/1.c", "src/a/2.c", "src/b/1.c", "src/b/2.c"}
	test(expect)
	finder.Prune("src/b")
	expect = []string{
		"lib/sub/x.c", "src/a/1.c", "src/a/2.c"}
	test(expect)

	finder = NewFinderNode("**/b/?.h")
	expect = []string{"src/b/2.h", "src/b/3.h", "src/b/b/2.h"}
	test(expect)
	finder.Prune("src/b/b")
	expect = []string{"src/b/2.h", "src/b/3.h"}
	test(expect)
	finder.Prune("src/b")
	expect = []string{}
	test(expect)
}
Пример #6
0
func Test_mkdir(t *testing.T) {
	cleanup := testutils.Chtemp()
	defer cleanup()

	// mkdir() happily accepts an empty argument list, to allow for
	// cases where a user-defined list becomes the arg list, and it
	// just happens to be empty
	pargs := []types.FuObject{}
	args := RuntimeArgs{
		BasicArgs: types.MakeBasicArgs(nil, pargs, nil),
	}
	result, errs := fn_mkdir(args)
	assert.Nil(t, result)
	assert.Equal(t, 0, len(errs))
	assert.Equal(t, []string{}, dirContents("."))

	// easiest case: create a single dir
	pargs = types.MakeStringList("foo").List()
	args.SetArgs(pargs)
	result, errs = fn_mkdir(args)
	assert.Nil(t, result)
	assert.Equal(t, 0, len(errs))
	assert.Equal(t, []string{"foo"}, dirContents("."))
	assert.True(t, isDir("foo"))

	// create multiple dirs, including "foo" which already exists
	pargs = types.MakeStringList("meep/meep/meep", "foo", "meep/beep").List()
	args.SetArgs(pargs)
	result, errs = fn_mkdir(args)
	assert.Nil(t, result)
	assert.Equal(t, 0, len(errs))
	assert.Equal(t, []string{"foo", "meep"}, dirContents("."))
	assert.True(t, isDir("foo"))
	assert.True(t, isDir("meep/meep"))
	assert.True(t, isDir("meep/meep/meep"))
	assert.True(t, isDir("meep/beep"))

	// now with an error in the middle of the list (*but* we still
	// create the other requested dirs!)
	testutils.TouchFiles("meep/zap")
	pargs = types.MakeStringList("meep/bap", "meep/zap/zip", "foo/bar").List()
	args.SetArgs(pargs)
	result, errs = fn_mkdir(args)
	assert.Nil(t, result)
	assert.Equal(t, 1, len(errs))
	assert.Equal(t, "mkdir meep/zap: not a directory", errs[0].Error())
	assert.True(t, isDir("meep/bap"))
	assert.True(t, isDir("foo/bar"))

	// finally, with multiple errors
	pargs = append(pargs, types.MakeFuString("meep/zap/blop"))
	args.SetArgs(pargs)
	result, errs = fn_mkdir(args)
	assert.Nil(t, result)
	assert.Equal(t, 2, len(errs))
	assert.Equal(t, "mkdir meep/zap: not a directory", errs[0].Error())
	assert.Equal(t, "mkdir meep/zap: not a directory", errs[1].Error())
}
Пример #7
0
func touchSourceFiles(dag *DAG) {
	filenames := []string{}
	for id, node := range dag.nodes {
		if dag.parents[id].IsEmpty() {
			filenames = append(filenames, node.Name())
		}
	}
	testutils.TouchFiles(filenames...)
}
Пример #8
0
func Test_FinderNode_Add_Expand(t *testing.T) {
	cleanup := testutils.Chtemp()
	defer cleanup()
	testutils.TouchFiles(
		"src/foo.c", "src/foo.h", "main.c", "include/bop.h",
		"doc.txt", "doc/stuff.txt", "doc/blahblah.rst")

	finder1 := NewFinderNode("**/*.c")
	finder2 := NewFinderNode("doc/*.txt")

	// sum = <**/*.c> + <doc/*.txt>
	expect := []string{
		"main.c", "src/foo.c", "doc/stuff.txt"}
	sum, err := finder1.Add(finder2)
	assert.Nil(t, err)
	assertExpand(t, nil, expect, sum)

	// sum = sum + <"*c*/?o?.h">
	finder3 := NewFinderNode("*c*/?o?.h")
	expect = append(expect, "include/bop.h", "src/foo.h")
	sum, err = sum.Add(finder3)
	assert.Nil(t, err)
	assertExpand(t, nil, expect, sum)

	// sum = <*c*/?o?.h> + <**/*.c>
	expect = []string{
		"include/bop.h", "src/foo.h", "main.c", "src/foo.c"}
	sum, err = finder3.Add(finder1)
	assert.Nil(t, err)
	assertExpand(t, nil, expect, sum)

	// sum = <doc/*.txt> + sum
	// (effectively: sum = <doc/*.txt> + (<*c*/?o?.h> + <**/*.c>))
	expect = append([]string{"doc/stuff.txt"}, expect...)
	sum, err = finder2.Add(sum)
	assert.Nil(t, err)
	assertExpand(t, nil, expect, sum)

	// sum = <**/*.c> + "urgh"
	expect = []string{
		"main.c", "src/foo.c", "urgh"}
	sum, err = finder1.Add(types.MakeFuString("urgh"))
	assert.Nil(t, err)
	assertExpand(t, nil, expect, sum)

	// sum = <**/*.c> + ["a", "b", "c"]
	expect = []string{
		"main.c", "src/foo.c", "a", "b", "c"}
	list := types.MakeStringList("a", "b", "c")
	sum, err = finder1.Add(list)
	assert.Nil(t, err)
	assertExpand(t, nil, expect, sum)
}
Пример #9
0
func Test_FinderNode_Expand_empty(t *testing.T) {
	cleanup := testutils.Chtemp()
	defer cleanup()

	// no patterns, no files: of course we find nothing
	finder := &FinderNode{}
	assertExpand(t, nil, []string{}, finder)

	// patterns, but no files: still nothing
	finder.includes = []string{"**/*.c", "include/*.h", "*/*.txt"}
	assertExpand(t, nil, []string{}, finder)

	// no patterns, some files: still nothing
	finder.includes = finder.includes[0:0]
	testutils.TouchFiles(
		"lib1/foo.c", "lib1/sub/blah.c", "include/bop.h", "include/bip.h")
	assertExpand(t, nil, []string{}, finder)
}
Пример #10
0
func Test_FinderNode_Expand_double_recursion(t *testing.T) {
	// Java programmers love this sort of insanely deep structure, and
	// Ant supports patterns with multiple occurences of "**" ... so I
	// guess Fubsy has to support them too!
	cleanup := testutils.Chtemp()
	defer cleanup()

	testutils.TouchFiles(
		"app1/src/main/org/example/app1/App1.java",
		"app1/src/main/org/example/app1/Util.java",
		"app1/src/main/org/example/app1/doc.txt",
		"app1/src/main/org/example/app1/subpkg/Stuff.java",
		"app1/src/main/org/example/app1/subpkg/MoreStuff.java",
		"app1/src/test/org/example/app1/StuffTest.java",
		"misc/app2/src/main/org/example/app2/App2.java",
		"misc/app3/src/main/org/example/app3/App3.java",
		"misc/app3/src/main/org/example/app3/Helpers.java",
		"misc/app3/src/test/org/example/app3/TestHelpers.java",
		"misc/app3/src/test/org/example/app3/testdata",
	)

	var finder *FinderNode
	var expect []string
	finder = NewFinderNode("**/test/**/*.java")
	expect = []string{
		"app1/src/test/org/example/app1/StuffTest.java",
		"misc/app3/src/test/org/example/app3/TestHelpers.java",
	}
	assertExpand(t, nil, expect, finder)

	finder = NewFinderNode("**/test/**/*")
	expect = []string{
		"app1/src/test/org/example/app1/StuffTest.java",
		"misc/app3/src/test/org/example/app3/TestHelpers.java",
		"misc/app3/src/test/org/example/app3/testdata",
	}
	assertExpand(t, nil, expect, finder)

	finder = NewFinderNode("**/test/**")
	assertExpand(t, nil, expect, finder)
}
Пример #11
0
func Test_FileNode_Exists(t *testing.T) {
	cleanup := testutils.Chtemp()
	defer cleanup()

	testutils.TouchFiles("foo.txt", "a/a/a/a/foo.txt", "a/b/unreadable")

	testutils.ChmodNoAccess("a/b")
	defer testutils.ChmodOwnerAll("a/b")

	dag := NewDAG()
	tests := []struct {
		name   string
		exists bool
		err    string
	}{
		{"foo.txt", true, ""},
		{"a/a/a", false, "stat a/a/a: is a directory, not a regular file"},
		{"a/a/a/bogus", false, ""},
		{"a/a/a/a/foo.txt", true, ""},
		{"a/b/unreadable", false, "stat a/b/unreadable: permission denied"},
	}

	for _, test := range tests {
		node := MakeFileNode(dag, test.name)
		exists, err := node.Exists()
		if test.err != "" {
			assert.NotNil(t, err)
			assert.Equal(t, test.err, err.Error())
		}
		if test.exists && !exists {
			t.Errorf("%v: expected Exists() true, got false", node)
		} else if !test.exists && exists {
			t.Errorf("%v: expected Exists() false, got true", node)
		}
	}
}