Sunday, April 5, 2009

Specifications for Images

‹prev | My Chain | next›

My first instinct in trying to specify how images should be accessed is to request them via the normal RSpec get method:
    describe 'GET /recipes/:permalink/:image' do
it "should retrieve the image" do
data = RestClient.get "#{@@db}/#{@permalink}"
recipe = JSON.parse(data)

RestClient.put "#{@@db}/#{@permalink}/sample.jpg?rev=#{recipe['_rev']}",
File.read('spec/fixtures/sample.jpeg'),
:content_type => 'image/jpeg'

get "/images/#{@permalink}/sample.jpg"
response.should be_ok
end
The RestClient.put call to attach the image is by-the-book CouchDB. Similarly, the the get call is idiomatic RSpec—but only when expecting a text-based response. When a binary response comes back, bad things happen:
cstrom@jaynestown:~/repos/eee-code$ ruby ./spec/eee_spec.rb
.F*

Pending:

eee a CouchDB recipe GET /recipes/:permalink/:image should return 404 for a non-existent image (TODO)
./spec/eee_spec.rb:55

1)
Rack::Lint::LintError in 'eee a CouchDB recipe GET /recipes/:permalink/:image should retrieve the image'
Body yielded non-string value "<lots and LOTS of binary data output>"
/home/cstrom/.gem/ruby/1.8/gems/rack-0.9.1/lib/rack/lint.rb:16:in `assert'
/home/cstrom/.gem/ruby/1.8/gems/rack-0.9.1/lib/rack/lint.rb:437:in `each'
/home/cstrom/.gem/ruby/1.8/gems/rack-0.9.1/lib/rack/lint.rb:435:in `each'
/home/cstrom/.gem/ruby/1.8/gems/rack-0.9.1/lib/rack/mock.rb:126:in `initialize'
/home/cstrom/.gem/ruby/1.8/gems/rack-0.9.1/lib/rack/mock.rb:70:in `new'
/home/cstrom/.gem/ruby/1.8/gems/rack-0.9.1/lib/rack/mock.rb:70:in `request'
/home/cstrom/.gem/ruby/1.8/gems/sinatra-0.9.1.1/lib/sinatra/test.rb:41:in `make_request'
/home/cstrom/.gem/ruby/1.8/gems/sinatra-0.9.1.1/lib/sinatra/test.rb:44:in `get'
./spec/eee_spec.rb:50:
./spec/eee_spec.rb:3:

Finished in 0.0737 seconds

3 examples, 1 failure, 1 pending
I would try to make a RestClient call directly to the Sinatra sever—if it were running. Unfortunately, it is not—RSpec merely pretends that it is running.

My ultimate solution is completely unsatisfactory to me. I spec the errors that the testing environment gives me:
    describe 'GET /recipes/:permalink/:image' do
it "should retrieve the image" do
data = RestClient.get "#{@@db}/#{@permalink}"
recipe = JSON.parse(data)

RestClient.put "#{@@db}/#{@permalink}/sample.jpg?rev=#{recipe['_rev']}",
File.read('spec/fixtures/sample.jpg'),
:content_type => 'image/jpeg'


lambda { get "/images/#{@permalink}/sample.jpg" }.
should raise_error(Rack::Lint::LintError)
end

it "should return 404 for a non-existent image" do
get "/images/#{@permalink}/sample2.jpg"
response.should be_not_found
end
end
Maybe slightly better than not spec'ing at all, but at least it allows me to implement:
get '/images/:permalink/:image' do
content_type 'image/jpeg'
begin
RestClient.get "#{@@db}/#{params[:permalink]}/#{params[:image]}"
rescue
404
end
end
(commit)

No comments:

Post a Comment