Skip to content
This repository has been archived by the owner on May 11, 2022. It is now read-only.

Commit

Permalink
fix #26: improve code coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
kamilsk committed Apr 30, 2018
1 parent 95d0816 commit 24c478d
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 31 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ $ check completion zsh > /path/to/zsh-completions/_check.zsh

## Notes

- brief roadmap
- [ ] v1: MVP
- [ ] v2: check redirects
- [ ] v3: check repository
- [ ] v4: check package
- [ ] v5: distributed run
- [ ] integrate with Status, SaaS
- tested on Go 1.8, 1.9 and 1.10

---
Expand Down
17 changes: 9 additions & 8 deletions http/availability/pkg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,20 +177,21 @@ func (c *chain) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
c.Handler.ServeHTTP(rw, req)
}

type PrinterMock struct {
type CrawlerMock struct {
mock.Mock
shift func(availability.EventBus)
}

func (m *PrinterMock) Sites() <-chan availability.Site {
args := m.Called()
return args.Get(0).(<-chan availability.Site)
func (m *CrawlerMock) Visit(url string, bus availability.EventBus) error {
go m.shift(bus)
return m.Called(url, bus).Error(0)
}

type CrawlerMock struct {
type PrinterMock struct {
mock.Mock
}

func (m *CrawlerMock) Visit(url string, bus availability.EventBus) error {
args := m.Called(url, bus)
return args.Error(0)
func (m *PrinterMock) Sites() <-chan availability.Site {
args := m.Called()
return args.Get(0).(<-chan availability.Site)
}
8 changes: 4 additions & 4 deletions http/availability/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ func (p *Printer) Print() error {
return errors.Simple("nothing to print")
}
for site := range p.report.Sites() {
if err := site.Error(); err != nil {
critical().Fprintf(w, "report %q has error %q\n", site.Name(), err)
if stack := errors.StackTrace(err); stack != nil {
if site.Error != nil {
critical().Fprintf(w, "report %q has error %q\n", site.Name, site.Error)
if stack := errors.StackTrace(site.Error); stack != nil {
critical().Fprintf(ioutil.Discard, "stack trace: %#+v\n", stack) // for future
}
continue
Expand All @@ -83,7 +83,7 @@ func (p *Printer) Print() error {
}
}
if len(site.Problems) > 0 {
critical().Fprintf(w, "found problems on the site %q\n", site.Name())
critical().Fprintf(w, "found problems on the site %q\n", site.Name)
for i, problem := range site.Problems {
critical().Fprintf(w, "- [%d] %s `%+v`\n", i, problem.Message, problem.Context)
}
Expand Down
32 changes: 14 additions & 18 deletions http/availability/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ func (r *Report) Fill() *Report {
wg.Add(1)
go func(site *Site) {
var copied Site
copied.name = site.name
copied.Name = site.Name
defer wg.Done()
defer func() { r.ready <- copied }()
defer errors.Recover(&copied.error)
site.error = site.Fetch(r.crawler)
defer errors.Recover(&copied.Error)
site.Error = site.Fetch(r.crawler)
{
copied = *site
pages := make([]*Page, 0, len(site.Pages))
Expand Down Expand Up @@ -76,32 +76,28 @@ func (r *Report) Sites() <-chan Site {
func NewSite(rawURL string) *Site {
u, err := url.Parse(rawURL)
return &Site{
name: hostOrRawURL(u, rawURL),
url: u,
error: errors.Wrapf(err, "parse rawURL %q for report", rawURL),
Name: hostOrRawURL(u, rawURL),
Error: errors.Wrapf(err, "parse rawURL %q for report", rawURL),
}
}

type Site struct {
name string
url *url.URL
error error
url *url.URL

Name string
Error error
Pages []*Page
Problems []ProblemEvent
}

func (s *Site) Name() string { return s.name }

func (s *Site) Error() error { return s.error }

func (s *Site) Fetch(crawler Crawler) error {
if s.error != nil {
return s.error
if s.Error != nil {
return s.Error
}
if crawler == nil {
s.error = errors.Simple("crawler is not provided")
return s.error
s.Error = errors.Simple("crawler is not provided")
return s.Error
}
var unexpected error
wg, events := &sync.WaitGroup{}, make(chan event, 512)
Expand All @@ -111,12 +107,12 @@ func (s *Site) Fetch(crawler Crawler) error {
defer errors.Recover(&unexpected)
s.listen(events)
}()
s.error = crawler.Visit(s.url.String(), events)
s.Error = crawler.Visit(s.url.String(), events)
wg.Wait()
if unexpected != nil {
panic(unexpected)
}
return s.error
return s.Error
}

func (s *Site) listen(events <-chan event) {
Expand Down
65 changes: 64 additions & 1 deletion http/availability/report_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package availability_test

import (
"net/http"
"testing"

"github.com/kamilsk/check/errors"
"github.com/kamilsk/check/http/availability"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)

func TestReporter(t *testing.T) {
Expand All @@ -24,6 +27,58 @@ func TestReporter(t *testing.T) {
return ch
},
},
{
"bad site",
[]string{":bad"},
func() *availability.Report { return availability.NewReport() },
func() <-chan availability.Site {
ch := make(chan availability.Site, 1)
ch <- *availability.NewSite(":bad")
close(ch)
return ch
},
},
{
"without crawler",
[]string{"http://test.dev/"},
func() *availability.Report { return availability.NewReport() },
func() <-chan availability.Site {
ch := make(chan availability.Site, 1)
site := *availability.NewSite("http://test.dev/")
site.Error = errors.Simple("crawler is not provided")
ch <- site
close(ch)
return ch
},
},
{
"normal case",
[]string{"http://test.dev/"},
func() *availability.Report {
crawler := &CrawlerMock{shift: func(to availability.EventBus) {
to <- availability.ResponseEvent{StatusCode: http.StatusOK, Location: "http://test.dev/"}
to <- availability.WalkEvent{Page: "http://test.dev/", Href: "http://accepted.dev/"}
to <- availability.WalkEvent{Page: "http://test.dev/", Href: "http://redirect.dev/"}
to <- availability.WalkEvent{Page: "http://test.dev/", Href: "http://noaccess.dev/"}
to <- availability.ProblemEvent{Message: "bad url", Context: ":bad"}
to <- availability.ResponseEvent{StatusCode: http.StatusAccepted, Location: "http://accepted.dev/"}
to <- availability.ErrorEvent{StatusCode: http.StatusFound,
Location: "http://redirect.dev/", Redirect: "https://redirect.dev/"}
to <- availability.ErrorEvent{StatusCode: http.StatusForbidden, Location: "http://noaccess.dev/"}
close(to)
}}
crawler.On("Visit", "http://test.dev/", mock.Anything).Return(nil)
report := availability.NewReport(availability.CrawlerForSites(crawler))
return report
},
func() <-chan availability.Site {
ch := make(chan availability.Site, 1)
ch <- *availability.NewSite("http://test.dev/")
close(ch)
return ch
},
},
// TODO check panics
}
for _, test := range tests {
tc := test
Expand All @@ -39,7 +94,15 @@ func TestReporter(t *testing.T) {
for site := range expectedPipe {
expected = append(expected, site)
}
assert.Equal(t, expected, obtained)
for i := range expected {
assert.Equal(t, expected[i].Name, obtained[i].Name)
if expected[i].Error != nil {
assert.EqualError(t, obtained[i].Error, expected[i].Error.Error())
} else {
assert.NoError(t, obtained[i].Error)
}
// TODO check site tree
}
})
}
}

0 comments on commit 24c478d

Please sign in to comment.