package main import ( "encoding/json" "flag" "os" "os/exec" "reflect" "strings" "testing" "src.opensuse.org/autogits/common" ) func TestMain(m *testing.M) { if os.Getenv("BE_MAIN") == "1" { main() return } os.Exit(m.Run()) } func TestRun(t *testing.T) { tests := []struct { name string inData string expectedOut string params []string expectedError string isDir bool }{ { name: "add user to existing package", inData: `{"pkg1": ["user1"]}`, params: []string{"-package", "pkg1", "-add", "user2"}, expectedOut: `{"pkg1": ["user1", "user2"]}`, }, { name: "add user to new package", inData: `{"pkg1": ["user1"]}`, params: []string{"-package", "pkg2", "-add", "user2"}, expectedOut: `{"pkg1": ["user1"], "pkg2": ["user2"]}`, }, { name: "no-op with no users", inData: `{"pkg1": ["user1"]}`, params: []string{"-package", "pkg1", "-add"}, expectedOut: `{"pkg1": ["user1"]}`, }, { name: "add existing user", inData: `{"pkg1": ["user1", "user2"]}`, params: []string{"-package", "pkg1", "-add", "user2"}, expectedOut: `{"pkg1": ["user1", "user2"]}`, }, { name: "remove user from package", inData: `{"pkg1": ["user1", "user2"]}`, params: []string{"-package", "pkg1", "-rm", "user2"}, expectedOut: `{"pkg1": ["user1"]}`, }, { name: "remove last user from package", inData: `{"pkg1": ["user1"]}`, params: []string{"-package", "pkg1", "-rm", "user1"}, expectedOut: `{}`, }, { name: "remove non-existent user", inData: `{"pkg1": ["user1"]}`, params: []string{"-package", "pkg1", "-rm", "user2"}, expectedOut: `{"pkg1": ["user1"]}`, }, { name: "lint only unsorted", inData: `{"pkg1": ["user2", "user1"]}`, params: []string{"-lint-only"}, expectedOut: `{"pkg1": ["user1", "user2"]}`, }, { name: "lint only no changes", inData: `{"pkg1": ["user1", "user2"]}`, params: []string{"-lint-only"}, expectedOut: `{"pkg1": ["user1", "user2"]}`, }, { name: "no file", params: []string{"-add"}, expectedError: "no such file or directory", }, { name: "invalid json", inData: `{"pkg1": ["user1"`, params: []string{"-add"}, expectedError: "Failed to parse JSON", }, { name: "add", inData: `{"pkg1": ["user1", "user2"]}`, params: []string{"-package", "pkg1", "-add", "user3"}, expectedOut: `{"pkg1": ["user1", "user2", "user3"]}`, }, { name: "lint specific file", inData: `{"pkg1": ["user2", "user1"]}`, params: []string{"-lint-only", "other.json"}, expectedOut: `{"pkg1": ["user1", "user2"]}`, }, { name: "add user to package when it was not there before", inData: `{}`, params: []string{"-package", "newpkg", "-add", "user1"}, expectedOut: `{"newpkg": ["user1"]}`, }, { name: "unreadable file (is a directory)", isDir: true, params: []string{"-rm"}, expectedError: "is a directory", }, { name: "remove user from non-existent package", inData: `{"pkg1": ["user1"]}`, params: []string{"-package", "pkg2", "-rm", "user2"}, expectedError: "No package pkg2 and not adding one.", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { dir := t.TempDir() oldWd, _ := os.Getwd() _ = os.Chdir(dir) defer os.Chdir(oldWd) targetFile := common.MaintainershipFile if tt.name == "lint specific file" { targetFile = "other.json" } if tt.isDir { _ = os.Mkdir(targetFile, 0755) } else if tt.inData != "" { _ = os.WriteFile(targetFile, []byte(tt.inData), 0644) } flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ContinueOnError) os.Args = append([]string{"cmd"}, tt.params...) err := run() if tt.expectedError != "" { if err == nil { t.Fatalf("expected error containing %q, but got none", tt.expectedError) } if !strings.Contains(err.Error(), tt.expectedError) { t.Fatalf("expected error containing %q, got %q", tt.expectedError, err.Error()) } } else if err != nil { t.Fatalf("unexpected error: %v", err) } if tt.expectedOut != "" { data, _ := os.ReadFile(targetFile) var got, expected map[string][]string _ = json.Unmarshal(data, &got) _ = json.Unmarshal([]byte(tt.expectedOut), &expected) if len(got) == 0 && len(expected) == 0 { return } if !reflect.DeepEqual(got, expected) { t.Fatalf("expected %v, got %v", expected, got) } } }) } } func TestMainRecursive(t *testing.T) { tests := []struct { name string inData string expectedOut string params []string expectExit bool }{ { name: "test main() via recursive call", inData: `{"pkg1": ["user1"]}`, params: []string{"-package", "pkg1", "-add", "user2"}, expectedOut: `{"pkg1": ["user1", "user2"]}`, }, { name: "test main() failure", params: []string{"-package", "pkg1"}, expectExit: true, }, } exe, _ := os.Executable() for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { dir := t.TempDir() oldWd, _ := os.Getwd() _ = os.Chdir(dir) defer os.Chdir(oldWd) if tt.inData != "" { _ = os.WriteFile(common.MaintainershipFile, []byte(tt.inData), 0644) } cmd := exec.Command(exe, append([]string{"-test.run=None"}, tt.params...)...) cmd.Env = append(os.Environ(), "BE_MAIN=1") out, runErr := cmd.CombinedOutput() if tt.expectExit { if runErr == nil { t.Fatalf("expected exit with error, but it succeeded") } return } if runErr != nil { t.Fatalf("unexpected error: %v: %s", runErr, string(out)) } if tt.expectedOut != "" { data, _ := os.ReadFile(common.MaintainershipFile) var got, expected map[string][]string _ = json.Unmarshal(data, &got) _ = json.Unmarshal([]byte(tt.expectedOut), &expected) if !reflect.DeepEqual(got, expected) { t.Fatalf("expected %v, got %v", expected, got) } } }) } }