segunda-feira, 11 de maio de 2009

Padrões de URLs com expressões regulares no Fakeweb

Ao usarmos o Fakeweb aqui onde trabalho encontramos a necessidade de registrar grupos de URLs de acordo com um padrão. Inspirado no Anselmo Alves, colega de minha equipe que corrigiu um bug nesta mesma gem, alterei-a de forma a permitir o registro de URLs utilizando regex.

Com essa alteração, se por exemplo você quiser que todas as chamadas a um determinado host sejam respondidas com uma determinada string, basta registrar como o mostrado abaixo:

FakeWeb.register_uri(:get, /programandosemcafeina\.blogspot\.com/, :string => "Meu blog")

O principal desafio no desenvolvimento dessa nova funcionalidade foi não quebrar compatibilidade com o uso anterior. Dessa forma, os registros de URLs absolutas passaram a ter uma prioridade maior independente da ordem em que forem registradas. Ou seja, os retornos de acordo com as expressões regulares só são executados se a URL absoluta solicitada não estiver registrada. Veja o exemplo abaixo:

FakeWeb.register_uri(:get, "http://programandosemcafeina.blogspot.com/search/label/rails", :string => "Label Rails")
FakeWeb.register_uri(:get, /programandosemcafeina\.blogspot\.com/, :string => "Meu blog")
FakeWeb.register_uri(:get, "http://programandosemcafeina.blogspot.com/search/label/ruby", :string => "Label Ruby")

Net::HTTP.get(URI.parse("http://programandosemcafeina.blogspot.com/search/label/rails"))
=> "Label Rails"

Net::HTTP.get(URI.parse("http://programandosemcafeina.blogspot.com/search/label/ruby"))
=> "Label Ruby"

Net::HTTP.get(URI.parse("http://programandosemcafeina.blogspot.com/search/label/rmagick"))
=> "Meu blog"

Já solicitei ao Chris Kampmeier a integração do meu fork, mas enquanto ela não é feita, você pode utilizar a gem gerada diretamente do meu repositório no Github. Basta intalar da seguinte forma:

gem sources -a http://gems.github.com
sudo gem install timotta-fakeweb

segunda-feira, 4 de maio de 2009

Undefined method request_uri com HTTParty

Dica rápida para quem está utilizando HTTParty: Se por um acaso você se deparar com o seguinde erro:

undefined method `request_uri' for #<URI::Generic:0xb03919c>
/mnt/apps/filmes/vendor/gems/httparty-0.3.1/lib/httparty/request.rb:56:in `setup_raw_request'
/mnt/apps/filmes/vendor/gems/httparty-0.3.1/lib/httparty/request.rb:39:in `perform'
/mnt/apps/filmes/vendor/gems/httparty-0.3.1/lib/httparty.rb:153:in `perform_request'
/mnt/apps/filmes/vendor/gems/httparty-0.3.1/lib/httparty.rb:119:in `get'
/mnt/apps/filmes/app/models/Filme.rb:25:in 'com_tags'

Não se desespere, URI:Generic realmente não possui o método request_uri. O problema é na incialização do HTTParty. Se base_uri estiver nulo qualquer requisição utilizando a classe obterá esse erro. Teste você mesmo algo como:

class A
include HTTParty
base_uri nil
format :xml
end

A.get('/search/label/ruby')

Ao corrigir a inicialização de base_uri o erro deixa de acontecer:

class A
include HTTParty
base_uri 'http://programandosemcafeina.blogspot.com'
format :xml
end

A.get('/search/label/ruby')

O problema é passível de ocorrer principalmente se base_uri for configurável de acordo com o ambiente em que a aplicação estiver rodando.