package updater import ( "context" "fmt" "log" "net/http" "net/http/httptest" "runtime" ) // mockGithubClient is a mock implementation of the GithubClient interface for testing. type mockGithubClient struct { getLatestRelease func(ctx context.Context, owner, repo, channel string) (*Release, error) getReleaseByPR func(ctx context.Context, owner, repo string, prNumber int) (*Release, error) getPublicRepos func(ctx context.Context, userOrOrg string) ([]string, error) getLatestReleaseCount int getReleaseByPRCount int getPublicReposCount int } func (m *mockGithubClient) GetLatestRelease(ctx context.Context, owner, repo, channel string) (*Release, error) { m.getLatestReleaseCount++ return m.getLatestRelease(ctx, owner, repo, channel) } func (m *mockGithubClient) GetReleaseByPullRequest(ctx context.Context, owner, repo string, prNumber int) (*Release, error) { m.getReleaseByPRCount++ return m.getReleaseByPR(ctx, owner, repo, prNumber) } func (m *mockGithubClient) GetPublicRepos(ctx context.Context, userOrOrg string) ([]string, error) { m.getPublicReposCount++ if m.getPublicRepos != nil { return m.getPublicRepos(ctx, userOrOrg) } return nil, fmt.Errorf("GetPublicRepos not implemented") } func ExampleCheckForNewerVersion() { originalNewGithubClient := NewGithubClient defer func() { NewGithubClient = originalNewGithubClient }() NewGithubClient = func() GithubClient { return &mockGithubClient{ getLatestRelease: func(ctx context.Context, owner, repo, channel string) (*Release, error) { return &Release{TagName: "v1.1.0"}, nil }, } } Version = "1.0.0" release, available, err := CheckForNewerVersion("owner", "repo", "stable", true) if err != nil { log.Fatalf("CheckForNewerVersion failed: %v", err) } if available { fmt.Printf("Newer version available: %s", release.TagName) } else { fmt.Println("No newer version available.") } // Output: Newer version available: v1.1.0 } func ExampleCheckForUpdates() { // Mock the functions to prevent actual updates and network calls originalDoUpdate := DoUpdate originalNewGithubClient := NewGithubClient defer func() { DoUpdate = originalDoUpdate NewGithubClient = originalNewGithubClient }() NewGithubClient = func() GithubClient { return &mockGithubClient{ getLatestRelease: func(ctx context.Context, owner, repo, channel string) (*Release, error) { return &Release{ TagName: "v1.1.0", Assets: []ReleaseAsset{{Name: fmt.Sprintf("test-asset-%s-%s", runtime.GOOS, runtime.GOARCH), DownloadURL: "http://example.com/asset"}}, }, nil }, } } DoUpdate = func(url string) error { fmt.Printf("Update would be applied from: %s", url) return nil } Version = "1.0.0" err := CheckForUpdates("owner", "repo", "stable", true, "") if err != nil { log.Fatalf("CheckForUpdates failed: %v", err) } // Output: // Newer version v1.1.0 found (current: v1.0.0). Applying update... // Update would be applied from: http://example.com/asset } func ExampleCheckOnly() { originalNewGithubClient := NewGithubClient defer func() { NewGithubClient = originalNewGithubClient }() NewGithubClient = func() GithubClient { return &mockGithubClient{ getLatestRelease: func(ctx context.Context, owner, repo, channel string) (*Release, error) { return &Release{TagName: "v1.1.0"}, nil }, } } Version = "1.0.0" err := CheckOnly("owner", "repo", "stable", true, "") if err != nil { log.Fatalf("CheckOnly failed: %v", err) } // Output: New release found: v1.1.0 (current version: v1.0.0) } func ExampleCheckForUpdatesByTag() { // Mock the functions to prevent actual updates and network calls originalDoUpdate := DoUpdate originalNewGithubClient := NewGithubClient defer func() { DoUpdate = originalDoUpdate NewGithubClient = originalNewGithubClient }() NewGithubClient = func() GithubClient { return &mockGithubClient{ getLatestRelease: func(ctx context.Context, owner, repo, channel string) (*Release, error) { if channel == "stable" { return &Release{ TagName: "v1.1.0", Assets: []ReleaseAsset{{Name: fmt.Sprintf("test-asset-%s-%s", runtime.GOOS, runtime.GOARCH), DownloadURL: "http://example.com/asset"}}, }, nil } return nil, nil }, } } DoUpdate = func(url string) error { fmt.Printf("Update would be applied from: %s", url) return nil } Version = "1.0.0" // A version that resolves to the "stable" channel err := CheckForUpdatesByTag("owner", "repo") if err != nil { log.Fatalf("CheckForUpdatesByTag failed: %v", err) } // Output: // Newer version v1.1.0 found (current: v1.0.0). Applying update... // Update would be applied from: http://example.com/asset } func ExampleCheckOnlyByTag() { originalNewGithubClient := NewGithubClient defer func() { NewGithubClient = originalNewGithubClient }() NewGithubClient = func() GithubClient { return &mockGithubClient{ getLatestRelease: func(ctx context.Context, owner, repo, channel string) (*Release, error) { if channel == "stable" { return &Release{TagName: "v1.1.0"}, nil } return nil, nil }, } } Version = "1.0.0" // A version that resolves to the "stable" channel err := CheckOnlyByTag("owner", "repo") if err != nil { log.Fatalf("CheckOnlyByTag failed: %v", err) } // Output: New release found: v1.1.0 (current version: v1.0.0) } func ExampleCheckForUpdatesByPullRequest() { // Mock the functions to prevent actual updates and network calls originalDoUpdate := DoUpdate originalNewGithubClient := NewGithubClient defer func() { DoUpdate = originalDoUpdate NewGithubClient = originalNewGithubClient }() NewGithubClient = func() GithubClient { return &mockGithubClient{ getReleaseByPR: func(ctx context.Context, owner, repo string, prNumber int) (*Release, error) { if prNumber == 123 { return &Release{ TagName: "v1.1.0-alpha.pr.123", Assets: []ReleaseAsset{{Name: fmt.Sprintf("test-asset-%s-%s", runtime.GOOS, runtime.GOARCH), DownloadURL: "http://example.com/asset-pr"}}, }, nil } return nil, nil }, } } DoUpdate = func(url string) error { fmt.Printf("Update would be applied from: %s", url) return nil } err := CheckForUpdatesByPullRequest("owner", "repo", 123, "") if err != nil { log.Fatalf("CheckForUpdatesByPullRequest failed: %v", err) } // Output: // Release v1.1.0-alpha.pr.123 found for PR #123. Applying update... // Update would be applied from: http://example.com/asset-pr } func ExampleCheckForUpdatesHTTP() { // Create a mock HTTP server server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/latest.json" { _, _ = fmt.Fprintln(w, `{"version": "1.1.0", "url": "http://example.com/update"}`) } })) defer server.Close() // Mock the doUpdateFunc to prevent actual updates originalDoUpdate := DoUpdate defer func() { DoUpdate = originalDoUpdate }() DoUpdate = func(url string) error { fmt.Printf("Update would be applied from: %s", url) return nil } Version = "1.0.0" err := CheckForUpdatesHTTP(server.URL) if err != nil { log.Fatalf("CheckForUpdatesHTTP failed: %v", err) } // Output: // Newer version 1.1.0 found (current: 1.0.0). Applying update... // Update would be applied from: http://example.com/update } func ExampleCheckOnlyHTTP() { // Create a mock HTTP server server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/latest.json" { _, _ = fmt.Fprintln(w, `{"version": "1.1.0", "url": "http://example.com/update"}`) } })) defer server.Close() Version = "1.0.0" err := CheckOnlyHTTP(server.URL) if err != nil { log.Fatalf("CheckOnlyHTTP failed: %v", err) } // Output: New release found: 1.1.0 (current version: 1.0.0) }