github.com/charypar/monobuild@v0.0.0-20211122220434-fd884ed50212/manifests/manifests_test.go (about)

     1  package manifests
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"reflect"
     7  	"sort"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/bmatcuk/doublestar"
    12  )
    13  
    14  func chdir(dir string) {
    15  	err := os.Chdir(dir)
    16  	if err != nil {
    17  		panic(fmt.Errorf("Error returning to current directory: %s", err))
    18  	}
    19  }
    20  
    21  func Test_Read(t *testing.T) {
    22  	cwd, err := os.Getwd()
    23  	if err != nil {
    24  		panic(fmt.Errorf("Error finding current directory: %s", err))
    25  	}
    26  
    27  	tests := []struct {
    28  		name    string
    29  		cwd     string
    30  		pattern string
    31  		want    []string
    32  		want1   Dependencies
    33  		wantErr bool
    34  	}{
    35  		{
    36  			"reads tests manifests correctly",
    37  			"../test/fixtures/manifests-test",
    38  			"**/Dependencies",
    39  			[]string{
    40  				"app1",
    41  				"app2",
    42  				"app3",
    43  				"app4",
    44  				"app4/lib",
    45  				"libs/lib1",
    46  				"libs/lib2",
    47  				"libs/lib3",
    48  				"stack1",
    49  			},
    50  			Dependencies{deps: map[string][]Dependency{
    51  				"app1":      []Dependency{{"app1", Weak}, {"libs/lib1", Weak}, {"libs/lib2", Weak}},
    52  				"app2":      []Dependency{{"app2", Weak}, {"libs/lib2", Weak}, {"libs/lib3", Weak}},
    53  				"app3":      []Dependency{{"app3", Weak}, {"libs/lib3", Weak}, {"app4/lib", Weak}},
    54  				"app4":      []Dependency{{"app4", Weak}},
    55  				"app4/lib":  []Dependency{{"app4/lib", Weak}},
    56  				"libs/lib1": []Dependency{{"libs/lib1", Weak}, {"libs/lib3", Weak}},
    57  				"libs/lib2": []Dependency{{"libs/lib2", Weak}, {"libs/lib3", Weak}},
    58  				"libs/lib3": []Dependency{{"libs/lib3", Weak}},
    59  				"stack1":    []Dependency{{"stack1", Weak}, {"app1", Strong}, {"app2", Strong}, {"app3", Strong}},
    60  			}},
    61  			false,
    62  		},
    63  		{
    64  			"fails on a bad manifest",
    65  			"../test/fixtures/bad-manifests",
    66  			"**/Dependencies",
    67  			nil,
    68  			Dependencies{},
    69  			true,
    70  		},
    71  	}
    72  
    73  	for _, tt := range tests {
    74  		t.Run(tt.name, func(t *testing.T) {
    75  			chdir(tt.cwd)
    76  			defer chdir(cwd)
    77  
    78  			manifests, err := doublestar.Glob("**/Dependencies")
    79  			if err != nil {
    80  				panic(fmt.Errorf("Error finding dependency manifests: %s", err))
    81  			}
    82  
    83  			got, got1, errs := Read(manifests, true)
    84  			if (errs != nil) != tt.wantErr {
    85  				t.Errorf("Read() error = %v, wantErr %v", errs, tt.wantErr)
    86  				return
    87  			}
    88  
    89  			sort.Strings(got)
    90  
    91  			if !reflect.DeepEqual(got, tt.want) {
    92  				t.Errorf("Read() got = %#v, want %#v", got, tt.want)
    93  			}
    94  			if !reflect.DeepEqual(got1, tt.want1) {
    95  				t.Errorf("Read() got1 = %#v, want %#v", got1, tt.want1)
    96  			}
    97  		})
    98  	}
    99  }
   100  
   101  func Test_ReadManifest(t *testing.T) {
   102  	type args struct {
   103  		path string
   104  	}
   105  	tests := []struct {
   106  		name  string
   107  		args  args
   108  		want  string
   109  		want1 []Dependency
   110  		want2 []error
   111  	}{
   112  		// TODO: Add test cases.
   113  	}
   114  	for _, tt := range tests {
   115  		t.Run(tt.name, func(t *testing.T) {
   116  			got, got1, got2 := ReadManifest(tt.args.path)
   117  			if got != tt.want {
   118  				t.Errorf("ReadManifest() got = %v, want %v", got, tt.want)
   119  			}
   120  			if !reflect.DeepEqual(got1, tt.want1) {
   121  				t.Errorf("ReadManifest() got1 = %v, want %v", got1, tt.want1)
   122  			}
   123  			if !reflect.DeepEqual(got2, tt.want2) {
   124  				t.Errorf("ReadManifest() got2 = %v, want %v", got2, tt.want2)
   125  			}
   126  		})
   127  	}
   128  }
   129  
   130  func Test_FilterComponents(t *testing.T) {
   131  	type args struct {
   132  		components   []string
   133  		changedFiles []string
   134  	}
   135  	tests := []struct {
   136  		name string
   137  		args args
   138  		want []string
   139  	}{
   140  		{
   141  			"works with nothing",
   142  			args{[]string{}, []string{}},
   143  			[]string{},
   144  		},
   145  		{
   146  			"works with no components",
   147  			args{[]string{}, []string{"some/file/there.txt"}},
   148  			[]string{},
   149  		},
   150  		{
   151  			"works with no changes",
   152  			args{[]string{"component/one"}, []string{}},
   153  			[]string{},
   154  		},
   155  		{
   156  			"finds a changed component",
   157  			args{[]string{"component/one", "another"}, []string{"component/one/file/two.txt"}},
   158  			[]string{"component/one"},
   159  		},
   160  		{
   161  			"handles multiple files in a component",
   162  			args{
   163  				[]string{"component/one", "another"},
   164  				[]string{"component/one/file/one.txt", "component/one/file/two.txt"},
   165  			},
   166  			[]string{"component/one"},
   167  		},
   168  		{
   169  			"only matches full component name",
   170  			args{
   171  				[]string{"a/component", "a/component-v2"},
   172  				[]string{"a/component-v2/file.txt"},
   173  			},
   174  			[]string{"a/component-v2"},
   175  		},
   176  		{
   177  			"changes outside of components result in no changes",
   178  			args{
   179  				[]string{"component/one", "component/two", "something-else"},
   180  				[]string{".github/CODEOWNERS"},
   181  			},
   182  			[]string{},
   183  		},
   184  		{
   185  			"handles a complex case correctly",
   186  			args{
   187  				[]string{
   188  					"stack",
   189  					"application-one",
   190  					"application-two",
   191  					"libraries/one",
   192  					"libraries/two",
   193  				},
   194  				[]string{
   195  					"stack/config.json",
   196  					"application-one/src/public/index.js",
   197  					"libraries/two/src/index.go",
   198  				},
   199  			},
   200  			[]string{
   201  				"stack",
   202  				"application-one",
   203  				"libraries/two",
   204  			},
   205  		},
   206  	}
   207  	for _, tt := range tests {
   208  		t.Run(tt.name, func(t *testing.T) {
   209  			if got := FilterComponents(tt.args.components, tt.args.changedFiles); !reflect.DeepEqual(got, tt.want) {
   210  				t.Errorf("changedComponents() = %v, want %v", got, tt.want)
   211  			}
   212  		})
   213  	}
   214  }
   215  
   216  func joinErrors(message string, errors []error) error {
   217  	errstrings := make([]string, len(errors))
   218  	for i, e := range errors {
   219  		errstrings[i] = string(e.Error())
   220  	}
   221  
   222  	return fmt.Errorf("%s\n%s", message, strings.Join(errstrings, "\n"))
   223  }
   224  
   225  func TestReadRepoManifest(t *testing.T) {
   226  	tests := []struct {
   227  		name     string
   228  		manifest string
   229  		want     []string
   230  		want1    Dependencies
   231  		wantErrs bool
   232  		errors   []error
   233  	}{
   234  		// TODO: Add test cases.
   235  		{
   236  			"Empty manifest",
   237  			"",
   238  			[]string{},
   239  			Dependencies{deps: map[string][]Dependency{}},
   240  			false,
   241  			nil,
   242  		},
   243  		{
   244  			"Single component",
   245  			"lib1:",
   246  			[]string{
   247  				"lib1",
   248  			},
   249  			Dependencies{deps: map[string][]Dependency{
   250  				"lib1": []Dependency{{"lib1", Weak}},
   251  			}},
   252  			false,
   253  			nil,
   254  		},
   255  		{
   256  			"Component with a dependency",
   257  			"lib1: lib2\nlib2: ",
   258  			[]string{"lib1", "lib2"},
   259  			Dependencies{deps: map[string][]Dependency{
   260  				"lib1": []Dependency{{"lib1", Weak}, {"lib2", Weak}},
   261  				"lib2": []Dependency{{"lib2", Weak}},
   262  			}},
   263  			false,
   264  			nil,
   265  		},
   266  		{
   267  			"Component with multiple dependencies",
   268  			"lib1: lib2, lib3\nlib2: \nlib3: ",
   269  			[]string{"lib1", "lib2", "lib3"},
   270  			Dependencies{deps: map[string][]Dependency{
   271  				"lib1": []Dependency{{"lib1", Weak}, {"lib2", Weak}, {"lib3", Weak}},
   272  				"lib2": []Dependency{{"lib2", Weak}},
   273  				"lib3": []Dependency{{"lib3", Weak}},
   274  			}},
   275  			false,
   276  			nil,
   277  		},
   278  		{
   279  			"Complex manifest",
   280  			"# comment\napp1: lib1, lib2, lib3\napp2: \nlib1: \nlib2: lib3\nlib3: \n\nstack1: !app1, !app2",
   281  			[]string{"app1", "app2", "lib1", "lib2", "lib3", "stack1"},
   282  			Dependencies{deps: map[string][]Dependency{
   283  				"app1":   []Dependency{{"app1", Weak}, {"lib1", Weak}, {"lib2", Weak}, {"lib3", Weak}},
   284  				"app2":   []Dependency{{"app2", Weak}},
   285  				"lib1":   []Dependency{{"lib1", Weak}},
   286  				"lib2":   []Dependency{{"lib2", Weak}, {"lib3", Weak}},
   287  				"lib3":   []Dependency{{"lib3", Weak}},
   288  				"stack1": []Dependency{{"stack1", Weak}, {"app1", Strong}, {"app2", Strong}},
   289  			}},
   290  			false,
   291  			nil,
   292  		},
   293  		{
   294  			"Malformed line manifest",
   295  			"# comment\napp1: lib1, lib2, lib3\nWHAT\napp2: \nlib1: \nlib2: lib3\nlib3: \n\nstack1: !app1, !app2",
   296  			nil,
   297  			Dependencies{},
   298  			true,
   299  			[]error{fmt.Errorf("bad line format: 'WHAT' expected 'componnennt: dependency, dependency, ...'")},
   300  		},
   301  		{
   302  			"Incomplete manifest",
   303  			"# comment\napp1: lib1, lib2, lib3, unknown\n\napp2: \nlib1: \nlib2: lib3\nlib3: \n\nstack1: !app1, !app2",
   304  			nil,
   305  			Dependencies{},
   306  			true,
   307  			[]error{fmt.Errorf("unknown dependency 'unknown' of 'app1'")},
   308  		}}
   309  	for _, tt := range tests {
   310  		t.Run(tt.name, func(t *testing.T) {
   311  			got, got1, gotErr := ReadRepoManifest(tt.manifest, true)
   312  
   313  			if !tt.wantErrs && gotErr != nil {
   314  				t.Errorf("ReadRepoManifest() received errors %#v", gotErr)
   315  			}
   316  
   317  			sort.Strings(got)
   318  			if !reflect.DeepEqual(got, tt.want) {
   319  				t.Errorf("ReadRepoManifest() got = %#v, want %#v", got, tt.want)
   320  			}
   321  			if !reflect.DeepEqual(got1, tt.want1) {
   322  				t.Errorf("ReadRepoManifest() got1 = %#v, want %#v", got1, tt.want1)
   323  			}
   324  			if !reflect.DeepEqual(joinErrors("", gotErr), joinErrors("", tt.errors)) {
   325  				t.Errorf("ReadRepoManifest() gotErr = %d, want %d", joinErrors("", gotErr), joinErrors("", tt.errors))
   326  			}
   327  		})
   328  	}
   329  }