gitech

Форк
0
/
references_test.go 
560 строк · 15.0 Кб
1
// Copyright 2019 The Gitea Authors. All rights reserved.
2
// SPDX-License-Identifier: MIT
3

4
package references
5

6
import (
7
	"regexp"
8
	"testing"
9

10
	"code.gitea.io/gitea/modules/setting"
11

12
	"github.com/stretchr/testify/assert"
13
)
14

15
type testFixture struct {
16
	input    string
17
	expected []testResult
18
}
19

20
type testResult struct {
21
	Index          int64
22
	Owner          string
23
	Name           string
24
	Issue          string
25
	IsPull         bool
26
	Action         XRefAction
27
	RefLocation    *RefSpan
28
	ActionLocation *RefSpan
29
	TimeLog        string
30
}
31

32
func TestConvertFullHTMLReferencesToShortRefs(t *testing.T) {
33
	re := regexp.MustCompile(`(\s|^|\(|\[)` +
34
		regexp.QuoteMeta("https://ourgitea.com/git/") +
35
		`([0-9a-zA-Z-_\.]+/[0-9a-zA-Z-_\.]+)/` +
36
		`((?:issues)|(?:pulls))/([0-9]+)(?:\s|$|\)|\]|[:;,.?!]\s|[:;,.?!]$)`)
37
	test := `this is a https://ourgitea.com/git/owner/repo/issues/123456789, foo
38
https://ourgitea.com/git/owner/repo/pulls/123456789
39
  And https://ourgitea.com/git/owner/repo/pulls/123
40
`
41
	expect := `this is a owner/repo#123456789, foo
42
owner/repo!123456789
43
  And owner/repo!123
44
`
45

46
	contentBytes := []byte(test)
47
	convertFullHTMLReferencesToShortRefs(re, &contentBytes)
48
	result := string(contentBytes)
49
	assert.EqualValues(t, expect, result)
50
}
51

