jekyll-feed 0.13.0 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/History.markdown +52 -0
  3. data/README.md +53 -4
  4. data/lib/jekyll-feed/feed.xml +24 -8
  5. data/lib/jekyll-feed/generator.rb +33 -4
  6. data/lib/jekyll-feed/meta-tag.rb +12 -22
  7. data/lib/jekyll-feed/version.rb +1 -1
  8. metadata +11 -59
  9. data/.gitignore +0 -21
  10. data/.rspec +0 -2
  11. data/.rubocop.yml +0 -27
  12. data/.travis.yml +0 -32
  13. data/Gemfile +0 -11
  14. data/Rakefile +0 -8
  15. data/appveyor.yml +0 -29
  16. data/jekyll-feed.gemspec +0 -30
  17. data/script/bootstrap +0 -3
  18. data/script/cibuild +0 -7
  19. data/script/fmt +0 -10
  20. data/script/release +0 -7
  21. data/script/test +0 -4
  22. data/spec/fixtures/_collection/2018-01-01-collection-doc.md +0 -4
  23. data/spec/fixtures/_collection/2018-01-02-collection-category-doc.md +0 -5
  24. data/spec/fixtures/_config.yml +0 -9
  25. data/spec/fixtures/_data/authors.yml +0 -5
  26. data/spec/fixtures/_drafts/2015-01-12-a-draft.md +0 -4
  27. data/spec/fixtures/_layouts/some_default.html +0 -11
  28. data/spec/fixtures/_posts/2013-12-12-dec-the-second.md +0 -7
  29. data/spec/fixtures/_posts/2014-03-02-march-the-second.md +0 -6
  30. data/spec/fixtures/_posts/2014-03-04-march-the-fourth.md +0 -9
  31. data/spec/fixtures/_posts/2015-01-18-jekyll-last-modified-at.md +0 -5
  32. data/spec/fixtures/_posts/2015-02-12-strip-newlines.md +0 -6
  33. data/spec/fixtures/_posts/2015-05-12-liquid.md +0 -7
  34. data/spec/fixtures/_posts/2015-05-12-pre.html +0 -8
  35. data/spec/fixtures/_posts/2015-05-18-author-detail.md +0 -9
  36. data/spec/fixtures/_posts/2015-08-08-stuck-in-the-middle.html +0 -6
  37. data/spec/fixtures/_posts/2016-04-25-author-reference.md +0 -6
  38. data/spec/fixtures/feed.xslt.xml +0 -0
  39. data/spec/jekyll-feed_spec.rb +0 -524
  40. data/spec/spec_helper.rb +0 -30
