forked from avelino/awesome-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main_test.go
135 lines (116 loc) · 3.37 KB
/
main_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package main
import (
"bytes"
"github.com/avelino/awesome-go/pkg/markdown"
"os"
"regexp"
"sort"
"strings"
"testing"
"github.com/PuerkitoBio/goquery"
)
var (
reContainsLink = regexp.MustCompile(`\* \[.*\]\(.*\)`)
reOnlyLink = regexp.MustCompile(`\* \[.*\]\([^()]*\)$`)
reLinkWithDescription = regexp.MustCompile(`\* \[.*\]\(.*\) - \S.*[\.\!]`)
)
func requireNoErr(t *testing.T, err error, msg string) {
// FIXME: replace to github.com/stretchr/testify
t.Helper()
if msg == "" {
msg = "unknown error"
}
if err != nil {
t.Fatalf("Received unexpected error [%s]: %+v", msg, err)
}
}
func goqueryFromReadme(t *testing.T) *goquery.Document {
t.Helper()
input, err := os.ReadFile(readmePath)
requireNoErr(t, err, "readme file should be exists")
html, err := markdown.ToHTML(input)
requireNoErr(t, err, "markdown should be rendered to html")
buf := bytes.NewBuffer(html)
doc, err := goquery.NewDocumentFromReader(buf)
requireNoErr(t, err, "html must be valid for goquery")
return doc
}
func TestAlpha(t *testing.T) {
doc := goqueryFromReadme(t)
doc.Find("body > ul").Each(func(i int, s *goquery.Selection) {
if i != 0 {
// skip content menu
// TODO: the sub items (with 3 hash marks `###`) are staying in
// the main list, not respecting the hierarchy and making it
// impossible to test the alphabetical order
testList(t, s)
}
})
}
func TestDuplicatedLinks(t *testing.T) {
doc := goqueryFromReadme(t)
links := make(map[string]bool, 0)
doc.Find("body li > a:first-child").Each(func(_ int, s *goquery.Selection) {
t.Run(s.Text(), func(t *testing.T) {
href, ok := s.Attr("href")
if !ok {
t.Error("expected to have href")
}
if links[href] {
t.Fatalf("duplicated link '%s'", href)
}
links[href] = true
})
})
}
// Test if an entry has description, it must be separated from link with ` - `
func TestSeparator(t *testing.T) {
var matched, containsLink, noDescription bool
input, err := os.ReadFile(readmePath)
requireNoErr(t, err, "readme should be exists")
lines := strings.Split(string(input), "\n")
for _, line := range lines {
line = strings.Trim(line, " ")
containsLink = reContainsLink.MatchString(line)
if containsLink {
noDescription = reOnlyLink.MatchString(line)
if noDescription {
continue
}
matched = reLinkWithDescription.MatchString(line)
if !matched {
t.Errorf("expected entry to be in form of `* [link] - description.`, got '%s'", line)
}
}
}
}
func TestRenderIndex(t *testing.T) {
requireNoErr(t, mkdirAll(outDir), "output dir should exists")
err := renderIndex(readmePath, outIndexFile)
requireNoErr(t, err, "html should be rendered")
}
func testList(t *testing.T, list *goquery.Selection) {
list.Find("ul").Each(func(_ int, items *goquery.Selection) {
testList(t, items)
items.RemoveFiltered("ul")
})
t.Run(list.Prev().Text(), func(t *testing.T) {
checkAlphabeticOrder(t, list)
})
}
func checkAlphabeticOrder(t *testing.T, s *goquery.Selection) {
items := s.Find("li > a:first-child").Map(func(_ int, li *goquery.Selection) string {
return strings.ToLower(li.Text())
})
sorted := make([]string, len(items))
copy(sorted, items)
sort.Strings(sorted)
for k, item := range items {
if item != sorted[k] {
t.Errorf("expected '%s' but actual is '%s'", sorted[k], item)
}
}
if t.Failed() {
t.Logf("expected order is:\n%s", strings.Join(sorted, "\n"))
}
}