52
func TestFindAllIssueReferences(t *testing.T) {
53
	fixtures := []testFixture{
54
		{
55
			"Simply closes: #29 yes",
56
			[]testResult{
57
				{29, "", "", "29", false, XRefActionCloses, &RefSpan{Start: 15, End: 18}, &RefSpan{Start: 7, End: 13}, ""},
58
			},
59
		},
60
		{
61
			"Simply closes: !29 yes",
62
			[]testResult{
63
				{29, "", "", "29", true, XRefActionCloses, &RefSpan{Start: 15, End: 18}, &RefSpan{Start: 7, End: 13}, ""},
64
			},
65
		},
66
		{
67
			" #124 yes, this is a reference.",
68
			[]testResult{
69
				{124, "", "", "124", false, XRefActionNone, &RefSpan{Start: 0, End: 4}, nil, ""},
70
			},
71
		},
72
		{
73
			"```\nThis is a code block.\n#723 no, it's a code block.```",
74
			[]testResult{},
75
		},
76
		{
77
			"This `#724` no, it's inline code.",
78
			[]testResult{},
79
		},
80
		{
81
			"This org3/repo4#200 yes.",
82
			[]testResult{
83
				{200, "org3", "repo4", "200", false, XRefActionNone, &RefSpan{Start: 5, End: 19}, nil, ""},
84
			},
85
		},
86
		{
87
			"This org3/repo4!200 yes.",
88
			[]testResult{
89
				{200, "org3", "repo4", "200", true, XRefActionNone, &RefSpan{Start: 5, End: 19}, nil, ""},
90
			},
91
		},
92
		{
93
			"This [one](#919) no, this is a URL fragment.",
94
			[]testResult{},
95
		},
96
		{
97
			"This [two](/user2/repo1/issues/921) yes.",
98
			[]testResult{
99
				{921, "user2", "repo1", "921", false, XRefActionNone, nil, nil, ""},
100
			},
101
		},
102
		{
103
			"This [three](/user2/repo1/pulls/922) yes.",
104
			[]testResult{
105
				{922, "user2", "repo1", "922", true, XRefActionNone, nil, nil, ""},
106
			},
107
		},
108
		{
109
			"This [four](http://gitea.com:3000/org3/repo4/issues/203) yes.",
110
			[]testResult{
111
				{203, "org3", "repo4", "203", false, XRefActionNone, nil, nil, ""},
112
			},
113
		},
114
		{
115
			"This [five](http://github.com/org3/repo4/issues/204) no.",
116
			[]testResult{},
117
		},
118
		{
119
			"This http://gitea.com:3000/user4/repo5/201 no, bad URL.",
120
			[]testResult{},
121
		},
122
		{
123
			"This http://gitea.com:3000/user4/repo5/pulls/202 yes.",
124
			[]testResult{
125
				{202, "user4", "repo5", "202", true, XRefActionNone, nil, nil, ""},
126
			},
127
		},
128
		{
129
			"This http://gitea.com:3000/user4/repo5/pulls/202 yes. http://gitea.com:3000/user4/repo5/pulls/203 no",
130
			[]testResult{
131
				{202, "user4", "repo5", "202", true, XRefActionNone, nil, nil, ""},
132
				{203, "user4", "repo5", "203", true, XRefActionNone, nil, nil, ""},
133
			},
134
		},
135
		{
136
			"This http://GiTeA.COM:3000/user4/repo6/pulls/205 yes.",
137
			[]testResult{
138
				{205, "user4", "repo6", "205", true, XRefActionNone, nil, nil, ""},
139
			},
140
		},
141
		{
142
			"Reopens #15 yes",
143
			[]testResult{
144
				{15, "", "", "15", false, XRefActionReopens, &RefSpan{Start: 8, End: 11}, &RefSpan{Start: 0, End: 7}, ""},
145
			},
146
		},
147
		{
148
			"This closes #20 for you yes",
149
			[]testResult{
150
				{20, "", "", "20", false, XRefActionCloses, &RefSpan{Start: 12, End: 15}, &RefSpan{Start: 5, End: 11}, ""},
151
			},
152
		},
153
		{
154
			"Do you fix org6/repo6#300 ? yes",
155
			[]testResult{
156
				{300, "org6", "repo6", "300", false, XRefActionCloses, &RefSpan{Start: 11, End: 25}, &RefSpan{Start: 7, End: 10}, ""},
157
			},
158
		},
159
		{
160
			"For 999 #1235 no keyword, but yes",
161
			[]testResult{
162
				{1235, "", "", "1235", false, XRefActionNone, &RefSpan{Start: 8, End: 13}, nil, ""},
163
			},
164
		},
165
		{
166
			"For [!123] yes",
167
			[]testResult{
168
				{123, "", "", "123", true, XRefActionNone, &RefSpan{Start: 5, End: 9}, nil, ""},
169
			},
170
		},
171
		{
172
			"For (#345) yes",
173
			[]testResult{
174
				{345, "", "", "345", false, XRefActionNone, &RefSpan{Start: 5, End: 9}, nil, ""},
175
			},
176
		},
177
		{
178
			"For #22,#23 no, neither #28:#29 or !30!31#32;33 should",
179
			[]testResult{},
180
		},
181
		{
182
			"For #24, and #25. yes; also #26; #27? #28! and #29: should",
183
			[]testResult{
184
				{24, "", "", "24", false, XRefActionNone, &RefSpan{Start: 4, End: 7}, nil, ""},
185
				{25, "", "", "25", false, XRefActionNone, &RefSpan{Start: 13, End: 16}, nil, ""},
186
				{26, "", "", "26", false, XRefActionNone, &RefSpan{Start: 28, End: 31}, nil, ""},
187
				{27, "", "", "27", false, XRefActionNone, &RefSpan{Start: 33, End: 36}, nil, ""},
188
				{28, "", "", "28", false, XRefActionNone, &RefSpan{Start: 38, End: 41}, nil, ""},
189
				{29, "", "", "29", false, XRefActionNone, &RefSpan{Start: 47, End: 50}, nil, ""},
190
			},
191
		},
192
		{
193
			"This org3/repo4#200, yes.",
194
			[]testResult{
195
				{200, "org3", "repo4", "200", false, XRefActionNone, &RefSpan{Start: 5, End: 19}, nil, ""},
196
			},
197
		},
198
		{
199
			"Merge pull request '#12345 My fix for a bug' (!1337) from feature-branch into main",
200
			[]testResult{
201
				{12345, "", "", "12345", false, XRefActionNone, &RefSpan{Start: 20, End: 26}, nil, ""},
202
				{1337, "", "", "1337", true, XRefActionNone, &RefSpan{Start: 46, End: 51}, nil, ""},
203
			},
204
		},
205
		{
206
			"Which abc. #9434 same as above",
207
			[]testResult{
208
				{9434, "", "", "9434", false, XRefActionNone, &RefSpan{Start: 11, End: 16}, nil, ""},
209
			},
210
		},
211
		{
212
			"This closes #600 and reopens #599",
213
			[]testResult{
214
				{600, "", "", "600", false, XRefActionCloses, &RefSpan{Start: 12, End: 16}, &RefSpan{Start: 5, End: 11}, ""},
215
				{599, "", "", "599", false, XRefActionReopens, &RefSpan{Start: 29, End: 33}, &RefSpan{Start: 21, End: 28}, ""},
216
			},
217
		},
218
		{
219
			"This fixes #100 spent @40m and reopens #101, also fixes #102 spent @4h15m",
220
			[]testResult{
221
				{100, "", "", "100", false, XRefActionCloses, &RefSpan{Start: 11, End: 15}, &RefSpan{Start: 5, End: 10}, "40m"},
222
				{101, "", "", "101", false, XRefActionReopens, &RefSpan{Start: 39, End: 43}, &RefSpan{Start: 31, End: 38}, ""},
223
				{102, "", "", "102", false, XRefActionCloses, &RefSpan{Start: 56, End: 60}, &RefSpan{Start: 50, End: 55}, "4h15m"},
224
			},
225
		},
226
	}
227

228
	testFixtures(t, fixtures, "default")
229

230
	type alnumFixture struct {
231
		input          string
232
		issue          string
233
		refLocation    *RefSpan
234
		action         XRefAction
235
		actionLocation *RefSpan
236
	}
237

238
	alnumFixtures := []alnumFixture{
239
		{
240
			"This ref ABC-123 is alphanumeric",
241
			"ABC-123", &RefSpan{Start: 9, End: 16},
242
			XRefActionNone, nil,
243
		},
244
		{
245
			"This closes ABCD-1234 alphanumeric",
246
			"ABCD-1234", &RefSpan{Start: 12, End: 21},
247
			XRefActionCloses, &RefSpan{Start: 5, End: 11},
248
		},
249
	}
250

251
	for _, fixture := range alnumFixtures {
252
		found, ref := FindRenderizableReferenceAlphanumeric(fixture.input)
253
		if fixture.issue == "" {
254
			assert.False(t, found, "Failed to parse: {%s}", fixture.input)
255
		} else {
256
			assert.True(t, found, "Failed to parse: {%s}", fixture.input)
257
			assert.Equal(t, fixture.issue, ref.Issue, "Failed to parse: {%s}", fixture.input)
258
			assert.Equal(t, fixture.refLocation, ref.RefLocation, "Failed to parse: {%s}", fixture.input)
259
			assert.Equal(t, fixture.action, ref.Action, "Failed to parse: {%s}", fixture.input)
260
			assert.Equal(t, fixture.actionLocation, ref.ActionLocation, "Failed to parse: {%s}", fixture.input)
261
		}
262
	}
263
}
264

