...

Source file src/github.com/cli/go-gh/v2/internal/git/url_test.go

Documentation: github.com/cli/go-gh/v2/internal/git

     1  package git
     2  
     3  import (
     4  	"net/url"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  )
     9  
    10  func TestIsURL(t *testing.T) {
    11  	tests := []struct {
    12  		name string
    13  		url  string
    14  		want bool
    15  	}{
    16  		{
    17  			name: "scp-like",
    18  			url:  "git@example.com:owner/repo",
    19  			want: true,
    20  		},
    21  		{
    22  			name: "scp-like with no user",
    23  			url:  "example.com:owner/repo",
    24  			want: false,
    25  		},
    26  		{
    27  			name: "ssh",
    28  			url:  "ssh://git@example.com/owner/repo",
    29  			want: true,
    30  		},
    31  		{
    32  			name: "git",
    33  			url:  "git://example.com/owner/repo",
    34  			want: true,
    35  		},
    36  		{
    37  			name: "git with extension",
    38  			url:  "git://example.com/owner/repo.git",
    39  			want: true,
    40  		},
    41  		{
    42  			name: "git+ssh",
    43  			url:  "git+ssh://git@example.com/owner/repo.git",
    44  			want: true,
    45  		},
    46  		{
    47  			name: "git+https",
    48  			url:  "git+https://example.com/owner/repo.git",
    49  			want: true,
    50  		},
    51  		{
    52  			name: "http",
    53  			url:  "http://example.com/owner/repo.git",
    54  			want: true,
    55  		},
    56  		{
    57  			name: "https",
    58  			url:  "https://example.com/owner/repo.git",
    59  			want: true,
    60  		},
    61  		{
    62  			name: "no protocol",
    63  			url:  "example.com/owner/repo",
    64  			want: false,
    65  		},
    66  	}
    67  	for _, tt := range tests {
    68  		t.Run(tt.name, func(t *testing.T) {
    69  			assert.Equal(t, tt.want, IsURL(tt.url))
    70  		})
    71  	}
    72  }
    73  
    74  func TestParseURL(t *testing.T) {
    75  	type url struct {
    76  		Scheme string
    77  		User   string
    78  		Host   string
    79  		Path   string
    80  	}
    81  
    82  	tests := []struct {
    83  		name    string
    84  		url     string
    85  		want    url
    86  		wantErr bool
    87  	}{
    88  		{
    89  			name: "HTTPS",
    90  			url:  "https://example.com/owner/repo.git",
    91  			want: url{
    92  				Scheme: "https",
    93  				User:   "",
    94  				Host:   "example.com",
    95  				Path:   "/owner/repo.git",
    96  			},
    97  		},
    98  		{
    99  			name: "HTTP",
   100  			url:  "http://example.com/owner/repo.git",
   101  			want: url{
   102  				Scheme: "http",
   103  				User:   "",
   104  				Host:   "example.com",
   105  				Path:   "/owner/repo.git",
   106  			},
   107  		},
   108  		{
   109  			name: "git",
   110  			url:  "git://example.com/owner/repo.git",
   111  			want: url{
   112  				Scheme: "git",
   113  				User:   "",
   114  				Host:   "example.com",
   115  				Path:   "/owner/repo.git",
   116  			},
   117  		},
   118  		{
   119  			name: "ssh",
   120  			url:  "ssh://git@example.com/owner/repo.git",
   121  			want: url{
   122  				Scheme: "ssh",
   123  				User:   "git",
   124  				Host:   "example.com",
   125  				Path:   "/owner/repo.git",
   126  			},
   127  		},
   128  		{
   129  			name: "ssh with port",
   130  			url:  "ssh://git@example.com:443/owner/repo.git",
   131  			want: url{
   132  				Scheme: "ssh",
   133  				User:   "git",
   134  				Host:   "example.com",
   135  				Path:   "/owner/repo.git",
   136  			},
   137  		},
   138  		{
   139  			name: "git+ssh",
   140  			url:  "git+ssh://example.com/owner/repo.git",
   141  			want: url{
   142  				Scheme: "ssh",
   143  				User:   "",
   144  				Host:   "example.com",
   145  				Path:   "/owner/repo.git",
   146  			},
   147  		},
   148  		{
   149  			name: "git+https",
   150  			url:  "git+https://example.com/owner/repo.git",
   151  			want: url{
   152  				Scheme: "https",
   153  				User:   "",
   154  				Host:   "example.com",
   155  				Path:   "/owner/repo.git",
   156  			},
   157  		},
   158  		{
   159  			name: "scp-like",
   160  			url:  "git@example.com:owner/repo.git",
   161  			want: url{
   162  				Scheme: "ssh",
   163  				User:   "git",
   164  				Host:   "example.com",
   165  				Path:   "/owner/repo.git",
   166  			},
   167  		},
   168  		{
   169  			name: "scp-like, leading slash",
   170  			url:  "git@example.com:/owner/repo.git",
   171  			want: url{
   172  				Scheme: "ssh",
   173  				User:   "git",
   174  				Host:   "example.com",
   175  				Path:   "/owner/repo.git",
   176  			},
   177  		},
   178  		{
   179  			name: "file protocol",
   180  			url:  "file:///example.com/owner/repo.git",
   181  			want: url{
   182  				Scheme: "file",
   183  				User:   "",
   184  				Host:   "",
   185  				Path:   "/example.com/owner/repo.git",
   186  			},
   187  		},
   188  		{
   189  			name: "file path",
   190  			url:  "/example.com/owner/repo.git",
   191  			want: url{
   192  				Scheme: "",
   193  				User:   "",
   194  				Host:   "",
   195  				Path:   "/example.com/owner/repo.git",
   196  			},
   197  		},
   198  		{
   199  			name: "Windows file path",
   200  			url:  "C:\\example.com\\owner\\repo.git",
   201  			want: url{
   202  				Scheme: "c",
   203  				User:   "",
   204  				Host:   "",
   205  				Path:   "",
   206  			},
   207  		},
   208  	}
   209  	for _, tt := range tests {
   210  		t.Run(tt.name, func(t *testing.T) {
   211  			u, err := ParseURL(tt.url)
   212  			if tt.wantErr {
   213  				assert.Error(t, err)
   214  				return
   215  			}
   216  			assert.NoError(t, err)
   217  			assert.Equal(t, tt.want.Scheme, u.Scheme)
   218  			assert.Equal(t, tt.want.User, u.User.Username())
   219  			assert.Equal(t, tt.want.Host, u.Host)
   220  			assert.Equal(t, tt.want.Path, u.Path)
   221  		})
   222  	}
   223  }
   224  
   225  func TestRepoInfoFromURL(t *testing.T) {
   226  	tests := []struct {
   227  		name       string
   228  		input      string
   229  		wantHost   string
   230  		wantOwner  string
   231  		wantRepo   string
   232  		wantErr    bool
   233  		wantErrMsg string
   234  	}{
   235  		{
   236  			name:      "github.com URL",
   237  			input:     "https://github.com/monalisa/octo-cat.git",
   238  			wantHost:  "github.com",
   239  			wantOwner: "monalisa",
   240  			wantRepo:  "octo-cat",
   241  		},
   242  		{
   243  			name:      "github.com URL with trailing slash",
   244  			input:     "https://github.com/monalisa/octo-cat/",
   245  			wantHost:  "github.com",
   246  			wantOwner: "monalisa",
   247  			wantRepo:  "octo-cat",
   248  		},
   249  		{
   250  			name:      "www.github.com URL",
   251  			input:     "http://www.GITHUB.com/monalisa/octo-cat.git",
   252  			wantHost:  "github.com",
   253  			wantOwner: "monalisa",
   254  			wantRepo:  "octo-cat",
   255  		},
   256  		{
   257  			name:       "too many path components",
   258  			input:      "https://github.com/monalisa/octo-cat/pulls",
   259  			wantErr:    true,
   260  			wantErrMsg: "invalid path: /monalisa/octo-cat/pulls",
   261  		},
   262  		{
   263  			name:      "non-GitHub hostname",
   264  			input:     "https://example.com/one/two",
   265  			wantHost:  "example.com",
   266  			wantOwner: "one",
   267  			wantRepo:  "two",
   268  		},
   269  		{
   270  			name:       "filesystem path",
   271  			input:      "/path/to/file",
   272  			wantErr:    true,
   273  			wantErrMsg: "no hostname detected",
   274  		},
   275  		{
   276  			name:       "filesystem path with scheme",
   277  			input:      "file:///path/to/file",
   278  			wantErr:    true,
   279  			wantErrMsg: "no hostname detected",
   280  		},
   281  		{
   282  			name:      "github.com SSH URL",
   283  			input:     "ssh://github.com/monalisa/octo-cat.git",
   284  			wantHost:  "github.com",
   285  			wantOwner: "monalisa",
   286  			wantRepo:  "octo-cat",
   287  		},
   288  		{
   289  			name:      "github.com HTTPS+SSH URL",
   290  			input:     "https+ssh://github.com/monalisa/octo-cat.git",
   291  			wantHost:  "github.com",
   292  			wantOwner: "monalisa",
   293  			wantRepo:  "octo-cat",
   294  		},
   295  		{
   296  			name:      "github.com git URL",
   297  			input:     "git://github.com/monalisa/octo-cat.git",
   298  			wantHost:  "github.com",
   299  			wantOwner: "monalisa",
   300  			wantRepo:  "octo-cat",
   301  		},
   302  	}
   303  
   304  	for _, tt := range tests {
   305  		t.Run(tt.name, func(t *testing.T) {
   306  			u, err := url.Parse(tt.input)
   307  			assert.NoError(t, err)
   308  			host, owner, repo, err := RepoInfoFromURL(u)
   309  			if tt.wantErr {
   310  				assert.EqualError(t, err, tt.wantErrMsg)
   311  				return
   312  			}
   313  			assert.NoError(t, err)
   314  			assert.Equal(t, tt.wantHost, host)
   315  			assert.Equal(t, tt.wantOwner, owner)
   316  			assert.Equal(t, tt.wantRepo, repo)
   317  		})
   318  	}
   319  }
   320  

View as plain text