diff --git a/lib/data_uri/uri.rb b/lib/data_uri/uri.rb index 4a6f110..d89eded 100644 --- a/lib/data_uri/uri.rb +++ b/lib/data_uri/uri.rb @@ -33,6 +33,23 @@ def initialize(*args) @data.force_encoding(charset) end end + + def self.build(arg) + data = nil + content_type = nil + case arg + when IO + data = arg + when Hash + data = arg[:data] + content_type = arg[:content_type] + end + raise 'Invalid build argument: ' + arg.inspect unless data + if !content_type && data.respond_to?(:content_type) + content_type = data.content_type + end + new('data', nil, nil, nil, nil, nil, "#{content_type};base64,#{Base64.encode64(data.read).chop}", nil, nil) + end end @@schemes['DATA'] = Data diff --git a/test/test_data_uri.rb b/test/test_data_uri.rb index 7882ff4..a6009f0 100644 --- a/test/test_data_uri.rb +++ b/test/test_data_uri.rb @@ -4,64 +4,95 @@ describe URI::Data do - describe "a base64 encoded image/gif data URI" do - - before do - @base64 = "R0lGODlhAQABAIABAAAAAP///yH5BAEAAAEALAAAAAABAAEAQAICTAEAOw==" - @uri = URI.parse("data:image/gif;base64,#{@base64}") - end - - it "should parse as a URI::Data object" do - @uri.class.must_equal URI::Data + describe "parsing" do + + describe "a base64 encoded image/gif data URI" do + + before do + @base64 = "R0lGODlhAQABAIABAAAAAP///yH5BAEAAAEALAAAAAABAAEAQAICTAEAOw==" + @uri = URI.parse("data:image/gif;base64,#{@base64}") + end + + it "should parse as a URI::Data object" do + @uri.class.must_equal URI::Data + end + + it "should have a content_type of image/gif" do + @uri.content_type.must_equal 'image/gif' + end + + it "should have data" do + require 'base64' + @uri.data.must_equal Base64.decode64(@base64) + end + end - - it "should have a content_type of image/gif" do - @uri.content_type.must_equal 'image/gif' + + describe "a text/plain data URI" do + + before do + @uri = URI.parse("data:,A%20brief%20note") + end + + it "should parse as a URI::Data object" do + @uri.class.must_equal URI::Data + end + + it "should have a content_type of text/plain" do + @uri.content_type.must_equal 'text/plain' + end + + it "should have data" do + @uri.data.must_equal 'A brief note' + end + end - - it "should have data" do - require 'base64' - @uri.data.must_equal Base64.decode64(@base64) + + describe "a text/html data URI with a charset" do + + before do + @uri = URI.parse("data:text/html;charset=utf-8,%3C%21DOCTYPE%20html%3E%0D%0A%3Chtml%20lang%3D%22en%22%3E%0D%0A%3Chead%3E%3Ctitle%3EEmbedded%20Window%3C%2Ftitle%3E%3C%2Fhead%3E%0D%0A%3Cbody%3E%3Ch1%3E42%3C%2Fh1%3E%3C%2Fbody%3E%0A%3C%2Fhtml%3E%0A%0D%0A") + end + + it "should parse as a URI::Data object" do + @uri.class.must_equal URI::Data + end + + it "should have a content_type of text/html" do + @uri.content_type.must_equal 'text/html' + end + + it "should have data" do + @uri.data.must_equal "\r\n\r\n