265
func testFixtures(t *testing.T, fixtures []testFixture, context string) {
266
	// Save original value for other tests that may rely on it
267
	prevURL := setting.AppURL
268
	setting.AppURL = "https://gitea.com:3000/"
269

270
	for _, fixture := range fixtures {
271
		expraw := make([]*rawReference, len(fixture.expected))
272
		for i, e := range fixture.expected {
273
			expraw[i] = &rawReference{
274
				index:          e.Index,
275
				owner:          e.Owner,
276
				name:           e.Name,
277
				isPull:         e.IsPull,
278
				action:         e.Action,
279
				issue:          e.Issue,
280
				refLocation:    e.RefLocation,
281
				actionLocation: e.ActionLocation,
282
				timeLog:        e.TimeLog,
283
			}
284
		}
285
		expref := rawToIssueReferenceList(expraw)
286
		refs := FindAllIssueReferencesMarkdown(fixture.input)
287
		assert.EqualValues(t, expref, refs, "[%s] Failed to parse: {%s}", context, fixture.input)
288
		rawrefs := findAllIssueReferencesMarkdown(fixture.input)
289
		assert.EqualValues(t, expraw, rawrefs, "[%s] Failed to parse: {%s}", context, fixture.input)
290
	}
291

292
	// Restore for other tests that may rely on the original value
293
	setting.AppURL = prevURL
294
}
295

296
func TestFindAllMentions(t *testing.T) {
297
	res := FindAllMentionsBytes([]byte("@tasha, @mike; @lucy: @john"))
298
	assert.EqualValues(t, []RefSpan{
299
		{Start: 0, End: 6},
300
		{Start: 8, End: 13},
301
		{Start: 15, End: 20},
302
		{Start: 22, End: 27},
303
	}, res)
304
}
305

