github.com/please-build/puku@v1.7.3-0.20240516143641-f7d7f4941f57/generate/generate_test.go (about)

     1  package generate
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/assert"
     7  	"github.com/stretchr/testify/require"
     8  
     9  	"github.com/please-build/puku/config"
    10  	"github.com/please-build/puku/edit"
    11  	"github.com/please-build/puku/kinds"
    12  	"github.com/please-build/puku/please"
    13  )
    14  
    15  func TestAllocateSources(t *testing.T) {
    16  	foo := newRule(edit.NewRuleExpr("go_library", "foo"), kinds.DefaultKinds["go_library"], "")
    17  	fooTest := newRule(edit.NewRuleExpr("go_test", "foo_test"), kinds.DefaultKinds["go_test"], "")
    18  
    19  	foo.addSrc("foo.go")
    20  	fooTest.addSrc("foo_test.go")
    21  
    22  	rules := []*rule{foo, fooTest}
    23  
    24  	files := map[string]*GoFile{
    25  		"bar.go": {
    26  			Name:     "foo",
    27  			FileName: "bar.go",
    28  		},
    29  		"bar_test.go": {
    30  			Name:     "foo",
    31  			FileName: "bar_test.go",
    32  		},
    33  		"external_test.go": {
    34  			Name:     "foo_test",
    35  			FileName: "external_test.go",
    36  		},
    37  		"foo.go": {
    38  			Name:     "foo",
    39  			FileName: "foo.go",
    40  		},
    41  		"foo_test.go": {
    42  			Name:     "foo",
    43  			FileName: "foo_test.go",
    44  		},
    45  	}
    46  
    47  	u := newUpdater(new(please.Config))
    48  	conf := &config.Config{PleasePath: "plz"}
    49  	newRules, err := u.allocateSources(conf, "foo", files, rules)
    50  	require.NoError(t, err)
    51  
    52  	require.Len(t, newRules, 1)
    53  	assert.Equal(t, "foo_test", newRules[0].Name())
    54  	assert.ElementsMatch(t, []string{"external_test.go"}, mustGetSources(t, u, newRules[0]))
    55  
    56  	assert.ElementsMatch(t, []string{"foo.go", "bar.go"}, mustGetSources(t, u, rules[0]))
    57  	assert.ElementsMatch(t, []string{"foo_test.go", "bar_test.go"}, mustGetSources(t, u, rules[1]))
    58  }
    59  
    60  func TestAddingLibDepToTest(t *testing.T) {
    61  	foo := newRule(edit.NewRuleExpr("go_library", "foo"), kinds.DefaultKinds["go_library"], "")
    62  	fooTest := newRule(edit.NewRuleExpr("go_test", "foo_test"), kinds.DefaultKinds["go_test"], "")
    63  
    64  	files := map[string]*GoFile{
    65  		"foo.go": {
    66  			Name:     "foo",
    67  			FileName: "foo.go",
    68  		},
    69  		"foo_test.go": {
    70  			Name:     "foo",
    71  			FileName: "foo_test.go",
    72  		},
    73  	}
    74  
    75  	foo.SetAttr(foo.SrcsAttr(), edit.NewStringList([]string{"foo.go"}))
    76  	fooTest.SetAttr(fooTest.SrcsAttr(), edit.NewStringList([]string{"foo_test.go"}))
    77  
    78  	u := newUpdater(new(please.Config))
    79  	conf := &config.Config{PleasePath: "plz"}
    80  	err := u.updateRuleDeps(conf, fooTest, []*rule{foo, fooTest}, files)
    81  	require.NoError(t, err)
    82  
    83  	assert.Equal(t, fooTest.AttrStrings("deps"), []string{":foo"})
    84  }
    85  
    86  func TestAllocateSourcesToCustomKind(t *testing.T) {
    87  	exampleKind := &kinds.Kind{
    88  		Name:     "go_example_lib",
    89  		Type:     kinds.Lib,
    90  		SrcsAttr: "go_srcs",
    91  	}
    92  
    93  	satKind := &kinds.Kind{
    94  		Name: "service_acceptance_test",
    95  		Type: kinds.Test,
    96  	}
    97  
    98  	foo := newRule(edit.NewRuleExpr("go_example_lib", "foo"), exampleKind, "")
    99  	fooTest := newRule(edit.NewRuleExpr("go_test", "foo_test"), satKind, "")
   100  
   101  	foo.addSrc("foo.go")
   102  	fooTest.addSrc("foo_test.go")
   103  
   104  	rules := []*rule{foo, fooTest}
   105  
   106  	files := map[string]*GoFile{
   107  		"bar.go": {
   108  			Name:     "foo",
   109  			FileName: "bar.go",
   110  		},
   111  		"bar_test.go": {
   112  			Name:     "foo",
   113  			FileName: "bar_test.go",
   114  		},
   115  		"foo.go": {
   116  			Name:     "foo",
   117  			FileName: "foo.go",
   118  		},
   119  		"foo_test.go": {
   120  			Name:     "foo",
   121  			FileName: "foo_test.go",
   122  		},
   123  	}
   124  
   125  	u := newUpdater(new(please.Config))
   126  	conf := &config.Config{PleasePath: "plz"}
   127  	newRules, err := u.allocateSources(conf, "foo", files, rules)
   128  	require.NoError(t, err)
   129  
   130  	assert.Len(t, newRules, 0)
   131  
   132  	assert.ElementsMatch(t, []string{"foo.go", "bar.go"}, mustGetSources(t, u, rules[0]))
   133  	assert.Equal(t, rules[0].SrcsAttr(), exampleKind.SrcsAttr)
   134  	assert.ElementsMatch(t, []string{"foo_test.go", "bar_test.go"}, mustGetSources(t, u, rules[1]))
   135  }
   136  
   137  func TestAllocateSourcesToNonGoKind(t *testing.T) {
   138  	exampleKind := &kinds.Kind{
   139  		Name:         "go_example_lib",
   140  		Type:         kinds.Lib,
   141  		NonGoSources: true,
   142  	}
   143  
   144  	foo := newRule(edit.NewRuleExpr("go_example_lib", "nogo"), exampleKind, "")
   145  
   146  	rules := []*rule{foo}
   147  
   148  	files := map[string]*GoFile{
   149  		"foo.go": {
   150  			Name:     "foo",
   151  			FileName: "foo.go",
   152  		},
   153  	}
   154  
   155  	u := newUpdater(new(please.Config))
   156  	u.plzConf = &please.Config{}
   157  	newRules, err := u.allocateSources(new(config.Config), "foo", files, rules)
   158  	require.NoError(t, err)
   159  
   160  	require.Len(t, newRules, 1)
   161  
   162  	assert.ElementsMatch(t, []string{}, mustGetSources(t, u, foo))
   163  	assert.Equal(t, "go_library", newRules[0].Kind())
   164  	assert.ElementsMatch(t, []string{"foo.go"}, mustGetSources(t, u, newRules[0]))
   165  }
   166  
   167  func TestUpdateDeps(t *testing.T) {
   168  	type ruleKind struct {
   169  		kind *kinds.Kind
   170  		srcs []string
   171  	}
   172  
   173  	testCases := []struct {
   174  		name         string
   175  		srcs         []*GoFile
   176  		rule         *ruleKind
   177  		expectedDeps []string
   178  		modules      []string
   179  		installs     map[string]string
   180  		conf         *config.Config
   181  		proxy        FakeProxy
   182  	}{
   183  		{
   184  			name: "adds import from known module",
   185  			srcs: []*GoFile{
   186  				{
   187  					FileName: "foo.go",
   188  					Imports:  []string{"github.com/example/module/foo"},
   189  					Name:     "foo",
   190  				},
   191  			},
   192  			modules: []string{"github.com/example/module"},
   193  			rule: &ruleKind{
   194  				srcs: []string{"foo.go"},
   195  				kind: kinds.DefaultKinds["go_library"],
   196  			},
   197  			expectedDeps: []string{"///third_party/go/github.com_example_module//foo"},
   198  		},
   199  		{
   200  			name: "handles installs",
   201  			srcs: []*GoFile{
   202  				{
   203  					FileName: "foo.go",
   204  					Imports: []string{
   205  						"github.com/example/module1/foo",
   206  						"github.com/example/module2/foo/bar/baz",
   207  					},
   208  					Name: "foo",
   209  				},
   210  			},
   211  			modules: []string{},
   212  			installs: map[string]string{
   213  				"github.com/example/module1/foo": "//third_party/go:module1",
   214  				"github.com/example/module2/...": "//third_party/go:module2",
   215  			},
   216  			rule: &ruleKind{
   217  				srcs: []string{"foo.go"},
   218  				kind: kinds.DefaultKinds["go_library"],
   219  			},
   220  
   221  			expectedDeps: []string{"//third_party/go:module1", "//third_party/go:module2"},
   222  		},
   223  		{
   224  			name: "handles custom kinds",
   225  			srcs: []*GoFile{
   226  				{
   227  					FileName: "foo.go",
   228  					Imports: []string{
   229  						"github.com/example/module/foo",
   230  						"github.com/example/module/bar",
   231  					},
   232  					Name: "foo",
   233  				},
   234  			},
   235  			modules: []string{"github.com/example/module"},
   236  			rule: &ruleKind{
   237  				srcs: []string{"foo.go"},
   238  				kind: &kinds.Kind{
   239  					Name:         "example_library",
   240  					Type:         kinds.Lib,
   241  					ProvidedDeps: []string{"///third_party/go/github.com_example_module//foo"},
   242  				},
   243  			},
   244  			expectedDeps: []string{"///third_party/go/github.com_example_module//bar"},
   245  		},
   246  		{
   247  			name:    "handles missing src",
   248  			srcs:    []*GoFile{},
   249  			modules: []string{"github.com/example/module"},
   250  			rule: &ruleKind{
   251  				srcs: []string{"foo.go"},
   252  				kind: &kinds.Kind{
   253  					Name:         "example_library",
   254  					Type:         kinds.Lib,
   255  					ProvidedDeps: []string{"///third_party/go/github.com_example_module//foo"},
   256  				},
   257  			},
   258  			expectedDeps: []string{},
   259  		},
   260  	}
   261  
   262  	for _, tc := range testCases {
   263  		t.Run(tc.name, func(t *testing.T) {
   264  			plzConf := new(please.Config)
   265  			plzConf.Plugin.Go.ImportPath = []string{"github.com/this/module"}
   266  			u := newUpdater(plzConf)
   267  			u.modules = tc.modules
   268  			u.proxy = tc.proxy
   269  
   270  			for path, value := range tc.installs {
   271  				u.installs.Add(path, value)
   272  			}
   273  
   274  			conf := tc.conf
   275  			if conf == nil {
   276  				conf = new(config.Config)
   277  			}
   278  
   279  			r := newRule(edit.NewRuleExpr(tc.rule.kind.Name, "rule"), tc.rule.kind, "")
   280  			for _, src := range tc.rule.srcs {
   281  				r.addSrc(src)
   282  			}
   283  
   284  			files := make(map[string]*GoFile, len(tc.srcs))
   285  			srcNames := make([]string, 0, len(tc.srcs))
   286  			for _, f := range tc.srcs {
   287  				files[f.FileName] = f
   288  				srcNames = append(srcNames, f.FileName)
   289  			}
   290  
   291  			err := u.updateRuleDeps(conf, r, []*rule{}, files)
   292  			require.NoError(t, err)
   293  			assert.ElementsMatch(t, tc.expectedDeps, r.AttrStrings("deps"))
   294  			assert.ElementsMatch(t, srcNames, r.AttrStrings(r.SrcsAttr()))
   295  		})
   296  	}
   297  }
   298  
   299  func mustGetSources(t *testing.T, u *updater, rule *rule) []string {
   300  	t.Helper()
   301  
   302  	srcs, err := u.eval.EvalGlobs(rule.dir, rule.Rule, rule.SrcsAttr())
   303  	require.NoError(t, err)
   304  	return srcs
   305  }