123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- package main
- import (
- "bytes"
- "context"
- "fmt"
- "io/ioutil"
- "net/http"
- "net/http/httptest"
- "os"
- "strings"
- "sync"
- "sync/atomic"
- "syscall"
- "testing"
- "time"
- log "github.com/go-pkgz/lgr"
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
- "git.lattuga.net/boyska/rss2twitter/app/rss"
- )
- func TestMain(t *testing.T) {
- var n int32
- ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- log.Printf("req %+v", r)
- fnum := atomic.AddInt32(&n, int32(1))
- if fnum > 2 {
- fnum = 2
- }
- data, err := ioutil.ReadFile(fmt.Sprintf("rss/testdata/f%d.xml", fnum))
- require.NoError(t, err)
- w.WriteHeader(200)
- w.Write(data)
- }))
- defer ts.Close()
- os.Args = []string{"app", "--feed=" + ts.URL + "/rss", "--dry", "--dbg", "--refresh=100ms"}
- go func() {
- time.Sleep(500 * time.Millisecond)
- err := syscall.Kill(syscall.Getpid(), syscall.SIGTERM)
- require.Nil(t, err, "kill")
- }()
- wg := sync.WaitGroup{}
- wg.Add(1)
- go func() {
- st := time.Now()
- main()
- require.True(t, time.Since(st).Seconds() < 1, "should take about 500msec")
- wg.Done()
- }()
- wg.Wait()
- }
- func TestSetupDry(t *testing.T) {
- o := opts{Feed: "http://example.com", Dry: true}
- n, p, err := setup(o)
- require.NoError(t, err)
- assert.NotNil(t, n)
- assert.Equal(t, "publisher.Stdout", fmt.Sprintf("%T", p))
- }
- func TestSetupFull(t *testing.T) {
- o := opts{Feed: "http://example.com", Dry: false,
- ConsumerKey: "1", ConsumerSecret: "1", AccessToken: "1", AccessSecret: "1"}
- n, p, err := setup(o)
- require.NoError(t, err)
- assert.NotNil(t, n)
- assert.Equal(t, "publisher.Twitter", fmt.Sprintf("%T", p))
- }
- func TestSetupFailed(t *testing.T) {
- o := opts{Feed: "http://example.com", Dry: false,
- ConsumerKey: "1", ConsumerSecret: "1"}
- _, _, err := setup(o)
- assert.NotNil(t, err)
- }
- func TestDo(t *testing.T) {
- pub := pubMock{buf: bytes.Buffer{}}
- notif := notifierMock{delay: 100 * time.Millisecond, events: []rss.Event{
- {GUID: "1", Title: "t1", Link: "l1", Text: "ttt2"},
- {GUID: "2", Title: "t2", Link: "l2", Text: "ttt2"},
- {GUID: "3", Title: "t4", Link: "l3", Text: "ttt3"},
- }}
- ctx, cancel := context.WithCancel(context.Background())
- do(ctx, ¬if, &pub, "{{.Title}} - {{.Link}}")
- cancel()
- assert.Equal(t, "t1 - l1\nt2 - l2\nt4 - l3\n", pub.buf.String())
- }
- func TestDoCanceled(t *testing.T) {
- pub := pubMock{buf: bytes.Buffer{}}
- notif := notifierMock{delay: 100 * time.Millisecond, events: []rss.Event{
- {GUID: "1", Title: "t1", Link: "l1", Text: "ttt2"},
- {GUID: "2", Title: "t2", Link: "l2", Text: "ttt2"},
- {GUID: "3", Title: "t4", Link: "l3", Text: "ttt3"},
- }}
- ctx, cancel := context.WithCancel(context.Background())
- time.AfterFunc(time.Millisecond*150, func() { cancel() })
- do(ctx, ¬if, &pub, "{{.Title}} - {{.Link}} {{.Text}}")
- assert.Equal(t, "t1 - l1 ttt2\n", pub.buf.String())
- }
- func TestFormat(t *testing.T) {
- tbl := []struct {
- inp string
- out string
- size int
- }{
- {"blah", "blah", 100},
- {"blah <p>xyx</p>", "blah xyx", 100},
- {"blah <p>xyx</p> something 122 abcdefg 12345 qwer", "blah xyx ...", 15},
- {"blah <p>xyx</p> something 122 abcdefg 12345 qwerty", "blah xyx something ...", 20},
- {"<p>xyx</p><title>", "xyx", 20},
- }
- for i, tt := range tbl {
- t.Run(fmt.Sprintf("check-%d", i), func(t *testing.T) {
- out := format(tt.inp, tt.size)
- assert.Equal(t, tt.out, out)
- })
- }
- }
- func TestGetDump(t *testing.T) {
- dump := getDump()
- assert.True(t, strings.Contains(dump, "goroutine"))
- assert.True(t, strings.Contains(dump, "[running]"))
- assert.True(t, strings.Contains(dump, "app/main.go"))
- log.Printf("\n dump: %s", dump)
- }
- type pubMock struct {
- buf bytes.Buffer
- }
- func (m *pubMock) Publish(event rss.Event, formatter func(rss.Event) string) error {
- _, err := m.buf.WriteString(formatter(event) + "\n")
- return err
- }
- type notifierMock struct {
- events []rss.Event
- delay time.Duration
- }
- func (m *notifierMock) Go(ctx context.Context) <-chan rss.Event {
- ch := make(chan rss.Event)
- go func() {
- for _, e := range m.events {
- select {
- case <-ctx.Done():
- break
- case <-time.After(m.delay):
- ch <- e
- }
- }
- close(ch)
- }()
- return ch
- }
|