306
func TestFindRenderizableCommitCrossReference(t *testing.T) {
307
	cases := []struct {
308
		Input    string
309
		Expected *RenderizableReference
310
	}{
311
		{
312
			Input:    "",
313
			Expected: nil,
314
		},
315
		{
316
			Input:    "test",
317
			Expected: nil,
318
		},
319
		{
320
			Input:    "go-gitea/gitea@test",
321
			Expected: nil,
322
		},
323
		{
324
			Input:    "go-gitea/gitea@ab1234",
325
			Expected: nil,
326
		},
327
		{
328
			Input: "go-gitea/gitea@abcd1234",
329
			Expected: &RenderizableReference{
330
				Owner:       "go-gitea",
331
				Name:        "gitea",
332
				CommitSha:   "abcd1234",
333
				RefLocation: &RefSpan{Start: 0, End: 23},
334
			},
335
		},
336
		{
337
			Input: "go-gitea/gitea@abcd1234abcd1234abcd1234abcd1234abcd1234",
338
			Expected: &RenderizableReference{
339
				Owner:       "go-gitea",
340
				Name:        "gitea",
341
				CommitSha:   "abcd1234abcd1234abcd1234abcd1234abcd1234",
342
				RefLocation: &RefSpan{Start: 0, End: 55},
343
			},
344
		},
345
		{
346
			Input:    "go-gitea/gitea@abcd1234abcd1234abcd1234abcd1234abcd12341234512345123451234512345", // longer than 64 characters
347
			Expected: nil,
348
		},
349
		{
350
			Input: "test go-gitea/gitea@abcd1234 test",
351
			Expected: &RenderizableReference{
352
				Owner:       "go-gitea",
353
				Name:        "gitea",
354
				CommitSha:   "abcd1234",
355
				RefLocation: &RefSpan{Start: 5, End: 28},
356
			},
357
		},
358
	}
359

360
	for _, c := range cases {
361
		found, ref := FindRenderizableCommitCrossReference(c.Input)
362
		assert.Equal(t, ref != nil, found)
363
		assert.Equal(t, c.Expected, ref)
364
	}
365
}
366

367
func TestRegExp_mentionPattern(t *testing.T) {
368
	trueTestCases := []struct {
369
		pat string
370
		exp string
371
	}{
372
		{"@User", "@User"},
373
		{"@ANT_123", "@ANT_123"},
374
		{"@xxx-DiN0-z-A..uru..s-xxx", "@xxx-DiN0-z-A..uru..s-xxx"},
375
		{"   @lol   ", "@lol"},
376
		{" @Te-st", "@Te-st"},
377
		{"(@gitea)", "@gitea"},
378
		{"[@gitea]", "@gitea"},
379
		{"@gitea! this", "@gitea"},
380
		{"@gitea? this", "@gitea"},
381
		{"@gitea. this", "@gitea"},
382
		{"@gitea, this", "@gitea"},
383
		{"@gitea; this", "@gitea"},
384
		{"@gitea!\nthis", "@gitea"},
385
		{"\n@gitea?\nthis", "@gitea"},
386
		{"\t@gitea.\nthis", "@gitea"},
387
		{"@gitea,\nthis", "@gitea"},
388
		{"@gitea;\nthis", "@gitea"},
389
		{"@gitea!", "@gitea"},
390
		{"@gitea?", "@gitea"},
391
		{"@gitea.", "@gitea"},
392
		{"@gitea,", "@gitea"},
393
		{"@gitea;", "@gitea"},
394
		{"@gitea/team1;", "@gitea/team1"},
395
	}
396
	falseTestCases := []string{
397
		"@ 0",
398
		"@ ",
399
		"@",
400
		"",
401
		"ABC",
402
		"@.ABC",
403
		"/home/gitea/@gitea",
404
		"\"@gitea\"",
405
		"@@gitea",
406
		"@gitea!this",
407
		"@gitea?this",
408
		"@gitea,this",
409
		"@gitea;this",
410
		"@gitea/team1/more",
411
	}
412

413
	for _, testCase := range trueTestCases {
414
		found := mentionPattern.FindStringSubmatch(testCase.pat)
415
		assert.Len(t, found, 2)
416
		assert.Equal(t, testCase.exp, found[1])
417
	}
418
	for _, testCase := range falseTestCases {
419
		res := mentionPattern.MatchString(testCase)
420
		assert.False(t, res, "[%s] should be false", testCase)
421
	}
422
}
423

424
func TestRegExp_issueNumericPattern(t *testing.T) {
425
	trueTestCases := []string{
426
		"#1234",
427
		"#0",
428
		"#1234567890987654321",
429
		"  #12",
430
		"#12:",
431
		"ref: #12: msg",
432
		"\"#1234\"",
433
		"'#1234'",
434
	}
435
	falseTestCases := []string{
436
		"# 1234",
437
		"# 0",
438
		"# ",
439
		"#",
440
		"#ABC",
441
		"#1A2B",
442
		"",
443
		"ABC",
444
	}
445

446
	for _, testCase := range trueTestCases {
447
		assert.True(t, issueNumericPattern.MatchString(testCase))
448
	}
449
	for _, testCase := range falseTestCases {
450
		assert.False(t, issueNumericPattern.MatchString(testCase))
451
	}
452
}
453

