akregator/src/librss

testlibrss.cpp
1#include "testlibrss.h"
2
3#include <tqdatetime.h>
4#include <tqfile.h>
5
6#include <tdeaboutdata.h>
7#include <tdecmdlineargs.h>
8#include <tdeapplication.h>
9#include <kdebug.h>
10#include <krfcdate.h>
11
12#include "image.h"
13#include "enclosure.h"
14
15#include <cstdlib>
16
17using namespace RSS;
18
19
20TestRetriever::TestRetriever()
21 : m_errorCode(0)
22{
23}
24
25TestRetriever::~TestRetriever()
26{
27}
28
29void TestRetriever::retrieveData(const KURL &url)
30{
31 // Test files are local paths
32 TQFile file(url.path());
33 if (file.open(IO_ReadOnly))
34 {
35 TQStringList lines;
36 TQTextStream stream(&file);
37
38 while (!stream.atEnd())
39 {
40 lines += stream.readLine();
41 }
42 file.close();
43
44 TQCString content = lines.join("\n").local8Bit();
45 TQByteArray data;
46 data.duplicate(content, content.length());
47 emit dataRetrieved(data, true);
48 }
49 else
50 {
51 kdError() << "Failed to retrieveData: " << file.errorString() << endl;
52 m_errorCode = file.status();
53 emit dataRetrieved(TQByteArray{}, false);
54 }
55}
56
57static const TDECmdLineOptions options[] =
58{
59 { "+url", I18N_NOOP("URL of feed"), 0 },
60 TDECmdLineLastOption
61};
62
63template<typename ActualType, typename ExpectedType>
64static void assertEquals(const ActualType& actual, const ExpectedType& expected)
65{
66 if (actual != expected)
67 {
68 kdError() << "Assertion failed: actual == expected\n"
69 << " actual: " << actual << "\n"
70 << " expected: " << expected << endl;
71 tdeApp->exit(1);
72 }
73}
74
75static void checkRSS091(const Document& document)
76{
77 assertEquals(document.title(), "WriteTheWeb");
78 assertEquals(document.link().url(), "http://writetheweb.com");
79 assertEquals(document.description(), "News for web users that write back");
80 assertEquals(document.language(), Language::en_us);
81 assertEquals(document.copyright(), "Copyright 2000, WriteTheWeb team.");
82 assertEquals(document.managingEditor(), "editor@writetheweb.com");
83 assertEquals(document.webMaster(), "webmaster@writetheweb.com");
84
85 const Image* image = document.image();
86 if (!image)
87 {
88 kdError() << "Expected an <image> element to be found" << endl;
89 tdeApp->exit(1);
90 }
91
92 assertEquals(image->title(), "WriteTheWeb");
93 assertEquals(image->url().url(), "http://writetheweb.com/images/mynetscape88.gif");
94 assertEquals(image->link().url(), "http://writetheweb.com");
95 assertEquals(image->description(), "News for web users that write back");
96 assertEquals(image->width(), 88);
97 assertEquals(image->height(), 31);
98
99 assertEquals(document.articles().count(), 6);
100
101 Article article = document.articles().first();
102 assertEquals(article.title(), "Giving the world a pluggable Gnutella");
103 assertEquals(article.link().url(), "http://writetheweb.com/read.php?item=24");
104 assertEquals(article.description(), "WorldOS is a framework on which to build programs that work like Freenet or Gnutella -allowing distributed applications using peer-to-peer routing.");
105}
106
107static void checkWFW(const Document& document)
108{
109 assertEquals(document.link().url(), "http://wellformedweb.org/news/");
110 assertEquals(document.description(), "Exploring the limits of XML and HTTP");
111
112 assertEquals(document.articles().count(), 5);
113
114 Article article = document.articles().front();
115 assertEquals(article.title(), "Should you use Content Negotiation in your Web Services?");
116 assertEquals(article.commentsLink().url(), "http://bitworking.org/news/comments/WebServicesAndContentNegotiation");
117}
118
119static void checkDC(const Document& document)
120{
121 // librss will use dc:date if it is provided, otherwise it will use pubDate
122 assertEquals(document.link().url(), "https://www.theguardian.com/us");
123
124 TQDateTime expectedTime;
125 time_t time = KRFCDate::parseDateISO8601("2025-03-13T07:28:39Z");
126 expectedTime.setTime_t(time);
127 assertEquals(document.pubDate(), expectedTime);
128
129 assertEquals(document.articles().count(), 1);
130
131 Article article = document.articles().first();
132 time = KRFCDate::parseDateISO8601("2025-03-13T05:22:00Z");
133 expectedTime.setTime_t(time);
134 assertEquals(article.pubDate(), expectedTime);
135
136 assertEquals(article.author(), "Hugo Lowell in Washington");
137}
138
139static void checkRDF(const Document& document)
140{
141 assertEquals(document.title(), "XML.com");
142 assertEquals(document.link().url(), "http://xml.com/pub");
143
144 assertEquals(document.articles().count(), 2);
145
146 Article article = document.articles().first();
147
148 assertEquals(article.title(), "Processing Inclusions with XSLT");
149 assertEquals(article.link().url(), "http://xml.com/pub/2000/08/09/xslt/xslt.html");
150 assertEquals(article.guid(), "http://xml.com/pub/2000/08/09/xslt/xslt.html");
151 assertEquals(article.guidIsPermaLink(), false);
152}
153
154static void checkAtom10(const Document& document)
155{
156 assertEquals(document.title(), "dive into mark");
157 assertEquals(document.description(), "A <em>lot</em> of effort went into making this effortless");
158 kdWarning() << "Skipping check for Atom \"rights\" (Document::copyright) -- not implemented." << endl;
159 // assertEquals(document.copyright(), "Copyright (c) 2003, Mark Pilgrim");
160 assertEquals(document.language(), Language::en_us);
161
162 // 2005-07-31T12:29:29Z
163 // TQDateTime compTime;
164 // time_t time = KRFCDate::parseDateISO8601("2005-07-31T12:29:29Z");
165 // compTime.setTime_t(time);
166 // assertEquals(document.pubDate(), compTime);
167 kdWarning() << "Skipping check for Atom \"updated\" (Document::pubDate/lastBuildDate) -- not implemented." << endl;
168
169 assertEquals(document.link().url(), "http://example.org/");
170
171 assertEquals(document.articles().count(), 1);
172
173 Article article = document.articles().first();
174
175 assertEquals(article.title(), "Atom draft-07 snapshot");
176 assertEquals(article.link().url(), "http://example.org/2005/04/02/atom");
177
178 if (article.description().isNull())
179 {
180 kdError() << "Empty Atom article description." << endl;
181 tdeApp->exit(1);
182 }
183
184 // Enclosure enclosure = article.enclosure();
185 // assertEquals(enclosure.url(), "http://example.org/audio/ph34r_my_podcast.mp3");
186 // assertEquals(enclosure.length(), 1337);
187 // assertEquals(enclosure.type(), "audio/mpeg");
188 kdWarning() << "Skipping check for Atom \"enclosure\" links -- not implemented." << endl;
189
190 assertEquals(article.guid(), "tag:example.org,2003:3.2397");
191
192 // 2005-07-31T12:29:29Z
193 // Need a little workaround since librss converts the timestamp to local time.
194 // NOTE: Atom provides both 'published' and 'updated'; librss uses 'updated'.
195 TQDateTime articlePublishedDate;
196 time_t publishedTime = KRFCDate::parseDateISO8601("2005-07-31T12:29:29Z");
197 articlePublishedDate.setTime_t(publishedTime);
198 assertEquals(article.pubDate(), articlePublishedDate);
199
200 assertEquals(article.author(), "<a href=\"mailto:f8dy@example.com\">Mark Pilgrim</a>");
201}
202
203void Tester::test( const TQString &url )
204{
205 Loader *loader = Loader::create();
206 connect( loader, TQ_SIGNAL( loadingComplete( Loader *, Document, Status ) ),
207 this, TQ_SLOT( slotLoadingComplete( Loader *, Document, Status ) ) );
208 loader->loadFrom( url, new TestRetriever );
209}
210
211void Tester::slotLoadingComplete( Loader *loader, Document doc, Status status )
212{
213 if (status != Success)
214 {
215 kdError() << "Failed to load Document: ec=" << loader->errorCode() << " status=" << status << endl;
216 exit(1);
217 }
218
219 switch (doc.version())
220 {
221 case RSS::v0_91:
222 {
223 checkRSS091(doc);
224 break;
225 }
226 case RSS::v2_0:
227 {
228 if (doc.title() == "The Well-Formed Web")
229 {
230 checkWFW(doc);
231 break;
232 }
233 else if (doc.title() == "The Guardian")
234 {
235 checkDC(doc);
236 break;
237 }
238 else if (doc.title() == "XML.com")
239 {
240 checkRDF(doc);
241 break;
242 }
243 kdError() << "Unknown RSS 2.0 document '" << doc.title() << "'" << endl;
244 exit(1);
245 }
246 case RSS::vAtom_1_0:
247 {
248 checkAtom10(doc);
249 break;
250 }
251 default:
252 {
253 break;
254 }
255 }
256
257 exit(0);
258}
259
260int main( int argc, char **argv )
261{
262 TDEAboutData aboutData( "testlibrss", "testlibrss", "0.1" );
263 TDECmdLineArgs::init( argc, argv, &aboutData );
264 TDECmdLineArgs::addCmdLineOptions( options );
265 TDEApplication app(false, false);
266
267 TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs();
268 if ( args->count() != 1 ) args->usage();
269
270 Tester tester;
271 tester.test( args->arg( 0 ) );
272
273 return app.exec();
274}
275
276#include "testlibrss.moc"
Represents an article as stored in a RSS file.
Definition: article.h:38
TQString guid() const
RSS 2.0 and upwards.
Definition: article.cpp:231
TQString title() const
RSS 0.90 and upwards.
Definition: article.cpp:211
bool guidIsPermaLink() const
RSS 2.0 and upwards.
Definition: article.cpp:236
TQString author() const
a string desribing the author of the item.
Definition: article.cpp:216
const TQDateTime & pubDate() const
RSS 2.0 and upwards.
Definition: article.cpp:241
const KURL & link() const
RSS 0.90 and upwards.
Definition: article.cpp:221
TQString description() const
RSS 0.91 and upwards.
Definition: article.cpp:226
Represents a RSS document and provides all the features and properties as stored in it.
Definition: document.h:32
Image * image()
RSS 0.90 and upwards.
Definition: document.cpp:562
Language language() const
RSS 0.91 and upwards.
Definition: document.cpp:587
const TQDateTime & pubDate() const
RSS 0.91 and upwards.
Definition: document.cpp:597
TQString description() const
RSS 0.90 and upwards.
Definition: document.cpp:552
const KURL & link() const
RSS 0.90 and upwards.
Definition: document.cpp:557
TQString managingEditor() const
RSS 0.91 and upwards.
Definition: document.cpp:617
TQString webMaster() const
RSS 0.91 and upwards.
Definition: document.cpp:622
TQString title() const
RSS 0.90 and upwards.
Definition: document.cpp:547
TQString copyright() const
RSS 0.91 and upwards.
Definition: document.cpp:592
Version version() const
Definition: document.cpp:524
const Article::List & articles() const
RSS 0.90 and upwards.
Definition: document.cpp:582
Represents an image as stored in a RSS file.
Definition: image.h:35
TQString title() const
RSS 0.90 and upwards.
Definition: image.cpp:75
unsigned int height() const
RSS 0.91 and upwards.
Definition: image.cpp:95
TQString description() const
RSS 0.91 and upwards.
Definition: image.cpp:90
unsigned int width() const
RSS 0.91 and upwards.
Definition: image.cpp:100
const KURL & link() const
RSS 0.90 and upwards.
Definition: image.cpp:85
const KURL & url() const
RSS 0.90 and upwards.
Definition: image.cpp:80
This class is the preferred way of loading RSS files.
Definition: loader.h:258
int errorCode() const
Retrieves the error code of the last loading process (if any), as reported by the employed data retre...
Definition: loader.cpp:299
void loadFrom(const KURL &url, DataRetriever *retriever)
Loads the RSS file referenced by the given URL using the specified retrieval algorithm.
Definition: loader.cpp:285