Skip to content
Browse files

Allow feeds to be restricted to a particular subset of snips.

This sidesteps a deeper issue - not all snips can be rendered directly. For example, attempting to render the `link_to` snip results in an error, and other snips seem to result in infinite loops. This will be addressed later.

Upgrading to the latest `soup` gem gives a controlled mechanism for stubbing the contents of an app soup, which is useful in this case, although I did spend a lot of time kicking around until I figured out that I also needed to explicitly add the contents of the snips I wanted to test in the stubbed soup.
  • Loading branch information...
1 parent 6291dd7 commit 33330aa17ac2ae166e3c9435c8e8596a479ad456 @lazyatom committed Jul 29, 2011
View
4 Gemfile.lock
@@ -9,7 +9,7 @@ PATH
rack (>= 0.9.1)
rack-test (>= 0.5.7)
ratom (>= 0.3.5)
- soup (>= 1.0.8)
+ soup (>= 1.0.9)
GEM
remote: http://rubygems.org/
@@ -58,7 +58,7 @@ GEM
ffi (>= 1.0.7)
json_pure
rubyzip
- soup (1.0.8)
+ soup (1.0.9)
xpath (0.1.3)
nokogiri (~> 1.3)
View
2 Rakefile
@@ -54,7 +54,7 @@ if Object.const_defined?(:Gem)
# All the other gems we need.
s.add_dependency("rack", ">= 0.9.1")
- s.add_dependency("soup", ">= 1.0.8")
+ s.add_dependency("soup", ">= 1.0.9")
s.add_dependency("ratom", ">= 0.3.5")
s.add_dependency("RedCloth", ">= 4.1.1")
s.add_dependency("BlueCloth", ">= 1.0.0")
View
12 lib/vanilla/atom_feed.rb
@@ -8,9 +8,17 @@ def initialize(params={})
@domain = params[:domain] || "yourdomain.example.com"
@title = params[:title] || domain
@app = params[:app]
- @snips = params[:snips] || app.soup.all_snips
+ @criteria = params[:matching]
+ @snips = params[:snips]
+ if @snips.nil?
+ if @criteria.nil?
+ @snips = app.soup.all_snips
+ else
+ @snips = app.soup[@criteria]
+ end
+ end
end
-
+
def to_s
Atom::Feed.new do |f|
f.title = title
View
6 lib/vanilla/test_helper.rb
@@ -2,10 +2,12 @@
require "rack/test"
require "tmpdir"
require "fileutils"
+require "soup"
module Vanilla
module TestHelper
include Rack::Test::Methods
+ include Soup::TestHelper
def app(klass=Vanilla.apps.first)
unless @__app
@@ -54,5 +56,9 @@ def test_soup_path
def vanilla_teardown
FileUtils.rm_rf(test_soup_path)
end
+
+ def stub_app_soup(*snips)
+ app.stubs(:soup).returns(stub_soup(*snips))
+ end
end
end
View
7 pristine_app/soups/base/feed.rb
@@ -1,8 +1,11 @@
+require "vanilla/dynasnip"
+
class Feed < Dynasnip
def handle(*args)
app.atom_feed({
- :domain => "yourdomain.example.com", # change this!
- :title => "My Feed", # and this!
+ :domain => "yourdomain.example.com", # change this
+ :title => "My Feed", # and this,
+ :matching => {:kind => "blog"}, # but probably not this, although you can if you like.
})
end
self
View
69 test/core/atom_feed_test.rb
@@ -3,49 +3,70 @@
context "An atom feed" do
should "include snips" do
- stub_soup({:name => "Hello", :content => "This is the content"},
- {:name => "Goodbye", :content => "More content"})
+ stub_app_soup({:name => "Hello", :content => "This is the content"},
+ {:name => "Goodbye", :content => "More content"})
feed_xml = Vanilla::AtomFeed.new(:domain => "yourdomain.example.com", :app => app).to_s
feed = Atom::Feed.load_feed(feed_xml)
assert_equal 2, feed.entries.length
end
should "ensure that all links are made absolute" do
- stub_soup({:name => "alpha", :content => %|alpha <a href="/beta">beta</a>.|},
- {:name => "beta", :content => %|beta <a href='/alpha'>alpha</a>.|})
+ stub_app_soup({:name => "x", :content => %|<a href="/x">x</a>.|})
- assert get_feed.entries[0].content =~ %r{http://yourdomain\.example\.com/beta},
- "making double-quoted links external should work"
- assert get_feed.entries[1].content =~ %r{http://yourdomain\.example\.com/alpha},
- "making single-quoted links external should work"
+ feed = get_feed
+ assert feed.entries.first.content =~ %r{http://yourdomain\.example\.com/x},
+ "double-quoted links external should work (got: #{feed.entries.first.content})"
+
+
+ stub_app_soup({:name => "x", :content => %|<a href='/x'>x</a>.|})
+
+ feed = get_feed
+ assert feed.entries.first.content =~ %r{http://yourdomain\.example\.com/x},
+ "single-quoted links external should work (got: #{feed.entries.first.content})"
end
should "allow inclusion of only specific snips" do
snip_a_data = {:name => "a", :content => "x"}
snip_b_data = {:name => "b", :content => "x"}
- stub_soup(snip_a_data, snip_b_data)
-
- feed_xml = app.atom_feed(:domain => "whatever", :snips => [snip(snip_a_data)]).to_s
+ stub_app_soup(snip_a_data, snip_b_data)
+
+ feed_xml = app.atom_feed(:domain => "whatever", :snips => [app.soup["a"]]).to_s
feed = Atom::Feed.load_feed(feed_xml)
assert_equal 1, feed.entries.length
assert_equal "a", feed.entries.first.title
end
+ should "allow filtering of snips by matching criteria" do
+ stub_app_soup({:name => "a", :content => "x", :kind => "blog"},
+ {:name => "b", :content => "x", :kind => "draft"},
+ {:name => "c", :content => "x", :kind => "blog"})
+
+ feed_xml = app.atom_feed(:domain => "whatever", :matching => {:kind => "blog"}).to_s
+ feed = Atom::Feed.load_feed(feed_xml)
+ assert_equal 2, feed.entries.length
+ assert_equal ["a", "c"], feed.entries.map { |e| e.title }
+ end
+
should "set updated to be the latest updated_at of the included snips" do
snip_a_data = {:name => "a", :content => "x", :updated_at => Time.parse("2011-05-22 12:00")}
snip_b_data = {:name => "b", :content => "x", :updated_at => Time.parse("2011-05-23 12:34")}
snip_c_data = {:name => "c", :content => "x", :updated_at => Time.parse("2011-05-24 12:34")}
- stub_soup(snip_a_data, snip_b_data, snip_c_data)
-
- feed_xml = app.atom_feed(:domain => "whatever", :snips => [snip(snip_a_data), snip(snip_b_data)]).to_s
+ stub_app_soup(snip_a_data, snip_b_data, snip_c_data)
+
+ feed_xml = app.atom_feed(:domain => "whatever", :snips => [app.soup["a"], app.soup["b"]]).to_s
feed = Atom::Feed.load_feed(feed_xml)
assert_equal Time.parse("2011-05-23 12:34"), feed.updated
end
+ should "work even without any snips" do
+ feed_xml = app.atom_feed(:domain => "whatever", :snips => []).to_s
+ feed = Atom::Feed.load_feed(feed_xml)
+ end
+
context "title" do
setup do
- stub_soup
+ stub_app_soup
end
should "be settable via the initialiser" do
@@ -63,8 +84,8 @@
context "entry" do
setup do
- stub_soup({:name => "Hello", :content => "The *content*",
- :render_as => "markdown", :created_at => Time.parse("2011-01-01 12:23").to_s})
+ stub_app_soup({:name => "Hello", :content => "The *content*",
+ :render_as => "markdown", :created_at => Time.parse("2011-01-01 12:23").to_s})
end
context "titles" do
@@ -73,7 +94,7 @@
end
should "use the title of the snip if present" do
- stub_soup({:name => "hello-mammy", :content => "x", :title => "Hello, Mammy"})
+ stub_app_soup({:name => "hello-mammy", :content => "x", :title => "Hello, Mammy"})
assert_equal "Hello, Mammy", get_feed.entries.first.title
end
end
@@ -84,7 +105,7 @@
end
should "set the authors if the snip provides" do
- stub_soup({:name => "a", :content => "x", :author => "james"})
+ stub_app_soup({:name => "a", :content => "x", :author => "james"})
assert_equal ["james"], get_feed.entries.first.authors.map { |a| a.name }
end
end
@@ -112,7 +133,7 @@
end
should "set the updated at to the snip attribute if it exists" do
- stub_soup({:name => "Hello", :content => "the content", :updated_at => Time.parse("2011-01-02 13:45").to_s})
+ stub_app_soup({:name => "Hello", :content => "the content", :updated_at => Time.parse("2011-01-02 13:45").to_s})
assert_equal Time.parse("2011-01-02 13:45"), get_feed.entries.first.updated
end
end
@@ -124,12 +145,4 @@ def get_feed
feed_xml = app.atom_feed(:domain => "yourdomain.example.com").to_s
Atom::Feed.load_feed(feed_xml)
end
-
- def stub_soup(*snips)
- app.soup.stubs(:all_snips).returns(snips.map { |s| snip({:created_at => Time.now}.merge(s)) })
- end
-
- def snip(attributes)
- Soup::Snip.new(attributes, nil)
- end
end
View
23 test/pristine_app/feed_test.rb
@@ -1,10 +1,13 @@
require "test_helper"
require "atom"
+require "base/feed"
context "The feed dynasnip" do
- should "include snips" do
- stub_soup({:name => "Hello", :content => "This is the content"},
- {:name => "Goodbye", :content => "More content"})
+ should "include snips of the specified kind" do
+ stub_app_soup({:name => "Hello", :content => "This is the content", :kind => "blog"},
+ {:name => "Goodbye", :content => "More content", :kind => "blog"},
+ {:name => "system", :content => "not to be shown"},
+ Feed.snip_attributes)
visit "/feed.xml"
@@ -13,21 +16,13 @@
end
should "included rendered snip contents" do
- stub_soup({:name => "Hello", :content => "This is *the* content", :render_as => "markdown"})
+ stub_app_soup({:name => "Hello", :content => "This is *the* content",
+ :render_as => "markdown", :kind => "blog"},
+ Feed.snip_attributes)
visit "/feed.xml"
feed = Atom::Feed.load_feed(page.source)
assert_equal "<p>This is <em>the</em> content</p>", feed.entries.first.content
end
-
- private
-
- def stub_soup(*snips)
- app.soup.stubs(:all_snips).returns(snips.map { |s| snip({:created_at => Time.now}.merge(s)) })
- end
-
- def snip(attributes)
- Soup::Snip.new(attributes, nil)
- end
end
View
1 test/pristine_app/test_helper.rb
@@ -7,6 +7,7 @@
require 'capybara/dsl'
require File.expand_path("../../../pristine_app/application", __FILE__)
+$LOAD_PATH.unshift File.expand_path("../../../pristine_app/soups", __FILE__)
module TestHelper
include Vanilla::TestHelper
View
12 vanilla.gemspec
@@ -6,7 +6,7 @@ Gem::Specification.new do |s|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["James Adam"]
- s.date = %q{2011-07-25}
+ s.date = %q{2011-07-29}
s.default_executable = %q{vanilla}
s.email = %q{james@lazyatom.com.com}
s.executables = ["vanilla"]
@@ -18,6 +18,7 @@ Gem::Specification.new do |s|
"README",
".gemtest",
"test/core",
+ "test/core/atom_feed_test.rb",
"test/core/configuration_test.rb",
"test/core/dynasnip_test.rb",
"test/core/renderers",
@@ -45,6 +46,7 @@ Gem::Specification.new do |s|
"test/pristine_app/test_helper.rb",
"lib/vanilla",
"lib/vanilla/app.rb",
+ "lib/vanilla/atom_feed.rb",
"lib/vanilla/config.rb",
"lib/vanilla/console.rb",
"lib/vanilla/dynasnip.rb",
@@ -74,6 +76,7 @@ Gem::Specification.new do |s|
"pristine_app/README",
"pristine_app/soups",
"pristine_app/soups/base",
+ "pristine_app/soups/base/feed.rb",
"pristine_app/soups/base/layout.snip",
"pristine_app/soups/base/start.snip",
"pristine_app/soups/extras",
@@ -84,7 +87,6 @@ Gem::Specification.new do |s|
"pristine_app/soups/system",
"pristine_app/soups/system/current_snip.rb",
"pristine_app/soups/system/debug.rb",
- "pristine_app/soups/system/feed.rb",
"pristine_app/soups/system/index.rb",
"pristine_app/soups/system/link_to.rb",
"pristine_app/soups/system/link_to_current_snip.rb",
@@ -124,7 +126,7 @@ Gem::Specification.new do |s|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
s.add_runtime_dependency(%q<rack>, [">= 0.9.1"])
- s.add_runtime_dependency(%q<soup>, [">= 1.0.8"])
+ s.add_runtime_dependency(%q<soup>, [">= 1.0.9"])
s.add_runtime_dependency(%q<ratom>, [">= 0.3.5"])
s.add_runtime_dependency(%q<RedCloth>, [">= 4.1.1"])
s.add_runtime_dependency(%q<BlueCloth>, [">= 1.0.0"])
@@ -137,7 +139,7 @@ Gem::Specification.new do |s|
s.add_development_dependency(%q<launchy>, [">= 0"])
else
s.add_dependency(%q<rack>, [">= 0.9.1"])
- s.add_dependency(%q<soup>, [">= 1.0.8"])
+ s.add_dependency(%q<soup>, [">= 1.0.9"])
s.add_dependency(%q<ratom>, [">= 0.3.5"])
s.add_dependency(%q<RedCloth>, [">= 4.1.1"])
s.add_dependency(%q<BlueCloth>, [">= 1.0.0"])
@@ -151,7 +153,7 @@ Gem::Specification.new do |s|
end
else
s.add_dependency(%q<rack>, [">= 0.9.1"])
- s.add_dependency(%q<soup>, [">= 1.0.8"])
+ s.add_dependency(%q<soup>, [">= 1.0.9"])
s.add_dependency(%q<ratom>, [">= 0.3.5"])
s.add_dependency(%q<RedCloth>, [">= 4.1.1"])
s.add_dependency(%q<BlueCloth>, [">= 1.0.0"])

0 comments on commit 33330aa

Please sign in to comment.
Something went wrong with that request. Please try again.