diff --git a/lib/microformats2.rb b/lib/microformats2.rb index 8515004..4359ecb 100644 --- a/lib/microformats2.rb +++ b/lib/microformats2.rb @@ -4,6 +4,7 @@ require "json" require "active_support/inflector" require "microformats2/version" +require "microformats2/absolute_uri" require "microformats2/parser" require "microformats2/format_parser" require "microformats2/property_parser" diff --git a/lib/microformats2/absolute_uri.rb b/lib/microformats2/absolute_uri.rb new file mode 100644 index 0000000..a28e0d0 --- /dev/null +++ b/lib/microformats2/absolute_uri.rb @@ -0,0 +1,26 @@ +module Microformats2 + class AbsoluteUri + attr_accessor :base, :relative + + def initialize(base, relative) + @base = base + @relative = relative + end + + def absolutize + return nil if relative.nil? or relative == "" + + uri = URI.parse(relative) + + if base && !uri.absolute? + uri = URI.join(base.to_s, relative.to_s) + end + + uri.normalize! + uri.to_s + + rescue URI::BadURIError, URI::InvalidURIError => e + relative.to_s + end + end +end diff --git a/lib/microformats2/collection.rb b/lib/microformats2/collection.rb index 8469ecc..5ed43e0 100644 --- a/lib/microformats2/collection.rb +++ b/lib/microformats2/collection.rb @@ -88,7 +88,7 @@ module Microformats2 if rel_values.member?("alternate") alternate_inst = {} - alternate_inst["url"] = absolutize(rel.attribute("href").text) + alternate_inst["url"] = Microformats2::AbsoluteUri.new(@base, rel.attribute("href").text).absolutize alternate_inst["rel"] = (rel_values - ["alternate"]).join(" ") unless rel.attribute("media").nil? alternate_inst["media"] = rel.attribute("media").text @@ -103,21 +103,10 @@ module Microformats2 else rel_values.each do |rel_value| @rels[rel_value] = [] unless @rels.has_key?(rel_value) - @rels[rel_value] << absolutize(rel.attribute("href").text) + @rels[rel_value] << Microformats2::AbsoluteUri.new(@base, rel.attribute("href").text).absolutize end end end end - - def absolutize(href) - uri = URI.parse(href) - - if @base && !uri.absolute? - uri = URI.join(@base, href) - end - - uri.normalize! - uri.to_s - end end end diff --git a/lib/microformats2/implied_property/url.rb b/lib/microformats2/implied_property/url.rb index 54ae407..26e0ea3 100644 --- a/lib/microformats2/implied_property/url.rb +++ b/lib/microformats2/implied_property/url.rb @@ -7,19 +7,7 @@ module Microformats2 end def to_s - @to_s = absolutize(super.to_s) if super.to_s != "" - end - - # TODO: make dry, repeated in Collection - def absolutize(href) - uri = URI.parse(href) - - if @base && !uri.absolute? - uri = URI.join(@base, href) - end - - uri.normalize! - uri.to_s + @to_s = Microformats2::AbsoluteUri.new(@base, super.to_s).absolutize end protected diff --git a/lib/microformats2/property/url.rb b/lib/microformats2/property/url.rb index 85847a6..c86c6b6 100644 --- a/lib/microformats2/property/url.rb +++ b/lib/microformats2/property/url.rb @@ -3,19 +3,7 @@ module Microformats2 class Url < Foundation def to_s - @to_s = absolutize(super.to_s) - end - - # TODO: make dry, repeated in Collection - def absolutize(href) - uri = URI.parse(href) - - if @base && !uri.absolute? - uri = URI.join(@base, href) - end - - uri.normalize! - uri.to_s + @to_s = Microformats2::AbsoluteUri.new(@base, super.to_s).absolutize end protected diff --git a/spec/lib/microformats2/absolute_uri_spec.rb b/spec/lib/microformats2/absolute_uri_spec.rb new file mode 100644 index 0000000..56b4ee5 --- /dev/null +++ b/spec/lib/microformats2/absolute_uri_spec.rb @@ -0,0 +1,48 @@ +require "spec_helper" +require "microformats2/absolute_uri" + +describe Microformats2::AbsoluteUri do + describe "#absolutize" do + subject { Microformats2::AbsoluteUri.new(base, relative).absolutize } + let(:base) { nil } + + context "when relative is nil" do + let(:relative) { nil } + it { should be_nil } + end + + context "when relative is an empty string" do + let(:relative) { "" } + it { should be_nil } + end + + context "when relative is a valid absolute URI" do + let(:relative) { "http://google.com" } + it { should eq("http://google.com/") } + end + + context "when relative is a valid non-absolute URI" do + let(:relative) { "bar/qux" } + + context "and base is present but not absolute" do + let(:base) { "foo" } + it { should eq("bar/qux") } + end + + context "and base is present and absolute" do + let(:base) { "http://google.com" } + it { should eq("http://google.com/bar/qux") } + end + + context "and base is not present" do + let(:base) { nil } + it { should eq("bar/qux") } + end + end + + context "when relative is an invalid URI" do + let(:relative) { "git@github.com:G5/microformats2.git" } + it { should eq("git@github.com:G5/microformats2.git") } + end + end +end