454
func TestRegExp_issueAlphanumericPattern(t *testing.T) {
455
	trueTestCases := []string{
456
		"ABC-1234",
457
		"A-1",
458
		"RC-80",
459
		"ABCDEFGHIJ-1234567890987654321234567890",
460
		"ABC-123.",
461
		"(ABC-123)",
462
		"[ABC-123]",
463
		"ABC-123:",
464
		"\"ABC-123\"",
465
		"'ABC-123'",
466
	}
467
	falseTestCases := []string{
468
		"RC-08",
469
		"PR-0",
470
		"ABCDEFGHIJK-1",
471
		"PR_1",
472
		"",
473
		"#ABC",
474
		"",
475
		"ABC",
476
		"GG-",
477
		"rm-1",
478
		"/home/gitea/ABC-1234",
479
		"MY-STRING-ABC-123",
480
	}
481

482
	for _, testCase := range trueTestCases {
483
		assert.True(t, issueAlphanumericPattern.MatchString(testCase))
484
	}
485
	for _, testCase := range falseTestCases {
486
		assert.False(t, issueAlphanumericPattern.MatchString(testCase))
487
	}
488
}
489

490
func TestCustomizeCloseKeywords(t *testing.T) {
491
	fixtures := []testFixture{
492
		{
493
			"Simplemente cierra: #29 yes",
494
			[]testResult{
495
				{29, "", "", "29", false, XRefActionCloses, &RefSpan{Start: 20, End: 23}, &RefSpan{Start: 12, End: 18}, ""},
496
			},
497
		},
498
		{
499
			"Closes: #123 no, this English.",
500
			[]testResult{
501
				{123, "", "", "123", false, XRefActionNone, &RefSpan{Start: 8, End: 12}, nil, ""},
502
			},
503
		},
504
		{
505
			"Cerró org6/repo6#300 yes",
506
			[]testResult{
507
				{300, "org6", "repo6", "300", false, XRefActionCloses, &RefSpan{Start: 7, End: 21}, &RefSpan{Start: 0, End: 6}, ""},
508
			},
509
		},
510
		{
511
			"Reabre org3/repo4#200 yes",
512
			[]testResult{
513
				{200, "org3", "repo4", "200", false, XRefActionReopens, &RefSpan{Start: 7, End: 21}, &RefSpan{Start: 0, End: 6}, ""},
514
			},
515
		},
516
	}
517

518
	issueKeywordsOnce.Do(func() {})
519

520
	doNewKeywords([]string{"cierra", "cerró"}, []string{"reabre"})
521
	testFixtures(t, fixtures, "spanish")
522

523
	// Restore default settings
524
	doNewKeywords(setting.Repository.PullRequest.CloseKeywords, setting.Repository.PullRequest.ReopenKeywords)
525
}
526

527
func TestParseCloseKeywords(t *testing.T) {
528
	// Test parsing of CloseKeywords and ReopenKeywords
529
	assert.Len(t, parseKeywords([]string{""}), 0)
530
	assert.Len(t, parseKeywords([]string{"  aa  ", " bb  ", "99", "#", "", "this is", "cc"}), 3)
531

532
	for _, test := range []struct {
533
		pattern  string
534
		match    string
535
		expected string
536
	}{
537
		{"close", "This PR will close ", "close"},
538
		{"cerró", "cerró ", "cerró"},
539
		{"cerró", "AQUÍ SE CERRÓ: ", "CERRÓ"},
540
		{"закрывается", "закрывается ", "закрывается"},
541
		{"κλείνει", "κλείνει: ", "κλείνει"},
542
		{"关闭", "关闭 ", "关闭"},
543
		{"閉じます", "閉じます ", "閉じます"},
544
		{",$!", "", ""},
545
		{"1234", "", ""},
546
	} {
547
		// The pattern only needs to match the part that precedes the reference.
548
		// getCrossReference() takes care of finding the reference itself.
549
		pat := makeKeywordsPat([]string{test.pattern})
550
		if test.expected == "" {
551
			assert.Nil(t, pat)
552
		} else {
553
			assert.NotNil(t, pat)
554
			res := pat.FindAllStringSubmatch(test.match, -1)
555
			assert.Len(t, res, 1)
556
			assert.Len(t, res[0], 2)
557
			assert.EqualValues(t, test.expected, res[0][1])
558
		}
559
	}
560
}
561

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.