<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Keep Learning &#187; Rails</title>
	<atom:link href="http://blog.lucashungaro.com/category/rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.lucashungaro.com</link>
	<description>Conhecimento nunca é o bastante</description>
	<lastBuildDate>Sat, 03 Sep 2011 19:36:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>SOLID Ruby: Single Responsibility Principle</title>
		<link>http://blog.lucashungaro.com/2011/05/04/solid-ruby-single-responsibility-principle/</link>
		<comments>http://blog.lucashungaro.com/2011/05/04/solid-ruby-single-responsibility-principle/#comments</comments>
		<pubDate>Wed, 04 May 2011 05:34:38 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://blog.lucashungaro.com/?p=409</guid>
		<description><![CDATA[Utilizamos BDD e técnicas do programação orientada a objetos não apenas para obter código mais limpo e bonito. Na verdade, essas são consequências do principal objetivo: criar código que tenha baixo custo de manutenção, isto é, não demande muito tempo e pessoas para correções e melhorias. Um conjunto de técnicas que podemos utilizar para atingir [...]]]></description>
			<content:encoded><![CDATA[<p>Utilizamos BDD e técnicas do programação orientada a objetos não apenas para obter código mais limpo e bonito. Na verdade, essas são consequências do principal objetivo: criar código que tenha baixo custo de manutenção, isto é, não demande muito tempo e pessoas para correções e melhorias.</p>
<p>Um conjunto de técnicas que podemos utilizar para atingir esse objetivo é chamada de <a href="http://en.wikipedia.org/wiki/Solid_(object-oriented_design)">SOLID</a>, um acrônimo que representa cinco técnicas:</p>
<ul>
<li>Single Responsibility Principle</li>
<li>Open-Closed Principle</li>
<li>Liskov Substitution Principle</li>
<li>Interface Segregation Principle</li>
<li>Dependency Inversion Principle</li>
</ul>
<p>O objetivo desses princípios é fazer com que alterações necessárias sejam feitas no menor número possível de locais no código. Em outras palavras, é diminuir o custo dessas mudanças através de um design que reduz os efeitos colaterais das modificações.</p>
<p>Nesse artigo vou mostrar um pouco sobre a aplicação do <a href="http://en.wikipedia.org/wiki/Single_responsibility_principle">Single Responsibility Principle</a> em Ruby.</p>
<p>Esse princípio nos diz que uma classe deve ter apenas uma responsabilidade e deve executá-la por completo (não devem haver outras classes que executem partes dela). É uma forma de conseguir alta <a href="http://en.wikipedia.org/wiki/Cohesion_(computer_science)">coesão</a>, uma qualidade desejável em código orientado a objetos. Uma classe coesa executa completamente uma responsabilidade, ou seja, essa responsabilidade não fica fragmentada e espalhada entre diferentes entidades no domínio.</p>
<p>Uma forma de pensar sobre o que é uma responsabilidade para facilitar a absorção do conceito é que esta representa <em>uma razão para mudar</em>. Então podemos definir o princípio como: uma classe tem uma e apenas uma razão para mudar.</p>
<p>Vamos a um exemplo de um modelo ActiveRecord que viola esse princípio (alerta para pseudo-código que nem deve funcionar, é apenas um exemplo):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Game <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  belongs_to <span style="color:#ff3333; font-weight:bold;">:category</span>
  validates_presence_of <span style="color:#ff3333; font-weight:bold;">:title</span>, <span style="color:#ff3333; font-weight:bold;">:category_id</span>, <span style="color:#ff3333; font-weight:bold;">:description</span>,
                        <span style="color:#ff3333; font-weight:bold;">:price</span>, <span style="color:#ff3333; font-weight:bold;">:platform</span>, <span style="color:#ff3333; font-weight:bold;">:year</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> get_official_price
    <span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;http://thegamedatabase.com/api/game/#{name}/price?api_key=ek2o1je&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#CC0066; font-weight:bold;">print</span>
    <span style="color:#006600; font-weight:bold;">&lt;&lt;-</span>EOF
      <span style="color:#008000; font-style:italic;">#{name}, #{platform}, #{year} </span>
      current value is <span style="color:#008000; font-style:italic;">#{get_official_price}</span>
    EOF
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Esse modelo tem como sua responsabilidade principal cuidar da lógica de negócio ligada à entidade Game. Porém, como podemos ver aqui, ele também está responsável por consultar um webservice para obter a cotação do jogo e por formatar sua exibição. Essa implementação possui baixa coesão pois essa classe possui mais de um motivo para mudar. Ela será alterada se os requisitos de validação de dados mudarem, se algum detalhe da chamada do webservice mudar ou se precisarmos exibir seus dados numa formatação diferente.</p>
<p>Uma forma de resolver isso seria desmembrar essa classe tendo esse resultado:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Game <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  belongs_to <span style="color:#ff3333; font-weight:bold;">:category</span>
  validates_presence_of <span style="color:#ff3333; font-weight:bold;">:title</span>, <span style="color:#ff3333; font-weight:bold;">:category_id</span>, <span style="color:#ff3333; font-weight:bold;">:description</span>,
                        <span style="color:#ff3333; font-weight:bold;">:price</span>, <span style="color:#ff3333; font-weight:bold;">:platform</span>, <span style="color:#ff3333; font-weight:bold;">:year</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> GamePriceService
  attr_accessor <span style="color:#ff3333; font-weight:bold;">:game</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># we could use a config file</span>
  BASE_URL = <span style="color:#996600;">&quot;http://thegamedatabase.com/api/game&quot;</span>
  API_KEY = <span style="color:#996600;">&quot;ek2o1je&quot;</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>game<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">game</span> = game
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> get_price
    data = <span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;#{BASE_URL}/#{game.name}/price?api_key=#{API_KEY}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    JsonParserLib.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span>data<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> GamePrinter
  attr_accessor <span style="color:#ff3333; font-weight:bold;">:game</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>game<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">game</span> = game
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#CC0066; font-weight:bold;">print</span>
    price_service = GamePriceService.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>game<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#006600; font-weight:bold;">&lt;&lt;-</span>EOF
      <span style="color:#008000; font-style:italic;">#{game.name}, #{game.platform}, #{game.year} </span>
      current value is <span style="color:#008000; font-style:italic;">#{price_service.get_price[:value]}</span>
    EOF
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Assim aumentamos bastante a coesão de nosso sofware. Cada classe possui apenas uma razão para mudar e atende ao SRP.</p>
<p>Um exemplo mais real pode ser visto no modelo <a href="https://github.com/spree/spree/blob/master/core/app/models/creditcard.rb">Creditcard</a> do <a href="http://spreecommerce.com/">Spree</a>. Note que, entre outras coisas, o modelo também é responsável pelos processos de compra e autorização do cartão (métodos purchase e authorize). Note como esse métodos implementam parte do processo e delegam outras partes para outros componentes quando a responsabilidade deveria ser 100% realizada em outra parte. Isso cria baixa coesão (múltiplas responsabilidades por classe) e alto acoplamento (uma responsabilidade dividida por várias classes interdependentes).</p>
<p>Como um exercício a parte podemos pensar sobre até que ponto modelos do ActiveRecord quebram o SRP por serem responsáveis por persistência e lógica de negócios (que inclui validação de dados). Há muitos desenvolvedores dos dois lados nessa questão. Acredito que há pequenas violações mas de uma forma não prejudicial, já que a persistência é implementada por uma classe especializada e apenas herdada em nossos modelos, de forma que essa é delegada ao framework (que cuida de possíveis modificações necessárias à persistência).</p>
<p>É preciso ter em mente que ser muito extremista com esses princípios também pode levar à problemas e a um excesso de preciosismo que torna-se prejudicial.</p>
<p>Bom, a partir daqui vamos para outros artigos onde serão explorados os outros princípios. O pseudo-código utilizado no exemplo acima ainda tem algumas coisas a ganhar através da aplicação de outros princípios.</p>
<p>Leitura recomendada:</p>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Cohesion_(computer_science)">Cohesion</a></li>
<li><a href="http://en.wikipedia.org/wiki/Coupling_(computer_science)">Coupling</a></li>
<li><a href="http://en.wikipedia.org/wiki/Separation_of_concerns">Separation of concerns</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.lucashungaro.com/2011/05/04/solid-ruby-single-responsibility-principle/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Dica rápida: formatação da saída do Test::Unit com a gem turn</title>
		<link>http://blog.lucashungaro.com/2011/01/26/dica-rapida-formatacao-da-saida-do-test-unit-com-a-gem-turn/</link>
		<comments>http://blog.lucashungaro.com/2011/01/26/dica-rapida-formatacao-da-saida-do-test-unit-com-a-gem-turn/#comments</comments>
		<pubDate>Wed, 26 Jan 2011 20:06:23 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Gem]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Test-Driven Development]]></category>

		<guid isPermaLink="false">http://blog.lucashungaro.com/?p=402</guid>
		<description><![CDATA[Recentemente voltei a brincar com um pet project para atualizá-lo do Rails 2.3 para o Rails 3. A suíte de testes do projeto foi escrita com Test::Unit e Shoulda e, quando a executei sob Ruby 1.9.2, vi que a saída não estava formatada, isto é, não havia alinhamento, as falhas não ficavam em vermelho e [...]]]></description>
			<content:encoded><![CDATA[<p>Recentemente voltei a brincar com um pet project para atualizá-lo do Rails 2.3 para o Rails 3. A suíte de testes do projeto foi escrita com Test::Unit e Shoulda e, quando a executei sob Ruby 1.9.2, vi que a saída não estava formatada, isto é, não havia alinhamento, as falhas não ficavam em vermelho e os sucessos em verde. Pelo que me lembro, quando rodava esses testes no Ruby 1.8, a saída era formatada e com cores. Provavelmente algo que foi retirado do Ruby 1.9, talvez na mudança de Test::Unit para MiniTest.</p>
<p>Bem, não me preocupei muito com o motivo disso. Busquei algumas maneiras de formatar essa saída e, entre outras, encontrei a gem <a href="https://github.com/TwP/turn">turn</a>. Configurei-a no Gemfile do projeto e tudo funcionou perfeitamente de primeira, sem nenhum incômodo. Além da formatação, uma feature interessante é que, ao invés de mostrar pontinhos e letras (ex: …..F…F.), o turn vai mostrando as descrições dos testes e seu status (passou/falhou) à medida que a suite é executada. Feedback bem mais útil.</p>
<p>Veja um exemplo de como fica a formatação através desse link: <a href="http://d.pr/mWPe">http://d.pr/mWPe</a> (assim não quebro todo o layout do blog). <img src='http://blog.lucashungaro.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lucashungaro.com/2011/01/26/dica-rapida-formatacao-da-saida-do-test-unit-com-a-gem-turn/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Utilizando rack-debug para debugging com Passenger</title>
		<link>http://blog.lucashungaro.com/2009/09/10/utilizando-rack-debug-para-debugging-com-passenger/</link>
		<comments>http://blog.lucashungaro.com/2009/09/10/utilizando-rack-debug-para-debugging-com-passenger/#comments</comments>
		<pubDate>Thu, 10 Sep 2009 20:06:27 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=294</guid>
		<description><![CDATA[Desenvolver aplicações Rails utilizando o Phusion Passenger (principalmente no Mac OS X com o Passenger preference pane) é muito prático. Porém, uma coisa que logo senti falta foi a possibilidade de utilizar a gem ruby-debug quando precisava de breakpoints para debuggar o código. Uma maneira de conseguir isso é através da gem/plugin rack-debug. Para utilizá-la, [...]]]></description>
			<content:encoded><![CDATA[<p>Desenvolver aplicações Rails utilizando o <a target="_blank" href="http://www.modrails.com/">Phusion Passenger</a> (principalmente no Mac OS X com o <a target="_blank" href="http://www.fngtps.com/passenger-preference-pane">Passenger preference pane</a>) é muito prático. Porém, uma coisa que logo senti falta foi a possibilidade de utilizar a gem <a target="_blank" href="http://rubyforge.org/projects/ruby-debug/">ruby-debug</a> quando precisava de breakpoints para <em>debuggar</em> o código.</p>
<p>Uma maneira de conseguir isso é através da gem/plugin <a target="_blank" href="http://github.com/ddollar/rack-debug/tree/master">rack-debug</a>. Para utilizá-la, segui os passos abaixo.</p>
<p>1. Instalação</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"> $ script<span style="color: #000000; font-weight: bold;">/</span>plugin <span style="color: #c20cb9; font-weight: bold;">install</span> <span style="color: #c20cb9; font-weight: bold;">git</span>:<span style="color: #000000; font-weight: bold;">//</span>github.com<span style="color: #000000; font-weight: bold;">/</span>ddollar<span style="color: #000000; font-weight: bold;">/</span>rack-debug.git
&nbsp;
 <span style="color: #666666; font-style: italic;"># config/environments/development.rb</span>
 config.middleware.use <span style="color: #ff0000;">&quot;Rack::Debug&quot;</span></pre></div></div>

<p>2. Chamar o debugger onde necessário:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> create
    <span style="color:#0066ff; font-weight:bold;">@status</span> = current_user.<span style="color:#9900CC;">statuses</span>.<span style="color:#9900CC;">create</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:status</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    debugger
    <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@status</span>.<span style="color:#9900CC;">valid</span>?
...</pre></div></div>

<p>3. Conectar-se ao debugger</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"> <span style="color: #666666; font-style: italic;"># No diretório da aplicação, chamar a task rake</span>
 $ rake debug
 Connected.</pre></div></div>

<p>4. Ao executar a linha onde o debugger foi chamado, a aplicação para e você tem acesso ao console do debugger</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"> <span style="color:#006600; font-weight:bold;">&#40;</span>rdb:<span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#CC0066; font-weight:bold;">p</span> <span style="color:#0066ff; font-weight:bold;">@status</span>
 <span style="color:#008000; font-style:italic;">#&lt;status id: 231, text: &quot;Testing rack-debug&quot;, user_id: 4, ...&gt;</span></pre></div></div>

<p>Pronto. Happy debugging! <img src='http://blog.lucashungaro.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>Update</strong>: ao chamar a task rake, pode ocorrer um erro com a mensagem &#8220;Server is not running or Passenger has spooled down&#8221;. Neste caso, reinicie o Apache e tudo deve funcionar normalmente.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lucashungaro.com/2009/09/10/utilizando-rack-debug-para-debugging-com-passenger/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Testes envolvendo tempo: usando a gem time-warp</title>
		<link>http://blog.lucashungaro.com/2009/08/28/testes-envolvendo-tempo-usando-a-gem-time-warp/</link>
		<comments>http://blog.lucashungaro.com/2009/08/28/testes-envolvendo-tempo-usando-a-gem-time-warp/#comments</comments>
		<pubDate>Fri, 28 Aug 2009 16:46:23 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Test-Driven Development]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=269</guid>
		<description><![CDATA[É comum que precisemos &#8220;manipular o tempo&#8221; quando escrevendo testes para código cujo comportamento depende do momento no tempo. Uma técnica comum é utilizar um mock ou stub na classe Time do Ruby para manipular o horário de acordo com o desejado. Isso vai contra um princípio importante do uso de fake objects em testes: [...]]]></description>
			<content:encoded><![CDATA[<p>É comum que precisemos &#8220;manipular o tempo&#8221; quando escrevendo testes para código cujo comportamento depende do momento no tempo.</p>
<p>Uma técnica comum é utilizar um mock ou stub na classe Time do Ruby para manipular o horário de acordo com o desejado. Isso vai contra um princípio importante do uso de fake objects em testes: &#8220;<a target="_blank" href="http://www.infoq.com/news/2008/08/Mock-Roles-Pryce-and-Freeman">Não use fakes em objetos que não são seus</a>&#8220;. Na maioria do tempo isso pode não causar problemas, mas alterar o comportamento de uma classe usada internamente pela linguagem não soa bem e pode causar bugs difíceis de rastrear.</p>
<p>Aí entra a gem <a target="_blank" href="http://github.com/iridesco/time-warp/tree/master">time-warp</a>. Ela ainda trabalha sobre as classes do Ruby, mas provê uma camada específica para testes para todo código executado em um bloco definido pelo programador. Um exemplo de uso (da <a target="_blank" href="http://twtapp.info/">nossa aplicação feita para o Rails Rumble</a>):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">it <span style="color:#996600;">&quot;should only silence tweets with the desired word inside the configured time interval&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  pretend_now_is<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>.<span style="color:#9900CC;">utc</span>.<span style="color:#9900CC;">beginning_of_day</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span>.<span style="color:#9900CC;">hour</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    tweet1.<span style="color:#9900CC;">sent_at</span> = <span style="color:#006666;">2</span>.<span style="color:#9900CC;">minutes</span>.<span style="color:#9900CC;">ago</span>
    tweet2.<span style="color:#9900CC;">sent_at</span> = <span style="color:#006666;">32</span>.<span style="color:#9900CC;">minutes</span>.<span style="color:#9900CC;">from_now</span>
    tweet3.<span style="color:#9900CC;">sent_at</span> = <span style="color:#006666;">1</span>.<span style="color:#9900CC;">hour</span>.<span style="color:#9900CC;">from_now</span>
&nbsp;
    collection = <span style="color:#006600; font-weight:bold;">&#91;</span>tweet1, tweet2, tweet3<span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
    Silencer.<span style="color:#9900CC;">apply</span><span style="color:#006600; font-weight:bold;">&#40;</span>collection, <span style="color:#006600; font-weight:bold;">&#123;</span>:word <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;soccer&quot;</span>, :<span style="color:#9966CC; font-weight:bold;">until</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">30</span>.<span style="color:#9900CC;">minutes</span>.<span style="color:#9900CC;">from_now</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  tweet1.<span style="color:#9900CC;">should</span> be_filtered
  tweet2.<span style="color:#9900CC;">should</span> be_filtered
  tweet3.<span style="color:#9900CC;">should_not</span> be_filtered
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>A gem adiciona o método &#8220;pretend_now_is&#8221;, que recebe um parâmetro com o horário desejado e um bloco. Dentro desse bloco, todo código executado é &#8220;transportado no tempo&#8221; para o horário definido. Além de tornar a manipulação das classes de tempo mais segura, o código fica muito mais elegante.</p>
<p>Veja mais detalhes no <a target="_blank" href="http://github.com/iridesco/time-warp/blob/884623fec90687c7f3c28b8e8074a39c96946cbb/README.md">README da gem</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lucashungaro.com/2009/08/28/testes-envolvendo-tempo-usando-a-gem-time-warp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slides e notas da minha sessão no FISL10</title>
		<link>http://blog.lucashungaro.com/2009/06/25/slides-e-notas-da-minha-sessao-no-fisl10/</link>
		<comments>http://blog.lucashungaro.com/2009/06/25/slides-e-notas-da-minha-sessao-no-fisl10/#comments</comments>
		<pubDate>Thu, 25 Jun 2009 16:52:25 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Apresentações]]></category>
		<category><![CDATA[Eventos]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Test-Driven Development]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=228</guid>
		<description><![CDATA[Pessoal, abaixo está o link para download, em formato PDF, dos slides com notas que eu utilizei na minha sessão ontem no FISL10, entitulada &#8220;TDD e Rails: Mais rápido, mais forte e melhor&#8221;. Download. Obrigado a todos que apareceram por lá! Qualquer feedback é muito bem-vindo.]]></description>
			<content:encoded><![CDATA[<p>Pessoal, abaixo está o link para download, em formato PDF, dos slides com notas que eu utilizei na minha sessão ontem no FISL10, entitulada &#8220;TDD e Rails: Mais rápido, mais forte e melhor&#8221;.</p>
<p><a href="http://makemesimple.com/files/fisl10.pdf" target="_blank">Download</a>.</p>
<p>Obrigado a todos que apareceram por lá! Qualquer feedback é muito bem-vindo. <img src='http://blog.lucashungaro.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lucashungaro.com/2009/06/25/slides-e-notas-da-minha-sessao-no-fisl10/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Ruby Quick Tip: Aprendendo através de testes</title>
		<link>http://blog.lucashungaro.com/2009/02/08/ruby-quick-tip-aprendendo-atraves-de-testes/</link>
		<comments>http://blog.lucashungaro.com/2009/02/08/ruby-quick-tip-aprendendo-atraves-de-testes/#comments</comments>
		<pubDate>Sun, 08 Feb 2009 21:07:09 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=156</guid>
		<description><![CDATA[Se você não conhece (completamente ou pacialmente) alguma biblioteca, uma boa forma de fazer isso é através de um caso de testes. Um benefício resultante dessa prática é poder executar os testes contra várias versões do Ruby e, assim, verificar alterações em sua estrutura. Se você usa o TextMate, é muito fácil criar um caso [...]]]></description>
			<content:encoded><![CDATA[<p>Se você não conhece (completamente ou pacialmente) alguma biblioteca, uma boa forma de fazer isso é através de um caso de testes.</p>
<p>Um benefício resultante dessa prática é poder executar os testes contra várias versões do Ruby e, assim, verificar alterações em sua estrutura.</p>
<p>Se você usa o TextMate, é muito fácil criar um caso de testes. Basta abrir uma janela do editor, ativar o bundle do Ruby, digitar <em>tc</em> e pressionar a tecla <em>tab</em>:</p>
<p><img src="http://blog.lucashungaro.com/wp-content/uploads/2009/02/ishot-1.jpg" alt="TextMate" title="TextMate" width="475" height="449" class="aligncenter size-full wp-image-161" /></p>
<p><img src="http://blog.lucashungaro.com/wp-content/uploads/2009/02/ishot-2.jpg" alt="test case scaffold" title="test case scaffold" width="475" height="449" class="aligncenter size-full wp-image-162" /></p>
<p>Com isso temos um &#8220;esqueleto&#8221; de um caso de testes pronto. Pressionando tab, o foco do cursor passa por pontos importantes, como o require da biblioteca a ser testada, o nome do caso de testes etc. Agora, basta modificar de acordo com o que queremos testar e, através do atalho command+R, executar os testes e verificar o resultado:</p>
<p><img src="http://blog.lucashungaro.com/wp-content/uploads/2009/02/ishot-3.jpg" alt="test" title="test" width="475" height="449" class="aligncenter size-full wp-image-163" /></p>
<p><img src="http://blog.lucashungaro.com/wp-content/uploads/2009/02/ishot-41.jpg" alt="ishot-41" title="ishot-41" width="500" height="331" class="aligncenter size-full wp-image-174" /></p>
<p><strong>Veja também</strong>:</p>
<p><a href="http://www.makemesimple.com/blog/2007/08/27/aprendizado-orientado-por-testes/">Aprendizado orientado por testes</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lucashungaro.com/2009/02/08/ruby-quick-tip-aprendendo-atraves-de-testes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Seu framework não faz BDD</title>
		<link>http://blog.lucashungaro.com/2009/01/08/seu-framework-nao-faz-bdd/</link>
		<comments>http://blog.lucashungaro.com/2009/01/08/seu-framework-nao-faz-bdd/#comments</comments>
		<pubDate>Thu, 08 Jan 2009 03:49:51 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Opinião]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Test-Driven Development]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=142</guid>
		<description><![CDATA[Eu sinto uma &#8220;pontada&#8221; no cérebro quando ouço ou leio coisas como &#8220;o RSpec (ou Shoulda, test/spec etc) é um framework BDD&#8221;. Não existe algo como um &#8220;framework BDD&#8221;. Tenha em mente que quem pratica ou não o BDD é o desenvolvedor. O que existe são frameworks ou bibliotecas que adicionam uma boa dose de [...]]]></description>
			<content:encoded><![CDATA[<p>Eu sinto uma &#8220;pontada&#8221; no cérebro quando ouço ou leio coisas como &#8220;o RSpec (ou Shoulda, test/spec etc) é um framework BDD&#8221;.</p>
<p>Não existe algo como um &#8220;framework BDD&#8221;. Tenha em mente que quem pratica ou não o BDD é o desenvolvedor. O que existe são frameworks ou bibliotecas que adicionam uma boa dose de açúcar sintático para facilitar o estilo de escrita para quem deseja praticar essa técnica de testes.</p>
<p>Os <a href="http://dannorth.net/introducing-bdd" target="_blank">maiores</a> <a href="http://blog.daveastels.com/files/BDD_Intro.pdf" target="_blank">proponentes</a> do BDD enfatizam que a maior mudança em relação às técnicas tradicionais é mesmo a sintaxe. Porém, isso não quer dizer que basta utilizar uma sintaxe &#8220;mais legível&#8221; (o que é discutível também) para pular no vagão do BDD. A sintaxe bonitinha é um auxílio, uma ferramenta com o objetivo de diminuir as dificuldades na transição de um <strong>modo de pensar</strong>, que é onde a verdadeira diferença reside. Muitas dessas dificuldades são, inclusive, ditas de origem &#8220;psicológica&#8221;, como a abolição da palavra &#8220;test&#8221; nos nomes dos métodos para forçar o pensamento no sentido de uma verificação de comportamento ao invés de um teste de estado (medida defendida através da <a href="http://pt.wikipedia.org/wiki/Hip%C3%B3tese_de_Sapir-Whorf" target="_blank">hipótese de Sapir-Whorf</a>).</p>
<p>De fato, posso afirmar que a maior parte das suítes de testes escritas em RSpec, Shoulda ou test/spec que já tive a oportunidade de examinar (seja trabalhando, seja &#8220;navegando&#8221; por projetos open source &#8211; uma grande fonte de aprendizado), falha miseravelmente na tentativa de adotar o BDD, tropeçando feio em erros como verificar estado ao invés de comportamento, testar funcionalidades da linguagem ou framework e, principalmente, overmocking &#8211; chegando ao ponto em que um teste não verifica mais nada, apenas mocks e stubs &#8211; o que nos leva a testes quebradiços ou testes que não falham mesmo que você apague o código que eles deveriam verificar.</p>
<p>Esse último item leva a um outro ponto importante (e, aqui, uma visão muito pessoal &#8211; acredito ser compartilhada por poucos): acredita-se que o uso de mocks configura o uso do BDD, pois estabelecer expectativas em relação à interfaces e, consequentemente, isolar horizontalmente os componentes testados, passa a ser, &#8220;automaticamente&#8221;, verificação de comportamento. O uso de mocks não estabelece nada além de uma expectativa de interação &#8211; uma interface.</p>
<p>Como um <a href="http://martinfowler.com/articles/mocksArentStubs.html#ClassicalAndMockistTesting" target="_blank">classicista</a> evito o uso de mocks (e dublês em geral), reservando-os para onde realmente é difícil ou pouco prático o uso de um objeto real ou, como deveria ser seu principal uso, uma ferramenta de design de código através da qual modelamos interfaces ainda não existentes à medida em que praticamos o TDD (ou seja, escrevemos testes antes da implementação do código real) &#8211; e os substituo assim que a classe real é implementada, quando aplicável.</p>
<p>Então, não acredite que por utilizar alguma ferramenta facilitadora, você, instantâneamente, estará praticando BDD. Estude a técnica e a filosofia envolvida e você poderá utilizá-la com qualquer ferramenta para testes.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lucashungaro.com/2009/01/08/seu-framework-nao-faz-bdd/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Jogue fora os testes quebradiços</title>
		<link>http://blog.lucashungaro.com/2008/10/24/jogue-fora-os-testes-quebradicos/</link>
		<comments>http://blog.lucashungaro.com/2008/10/24/jogue-fora-os-testes-quebradicos/#comments</comments>
		<pubDate>Fri, 24 Oct 2008 17:23:03 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Opinião]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Test-Driven Development]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=141</guid>
		<description><![CDATA[É isso mesmo! Jogue fora. Todos eles! Você não precisa de deles. Você precisa de testes que garantam o comportamento do seu sistema. Software não é sobre o código escrito, software é sobre gerar o comportamento esperado a partir de um conjunto de requerimentos. Bem, não sou um especialista em testes nem um guru da [...]]]></description>
			<content:encoded><![CDATA[<p>É isso mesmo! Jogue fora. Todos eles! Você não precisa de deles. Você precisa de testes que garantam o comportamento do seu sistema. Software não é sobre o código escrito, software é sobre gerar o comportamento esperado a partir de um conjunto de requerimentos.</p>
<p>Bem, não sou um especialista em testes nem um guru da programação, mas tenho algumas opiniões. <img src='http://blog.lucashungaro.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong style="font-size: 15px;">O que é um teste quebradiço (ou &#8220;brittle test&#8221;)?</strong></p>
<p>Um teste quebradiço é aquele que passa a falhar após uma alteração em código não relacionado ao que ele deveria testar ou quando o código que ele testa é alterado, mas o comportamento do sistema não muda.</p>
<p>Além do custo de manutenção inerente à correção de testes que quebram &#8220;sem motivo&#8221;, ocorre também um impacto na moral e na motivação dos desenvolvedores. Se um desenvolvedor faz mudanças em um código e, ao integrá-lo, testes começam a falhar por motivos como inconsistência de dados em banco ou alto acoplamento, é praticamente certo que isso irá irritá-lo e, a médio prazo, fazer com que ele abandone os testes, criando verdadeiros &#8220;ferros-velhos&#8221; de testes sucateados. As quebras se tornarão cada vez mais frequentes e, logo, processos como integração contínua serão completamente abandonados.</p>
<p><strong style="font-size: 15px;">Casos comuns</strong></p>
<p><strong>Fixtures</strong></p>
<p>Manter os grafos de objetos através de fixtures torna-se exponencialmente mais complexo à medida que sua aplicação aumenta de tamanho e cria mais relacionamentos entre os objetos. Adicione um atributo ou relacionamento entre modelos e um grande número de testes automaticamente começará a quebrar, exigindo esforço considerável para correção.</p>
<p>Utilize algo como object_daddy e factory_girl que, sim, também precisarão de alguma manutenção após alterações na estrutura de dados, mas exigindo esforço muito menor.</p>
<p><strong>Testes de views em código</strong> (usando coisas como assert_tag ou o matcher have_tag)</p>
<p>Esses testes são uma completa e desnecessária perda de tempo. Uma mudança em alguma classe ou nome de campo e, bang!, testes quebrando sem que o comportamento da aplicação tenha sido afetado.</p>
<p>Você pode ser moderado nesses testes e não torná-los muito específicos para evitar isso mas, nesse caso, use algo como o Selenium, também com cuidado, pois é possível cair no mesmo erro com essa ferramenta.</p>
<p>Teste o que influi no comportamento, como o fluxo de redirecionamentos ou elementos com ids utilizados para chamadas ajax.</p>
<p>O Selenium também tem a vantagem de poder ser utilizado por testadores com algum conhecimento de estrutura Html.</p>
<p><strong>Abuso de mocks e stubs</strong></p>
<p>Isto é, para mim, um dos grandes vilões dos testes quebradiços. Esse abuso leva os testes a ficarem altamente acoplados a detalhes de implementação. Por exemplo (o exemplo é bobo, apenas para ilustrar):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Delivery
  <span style="color:#9966CC; font-weight:bold;">def</span> has_packages?
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">packages</span>.<span style="color:#9900CC;">count</span> <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#006666;">0</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> DeliveryTest <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#CC00FF; font-weight:bold;"><span style="color:#6666ff; font-weight:bold;">Test::Unit::TestCase</span></span>
  context <span style="color:#996600;">&quot;A scheduled delivery&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    setup <span style="color:#9966CC; font-weight:bold;">do</span>
      Delivery.<span style="color:#9900CC;">stubs</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:count</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">returns</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">10</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#0066ff; font-weight:bold;">@delivery</span> = Delivery.<span style="color:#9900CC;">new</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    should <span style="color:#996600;">&quot;have packages&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      assert <span style="color:#0066ff; font-weight:bold;">@delivery</span>.<span style="color:#9900CC;">has_packages</span>?
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Se, por um motivo qualquer, a implementação do método <em>has_packages?</em> mudar e passar a utilizar, por exemplo, o método <em>size</em> ao invés de <em>count</em>, o teste passará a quebrar sem que o comportamento tenha sido alterado. O exemplo é simples mas, em casos reais, isso é um grande problema. <del datetime="2009-02-05T03:37:15+00:00">Note que stubs tendem a deixar os testes mais acoplados do que mocks.</del></p>
<p>Algumas soluções pra isso são: não utilizar mocks e stubs (o que é um tanto extremista), aumentar o encapsulamento das classes ou aceitar isso e continuar.</p>
<p>Esse tipo de coisa costuma acontecer quando queremos utilizar mocks e stubs para tornarmos os testes independentes de recursos externos, como banco de dados. Nesses casos, o trade-off entre acoplamento do teste ao código e o ganho em velocidade de execução ou tempo de manutenção através do isolamento deve ser avaliado.</p>
<p><strong style="font-size: 15px;">Guias gerais</strong></p>
<p>Para evitar testes quebradiços, algumas guias podem ser utilizadas para a maioria dos casos:</p>
<ul>
<li>Especifique apenas o que você quer que aconteça e nada mais</li>
<li>Em termos de mocks e stubs: use stubs para queries (tudo o que retorna dados e não modifica estado) e mocks para comandos (que não necessariamente retornam algo, mas modificam estado)</li>
<li>Lembre-se de que o que importa é o comportamento do método/classe/sistema. Como isto é implementado, em nível de código, não deve fazer diferença nos seus testes</li>
</ul>
<p>Como já disse, não sou um especialista. Então, se você percebeu alguma grande besteira nesse post, não exite em discutir, eu tenho a mente aberta. <img src='http://blog.lucashungaro.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>Update</strong></p>
<p>Note que mocks e stubs, quando usados corretamente, são uma importante ferramenta de design. Esse tipo de ferramenta, além de isolar os testes de recursos externos, tem o intuito (e talvez até o principal objetivo) de servir como apoio à prática do TDD: enquanto escreve os testes antes do código, mocks e stubs (e dublês em geral) permitem que você especifique o comportamento de partes ainda não existentes da aplicação. Nesse processo, torna-se mais fácil detectar falhas como alto acoplamento e corrigí-las o quanto antes, gerando menos stress.</p>
<p>Leia mais:</p>
<ul>
<li><a href="http://szeryf.wordpress.com/2008/01/07/does-stubbing-make-your-tests-brittle/" target="_blank">Does stubbing make your tests brittle?</a></li>
<li><a href="http://evang.eli.st/blog/2008/2/4/sorry-you-re-just-not-my-type" target="_blank">Sorry, you&#8217;re just not my type</a></li>
<li><a href="http://giantrobots.thoughtbot.com/2007/9/6/brittle-tests" target="_blank">Brittle tests</a></li>
<li><a href="http://www.martinfowler.com/articles/mocksArentStubs.html" target="_blank">Mocks aren&#8217;t stubs</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.lucashungaro.com/2008/10/24/jogue-fora-os-testes-quebradicos/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Matchers vs Assertions: DSLs não são linguagens naturais</title>
		<link>http://blog.lucashungaro.com/2008/10/20/matchers-vs-assertions-dsls-nao-sao-linguagens-naturais/</link>
		<comments>http://blog.lucashungaro.com/2008/10/20/matchers-vs-assertions-dsls-nao-sao-linguagens-naturais/#comments</comments>
		<pubDate>Mon, 20 Oct 2008 03:15:54 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Opinião]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Test-Driven Development]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=139</guid>
		<description><![CDATA[Ok, todo o tempo eu escuto o mesmo argumento quando alguém fala do RSpec (o mesmo foi usado por Jay Fields em sua palestra no Rails Summit, semana passada): Matchers são superiores à asserções porque, quando estou conversando com alguém, eu não afirmo &#8220;Ei, assira que são iguais: 2, 1+1&#8243;, eu afirmo &#8220;Ei, 1+1 deve [...]]]></description>
			<content:encoded><![CDATA[<p>Ok, todo o tempo eu escuto o mesmo argumento quando alguém fala do RSpec (o mesmo foi usado por Jay Fields em sua palestra no Rails Summit, semana passada):</p>
<blockquote><p>Matchers são superiores à asserções porque, quando estou conversando com alguém, eu não afirmo &#8220;Ei, assira que são iguais: 2, 1+1&#8243;, eu afirmo &#8220;Ei, 1+1 deve ser igual a 2&#8243;.</p></blockquote>
<p><strong>Bullshit!</strong></p>
<p style="text-align: center"><img class="aligncenter size-medium wp-image-140" title="Bullshit" src="http://www.makemesimple.com/blog/wp-content/uploads/2008/10/originals_bullshit1_ranndino-225x300.jpg" alt="Absolute Bullshit!" width="225" height="300" /></p>
<p>Trata-se de uma falácia (<strong><em>Dicto Simpliciter</em></strong>) e bem frágil. O que é óbvio e passa despercebido nesse caso é que Linguagens Específicas de Domínio (Domain Specific Languages, DSLs) não são linguagens naturais. Uh-oh! <strong>Tão</strong> óbvio.</p>
<p>Você com certeza fica completamente perdido nas discussões médicas do seriado House. Tente conversar com um engenheiro elétrico sobre o processo de geração de energia elétrica numa usina nuclear. <strong>Tente</strong> entender 20% do que ele fala.</p>
<p>Linguagens específicas de domínio são utilizadas por <strong>especialistas</strong> no domínio em questão. Então me diga se, dentro de um teste, não está o pragmático desenvolvedor em um domínio <strong>muito específico</strong> onde, sim, asserções fazem todo o sentido. Nem sequer tente argumentar que especificações (que substituem os malfadados testes do TDD) são feitos para que clientes entendam. Don&#8217;t fool yourself.</p>
<p>Matchers <strong>não</strong> são ruins, não me entenda mal. São, sim, muito legais e <strong>legíveis</strong>. Mas dizer que asserções &#8220;não são naturais&#8221; e tentar fazer disso um ponto de superioridade é falta de conhecimento.</p>
<p><strong>Observações</strong>: sim, eu prefiro o Shoulda ao RSpec e não vejo problema nenhum na utilização de nenhum dos dois. O ponto aqui é lembrar que DSLs não são inglês ou português, são linguagens muito específicas em um dado contexto. O exemplo citado foi o que me veio à cabeça mais rapidamente, talvez devido ao Rails Summit e à palestra de Jay Fields.</p>
<p>Leia mais:</p>
<p><a href="http://pragdave.blogs.pragprog.com/pragdave/2008/03/the-language-in.html" target="_blank">The &#8216;Language&#8217; in Domain-Specific Language Doesn&#8217;t Mean English (or French, or Japanese, or &#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lucashungaro.com/2008/10/20/matchers-vs-assertions-dsls-nao-sao-linguagens-naturais/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Edit in place restful com Rails 2.1</title>
		<link>http://blog.lucashungaro.com/2008/09/03/edit-in-place-restful-com-rails-21/</link>
		<comments>http://blog.lucashungaro.com/2008/09/03/edit-in-place-restful-com-rails-21/#comments</comments>
		<pubDate>Wed, 03 Sep 2008 03:37:59 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=137</guid>
		<description><![CDATA[A funcionalidade &#8220;edit in place&#8221; é aquela na qual, ao clicar em um texto na página web, disponibiliza-se um campo para edição do texto clicado. Nas versões &#8220;não-Rest&#8221; do Rails, era comum o uso do plugin in_place_editing para conseguir essa funcionalidade. Para as versões mais novas, ainda é possível utilizar esse plugin, mas a solução [...]]]></description>
			<content:encoded><![CDATA[<p>A funcionalidade &#8220;edit in place&#8221; é aquela na qual, ao clicar em um texto na página web, disponibiliza-se um campo para edição do texto clicado.</p>
<p>Nas versões &#8220;não-Rest&#8221; do Rails, era comum o uso do plugin in_place_editing para conseguir essa funcionalidade. Para as versões mais novas, ainda é possível utilizar esse plugin, mas a solução acaba ficando bem grosseira. Pesquisando sobre isso, encontrei o plugin <a href="http://github.com/nakajima/better-edit-in-place/tree/master" target="_blank">better-edit-in-place</a>, que permite utilizar a interface Rest padrão do Rails para conseguir a funcionalidade.</p>
<p>Depois de instalar o plugin, você precisa de apenas três passos para fazer tudo funcionar:</p>
<p>1. Escrever/incrementar os testes funcionais do controller (test first, aqui com Shoulda e&#8230; ahn&#8230; fixtures&#8230;):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">context <span style="color:#996600;">&quot;on Ajax PUT to :update&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  setup <span style="color:#9966CC; font-weight:bold;">do</span>
    xhr <span style="color:#ff3333; font-weight:bold;">:put</span>, <span style="color:#ff3333; font-weight:bold;">:update</span>, <span style="color:#ff3333; font-weight:bold;">:id</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> emails<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:one</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">id</span>, <span style="color:#ff3333; font-weight:bold;">:email</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:address <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'new_email@email.com'</span><span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  should_assign_to <span style="color:#ff3333; font-weight:bold;">:email</span>
  should_respond_with <span style="color:#ff3333; font-weight:bold;">:success</span>
  should_not_set_the_flash
&nbsp;
  should <span style="color:#996600;">&quot;update the email address&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    assert_equal assigns<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:email</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">address</span>, <span style="color:#996600;">'new_email@email.com'</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>2. Criar uma ação update no controller do recurso ou adicionar o formato correto ao bloco respond_to:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> update
  <span style="color:#0066ff; font-weight:bold;">@email</span> = Email.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#0066ff; font-weight:bold;">@email</span>.<span style="color:#9900CC;">update_attribute</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:address</span>, params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:email</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:address</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">js</span> <span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:json</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@email</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#008000; font-style:italic;">#voce que sabe...</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>3. Ajustar seu markup para que a parte JavaScript do plugin funcione. Para isso, basta utilizar um helper disponibilizado pelo plugin:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&lt;%</span>= edit_in_place<span style="color:#006600; font-weight:bold;">&#40;</span>email, <span style="color:#ff3333; font-weight:bold;">:address</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">-%&gt;</span></pre></div></div>

<p>Pronto. Ao abrir a página e clicar sobre o elemento <em>span</em> que exibe o texto do atributo passado ao helper, o mesmo será substituído por uma caixa de texto com um botão para salvar e um link para cancelar a ação. Tudo simples e de forma muito mais limpa. O plugin também funciona com recursos aninhados.</p>
<p><strong>Obs:</strong> note que ignorei &#8220;detalhes&#8221; como validação do modelo, entre outros importantes. Fiz isso apenas pra encurtar o post, não faça o mesmo em aplicações reais. <img src='http://blog.lucashungaro.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lucashungaro.com/2008/09/03/edit-in-place-restful-com-rails-21/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

