github.com/git-chglog/git-chglog@v0.15.5-0.20240126074033-6a6993d52d69/chglog_test.go (about) 1 package chglog 2 3 import ( 4 "bytes" 5 "os" 6 "path/filepath" 7 "strings" 8 "testing" 9 "time" 10 11 "github.com/stretchr/testify/assert" 12 gitcmd "github.com/tsuyoshiwada/go-gitcmd" 13 ) 14 15 var ( 16 cwd string 17 testRepoRoot = ".tmp" 18 internalTimeFormat = "2006-01-02 15:04:05" 19 ) 20 21 type commitFunc = func(date, subject, body string) 22 type tagFunc = func(name string) 23 24 func TestMain(m *testing.M) { 25 cwd, _ = os.Getwd() 26 cleanup() 27 code := m.Run() 28 cleanup() 29 os.Exit(code) 30 } 31 32 func setup(dir string, setupRepo func(commitFunc, tagFunc, gitcmd.Client)) { 33 testDir := filepath.Join(cwd, testRepoRoot, dir) 34 35 _ = os.RemoveAll(testDir) 36 _ = os.MkdirAll(testDir, os.ModePerm) 37 _ = os.Chdir(testDir) 38 39 loc, _ := time.LoadLocation("UTC") 40 time.Local = loc 41 42 git := gitcmd.New(nil) 43 _, _ = git.Exec("init") 44 _, _ = git.Exec("config", "user.name", "test_user") 45 _, _ = git.Exec("config", "user.email", "test@example.com") 46 47 var commit = func(date, subject, body string) { 48 msg := subject 49 if body != "" { 50 msg += "\n\n" + body 51 } 52 t, _ := time.Parse(internalTimeFormat, date) 53 d := t.Format("Mon Jan 2 15:04:05 2006 +0000") 54 _, _ = git.Exec("commit", "--allow-empty", "--date", d, "-m", msg) 55 } 56 57 var tag = func(name string) { 58 _, _ = git.Exec("tag", name) 59 } 60 61 setupRepo(commit, tag, git) 62 63 _ = os.Chdir(cwd) 64 } 65 66 func cleanup() { 67 _ = os.Chdir(cwd) 68 _ = os.RemoveAll(filepath.Join(cwd, testRepoRoot)) 69 } 70 71 func TestGeneratorNotFoundTags(t *testing.T) { 72 assert := assert.New(t) 73 testName := "not_found" 74 75 setup(testName, func(commit commitFunc, _ tagFunc, _ gitcmd.Client) { 76 commit("2018-01-01 00:00:00", "feat(*): New feature", "") 77 }) 78 79 gen := NewGenerator(NewLogger(os.Stdout, os.Stderr, false, true), 80 &Config{ 81 Bin: "git", 82 WorkingDir: filepath.Join(testRepoRoot, testName), 83 Template: filepath.Join(cwd, "testdata", testName+".md"), 84 Info: &Info{ 85 RepositoryURL: "https://github.com/git-chglog/git-chglog", 86 }, 87 Options: &Options{}, 88 }) 89 90 buf := &bytes.Buffer{} 91 err := gen.Generate(buf, "") 92 expected := strings.TrimSpace(buf.String()) 93 94 assert.Error(err) 95 assert.Contains(err.Error(), "git-tag does not exist") 96 assert.Equal("", expected) 97 } 98 99 func TestGeneratorNotFoundCommits(t *testing.T) { 100 assert := assert.New(t) 101 testName := "not_found" 102 103 setup(testName, func(commit commitFunc, tag tagFunc, _ gitcmd.Client) { 104 commit("2018-01-01 00:00:00", "feat(*): New feature", "") 105 tag("1.0.0") 106 }) 107 108 gen := NewGenerator(NewLogger(os.Stdout, os.Stderr, false, true), 109 &Config{ 110 Bin: "git", 111 WorkingDir: filepath.Join(testRepoRoot, testName), 112 Template: filepath.Join(cwd, "testdata", testName+".md"), 113 Info: &Info{ 114 RepositoryURL: "https://github.com/git-chglog/git-chglog", 115 }, 116 Options: &Options{}, 117 }) 118 119 buf := &bytes.Buffer{} 120 err := gen.Generate(buf, "foo") 121 expected := strings.TrimSpace(buf.String()) 122 123 assert.Error(err) 124 assert.Equal("", expected) 125 } 126 127 func TestGeneratorNotFoundCommitsOne(t *testing.T) { 128 assert := assert.New(t) 129 testName := "not_found" 130 131 setup(testName, func(commit commitFunc, tag tagFunc, _ gitcmd.Client) { 132 commit("2018-01-01 00:00:00", "chore(*): First commit", "") 133 tag("1.0.0") 134 }) 135 136 gen := NewGenerator(NewLogger(os.Stdout, os.Stderr, false, true), 137 &Config{ 138 Bin: "git", 139 WorkingDir: filepath.Join(testRepoRoot, testName), 140 Template: filepath.Join(cwd, "testdata", testName+".md"), 141 Info: &Info{ 142 RepositoryURL: "https://github.com/git-chglog/git-chglog", 143 }, 144 Options: &Options{ 145 CommitFilters: map[string][]string{}, 146 CommitSortBy: "Scope", 147 CommitGroupBy: "Type", 148 CommitGroupSortBy: "Title", 149 CommitGroupTitleMaps: map[string]string{}, 150 HeaderPattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:\\s(.*)$", 151 HeaderPatternMaps: []string{ 152 "Type", 153 "Scope", 154 "Subject", 155 }, 156 IssuePrefix: []string{ 157 "#", 158 "gh-", 159 }, 160 RefActions: []string{}, 161 MergePattern: "^Merge pull request #(\\d+) from (.*)$", 162 MergePatternMaps: []string{ 163 "Ref", 164 "Source", 165 }, 166 RevertPattern: "^Revert \"([\\s\\S]*)\"$", 167 RevertPatternMaps: []string{ 168 "Header", 169 }, 170 NoteKeywords: []string{ 171 "BREAKING CHANGE", 172 }, 173 }, 174 }) 175 176 buf := &bytes.Buffer{} 177 err := gen.Generate(buf, "foo") 178 expected := strings.TrimSpace(buf.String()) 179 180 assert.Error(err) 181 assert.Contains(err.Error(), "\"foo\" was not found") 182 assert.Equal("", expected) 183 } 184 185 func TestGeneratorWithTypeScopeSubject(t *testing.T) { 186 assert := assert.New(t) 187 testName := "type_scope_subject" 188 189 setup(testName, func(commit commitFunc, tag tagFunc, _ gitcmd.Client) { 190 commit("2018-01-01 00:00:00", "chore(*): First commit", "") 191 commit("2018-01-01 00:01:00", "feat(core): Add foo bar", "") 192 commit("2018-01-01 00:02:00", "docs(readme): Update usage #123", "") 193 tag("1.0.0") 194 195 commit("2018-01-02 00:00:00", "feat(parser): New some super options #333", "") 196 commit("2018-01-02 00:01:00", "Merge pull request #999 from tsuyoshiwada/patch-1", "") 197 commit("2018-01-02 00:02:00", "Merge pull request #1000 from tsuyoshiwada/patch-1", "") 198 commit("2018-01-02 00:03:00", "Revert \"feat(core): Add foo bar @mention and issue #987\"", "") 199 tag("1.1.0") 200 201 commit("2018-01-03 00:00:00", "feat(context): Online breaking change", "BREAKING CHANGE: Online breaking change message.") 202 commit("2018-01-03 00:01:00", "feat(router): Multiple breaking change", `This is body, 203 204 BREAKING CHANGE: 205 Multiple 206 breaking 207 change message.`) 208 tag("2.0.0-beta.0") 209 210 commit("2018-01-04 00:00:00", "refactor(context): gofmt", "") 211 commit("2018-01-04 00:01:00", "fix(core): Fix commit\n\nThis is body message.", "") 212 }) 213 214 gen := NewGenerator(NewLogger(os.Stdout, os.Stderr, false, true), 215 &Config{ 216 Bin: "git", 217 WorkingDir: filepath.Join(testRepoRoot, testName), 218 Template: filepath.Join(cwd, "testdata", testName+".md"), 219 Info: &Info{ 220 Title: "CHANGELOG Example", 221 RepositoryURL: "https://github.com/git-chglog/git-chglog", 222 }, 223 Options: &Options{ 224 Sort: "date", 225 CommitFilters: map[string][]string{ 226 "Type": { 227 "feat", 228 "fix", 229 }, 230 }, 231 CommitSortBy: "Scope", 232 CommitGroupBy: "Type", 233 CommitGroupSortBy: "Title", 234 CommitGroupTitleMaps: map[string]string{ 235 "feat": "Features", 236 "fix": "Bug Fixes", 237 }, 238 HeaderPattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:\\s(.*)$", 239 HeaderPatternMaps: []string{ 240 "Type", 241 "Scope", 242 "Subject", 243 }, 244 IssuePrefix: []string{ 245 "#", 246 "gh-", 247 }, 248 RefActions: []string{}, 249 MergePattern: "^Merge pull request #(\\d+) from (.*)$", 250 MergePatternMaps: []string{ 251 "Ref", 252 "Source", 253 }, 254 RevertPattern: "^Revert \"([\\s\\S]*)\"$", 255 RevertPatternMaps: []string{ 256 "Header", 257 }, 258 NoteKeywords: []string{ 259 "BREAKING CHANGE", 260 }, 261 }, 262 }) 263 264 buf := &bytes.Buffer{} 265 err := gen.Generate(buf, "") 266 expected := strings.TrimSpace(buf.String()) 267 268 assert.Nil(err) 269 assert.Equal(`<a name="unreleased"></a> 270 ## [Unreleased] 271 272 ### Bug Fixes 273 - **core:** Fix commit 274 275 276 <a name="2.0.0-beta.0"></a> 277 ## [2.0.0-beta.0] - 2018-01-03 278 ### Features 279 - **context:** Online breaking change 280 - **router:** Multiple breaking change 281 282 ### BREAKING CHANGE 283 284 Multiple 285 breaking 286 change message. 287 288 Online breaking change message. 289 290 291 <a name="1.1.0"></a> 292 ## [1.1.0] - 2018-01-02 293 ### Features 294 - **parser:** New some super options #333 295 296 ### Reverts 297 - feat(core): Add foo bar @mention and issue #987 298 299 ### Pull Requests 300 - Merge pull request #1000 from tsuyoshiwada/patch-1 301 - Merge pull request #999 from tsuyoshiwada/patch-1 302 303 304 <a name="1.0.0"></a> 305 ## 1.0.0 - 2018-01-01 306 ### Features 307 - **core:** Add foo bar 308 309 310 [Unreleased]: https://github.com/git-chglog/git-chglog/compare/2.0.0-beta.0...HEAD 311 [2.0.0-beta.0]: https://github.com/git-chglog/git-chglog/compare/1.1.0...2.0.0-beta.0 312 [1.1.0]: https://github.com/git-chglog/git-chglog/compare/1.0.0...1.1.0`, expected) 313 } 314 315 func TestGeneratorWithNextTag(t *testing.T) { 316 assert := assert.New(t) 317 testName := "type_scope_subject" 318 319 setup(testName, func(commit commitFunc, tag tagFunc, _ gitcmd.Client) { 320 commit("2018-01-01 00:00:00", "feat(core): version 1.0.0", "") 321 tag("1.0.0") 322 323 commit("2018-02-01 00:00:00", "feat(core): version 2.0.0", "") 324 tag("2.0.0") 325 326 commit("2018-03-01 00:00:00", "feat(core): version 3.0.0", "") 327 }) 328 329 gen := NewGenerator(NewLogger(os.Stdout, os.Stderr, false, true), 330 &Config{ 331 Bin: "git", 332 WorkingDir: filepath.Join(testRepoRoot, testName), 333 Template: filepath.Join(cwd, "testdata", testName+".md"), 334 Info: &Info{ 335 Title: "CHANGELOG Example", 336 RepositoryURL: "https://github.com/git-chglog/git-chglog", 337 }, 338 Options: &Options{ 339 Sort: "date", 340 NextTag: "3.0.0", 341 CommitFilters: map[string][]string{ 342 "Type": { 343 "feat", 344 }, 345 }, 346 CommitSortBy: "Scope", 347 CommitGroupBy: "Type", 348 CommitGroupSortBy: "Title", 349 CommitGroupTitleMaps: map[string]string{ 350 "feat": "Features", 351 }, 352 HeaderPattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:\\s(.*)$", 353 HeaderPatternMaps: []string{ 354 "Type", 355 "Scope", 356 "Subject", 357 }, 358 }, 359 }) 360 361 buf := &bytes.Buffer{} 362 err := gen.Generate(buf, "") 363 expected := strings.TrimSpace(buf.String()) 364 365 assert.Nil(err) 366 assert.Equal(`<a name="unreleased"></a> 367 ## [Unreleased] 368 369 370 <a name="3.0.0"></a> 371 ## [3.0.0] - 2018-03-01 372 ### Features 373 - **core:** version 3.0.0 374 375 376 <a name="2.0.0"></a> 377 ## [2.0.0] - 2018-02-01 378 ### Features 379 - **core:** version 2.0.0 380 381 382 <a name="1.0.0"></a> 383 ## 1.0.0 - 2018-01-01 384 ### Features 385 - **core:** version 1.0.0 386 387 388 [Unreleased]: https://github.com/git-chglog/git-chglog/compare/3.0.0...HEAD 389 [3.0.0]: https://github.com/git-chglog/git-chglog/compare/2.0.0...3.0.0 390 [2.0.0]: https://github.com/git-chglog/git-chglog/compare/1.0.0...2.0.0`, expected) 391 392 buf = &bytes.Buffer{} 393 err = gen.Generate(buf, "3.0.0") 394 expected = strings.TrimSpace(buf.String()) 395 396 assert.Nil(err) 397 assert.Equal(`<a name="unreleased"></a> 398 ## [Unreleased] 399 400 401 <a name="3.0.0"></a> 402 ## [3.0.0] - 2018-03-01 403 ### Features 404 - **core:** version 3.0.0 405 406 407 [Unreleased]: https://github.com/git-chglog/git-chglog/compare/3.0.0...HEAD 408 [3.0.0]: https://github.com/git-chglog/git-chglog/compare/2.0.0...3.0.0`, expected) 409 } 410 411 func TestGeneratorWithTagFiler(t *testing.T) { 412 assert := assert.New(t) 413 testName := "type_scope_subject" 414 415 setup(testName, func(commit commitFunc, tag tagFunc, _ gitcmd.Client) { 416 commit("2018-01-01 00:00:00", "feat(core): version dev-1.0.0", "") 417 tag("dev-1.0.0") 418 419 commit("2018-02-01 00:00:00", "feat(core): version v1.0.0", "") 420 tag("v1.0.0") 421 }) 422 423 gen := NewGenerator(NewLogger(os.Stdout, os.Stderr, false, true), 424 &Config{ 425 Bin: "git", 426 WorkingDir: filepath.Join(testRepoRoot, testName), 427 Template: filepath.Join(cwd, "testdata", testName+".md"), 428 Info: &Info{ 429 Title: "CHANGELOG Example", 430 RepositoryURL: "https://github.com/git-chglog/git-chglog", 431 }, 432 Options: &Options{ 433 TagFilterPattern: "^v", 434 CommitFilters: map[string][]string{ 435 "Type": { 436 "feat", 437 }, 438 }, 439 CommitSortBy: "Scope", 440 CommitGroupBy: "Type", 441 CommitGroupSortBy: "Title", 442 CommitGroupTitleMaps: map[string]string{ 443 "feat": "Features", 444 }, 445 HeaderPattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:\\s(.*)$", 446 HeaderPatternMaps: []string{ 447 "Type", 448 "Scope", 449 "Subject", 450 }, 451 }, 452 }) 453 454 buf := &bytes.Buffer{} 455 err := gen.Generate(buf, "") 456 expected := strings.TrimSpace(buf.String()) 457 458 assert.Nil(err) 459 assert.Equal(`<a name="unreleased"></a> 460 ## [Unreleased] 461 462 463 <a name="v1.0.0"></a> 464 ## v1.0.0 - 2018-02-01 465 ### Features 466 - **core:** version v1.0.0 467 - **core:** version dev-1.0.0 468 469 470 [Unreleased]: https://github.com/git-chglog/git-chglog/compare/v1.0.0...HEAD`, expected) 471 472 } 473 474 func TestGeneratorWithTrimmedBody(t *testing.T) { 475 assert := assert.New(t) 476 testName := "trimmed_body" 477 478 setup(testName, func(commit commitFunc, tag tagFunc, _ gitcmd.Client) { 479 commit("2018-01-01 00:00:00", "feat: single line commit", "") 480 commit("2018-01-01 00:01:00", "feat: multi-line commit", ` 481 More details about the change and why it went in. 482 483 BREAKING CHANGE: 484 485 When using .TrimmedBody Notes are not included and can only appear in the Notes section. 486 487 Signed-off-by: First Last <first.last@mail.com> 488 489 Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>`) 490 491 commit("2018-01-01 00:00:00", "feat: another single line commit", "") 492 tag("1.0.0") 493 }) 494 495 gen := NewGenerator(NewLogger(os.Stdout, os.Stderr, false, true), 496 &Config{ 497 Bin: "git", 498 WorkingDir: filepath.Join(testRepoRoot, testName), 499 Template: filepath.Join(cwd, "testdata", testName+".md"), 500 Info: &Info{ 501 Title: "CHANGELOG Example", 502 RepositoryURL: "https://github.com/git-chglog/git-chglog", 503 }, 504 Options: &Options{ 505 CommitFilters: map[string][]string{ 506 "Type": { 507 "feat", 508 }, 509 }, 510 CommitSortBy: "Scope", 511 CommitGroupBy: "Type", 512 CommitGroupSortBy: "Title", 513 CommitGroupTitleMaps: map[string]string{ 514 "feat": "Features", 515 }, 516 HeaderPattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:\\s(.*)$", 517 HeaderPatternMaps: []string{ 518 "Type", 519 "Scope", 520 "Subject", 521 }, 522 NoteKeywords: []string{ 523 "BREAKING CHANGE", 524 }, 525 }, 526 }) 527 528 buf := &bytes.Buffer{} 529 err := gen.Generate(buf, "") 530 expected := strings.TrimSpace(buf.String()) 531 532 assert.Nil(err) 533 assert.Equal(`<a name="unreleased"></a> 534 ## [Unreleased] 535 536 537 <a name="1.0.0"></a> 538 ## 1.0.0 - 2018-01-01 539 ### Features 540 - another single line commit 541 - multi-line commit 542 More details about the change and why it went in. 543 - single line commit 544 545 ### BREAKING CHANGE 546 547 When using .TrimmedBody Notes are not included and can only appear in the Notes section. 548 549 550 [Unreleased]: https://github.com/git-chglog/git-chglog/compare/1.0.0...HEAD`, expected) 551 } 552 553 func TestGeneratorWithSprig(t *testing.T) { 554 assert := assert.New(t) 555 testName := "with_sprig" 556 557 setup(testName, func(commit commitFunc, tag tagFunc, _ gitcmd.Client) { 558 commit("2018-01-01 00:00:00", "feat(core): version 1.0.0", "") 559 tag("1.0.0") 560 561 commit("2018-02-01 00:00:00", "feat(core): version 2.0.0", "") 562 tag("2.0.0") 563 564 commit("2018-03-01 00:00:00", "feat(core): version 3.0.0", "") 565 }) 566 567 gen := NewGenerator(NewLogger(os.Stdout, os.Stderr, false, true), 568 &Config{ 569 Bin: "git", 570 WorkingDir: filepath.Join(testRepoRoot, testName), 571 Template: filepath.Join(cwd, "testdata", testName+".md"), 572 Info: &Info{ 573 Title: "CHANGELOG Example", 574 RepositoryURL: "https://github.com/git-chglog/git-chglog", 575 }, 576 Options: &Options{ 577 Sort: "date", 578 NextTag: "3.0.0", 579 CommitFilters: map[string][]string{ 580 "Type": { 581 "feat", 582 }, 583 }, 584 CommitSortBy: "Scope", 585 CommitGroupBy: "Type", 586 CommitGroupSortBy: "Title", 587 CommitGroupTitleMaps: map[string]string{ 588 "feat": "Features", 589 }, 590 HeaderPattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:\\s(.*)$", 591 HeaderPatternMaps: []string{ 592 "Type", 593 "Scope", 594 "Subject", 595 }, 596 }, 597 }) 598 599 buf := &bytes.Buffer{} 600 err := gen.Generate(buf, "") 601 expected := strings.TrimSpace(buf.String()) 602 603 assert.Nil(err) 604 assert.Equal(`My Changelog 605 <a name="unreleased"></a> 606 ## [Unreleased] 607 608 609 <a name="3.0.0"></a> 610 ## [3.0.0] - 2018-03-01 611 ### Features 612 - **CORE:** version 3.0.0 613 614 615 <a name="2.0.0"></a> 616 ## [2.0.0] - 2018-02-01 617 ### Features 618 - **CORE:** version 2.0.0 619 620 621 <a name="1.0.0"></a> 622 ## 1.0.0 - 2018-01-01 623 ### Features 624 - **CORE:** version 1.0.0 625 626 627 [Unreleased]: https://github.com/git-chglog/git-chglog/compare/3.0.0...HEAD 628 [3.0.0]: https://github.com/git-chglog/git-chglog/compare/2.0.0...3.0.0 629 [2.0.0]: https://github.com/git-chglog/git-chglog/compare/1.0.0...2.0.0`, expected) 630 631 }