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 }