@@ -1,524 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- describe(JekyllFeed) do
6
- let(:overrides) { {} }
7
- let(:config) do
8
- Jekyll.configuration(Jekyll::Utils.deep_merge_hashes({
9
- "full_rebuild" => true,
10
- "source" => source_dir,
11
- "destination" => dest_dir,
12
- "show_drafts" => true,
13
- "url" => "http://example.org",
14
- "name" => "My awesome site",
15
- "author" => {
16
- "name" => "Dr. Jekyll",
17
- },
18
- "collections" => {
19
- "my_collection" => { "output" => true },
20
- "other_things" => { "output" => false },
21
- },
22
- }, overrides))
23
- end
24
- let(:site) { Jekyll::Site.new(config) }
25
- let(:contents) { File.read(dest_dir("feed.xml")) }
26
- let(:context) { make_context(:site => site) }
27
- let(:feed_meta) { Liquid::Template.parse("{% feed_meta %}").render!(context, {}) }
28
- before(:each) do
29
- site.process
30
- end
31
-
32
- it "has no layout" do
33
- expect(contents).not_to match(%r!\ATHIS IS MY LAYOUT!)
34
- end
35
-
36
- it "creates a feed.xml file" do
37
- expect(Pathname.new(dest_dir("feed.xml"))).to exist
38
- end
39
-
40
- it "doesn't have multiple new lines or trailing whitespace" do
41
- expect(contents).to_not match %r!\s+\n!
42
- expect(contents).to_not match %r!\n{2,}!
43
- end
44
-
45
- it "puts all the posts in the feed.xml file" do
46
- expect(contents).to match "http://example.org/updates/jekyll/2014/03/04/march-the-fourth.html"
47
- expect(contents).to match "http://example.org/news/2014/03/02/march-the-second.html"
48
- expect(contents).to match "http://example.org/news/2013/12/12/dec-the-second.html"
49
- expect(contents).to match "http://example.org/2015/08/08/stuck-in-the-middle.html"
50
- expect(contents).to_not match "http://example.org/2016/02/09/a-draft.html"
51
- end
52
-
53
- it "does not include assets or any static files that aren't .html" do
54
- expect(contents).not_to match "http://example.org/images/hubot.png"
55
- expect(contents).not_to match "http://example.org/feeds/atom.xml"
56
- end
57
-
58
- it "preserves linebreaks in preformatted text in posts" do
59
- expect(contents).to match "Line 1\nLine 2\nLine 3"
60
- end
61
-
62
- it "supports post author name as an object" do
63
- expect(contents).to match %r!<author>\s*<name>Ben</name>\s*<email>ben@example\.com</email>\s*<uri>http://ben\.balter\.com</uri>\s*</author>!
64
- end
65
-
66
- it "supports post author name as a string" do
67
- expect(contents).to match %r!<author>\s*<name>Pat</name>\s*</author>!
68
- end
69
-
70
- it "does not output author tag no author is provided" do
71
- expect(contents).not_to match %r!<author>\s*<name></name>\s*</author>!
72
- end
73
-
74
- it "does use author reference with data from _data/authors.yml" do
75
- expect(contents).to match %r!<author>\s*<name>Garth</name>\s*<email>example@mail\.com</email>\s*<uri>http://garthdb\.com</uri>\s*</author>!
76
- end
77
-
78
- it "converts markdown posts to HTML" do
79
- expect(contents).to match %r!&lt;p&gt;March the second\!&lt;/p&gt;!
80
- end
81
-
82
- it "uses last_modified_at where available" do
83
- expect(contents).to match %r!<updated>2015-05-12T13:27:59\+00:00</updated>!
84
- end
85
-
86
- it "replaces newlines in posts to spaces" do
87
- expect(contents).to match '<title type="html">The plugin will properly strip newlines.</title>'
88
- end
89
-
90
- it "renders Liquid inside posts" do
91
- expect(contents).to match "Liquid is rendered."
92
- expect(contents).not_to match "Liquid is not rendered."
93
- end
94
-
95
- context "images" do
96
- let(:image1) { 'http://example.org/image.png' }
97
- let(:image2) { 'https://cdn.example.org/absolute.png?h=188&amp;w=250' }
98
- let(:image3) { 'http://example.org/object-image.png' }
99
-
100
- it "includes the item image" do
101
- expect(contents).to include(%(<media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="#{image1}" />))
102
- expect(contents).to include(%(<media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="#{image2}" />))
103
- expect(contents).to include(%(<media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="#{image3}" />))
104
- end
105
-
106
- it "included media content for mail templates (Mailchimp)" do
107
- expect(contents).to include(%(<media:content medium="image" url="#{image1}" xmlns:media="http://search.yahoo.com/mrss/" />))
108
- expect(contents).to include(%(<media:content medium="image" url="#{image2}" xmlns:media="http://search.yahoo.com/mrss/" />))
109
- expect(contents).to include(%(<media:content medium="image" url="#{image3}" xmlns:media="http://search.yahoo.com/mrss/" />))
110
- end
111
- end
112
-
113
- context "parsing" do
114
- let(:feed) { RSS::Parser.parse(contents) }
115
-
116
- it "outputs an RSS feed" do
117
- expect(feed.feed_type).to eql("atom")
118
- expect(feed.feed_version).to eql("1.0")
119
- expect(feed.encoding).to eql("UTF-8")
120
- expect(feed.lang).to be_nil
121
- expect(feed.valid?).to eql(true)
122
- end
123
-
124
- it "outputs the link" do
125
- expect(feed.link.href).to eql("http://example.org/feed.xml")
126
- end
127
-
128
- it "outputs the generator" do
129
- expect(feed.generator.content).to eql("Jekyll")
130
- expect(feed.generator.version).to eql(Jekyll::VERSION)
131
- end
132
-
133
- it "includes the items" do
134
- expect(feed.items.count).to eql(10)
135
- end
136
-
137
- it "includes item contents" do
138
- post = feed.items.last
139
- expect(post.title.content).to eql("Dec The Second")
140
- expect(post.link.href).to eql("http://example.org/news/2013/12/12/dec-the-second.html")
141
- expect(post.published.content).to eql(Time.parse("2013-12-12"))
142
- end
143
-
144
- it "includes the item's excerpt" do
145
- post = feed.items.last
146
- expect(post.summary.content).to eql("Foo")
147
- end
148
-
149
- it "doesn't include the item's excerpt if blank" do
150
- post = feed.items.first
151
- expect(post.summary).to be_nil
152
- end
153
-
154
- context "with site.lang set" do
155
- lang = "en_US"
156
- let(:overrides) { { "lang" => lang } }
157
- it "outputs a valid feed" do
158
- expect(feed.feed_type).to eql("atom")
159
- expect(feed.feed_version).to eql("1.0")
160
- expect(feed.encoding).to eql("UTF-8")
161
- expect(feed.valid?).to eql(true)
162
- end
163
-
164
- it "outputs the correct language" do
165
- expect(feed.lang).to eql(lang)
166
- end
167
-
168
- it "sets the language of entries" do
169
- post = feed.items.first
170
- expect(post.lang).to eql(lang)
171
- end
172
-
173
- it "renders the feed meta" do
174
- expected = %r!<link href="http://example.org/" rel="alternate" type="text/html" hreflang="#{lang}" />!
175
- expect(contents).to match(expected)
176
- end
177
- end
178
-
179
- context "with site.title set" do
180
- let(:site_title) { "My Site Title" }
181
- let(:overrides) { { "title" => site_title } }
182
-
183
- it "uses site.title for the title" do
184
- expect(feed.title.content).to eql(site_title)
185
- end
186
- end
187
-
188
- context "with site.name set" do
189
- let(:site_name) { "My Site Name" }
190
- let(:overrides) { { "name" => site_name } }
191
-
192
- it "uses site.name for the title" do
193
- expect(feed.title.content).to eql(site_name)
194
- end
195
- end
196
-
197
- context "with site.name and site.title set" do
198
- let(:site_title) { "My Site Title" }
199
- let(:site_name) { "My Site Name" }
200
- let(:overrides) { { "title" => site_title, "name" => site_name } }
201
-
202
- it "uses site.title for the title, dropping site.name" do
203
- expect(feed.title.content).to eql(site_title)
204
- end
205
- end
206
- end
207
-
208
- context "smartify" do
209
- let(:site_title) { "Pat's Site" }
210
- let(:overrides) { { "title" => site_title } }
211
- let(:feed) { RSS::Parser.parse(contents) }
212
-
213
- it "processes site title with SmartyPants" do
214
- expect(feed.title.content).to eql("Pat’s Site")
215
- end
216
- end
217
-
218
- context "validation" do
219
- it "validates" do
220
- skip "Typhoeus couldn't find the 'libcurl' module on Windows" if Gem.win_platform?
221
- # See https://validator.w3.org/docs/api.html
222
- url = "https://validator.w3.org/feed/check.cgi?output=soap12"
223
- response = Typhoeus.post(url, :body => { :rawdata => contents }, :accept_encoding => "gzip")
224
- pending "Something went wrong with the W3 validator" unless response.success?
225
- result = Nokogiri::XML(response.body)
226
- result.remove_namespaces!
227
-
228
- result.css("warning").each do |warning|
229
- # Quiet a warning that results from us passing the feed as a string
230
- next if warning.css("text").text =~ %r!Self reference doesn't match document location!
231
-
232
- # Quiet expected warning that results from blank summary test case
233
- next if warning.css("text").text =~ %r!(content|summary) should not be blank!
234
-
235
- # Quiet expected warning about multiple posts with same updated time
236
- next if warning.css("text").text =~ %r!Two entries with the same value for atom:updated!
237
-
238
- warn "Validation warning: #{warning.css("text").text} on line #{warning.css("line").text} column #{warning.css("column").text}"
239
- end
240
-
241
- errors = result.css("error").map do |error|
242
- "Validation error: #{error.css("text").text} on line #{error.css("line").text} column #{error.css("column").text}"
243
- end
244
-
245
- expect(result.css("validity").text).to eql("true"), errors.join("\n")
246
- end
247
- end
248
-
249
- context "with a baseurl" do
250
- let(:overrides) do
251
- { "baseurl" => "/bass" }
252
- end
253
-
254
- it "correctly adds the baseurl to the posts" do
255
- expect(contents).to match "http://example.org/bass/updates/jekyll/2014/03/04/march-the-fourth.html"
256
- expect(contents).to match "http://example.org/bass/news/2014/03/02/march-the-second.html"
257
- expect(contents).to match "http://example.org/bass/news/2013/12/12/dec-the-second.html"
258
- end
259
-
260
- it "renders the feed meta" do
261
- expected = 'href="http://example.org/bass/feed.xml"'
262
- expect(feed_meta).to include(expected)
263
- end
264
- end
265
-
266
- context "feed meta" do
267
- it "renders the feed meta" do
268
- expected = '<link type="application/atom+xml" rel="alternate" href="http://example.org/feed.xml" title="My awesome site" />'
269
- expect(feed_meta).to eql(expected)
270
- end
271
-
272
- context "with a blank site name" do
273
- let(:config) do
274
- Jekyll.configuration(
275
- "source" => source_dir,
276
- "destination" => dest_dir,
277
- "url" => "http://example.org"
278
- )
279
- end
280
-
281
- it "does not output blank title" do
282
- expect(feed_meta).not_to include("title=")
283
- end
284
- end
285
- end
286
-
287
- context "changing the feed path" do
288
- let(:overrides) do
289
- {
290
- "feed" => {
291
- "path" => "atom.xml",
292
- },
293
- }
294
- end
295
-
296
- it "should write to atom.xml" do
297
- expect(Pathname.new(dest_dir("atom.xml"))).to exist
298
- end
299
-
300
- it "renders the feed meta with custom feed path" do
301
- expected = 'href="http://example.org/atom.xml"'
302
- expect(feed_meta).to include(expected)
303
- end
304
- end
305
-
306
- context "changing the file path via collection meta" do
307
- let(:overrides) do
308
- {
309
- "feed" => {
310
- "collections" => {
311
- "posts" => {
312
- "path" => "atom.xml",
313
- },
314
- },
315
- },
316
- }
317
- end
318
-
319
- it "should write to atom.xml" do
320
- expect(Pathname.new(dest_dir("atom.xml"))).to exist
321
- end
322
-
323
- it "renders the feed meta with custom feed path" do
324
- expected = 'href="http://example.org/atom.xml"'
325
- expect(feed_meta).to include(expected)
326
- end
327
- end
328
-
329
- context "feed stylesheet" do
330
- it "includes the stylesheet" do
331
- expect(contents).to include('<?xml-stylesheet type="text/xml" href="http://example.org/feed.xslt.xml"?>')
332
- end
333
- end
334
-
335
- context "with site.lang set" do
336
- let(:overrides) { { "lang" => "en-US" } }
337
-
338
- it "should set the language" do
339
- expect(contents).to match 'type="text/html" hreflang="en-US" />'
340
- end
341
- end
342
-
343
- context "with post.lang set" do
344
- it "should set the language for that entry" do
345
- expect(contents).to match '<entry xml:lang="en">'
346
- expect(contents).to match '<entry>'
347
- end
348
- end
349
-
350
- context "categories" do
351
- context "with top-level post categories" do
352
- let(:overrides) do
353
- {
354
- "feed" => { "categories" => ["news"] },
355
- }
356
- end
357
- let(:news_feed) { File.read(dest_dir("feed/news.xml")) }
358
-
359
- it "outputs the primary feed" do
360
- expect(contents).to match "http://example.org/updates/jekyll/2014/03/04/march-the-fourth.html"
361
- expect(contents).to match "http://example.org/news/2014/03/02/march-the-second.html"
362
- expect(contents).to match "http://example.org/news/2013/12/12/dec-the-second.html"
363
- expect(contents).to match "http://example.org/2015/08/08/stuck-in-the-middle.html"
364
- expect(contents).to_not match "http://example.org/2016/02/09/a-draft.html"
365
- end
366
-
367
- it "outputs the category feed" do
368
- expect(news_feed).to match '<title type="html">My awesome site | News</title>'
369
- expect(news_feed).to match "http://example.org/news/2014/03/02/march-the-second.html"
370
- expect(news_feed).to match "http://example.org/news/2013/12/12/dec-the-second.html"
371
- expect(news_feed).to_not match "http://example.org/updates/jekyll/2014/03/04/march-the-fourth.html"
372
- expect(news_feed).to_not match "http://example.org/2015/08/08/stuck-in-the-middle.html"
373
- end
374
- end
375
-
376
- context "with collection-level post categories" do
377
- let(:overrides) do
378
- {
379
- "feed" => {
380
- "collections" => {
381
- "posts" => {
382
- "categories" => ["news"],
383
- },
384
- },
385
- },
386
- }
387
- end
388
- let(:news_feed) { File.read(dest_dir("feed/news.xml")) }
389
-
390
- it "outputs the primary feed" do
391
- expect(contents).to match "http://example.org/updates/jekyll/2014/03/04/march-the-fourth.html"
392
- expect(contents).to match "http://example.org/news/2014/03/02/march-the-second.html"
393
- expect(contents).to match "http://example.org/news/2013/12/12/dec-the-second.html"
394
- expect(contents).to match "http://example.org/2015/08/08/stuck-in-the-middle.html"
395
- expect(contents).to_not match "http://example.org/2016/02/09/a-draft.html"
396
- end
397
-
398
- it "outputs the category feed" do
399
- expect(news_feed).to match '<title type="html">My awesome site | News</title>'
400
- expect(news_feed).to match "http://example.org/news/2014/03/02/march-the-second.html"
401
- expect(news_feed).to match "http://example.org/news/2013/12/12/dec-the-second.html"
402
- expect(news_feed).to_not match "http://example.org/updates/jekyll/2014/03/04/march-the-fourth.html"
403
- expect(news_feed).to_not match "http://example.org/2015/08/08/stuck-in-the-middle.html"
404
- end
405
- end
406
- end
407
-
408
- context "collections" do
409
- let(:collection_feed) { File.read(dest_dir("feed/collection.xml")) }
410
-
411
- context "when initialized as an array" do
412
- let(:overrides) do
413
- {
414
- "collections" => {
415
- "collection" => {
416
- "output" => true,
417
- },
418
- },
419
- "feed" => { "collections" => ["collection"] },
420
- }
421
- end
422
-
423
- it "outputs the collection feed" do
424
- expect(collection_feed).to match '<title type="html">My awesome site | Collection</title>'
425
- expect(collection_feed).to match "http://example.org/collection/2018-01-01-collection-doc.html"
426
- expect(collection_feed).to match "http://example.org/collection/2018-01-02-collection-category-doc.html"
427
- expect(collection_feed).to_not match "http://example.org/updates/jekyll/2014/03/04/march-the-fourth.html"
428
- expect(collection_feed).to_not match "http://example.org/2015/08/08/stuck-in-the-middle.html"
429
- end
430
- end
431
-
432
- context "with categories" do
433
- let(:overrides) do
434
- {
435
- "collections" => {
436
- "collection" => {
437
- "output" => true,
438
- },
439
- },
440
- "feed" => {
441
- "collections" => {
442
- "collection" => {
443
- "categories" => ["news"],
444
- },
445
- },
446
- },
447
- }
448
- end
449
- let(:news_feed) { File.read(dest_dir("feed/collection/news.xml")) }
450
-
451
- it "outputs the collection category feed" do
452
- expect(news_feed).to match '<title type="html">My awesome site | Collection | News</title>'
453
- expect(news_feed).to match "http://example.org/collection/2018-01-02-collection-category-doc.html"
454
- expect(news_feed).to_not match "http://example.org/collection/2018-01-01-collection-doc.html"
455
- expect(news_feed).to_not match "http://example.org/updates/jekyll/2014/03/04/march-the-fourth.html"
456
- expect(news_feed).to_not match "http://example.org/2015/08/08/stuck-in-the-middle.html"
457
- end
458
- end
459
-
460
- context "with a custom path" do
461
- let(:overrides) do
462
- {
463
- "collections" => {
464
- "collection" => {
465
- "output" => true,
466
- },
467
- },
468
- "feed" => {
469
- "collections" => {
470
- "collection" => {
471
- "categories" => ["news"],
472
- "path" => "custom.xml",
473
- },
474
- },
475
- },
476
- }
477
- end
478
-
479
- it "should write to the custom path" do
480
- expect(Pathname.new(dest_dir("custom.xml"))).to exist
481
- expect(Pathname.new(dest_dir("feed/collection.xml"))).to_not exist
482
- expect(Pathname.new(dest_dir("feed/collection/news.xml"))).to exist
483
- end
484
- end
485
- end
486
-
487
- context "excerpt_only flag" do
488
- context "backward compatibility for no excerpt_only flag" do
489
- it "should be in contents" do
490
- expect(contents).to match '<content '
491
- end
492
- end
493
-
494
- context "when site.excerpt_only flag is true" do
495
- let(:overrides) do
496
- { "feed" => { "excerpt_only" => true } }
497
- end
498
-
499
- it "should not set any contents" do
500
- expect(contents).to_not match '<content '
501
- end
502
- end
503
-
504
- context "when site.excerpt_only flag is false" do
505
- let(:overrides) do
506
- { "feed" => { "excerpt_only" => false } }
507
- end
508
-
509
- it "should be in contents" do
510
- expect(contents).to match '<content '
511
- end
512
- end
513
-
514
- context "when post.excerpt_only flag is true" do
515
- let(:overrides) do
516
- { "feed" => { "excerpt_only" => false } }
517
- end
518
-
519
- it "should not be in contents" do
520
- expect(contents).to_not match "This content should not be in feed.</content>"
521
- end
522
- end
523
- end
524
- end
data/spec/spec_helper.rb DELETED
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "jekyll"
4
- require "typhoeus" unless Gem.win_platform?
5
- require "nokogiri"
6
- require "rss"
7
- require File.expand_path("../lib/jekyll-feed", __dir__)
8
-
9
- Jekyll.logger.log_level = :error
10
-
11
- RSpec.configure do |config|
12
- config.run_all_when_everything_filtered = true
13
- config.filter_run :focus
14
- config.order = "random"
15
-
16
- SOURCE_DIR = File.expand_path("fixtures", __dir__)
17
- DEST_DIR = File.expand_path("dest", __dir__)
18
-
19
- def source_dir(*files)
20
- File.join(SOURCE_DIR, *files)
21
- end
22
-
23
- def dest_dir(*files)
24
- File.join(DEST_DIR, *files)
25
- end
26
-
27
- def make_context(registers = {})
28
- Liquid::Context.new({}, {}, { :site => site }.merge(registers))
29
- end
30
- end