mirror of
https://codeberg.org/librarian/feeds
synced 2024-12-06 19:16:24 +01:00
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"io"
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -134,3 +135,11 @@ func (f *Feed) WriteJSON(w io.Writer) error {
|
||||
e.SetIndent("", " ")
|
||||
return e.Encode(feed)
|
||||
}
|
||||
|
||||
// Sort sorts the Items in the feed with the given less function.
|
||||
func (f *Feed) Sort(less func(a, b *Item) bool) {
|
||||
lessFunc := func(i, j int) bool {
|
||||
return less(f.Items[i], f.Items[j])
|
||||
}
|
||||
sort.SliceStable(f.Items, lessFunc)
|
||||
}
|
||||
|
||||
+225
@@ -255,3 +255,228 @@ func TestFeed(t *testing.T) {
|
||||
t.Errorf("JSON not what was expected. Got:\n||%s||\n\nExpected:\n||%s||\n", got, jsonOutput)
|
||||
}
|
||||
}
|
||||
|
||||
var atomOutputSorted = `<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom">
|
||||
<title>jmoiron.net blog</title>
|
||||
<id>http://jmoiron.net/blog</id>
|
||||
<updated>2013-01-16T21:52:35-05:00</updated>
|
||||
<rights>This work is copyright © Benjamin Button</rights>
|
||||
<subtitle>discussion about tech, footie, photos</subtitle>
|
||||
<link href="http://jmoiron.net/blog"></link>
|
||||
<author>
|
||||
<name>Jason Moiron</name>
|
||||
<email>jmoiron@jmoiron.net</email>
|
||||
</author>
|
||||
<entry>
|
||||
<title>Limiting Concurrency in Go</title>
|
||||
<updated>2013-01-18T21:52:35-05:00</updated>
|
||||
<id>tag:jmoiron.net,2013-01-18:/blog/limiting-concurrency-in-go/</id>
|
||||
<link href="http://jmoiron.net/blog/limiting-concurrency-in-go/" rel="alternate"></link>
|
||||
<summary type="html"></summary>
|
||||
</entry>
|
||||
<entry>
|
||||
<title>Logic-less Template Redux</title>
|
||||
<updated>2013-01-17T21:52:35-05:00</updated>
|
||||
<id>tag:jmoiron.net,2013-01-17:/blog/logicless-template-redux/</id>
|
||||
<link href="http://jmoiron.net/blog/logicless-template-redux/" rel="alternate"></link>
|
||||
<summary type="html"></summary>
|
||||
</entry>
|
||||
<entry>
|
||||
<title>Idiomatic Code Reuse in Go</title>
|
||||
<updated>2013-01-17T09:52:35-05:00</updated>
|
||||
<id>tag:jmoiron.net,2013-01-17:/blog/idiomatic-code-reuse-in-go/</id>
|
||||
<link href="http://jmoiron.net/blog/idiomatic-code-reuse-in-go/" rel="alternate"></link>
|
||||
<summary type="html"></summary>
|
||||
</entry>
|
||||
<entry>
|
||||
<title>Never Gonna Give You Up Mp3</title>
|
||||
<updated>2013-01-17T07:52:35-05:00</updated>
|
||||
<id>tag:example.com,2013-01-17:/RickRoll.mp3</id>
|
||||
<link href="http://example.com/RickRoll.mp3" rel="alternate"></link>
|
||||
<summary type="html"></summary>
|
||||
</entry>
|
||||
<entry>
|
||||
<title>String formatting in Go</title>
|
||||
<updated>2013-01-16T21:52:35-05:00</updated>
|
||||
<id>tag:example.com,2013-01-16:/strings</id>
|
||||
<link href="http://example.com/strings" rel="alternate"></link>
|
||||
<summary type="html"></summary>
|
||||
</entry>
|
||||
</feed>`
|
||||
|
||||
var rssOutputSorted = `<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
|
||||
<channel>
|
||||
<title>jmoiron.net blog</title>
|
||||
<link>http://jmoiron.net/blog</link>
|
||||
<description>discussion about tech, footie, photos</description>
|
||||
<copyright>This work is copyright © Benjamin Button</copyright>
|
||||
<managingEditor>jmoiron@jmoiron.net (Jason Moiron)</managingEditor>
|
||||
<pubDate>Wed, 16 Jan 2013 21:52:35 -0500</pubDate>
|
||||
<item>
|
||||
<title>Limiting Concurrency in Go</title>
|
||||
<link>http://jmoiron.net/blog/limiting-concurrency-in-go/</link>
|
||||
<description></description>
|
||||
<pubDate>Fri, 18 Jan 2013 21:52:35 -0500</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Logic-less Template Redux</title>
|
||||
<link>http://jmoiron.net/blog/logicless-template-redux/</link>
|
||||
<description></description>
|
||||
<pubDate>Thu, 17 Jan 2013 21:52:35 -0500</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Idiomatic Code Reuse in Go</title>
|
||||
<link>http://jmoiron.net/blog/idiomatic-code-reuse-in-go/</link>
|
||||
<description></description>
|
||||
<pubDate>Thu, 17 Jan 2013 09:52:35 -0500</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Never Gonna Give You Up Mp3</title>
|
||||
<link>http://example.com/RickRoll.mp3</link>
|
||||
<description></description>
|
||||
<pubDate>Thu, 17 Jan 2013 07:52:35 -0500</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>String formatting in Go</title>
|
||||
<link>http://example.com/strings</link>
|
||||
<description></description>
|
||||
<pubDate>Wed, 16 Jan 2013 21:52:35 -0500</pubDate>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>`
|
||||
|
||||
var jsonOutputSorted = `{
|
||||
"version": "https://jsonfeed.org/version/1",
|
||||
"title": "jmoiron.net blog",
|
||||
"home_page_url": "http://jmoiron.net/blog",
|
||||
"description": "discussion about tech, footie, photos",
|
||||
"author": {
|
||||
"name": "Jason Moiron"
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"id": "",
|
||||
"url": "http://jmoiron.net/blog/limiting-concurrency-in-go/",
|
||||
"title": "Limiting Concurrency in Go",
|
||||
"date_published": "2013-01-18T21:52:35-05:00"
|
||||
},
|
||||
{
|
||||
"id": "",
|
||||
"url": "http://jmoiron.net/blog/logicless-template-redux/",
|
||||
"title": "Logic-less Template Redux",
|
||||
"date_published": "2013-01-17T21:52:35-05:00"
|
||||
},
|
||||
{
|
||||
"id": "",
|
||||
"url": "http://jmoiron.net/blog/idiomatic-code-reuse-in-go/",
|
||||
"title": "Idiomatic Code Reuse in Go",
|
||||
"date_published": "2013-01-17T09:52:35-05:00"
|
||||
},
|
||||
{
|
||||
"id": "",
|
||||
"url": "http://example.com/RickRoll.mp3",
|
||||
"title": "Never Gonna Give You Up Mp3",
|
||||
"date_published": "2013-01-17T07:52:35-05:00"
|
||||
},
|
||||
{
|
||||
"id": "",
|
||||
"url": "http://example.com/strings",
|
||||
"title": "String formatting in Go",
|
||||
"date_published": "2013-01-16T21:52:35-05:00"
|
||||
}
|
||||
]
|
||||
}`
|
||||
|
||||
func TestFeedSorted(t *testing.T) {
|
||||
now, err := time.Parse(time.RFC3339, "2013-01-16T21:52:35-05:00")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
tz := time.FixedZone("EST", -5*60*60)
|
||||
now = now.In(tz)
|
||||
|
||||
feed := &Feed{
|
||||
Title: "jmoiron.net blog",
|
||||
Link: &Link{Href: "http://jmoiron.net/blog"},
|
||||
Description: "discussion about tech, footie, photos",
|
||||
Author: &Author{Name: "Jason Moiron", Email: "jmoiron@jmoiron.net"},
|
||||
Created: now,
|
||||
Copyright: "This work is copyright © Benjamin Button",
|
||||
}
|
||||
|
||||
feed.Items = []*Item{
|
||||
{
|
||||
Title: "Limiting Concurrency in Go",
|
||||
Link: &Link{Href: "http://jmoiron.net/blog/limiting-concurrency-in-go/"},
|
||||
Created: now.Add(time.Duration(time.Hour * 48)),
|
||||
},
|
||||
{
|
||||
Title: "Logic-less Template Redux",
|
||||
Link: &Link{Href: "http://jmoiron.net/blog/logicless-template-redux/"},
|
||||
Created: now.Add(time.Duration(time.Hour * 24)),
|
||||
},
|
||||
{
|
||||
Title: "Idiomatic Code Reuse in Go",
|
||||
Link: &Link{Href: "http://jmoiron.net/blog/idiomatic-code-reuse-in-go/"},
|
||||
Created: now.Add(time.Duration(time.Hour * 12)),
|
||||
},
|
||||
{
|
||||
Title: "Never Gonna Give You Up Mp3",
|
||||
Link: &Link{Href: "http://example.com/RickRoll.mp3"},
|
||||
Created: now.Add(time.Duration(time.Hour * 10)),
|
||||
},
|
||||
{
|
||||
Title: "String formatting in Go",
|
||||
Link: &Link{Href: "http://example.com/strings"},
|
||||
Created: now,
|
||||
}}
|
||||
|
||||
feed.Sort(func(a, b *Item) bool {
|
||||
return a.Created.After(b.Created)
|
||||
})
|
||||
atom, err := feed.ToAtom()
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error encoding Atom: %v", err)
|
||||
}
|
||||
if atom != atomOutputSorted {
|
||||
t.Errorf("Atom not what was expected. Got:\n%s\n\nExpected:\n%s\n", atom, atomOutputSorted)
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
if err := feed.WriteAtom(&buf); err != nil {
|
||||
t.Errorf("unexpected error writing Atom: %v", err)
|
||||
}
|
||||
if got := buf.String(); got != atomOutputSorted {
|
||||
t.Errorf("Atom not what was expected. Got:\n%s\n\nExpected:\n%s\n", got, atomOutputSorted)
|
||||
}
|
||||
|
||||
rss, err := feed.ToRss()
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error encoding RSS: %v", err)
|
||||
}
|
||||
|
||||
if rss != rssOutputSorted {
|
||||
t.Errorf("Rss not what was expected. Got:\n%s\n\nExpected:\n%s\n", rss, rssOutputSorted)
|
||||
}
|
||||
buf.Reset()
|
||||
if err := feed.WriteRss(&buf); err != nil {
|
||||
t.Errorf("unexpected error writing RSS: %v", err)
|
||||
}
|
||||
if got := buf.String(); got != rssOutputSorted {
|
||||
t.Errorf("Rss not what was expected. Got:\n%s\n\nExpected:\n%s\n", got, rssOutputSorted)
|
||||
}
|
||||
|
||||
json, err := feed.ToJSON()
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error encoding JSON: %v", err)
|
||||
}
|
||||
if json != jsonOutputSorted {
|
||||
t.Errorf("JSON not what was expected. Got:\n%s\n\nExpected:\n%s\n", json, jsonOutputSorted)
|
||||
}
|
||||
buf.Reset()
|
||||
if err := feed.WriteJSON(&buf); err != nil {
|
||||
t.Errorf("unexpected error writing JSON: %v", err)
|
||||
}
|
||||
if got := buf.String(); got != jsonOutputSorted+"\n" { //json.Encode appends a newline after the JSON output: https://github.com/golang/go/commit/6f25f1d4c901417af1da65e41992d71c30f64f8f#diff-50848cbd686f250623a2ef6ddb07e157
|
||||
t.Errorf("JSON not what was expected. Got:\n||%s||\n\nExpected:\n||%s||\n", got, jsonOutputSorted)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user