github.com/purpleclay/gitz@v0.8.2-0.20240515052600-43f80eea2fe1/gittest/log_test.go (about)

     1  /*
     2  Copyright (c) 2023 Purple Clay
     3  
     4  Permission is hereby granted, free of charge, to any person obtaining a copy
     5  of this software and associated documentation files (the "Software"), to deal
     6  in the Software without restriction, including without limitation the rights
     7  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     8  copies of the Software, and to permit persons to whom the Software is
     9  furnished to do so, subject to the following conditions:
    10  
    11  The above copyright notice and this permission notice shall be included in all
    12  copies or substantial portions of the Software.
    13  
    14  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    15  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    16  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    17  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    18  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    19  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    20  SOFTWARE.
    21  */
    22  
    23  package gittest_test
    24  
    25  import (
    26  	"testing"
    27  
    28  	"github.com/purpleclay/gitz/gittest"
    29  	"github.com/stretchr/testify/assert"
    30  	"github.com/stretchr/testify/require"
    31  )
    32  
    33  func TestParseLog(t *testing.T) {
    34  	log := `(HEAD -> new-feature, origin/new-feature) pass tests
    35  write tests for new feature
    36  (tag: 0.2.0, tag: v1, main, origin/main) feat: improve existing cli documentation
    37  docs: create initial mkdocs material documentation
    38  (tag: 0.1.0) feat: add secondary cli command to support filtering of results
    39  feat: scaffold initial cli and add first command`
    40  
    41  	entries := gittest.ParseLog(log)
    42  
    43  	require.Len(t, entries, 6)
    44  	assert.Equal(t, entries[0].Message, "pass tests")
    45  	assert.Empty(t, entries[0].Tags)
    46  	assert.ElementsMatch(t, []string{"HEAD -> new-feature", "origin/new-feature"}, entries[0].Branches)
    47  	assert.False(t, entries[0].IsTrunk)
    48  	assert.Equal(t, "new-feature", entries[0].HeadPointerRef)
    49  
    50  	assert.Equal(t, entries[1].Message, "write tests for new feature")
    51  	assert.Empty(t, entries[1].Tags)
    52  	assert.Empty(t, entries[1].Branches)
    53  	assert.False(t, entries[1].IsTrunk)
    54  	assert.Empty(t, entries[1].HeadPointerRef)
    55  
    56  	assert.Equal(t, entries[2].Message, "feat: improve existing cli documentation")
    57  	assert.ElementsMatch(t, []string{"0.2.0", "v1"}, entries[2].Tags)
    58  	assert.ElementsMatch(t, []string{"main", "origin/main"}, entries[2].Branches)
    59  	assert.True(t, entries[2].IsTrunk)
    60  	assert.Empty(t, entries[2].HeadPointerRef)
    61  
    62  	assert.Equal(t, entries[3].Message, "docs: create initial mkdocs material documentation")
    63  	assert.Empty(t, entries[3].Branches)
    64  	assert.False(t, entries[3].IsTrunk)
    65  	assert.Empty(t, entries[3].HeadPointerRef)
    66  
    67  	assert.Equal(t, entries[4].Message, "feat: add secondary cli command to support filtering of results")
    68  	assert.ElementsMatch(t, []string{"0.1.0"}, entries[4].Tags)
    69  	assert.Empty(t, entries[4].Branches)
    70  	assert.False(t, entries[4].IsTrunk)
    71  	assert.Empty(t, entries[4].HeadPointerRef)
    72  
    73  	assert.Equal(t, entries[5].Message, "feat: scaffold initial cli and add first command")
    74  	assert.Empty(t, entries[5].Branches)
    75  	assert.False(t, entries[5].IsTrunk)
    76  	assert.Empty(t, entries[5].HeadPointerRef)
    77  }
    78  
    79  func TestParseLogMultiLineMode(t *testing.T) {
    80  	log := `> (tag: 0.1.0, main, origin/main) fix: ensure parsing of multi-line commits is supported
    81  > feat(deps): bump github.com/stretchr/testify from 1.8.1 to 1.8.2
    82  
    83  Signed-off-by: dependabot[bot] <support@github.com>
    84  Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>`
    85  
    86  	entries := gittest.ParseLog(log)
    87  
    88  	require.Len(t, entries, 2)
    89  	assert.Equal(t, "fix: ensure parsing of multi-line commits is supported", entries[0].Message)
    90  	assert.ElementsMatch(t, []string{"0.1.0"}, entries[0].Tags)
    91  	assert.Equal(t, `feat(deps): bump github.com/stretchr/testify from 1.8.1 to 1.8.2
    92  
    93  Signed-off-by: dependabot[bot] <support@github.com>
    94  Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>`, entries[1].Message)
    95  }
    96  
    97  func TestParseLogWithOptionalLeadingHash(t *testing.T) {
    98  	log := `> b0d5429b967b9af0a0805fc2981b4420e10be38d feat: ensure parsing of optional leading hash is supported
    99  > 58d708cb071df97e2561903aadcd4129419e9631 feat: include additional flag in pretty statements`
   100  
   101  	entries := gittest.ParseLog(log)
   102  
   103  	require.Len(t, entries, 2)
   104  	assert.Equal(t, "b0d5429b967b9af0a0805fc2981b4420e10be38d", entries[0].Hash)
   105  	assert.Equal(t, "b0d5429", entries[0].AbbrevHash)
   106  	assert.Equal(t, "58d708cb071df97e2561903aadcd4129419e9631", entries[1].Hash)
   107  	assert.Equal(t, "58d708c", entries[1].AbbrevHash)
   108  }
   109  
   110  func TestParseLogEmpty(t *testing.T) {
   111  	entries := gittest.ParseLog("")
   112  	assert.Empty(t, entries)
   113  }
   114  
   115  func TestParseLogTrimsSpaces(t *testing.T) {
   116  	log := "   feat: testing if leading and trailing spaces are removed   "
   117  
   118  	entries := gittest.ParseLog(log)
   119  
   120  	require.Len(t, entries, 1)
   121  	assert.Equal(t, entries[0].Message, "feat: testing if leading and trailing spaces are removed")
   122  }
   123  
   124  func TestParseLogMalformedLine(t *testing.T) {
   125  	tests := []struct {
   126  		name     string
   127  		log      string
   128  		expected gittest.LogEntry
   129  	}{
   130  		{
   131  			name: "NoClosingParentheses",
   132  			log:  "(tag: 0.1.0, HEAD -> main, main feat: this is a brand new feature",
   133  			expected: gittest.LogEntry{
   134  				Message: "(tag: 0.1.0, HEAD -> main, main feat: this is a brand new feature",
   135  			},
   136  		},
   137  		{
   138  			name: "NoOpeningParentheses",
   139  			log:  "HEAD -> main, main) ci: updated existing github workflow",
   140  			expected: gittest.LogEntry{
   141  				Message: "HEAD -> main, main) ci: updated existing github workflow",
   142  			},
   143  		},
   144  		{
   145  			name: "MismatchedParentheses",
   146  			log:  "(tag: 0.2.0, HEAD -> main, main, new-feature)docs: include tests (and regressions) in guide",
   147  			expected: gittest.LogEntry{
   148  				Message:  "in guide",
   149  				Tags:     []string{"0.2.0"},
   150  				Branches: []string{"HEAD -> main", "main", "new-feature)docs: include tests (and regressions"},
   151  			},
   152  		},
   153  		{
   154  			name: "EmptyRefNames",
   155  			log:  "() chore: add new issue template",
   156  			expected: gittest.LogEntry{
   157  				Message: "chore: add new issue template",
   158  			},
   159  		},
   160  	}
   161  	for _, tt := range tests {
   162  		t.Run(tt.name, func(t *testing.T) {
   163  			entries := gittest.ParseLog(tt.log)
   164  
   165  			require.Len(t, entries, 1)
   166  			require.Equal(t, tt.expected.Message, entries[0].Message, "commit does not match")
   167  			require.ElementsMatch(t, tt.expected.Tags, entries[0].Tags, "tags slice mismatch")
   168  			require.ElementsMatch(t, tt.expected.Branches, entries[0].Branches, "branches slice mismatch")
   169  		})
   170  	}
   171  }