jekyll-feed 0.13.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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