changelog generator & diff tool stormlightlabs.github.io/git-storm/
changelog changeset markdown golang git
at main 6.1 kB view raw
1package tty 2 3import ( 4 "os" 5 "strings" 6 "testing" 7) 8 9func TestIsCI(t *testing.T) { 10 tests := []struct { 11 name string 12 envVars map[string]string 13 expected bool 14 }{ 15 { 16 name: "no CI vars", 17 envVars: map[string]string{}, 18 expected: false, 19 }, 20 { 21 name: "generic CI var", 22 envVars: map[string]string{"CI": "true"}, 23 expected: true, 24 }, 25 { 26 name: "GitHub Actions", 27 envVars: map[string]string{"GITHUB_ACTIONS": "true"}, 28 expected: true, 29 }, 30 { 31 name: "GitLab CI", 32 envVars: map[string]string{"GITLAB_CI": "true"}, 33 expected: true, 34 }, 35 { 36 name: "CircleCI", 37 envVars: map[string]string{"CIRCLECI": "true"}, 38 expected: true, 39 }, 40 { 41 name: "multiple CI vars", 42 envVars: map[string]string{"CI": "true", "TRAVIS": "true"}, 43 expected: true, 44 }, 45 } 46 47 for _, tt := range tests { 48 t.Run(tt.name, func(t *testing.T) { 49 ciEnvVars := []string{ 50 "CI", "CONTINUOUS_INTEGRATION", "GITHUB_ACTIONS", 51 "GITLAB_CI", "CIRCLECI", "TRAVIS", "JENKINS_URL", 52 "BUILDKITE", "DRONE", "TEAMCITY_VERSION", 53 } 54 for _, v := range ciEnvVars { 55 os.Unsetenv(v) 56 } 57 58 for k, v := range tt.envVars { 59 os.Setenv(k, v) 60 } 61 62 defer func() { 63 for k := range tt.envVars { 64 os.Unsetenv(k) 65 } 66 }() 67 68 result := IsCI() 69 if result != tt.expected { 70 t.Errorf("IsCI() = %v, expected %v", result, tt.expected) 71 } 72 }) 73 } 74} 75 76func TestGetCIName(t *testing.T) { 77 tests := []struct { 78 name string 79 envVar string 80 expected string 81 }{ 82 { 83 name: "GitHub Actions", 84 envVar: "GITHUB_ACTIONS", 85 expected: "GitHub Actions", 86 }, 87 { 88 name: "GitLab CI", 89 envVar: "GITLAB_CI", 90 expected: "GitLab CI", 91 }, 92 { 93 name: "CircleCI", 94 envVar: "CIRCLECI", 95 expected: "CircleCI", 96 }, 97 { 98 name: "Travis CI", 99 envVar: "TRAVIS", 100 expected: "Travis CI", 101 }, 102 { 103 name: "Jenkins", 104 envVar: "JENKINS_URL", 105 expected: "Jenkins", 106 }, 107 { 108 name: "Buildkite", 109 envVar: "BUILDKITE", 110 expected: "Buildkite", 111 }, 112 { 113 name: "Drone CI", 114 envVar: "DRONE", 115 expected: "Drone CI", 116 }, 117 { 118 name: "TeamCity", 119 envVar: "TEAMCITY_VERSION", 120 expected: "TeamCity", 121 }, 122 { 123 name: "Generic CI", 124 envVar: "CI", 125 expected: "CI", 126 }, 127 { 128 name: "No CI", 129 envVar: "", 130 expected: "", 131 }, 132 } 133 134 for _, tt := range tests { 135 t.Run(tt.name, func(t *testing.T) { 136 ciEnvVars := []string{ 137 "CI", "CONTINUOUS_INTEGRATION", "GITHUB_ACTIONS", 138 "GITLAB_CI", "CIRCLECI", "TRAVIS", "JENKINS_URL", 139 "BUILDKITE", "DRONE", "TEAMCITY_VERSION", 140 } 141 for _, v := range ciEnvVars { 142 os.Unsetenv(v) 143 } 144 145 if tt.envVar != "" { 146 os.Setenv(tt.envVar, "true") 147 } 148 149 defer func() { 150 if tt.envVar != "" { 151 os.Unsetenv(tt.envVar) 152 } 153 }() 154 155 result := GetCIName() 156 if result != tt.expected { 157 t.Errorf("GetCIName() = %q, expected %q", result, tt.expected) 158 } 159 }) 160 } 161} 162 163func TestErrorInteractiveRequired(t *testing.T) { 164 tests := []struct { 165 name string 166 commandName string 167 alternatives []string 168 ciEnv string 169 wantContains []string 170 }{ 171 { 172 name: "basic error", 173 commandName: "review", 174 wantContains: []string{ 175 "command 'review' requires an interactive terminal", 176 }, 177 }, 178 { 179 name: "with alternatives", 180 commandName: "review", 181 alternatives: []string{ 182 "Use 'storm unreleased list' to view entries", 183 "Use 'storm unreleased list --json' for JSON output", 184 }, 185 wantContains: []string{ 186 "command 'review' requires an interactive terminal", 187 "Alternatives:", 188 "Use 'storm unreleased list' to view entries", 189 "Use 'storm unreleased list --json' for JSON output", 190 }, 191 }, 192 { 193 name: "CI environment", 194 commandName: "diff", 195 ciEnv: "GITHUB_ACTIONS", 196 wantContains: []string{ 197 "command 'diff' requires an interactive terminal", 198 "detected GitHub Actions environment", 199 }, 200 }, 201 } 202 203 for _, tt := range tests { 204 t.Run(tt.name, func(t *testing.T) { 205 ciEnvVars := []string{ 206 "CI", "CONTINUOUS_INTEGRATION", "GITHUB_ACTIONS", 207 "GITLAB_CI", "CIRCLECI", "TRAVIS", "JENKINS_URL", 208 "BUILDKITE", "DRONE", "TEAMCITY_VERSION", 209 } 210 for _, v := range ciEnvVars { 211 os.Unsetenv(v) 212 } 213 214 if tt.ciEnv != "" { 215 os.Setenv(tt.ciEnv, "true") 216 defer os.Unsetenv(tt.ciEnv) 217 } 218 219 err := ErrorInteractiveRequired(tt.commandName, tt.alternatives) 220 if err == nil { 221 t.Fatal("ErrorInteractiveRequired() returned nil, expected error") 222 } 223 224 errMsg := err.Error() 225 for _, want := range tt.wantContains { 226 if !strings.Contains(errMsg, want) { 227 t.Errorf("ErrorInteractiveRequired() error message missing %q\nGot: %s", want, errMsg) 228 } 229 } 230 }) 231 } 232} 233 234func TestErrorInteractiveFlag(t *testing.T) { 235 tests := []struct { 236 name string 237 flagName string 238 ciEnv string 239 wantContains []string 240 }{ 241 { 242 name: "basic error", 243 flagName: "--interactive", 244 wantContains: []string{ 245 "flag '--interactive' requires an interactive terminal", 246 }, 247 }, 248 { 249 name: "CI environment", 250 flagName: "--interactive", 251 ciEnv: "GITLAB_CI", 252 wantContains: []string{ 253 "flag '--interactive' requires an interactive terminal", 254 "detected GitLab CI environment", 255 }, 256 }, 257 } 258 259 for _, tt := range tests { 260 t.Run(tt.name, func(t *testing.T) { 261 ciEnvVars := []string{ 262 "CI", "CONTINUOUS_INTEGRATION", "GITHUB_ACTIONS", 263 "GITLAB_CI", "CIRCLECI", "TRAVIS", "JENKINS_URL", 264 "BUILDKITE", "DRONE", "TEAMCITY_VERSION", 265 } 266 for _, v := range ciEnvVars { 267 os.Unsetenv(v) 268 } 269 270 if tt.ciEnv != "" { 271 os.Setenv(tt.ciEnv, "true") 272 defer os.Unsetenv(tt.ciEnv) 273 } 274 275 err := ErrorInteractiveFlag(tt.flagName) 276 if err == nil { 277 t.Fatal("ErrorInteractiveFlag() returned nil, expected error") 278 } 279 280 errMsg := err.Error() 281 for _, want := range tt.wantContains { 282 if !strings.Contains(errMsg, want) { 283 t.Errorf("ErrorInteractiveFlag() error message missing %q\nGot: %s", want, errMsg) 284 } 285 } 286 }) 287 } 288}