<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Simples Ideias. Por Nando Vieira.</title>
	
	<link>http://simplesideias.com.br</link>
	<description />
	<lastBuildDate>Sun, 25 Jul 2010 02:02:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/simplesideias" /><feedburner:info uri="simplesideias" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>simplesideias</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Criando sua própria RubyGem</title>
		<link>http://feedproxy.google.com/~r/simplesideias/~3/x1es71EXZMo/</link>
		<comments>http://simplesideias.com.br/criando-sua-propria-rubygem/#comments</comments>
		<pubDate>Sat, 24 Jul 2010 12:02:35 +0000</pubDate>
		<dc:creator>Nando Vieira</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Gem]]></category>
		<category><![CDATA[RubyGems]]></category>

		<guid isPermaLink="false">http://simplesideias.com.br/?p=544</guid>
		<description><![CDATA[Todo mundo já deve ter usado pelo menos uma vez na vida as famosas gems. Elas ajudam muito na hora distribuir e usar bibliotecas Ruby, sem dúvida nenhuma. Mas o que nem todo mundo sabe é que criar uma gem é muito mais fácil do que parece. Neste artigo você verá como criar e distribuir [...]]]></description>
			<content:encoded><![CDATA[<p>Todo mundo já deve ter usado pelo menos uma vez na vida as famosas <a rel="external" href="http://rubygems.org">gems</a>. Elas ajudam muito na hora distribuir e usar bibliotecas Ruby, sem dúvida nenhuma. Mas o que nem todo mundo sabe é que criar uma gem é muito mais fácil do que parece. Neste artigo você verá como criar e distribuir sua própria gem.</p>

<h3>Entendo a gem</h3>

<p>Uma gem nada mais é que um arquivo <code>.tar.gz</code>.</p>

<pre class="text"><code>$ tar -ztvf bundler-0.9.26.gem
-rw-r--r--  0 wheel  wheel   47579 Dec 31  1969 data.tar.gz
-rw-r--r--  0 wheel  wheel     993 Dec 31  1969 metadata.gz</code></pre>

<p>Neste arquivo, você encontra o código Ruby propriamente dito (<code>data.tar.gz</code>) e os metadados (<code>metadata.gz</code>), que é a <em>gem specification</em> (ou apenas gemspec) em formato <a rel="external" href="http://ruby-doc.org/core/classes/YAML.html">YAML</a>. Esta gemspec informa, dentre outras coisas, qual é o nome da gem, a versão e dependências do pacote, além dos arquivos que compoem a biblioteca.</p>

<p>Uma gem é composta por uma estrutura mais ou menos definida de arquivos e diretórios, como você pode ver abaixo.</p>

<p><img src="http://m.simplesideias.com.br/hello-world-gem.png" alt="Estrutura de arquivos e diretórios de uma gem" title=""></p>

<p>O diretório <code>lib</code> é de longe o mais importante. É nele que todo código Ruby fica armazenado. E é ele que é adicionado ao <code>GEM_PATH</code>, utilizado pelo RubyGems (gerenciador de pacotes) para saber quais bibliotecas estão disponíveis para uso.</p>

<p>O RubyGems substitui o método <code>Kernel#require</code> com sua própria implementação, que faz uma busca pela gem que você precisa utilizando os diretórios adicionados ao <code>GEM_PATH</code>. Então, sempre que você utilizar o método <code>require "some_library"</code>, o RubyGems irá procurar por um arquivo <code>lib/some_library.rb</code>, independente de qual gem tenha este arquivo.</p>

<h3>Criando a biblioteca HelloWorld</h3>

<p>Vamos criar nossa biblioteca <code>HelloWorld</code>, que será empacotada posteriormente como uma gem. O primeiro passo é gerar nossa estrutura de diretórios.</p>

<pre class="text"><code>$ mkdir -p hello_world/{lib/hello_world,test}</code></pre>

<p>Crie um arquivo de testes em <code>tests/hello_world_test.rb</code>. Nosso módulo terá um único método chamado <code>say</code>.</p>

<pre class="ruby"><code><span class="kw3">require</span> <span class="st0">&quot;test/unit&quot;</span>
&nbsp;
<span class="kw1">class</span> HelloWorldTest &lt; <span class="re2">Test::Unit::TestCase</span>
  <span class="kw1">def</span> test_say_hello_to_the_world
    assert_equal <span class="st0">&quot;Hello World!&quot;</span>, HelloWorld.<span class="me1">say</span>
  <span class="kw1">end</span>
<span class="kw1">end</span>
&nbsp;</code></pre>

<p>Você pode executar este teste com o comando <code>ruby test/hello_world_test.rb</code>. Ele irá falhar, como era de se esperar.</p>

<pre class="text"><code>$ ruby test/hello_world_test.rb
Loaded suite test/hello_world_test
Started
E
Finished in 0.000388 seconds.
&nbsp;
  1) Error:
test_say_hello_to_the_world(HelloWorldTest):
NameError: uninitialized constant HelloWorldTest::HelloWorld
    test/hello_world_test.rb:5:in `test_say_hello_to_the_world'
&nbsp;
1 tests, 0 assertions, 0 failures, 1 errors
&nbsp;</code></pre>

<p>Agora, crie o arquivo <code>lib/hello_world.rb</code>. Nossa implementação é bastante simples.</p>

<pre class="ruby"><code><span class="kw1">module</span> HelloWorld
  <span class="kw1">def</span> <span class="kw2">self</span>.<span class="me1">say</span>
    <span class="st0">&quot;Hello World!&quot;</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<p>Execute o comando <code>ruby test/hello_world_test.rb</code> mais uma vez. Como era de se esperar, o teste irá&#8230; falhar novamente. Isso acontece porque não estamos carregando o módulo <code>HelloWorld</code>. Embora você possa resolver isso de várias maneiras diferentes, vamos fazer do modo mais organizado: iremos criar uma <em>rake task</em> para executar nossos testes, adicionando o diretório <code>lib</code> ao <code>$LOAD_PATH</code>.</p>

<p>Crie um arquivo <code>Rakefile</code> com o seguinte código:</p>

<pre class="ruby"><code><span class="kw3">require</span> <span class="st0">&quot;rake/testtask&quot;</span>
&nbsp;
<span class="re2">Rake::TestTask</span>.<span class="me1">new</span> <span class="kw1">do</span> |t|
  t.<span class="me1">libs</span> &lt;&lt; <span class="st0">&quot;lib&quot;</span>
  t.<span class="me1">test_files</span> = <span class="kw4">Dir</span><span class="br0">&#91;</span><span class="st0">&quot;test/**/*_test.rb&quot;</span><span class="br0">&#93;</span>
<span class="kw1">end</span></code></pre>

<p>Altere o arquivo <code>test/hello_world_test.rb</code>, adicionando a linha que irá carregar o arquivo <code>hello_world.rb</code>.</p>

<pre class="ruby"><code><span class="kw3">require</span> <span class="st0">&quot;test/unit&quot;</span>
<span class="kw3">require</span> <span class="st0">&quot;hello_world&quot;</span>  <span class="co1"># Added</span>
&nbsp;
<span class="kw1">class</span> HelloWorldTest &lt; <span class="re2">Test::Unit::TestCase</span>
  <span class="kw1">def</span> test_say_hello_to_the_world
    assert_equal <span class="st0">&quot;Hello World!&quot;</span>, HelloWorld.<span class="me1">say</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<p>Rode o teste mais uma vez, só que agora usando o comando <code>rake test</code>.</p>

<pre class="text"><code>$ rake test
(in /Users/fnando/Sites/github/hello_world)
Loaded suite /Users/fnando/.gem/spaces/active/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
.
Finished in 0.00031 seconds.
&nbsp;
1 tests, 1 assertions, 0 failures, 0 errors</code></pre>

<p>Ótimo! Nossos testes estão passando e como terminamos toda nossa implementação, já podemos criar e distribuir nossa gem.</p>

<h3>Gerando nosso pacote</h3>

<p>Para gerar um arquivo <code>.gem</code>, precisamos escrever nossa gemspec. Crie um arquivo <code>hello_world.gemspec</code> e adicione o código abaixo.</p>

<pre class="ruby"><code><span class="re2">Gem::Specification</span>.<span class="me1">new</span> <span class="kw1">do</span> |s|
  s.<span class="me1">name</span>        = <span class="st0">&quot;hello_world&quot;</span>
  s.<span class="me1">version</span>     = <span class="st0">&quot;0.1.0&quot;</span>
  s.<span class="me1">description</span> = <span class="st0">&quot;A simple gem that says hello to the world!&quot;</span>
  s.<span class="me1">summary</span>     = <span class="st0">&quot;Say hello!&quot;</span>
  s.<span class="me1">author</span>      = <span class="st0">&quot;Nando Vieira&quot;</span>
  s.<span class="me1">files</span>       = <span class="kw4">Dir</span><span class="br0">&#91;</span><span class="st0">&quot;{lib/**/*.rb,README.rdoc,test/**/*.rb,Rakefile,*.gemspec}&quot;</span><span class="br0">&#93;</span>
<span class="kw1">end</span></code></pre>

<p>As opções da classe <code>Gem::Specification</code> são auto-descritivas; para saber mais sobre estas e outras opções, <a rel="external" href="http://rubygems.rubyforge.org/rubygems-update/Gem/Specification.html">consulte a documentação</a>.</p>

<p>Agora vem a parte mais fácil. Execute o comando <code>gem build hello_world.gemspec</code> e um arquivo <code>hello_world-0.1.0.gem</code> será gerado.</p>

<p>Você pode instalar este arquivo localmente utilizando o comando <code>gem install hello_world-0.1.0.gem --local</code>. Para listar o que foi instalado, execute <code>gem contents hello_world</code>.</p>

<pre class="text"><code>$ gem contents hello_world
/Users/fnando/.gem/spaces/active/gems/hello_world-1.0/lib/hello_world/version.rb
/Users/fnando/.gem/spaces/active/gems/hello_world-1.0/lib/hello_world.rb
/Users/fnando/.gem/spaces/active/gems/hello_world-1.0/README.rdoc
/Users/fnando/.gem/spaces/active/gems/hello_world-1.0/test/hello_world_test.rb
/Users/fnando/.gem/spaces/active/gems/hello_world-1.0/Rakefile
/Users/fnando/.gem/spaces/active/gems/hello_world-1.0/hello_world.gemspec</code></pre>

<p>E, claro, nossa gem também será listada com o comando <code>gem list</code>.</p>

<pre class="text"><code>$ gem list hello_world -d
&nbsp;
*** LOCAL GEMS ***
&nbsp;
hello_world (1.0)
    Author: Nando Vieira
    Installed at: /Users/fnando/.gem/spaces/active
&nbsp;
    Say hello!</code></pre>

<h3>Distribuindo nossa gem</h3>

<p>Para distribuir sua gem, é preciso criar uma conta no site <a rel="external" href="http://rubygems.org/sign_up">RubyGems.org</a>.</p>

<p>Depois, basta executar <code>gem push hello_world-0.1.0.gem</code>; informe seu e-mail e senha cadastrados no RubyGems.org quando solicitado. Se tudo der certo, você verá uma mensagem como esta:</p>

<pre class="text"><code>$ gem push hello_world-0.1.0.gem
Pushing gem to RubyGems.org...
Successfully registered gem: hello_world (0.1.0)</code></pre>

<p>Você pode acessar sua gem em <code>http://rubygems.org/gems/hello_world</code>.</p>

<p><strong>DICA:</strong> Antes de escrever sua gem, verifique se o nome está disponível. Um simples <code>gem list nome_da_gem -rd</code> já te dará a resposta. A gem <code>hello_world</code> já existia, por isso foi publicada como <a rel="external" href="http://rubygems.org/gems/fnando-hello_world">http://rubygems.org/gems/fnando-hello_world</a>.</p>

<h3>Versionamento dos pacotes</h3>

<p>É sua responsabilidade definir como será o versionamento de sua gem. Eu utilizo o formato <code>MAJOR.MINOR.PATCH</code>, como em <code>1.2.3</code>.</p>

<ul>
<li><code>MAJOR:</code> inclui alterações de API e pode quebrar compatibilidade com versões anteriores</li>
<li><code>MINOR:</code> inclui novas funcionalidades ou pouca alteração de API</li>
<li><code>PATCH:</code> corrige bugs ou traz melhorias em implementações já existentes</li>
</ul>

<p>No arquivo <code>lib/hello_world/version.rb</code> você pode ter algo como:</p>

<pre class="ruby"><code><span class="kw1">module</span> HelloWorld
  <span class="kw1">module</span> Version
    MAJOR = <span class="nu0">0</span>
    MINOR = <span class="nu0">1</span>
    PATCH = <span class="nu0">0</span>
    STRING = <span class="st0">&quot;#{MAJOR}.#{MINOR}.#{PATCH}&quot;</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<h3>E para finalizar&#8230;</h3>

<p>Gems como <a rel="external" href="http://github.com/technicalpickles/jeweler">Jeweler</a> (que sempre uso) também podem ajudar na hora de criar, distribuir e manter suas bibliotecas. Mas antes de utilizar uma dessas bibliotecas, entender o processo de criação de gems é fundamental. Afinal, é fazendo que se aprende!</p>
<img src="http://feeds.feedburner.com/~r/simplesideias/~4/x1es71EXZMo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simplesideias.com.br/criando-sua-propria-rubygem/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://simplesideias.com.br/criando-sua-propria-rubygem/</feedburner:origLink></item>
		<item>
		<title>Validando senhas fortes com Ruby on Rails e JavaScript</title>
		<link>http://feedproxy.google.com/~r/simplesideias/~3/YNDsw6tHgqA/</link>
		<comments>http://simplesideias.com.br/validando-senhas-fortes-com-ruby-on-rails-e-javascript/#comments</comments>
		<pubDate>Sat, 24 Apr 2010 16:47:14 +0000</pubDate>
		<dc:creator>Nando Vieira</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://simplesideias.com.br/?p=532</guid>
		<description><![CDATA[Em muitos projetos, é importante que o usuário informe senhas que tenham um mínimo de complexidade, evitando que sejam facilmente quebradas. Existem muitas soluções feitas em JavaScript, mas não encontrei nenhuma que fosse boa o bastante no backend. Pensando nisso, criei uma gem chamada Password Strength que faz validação de diversos padrões, a fim de [...]]]></description>
			<content:encoded><![CDATA[<p class="align-right">
	<img alt="" src="http://m.simplesideias.com.br/lock.jpg" title="Foto:  	
Dina Shoukry - http://bit.ly/ckhp6V" />
</p>

<p>Em muitos projetos, é importante que o usuário informe senhas que tenham um mínimo de complexidade, evitando que sejam facilmente quebradas. Existem muitas soluções feitas em JavaScript, mas não encontrei nenhuma que fosse boa o bastante no backend.</p>

<p>Pensando nisso, criei uma gem chamada <a href="http://github.com/fnando/password_strength">Password Strength</a> que faz validação de diversos padrões, a fim de identificar senhas que sejam fracas. Ela é composta por 2 módulos: ActiveRecord e JavaScript.</p>

<p>A validação da senha é feita com base nas seguintes regras:</p>

<ul>
<li>Tamanho da senha</li>
<li>Presença de letras, números e caracteres especiais</li>
<li>Presença de maiúsculas e minúsculas</li>
<li>Uso do login/e-mail na composição da senha</li>
<li>Sequências (123, abc, aaa)</li>
<li>Repetições</li>
</ul>

<p>Cada uma dessas regras recebe uma pontuação negativa ou positiva, que irá influenciar no resultado final.
Assim, com base nessas regras, podemos classificar as seguintes senhas:</p>

<ul>
<li><code>123</code> => fraca</li>
<li><code>123abc</code> => fraca</li>
<li><code>aaaaaa</code> => fraca</li>
<li><code>myPass145</code> => boa</li>
<li><code>myPass145$</code> => forte</li>
</ul>

<h3 id="instalao">Instalação</h3>

<p>Para instalar, basta executar o comando</p>

<pre class="bash"><code>sudo gem install password_strength</code></pre>

<p>Agora, configure seu aplicativo para carregá-la. No Rails 2, basta adicionar a linha abaixo ao seu arquivo <code>environment.rb</code>.</p>

<pre class="ruby"><code>config.<span class="me1">gem</span> <span class="st0">&quot;password_strength&quot;</span></code></pre>

<p>No Rails 3, adicione a linha abaixo ao arquivo <code>Gemfile</code>.</p>

<pre class="ruby"><code>gem <span class="st0">&quot;password_strength&quot;</span></code></pre>

<p>Se quiser usar o plugin para jQuery, você também precisará dos arquivos <a href="http://github.com/fnando/password_strength/raw/master/lib/password_strength.js">password_strength.js</a> e <a href="http://github.com/fnando/password_strength/raw/master/lib/jquery.strength.js">jquery.strength.js</a>.</p>

<h3>Usando na prática</h3>

<p>O Password Strength permite que você valide senhas sem a necessidade de usar o ActiveRecord.</p>

<pre class="ruby"><code>strength = PasswordStrength.<span class="me1">test</span><span class="br0">&#40;</span><span class="st0">&quot;johndoe&quot;</span>, <span class="st0">&quot;mypass&quot;</span><span class="br0">&#41;</span>
<span class="co1">#=&gt; return an object</span>
&nbsp;
strength.<span class="me1">good</span>?
<span class="co1">#=&gt; status == :good</span>
&nbsp;
strength.<span class="me1">weak</span>?
<span class="co1">#=&gt; status == :weak</span>
&nbsp;
strength.<span class="me1">strong</span>?
<span class="co1">#=&gt; status == :strong</span>
&nbsp;
strength.<span class="me1">status</span>
<span class="co1">#=&gt; can be :weak, :good, :strong</span>
&nbsp;
strength.<span class="me1">valid</span>?<span class="br0">&#40;</span><span class="re3">:strong</span><span class="br0">&#41;</span>
<span class="co1">#=&gt; status == :strong</span>
&nbsp;
strength.<span class="me1">valid</span>?<span class="br0">&#40;</span><span class="re3">:good</span><span class="br0">&#41;</span>
<span class="co1">#=&gt; [:good, :strong].include?(status)</span></code></pre>

<p>Muito simples!</p>

<h4 id="activerecord">ActiveRecord</h4>

<p>O Password Strength possui suporte para ActiveRecord 2.3+ (foi testado em 2.3.5 e 3.0.0-beta).</p>

<p>No seu modelo, adicione a validação <code>validates_strength_of</code>.</p>

<pre class="rails"><code><span class="kw1">class</span> User &lt; <span class="re2">ActiveRecord::Base</span>
  validates_strength_of <span class="re3">:password</span>
<span class="kw1">end</span></code></pre>

<p>Por padrão, as opções serão <code>:level =&gt; :good, :with =&gt; :username</code>. A opção <code>:level</code> define a complexidade mínima requerida e pode ser <code>:good</code>, <code>:strong</code> ou <code>:weak</code> (é desnecessário dizer que a última opção não faz o menor sentido, já que qualquer senha será aceita). Já a opção <code>:with</code> define qual o atributo que deverá ser usado na comparação da senha. Se quiser, pode definir um outro atributo:</p>

<pre class="rails"><code>validates_strength_of <span class="re3">:password</span>, <span class="re3">:with</span> =&gt; <span class="re3">:email</span></code></pre>

<p>Também é possível proibir senhas que usem determinados caracteres por completo com a opção <code>:exclude</code>. Podemos, por exemplo, evitar que senhas contendo a string <code>asdf</code> sejam usadas:</p>

<pre class="rails"><code>validates_strength_of <span class="re3">:password</span>, <span class="re3">:exclude</span> =&gt; /asdf/i</code></pre>

<p>Alternativamente, você pode definir uma lista de strings que não devem ser utilizadas:</p>

<pre class="rails"><code>validates_strength_of <span class="re3">:password</span>, <span class="re3">:exclude</span> =&gt; %w<span class="br0">&#91;</span> asdf qwert zxcv <span class="br0">&#93;</span></code></pre>

<h4>JavaScript</h4>

<p>No HTML, adicione os arquivos que você baixou.</p>

<pre class="html4strict"><code><span class="sc2"><span class="kw2">&lt;script</span> <span class="kw3">src</span>=<span class="st0">&quot;jquery-1.4.2.js&quot;</span> <span class="kw3">type</span>=<span class="st0">&quot;text/javascript&quot;</span><span class="kw2">&gt;</span></span><span class="sc2"><span class="kw2">&lt;/script&gt;</span></span>
<span class="sc2"><span class="kw2">&lt;script</span> <span class="kw3">src</span>=<span class="st0">&quot;password_strength.js&quot;</span> <span class="kw3">type</span>=<span class="st0">&quot;text/javascript&quot;</span><span class="kw2">&gt;</span></span><span class="sc2"><span class="kw2">&lt;/script&gt;</span></span>
<span class="sc2"><span class="kw2">&lt;script</span> <span class="kw3">src</span>=<span class="st0">&quot;jquery.strength.js&quot;</span> <span class="kw3">type</span>=<span class="st0">&quot;text/javascript&quot;</span><span class="kw2">&gt;</span></span><span class="sc2"><span class="kw2">&lt;/script&gt;</span></span></code></pre>

<p>Se você não usa jQuery, pode usar apenas o arquivo <code>password_strength.js</code> e criar o seu próprio adaptador.</p>

<p>A API do JavaScript é essencialmente a mesma, inclusive com as mesmas regras de verificação. Veja:</p>

<pre class="javascript"><code><span class="kw2">var</span> strength = PasswordStrength.<span class="me1">test</span><span class="br0">&#40;</span><span class="st0">&quot;johndoe&quot;</span>, <span class="st0">&quot;mypass&quot;</span><span class="br0">&#41;</span>;
strength.<span class="me1">isGood</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
strength.<span class="me1">isStrong</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
strength.<span class="me1">isWeak</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
strength.<span class="me1">isValid</span><span class="br0">&#40;</span><span class="st0">&quot;good&quot;</span><span class="br0">&#41;</span>;</code></pre>

<p>Você também pode usar a opção <code>:exclude</code> mas, no momento, apenas expressões regulares são aceitas.</p>

<pre class="javascript"><code><span class="kw2">var</span> strength = PasswordStrength.<span class="me1">test</span><span class="br0">&#40;</span><span class="st0">&quot;johndoe&quot;</span>, <span class="st0">&quot;password with whitespaces&quot;</span>, <span class="br0">&#123;</span>exclude: <span class="re0">/\s/</span><span class="br0">&#125;</span><span class="br0">&#41;</span>;
strength.<span class="me1">isInvalid</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</code></pre>

<p>Se você usa jQuery, pode utilizar o plugin que já vem com o Password Strength.</p>

<pre class="javascript"><code>$.<span class="me1">strength</span><span class="br0">&#40;</span><span class="st0">&quot;#username&quot;</span>, <span class="st0">&quot;#password&quot;</span><span class="br0">&#41;</span>;</code></pre>

<p>A definição acima irá utilizar o campo <code>#username</code> e <code>#password</code> para fazer a validação da senha.
Conforme a senha é digitada, uma imagem é colocada ao lado do campo de senha. Por padrão, as imagens utilizadas são
<code>/images/{weak,good,strong}.png</code>. Se você quiser, pode alterar esses caminhos:</p>

<pre class="javascript"><code>$.<span class="me1">strength</span>.<span class="me1">weakImage</span> = <span class="st0">&quot;/weak.png&quot;</span>;
$.<span class="me1">strength</span>.<span class="me1">goodImage</span> = <span class="st0">&quot;/good.png&quot;</span>;
$.<span class="me1">strength</span>.<span class="me1">strongImage</span> = <span class="st0">&quot;/strong.png&quot;</span>;</code></pre>

<p>Você também pode sobrescrever o callback padrão.</p>

<pre class="javascript"><code>$.<span class="me1">strength</span><span class="br0">&#40;</span><span class="st0">&quot;#username&quot;</span>, <span class="st0">&quot;#password&quot;</span>, <span class="kw2">function</span><span class="br0">&#40;</span>username, password, strength<span class="br0">&#41;</span><span class="br0">&#123;</span>
	<span class="co1">// do whatever you want</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span>;</code></pre>

<p>Se você quiser sobrescrever o callback globalmente, pode fazê-lo da seguinte maneira:</p>

<pre class="javascript"><code>$.<span class="me1">strength</span>.<span class="me1">callback</span> = <span class="kw2">function</span><span class="br0">&#40;</span>username, password, strength<span class="br0">&#41;</span> <span class="br0">&#123;</span>
	<span class="co1">// do whatever you want</span>
<span class="br0">&#125;</span>;</code></pre>

<p>Qualquer dúvida, mande um comentário!</p><img src="http://feeds.feedburner.com/~r/simplesideias/~4/YNDsw6tHgqA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simplesideias.com.br/validando-senhas-fortes-com-ruby-on-rails-e-javascript/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://simplesideias.com.br/validando-senhas-fortes-com-ruby-on-rails-e-javascript/</feedburner:origLink></item>
		<item>
		<title>Novo layout</title>
		<link>http://feedproxy.google.com/~r/simplesideias/~3/CubnCcCzZF8/</link>
		<comments>http://simplesideias.com.br/novo-layout-5/#comments</comments>
		<pubDate>Fri, 23 Apr 2010 11:30:50 +0000</pubDate>
		<dc:creator>Nando Vieira</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://simplesideias.com.br/?p=526</guid>
		<description><![CDATA[Dá para acreditar que já se passou 1 ano desde a última mudança de layout? Peguei duas horinhas dessa madruga para criar uma nova versão, alterada no ar mesmo. Para dar sua sugestão, crítica ou mesmo avisar de alguma coisa que esteja quebrada, envie um comentário!]]></description>
			<content:encoded><![CDATA[<p>Dá para acreditar que já se passou 1 ano desde a <a href="http://simplesideias.com.br/novo-layout-4/">última mudança de layout</a>?
Peguei duas horinhas dessa madruga para criar uma nova versão, alterada no ar mesmo.</p>

<p><img src="http://m.simplesideias.com.br/simplesideias-v6.png" alt="Novo layout - 2010" /></p>

<p>Para dar sua sugestão, crítica ou mesmo avisar de alguma coisa que esteja quebrada, envie um comentário!</p><img src="http://feeds.feedburner.com/~r/simplesideias/~4/CubnCcCzZF8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simplesideias.com.br/novo-layout-5/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		<feedburner:origLink>http://simplesideias.com.br/novo-layout-5/</feedburner:origLink></item>
		<item>
		<title>Autocompletion no RubyGems + Tweaks no IRB</title>
		<link>http://feedproxy.google.com/~r/simplesideias/~3/_iVpzdssOwE/</link>
		<comments>http://simplesideias.com.br/autocompletion-no-rubygems-tweaks-no-irb/#comments</comments>
		<pubDate>Tue, 20 Apr 2010 20:39:52 +0000</pubDate>
		<dc:creator>Nando Vieira</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[IRB]]></category>
		<category><![CDATA[RubyGems]]></category>
		<category><![CDATA[Terminal]]></category>

		<guid isPermaLink="false">http://simplesideias.com.br/?p=505</guid>
		<description><![CDATA[Se você não se lembra de todos os comandos e opções do RubyGems, não se desespere! Eu criei um arquivo para o Bash que fará autocompletion de todos os comandos e opções disponíveis. Para utilizá-lo, copie-o para sua $HOME. $ wget http://github.com/fnando/dotfiles/raw/master/gem_completion.sh -O ~/.gem_completion.sh Adicione-o ao seu arquivo de profile do terminal (~/.bashrc, ~/.bash_profile, ~/.profile, [...]]]></description>
			<content:encoded><![CDATA[<p>Se você não se lembra de todos os comandos e opções do RubyGems, não se desespere! Eu criei um arquivo para o Bash que fará autocompletion de todos os comandos e opções disponíveis.</p>

<p>Para utilizá-lo, copie-o para sua <code>$HOME</code>.</p>

<pre class="text"><code>$ wget http://github.com/fnando/dotfiles/raw/master/gem_completion.sh -O ~/.gem_completion.sh</code></pre>

<p>Adicione-o ao seu arquivo de profile do terminal (~/.bashrc, ~/.bash_profile, ~/.profile, etc).</p>

<pre class="bash"><code><span class="kw3">source</span> ~/.gem_completion.sh</code></pre>

<p>No vídeo abaixo você pode conferir como ficou!</p>

<p><video src="http://m.simplesideias.com.br/irb-tweaks.mov" width="740" height="500" preload="none" controls></video></p>

<p>Se o vídeo acima <strong>NÃO APARECE</strong>, acesse o link diretamente: <a href="http://m.simplesideias.com.br/irb-tweaks.mov">irb-tweaks.mov</a>.</p>

<p>Também fiz outros tweaks no IRB. Note que o output utiliza o <a href="http://github.com/michaeldv/awesome_print" rel="external">Awesome Print</a>. Particularmente, achei muito melhor que o <a href="http://github.com/cldwalker/hirb" rel="external">Hirb</a>. Além disso, exibo
a versão do Ruby e qual ambiente do Rails está sendo utilizado.</p>

<p>Eu estava tendo problemas com o Wirble, principalmente na parte de histórico de comandos que nunca funcionou como deveria. Eu criei minha própria versão que, até agora, funciona muito bem!</p>

<p>Se você gostou do meu terminal, dê uma olhada nos links abaixo, pois tem bastante coisa legal!</p>

<ul>
<li><a href="http://github.com/fnando/dotfiles/" rel="external">http://github.com/fnando/dotfiles/</a></li>
<li><a href="http://github.com/fnando/gem-open" rel="external">http://github.com/fnando/gem-open</a></li>
<li><a href="http://github.com/fnando/gemspace" rel="external">http://github.com/fnando/gemspace</a></li>
<li><a href="http://simplesideias.com.br/configurando-o-terminal-no-mac-os-x/">http://simplesideias.com.br/configurando-o-terminal-no-mac-os-x/</a></li>
</ul><img src="http://feeds.feedburner.com/~r/simplesideias/~4/_iVpzdssOwE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simplesideias.com.br/autocompletion-no-rubygems-tweaks-no-irb/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>

		<feedburner:origLink>http://simplesideias.com.br/autocompletion-no-rubygems-tweaks-no-irb/</feedburner:origLink><enclosure url="http://feedproxy.google.com/~r/simplesideias/~5/fm_yXaoUjEM/irb-tweaks.mov" length="2914359" type="video/quicktime" /><feedburner:origEnclosureLink>http://m.simplesideias.com.br/irb-tweaks.mov</feedburner:origEnclosureLink></item>
		<item>
		<title>Tracker</title>
		<link>http://feedproxy.google.com/~r/simplesideias/~3/R2wSEXjBr_8/</link>
		<comments>http://simplesideias.com.br/tracker/#comments</comments>
		<pubDate>Sun, 21 Mar 2010 16:53:16 +0000</pubDate>
		<dc:creator>Nando Vieira</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://simplesideias.com.br/?p=496</guid>
		<description><![CDATA[Coloquei no ar um app chamado Tracker que acompanha os preços de jogos para PlayStation 3, Nintendo Wii e XBox 360, vendidos no Submarino. A ideia é ter uma maneira simples de encontrar boas promoções, já que entrar no Submarino toda hora não é muito legal. Ele foi feito com Sinatra, ActiveRecord e Hpricot, e [...]]]></description>
			<content:encoded><![CDATA[<p>
Coloquei no ar um app chamado <a href="http://tracker.simplesideias.com.br">Tracker</a> que acompanha os preços de jogos para
			<a href="http://www.submarino.com.br/produto/12/21617329/playstation+3+slim+ps3+hd+120gb+-+sony?menuId=206519&#038;franq=184632">PlayStation 3</a>,
			<a href="http://www.submarino.com.br/produto/12/1792681/nintendo+wii+com+jogo+wii+sports?menuId=1493&#038;franq=184632">Nintendo Wii</a> e
			<a href="http://www.submarino.com.br/produto/12/21796278/kit+xbox+arcade+(fable+2+++banjo-kazooie+++cabo+hdmi)?menuId=1495&#038;franq=184632">XBox 360</a>,
			vendidos no <a href="http://www.submarino.com.br?franq=184632">Submarino</a>.
A ideia é ter uma maneira simples de encontrar boas promoções, já que entrar no Submarino toda hora não é muito legal.
</p>

<p><img src="http://m.simplesideias.com.br/tracker.png" alt="Tracker" /></p>

<p>Ele foi feito com Sinatra, ActiveRecord e Hpricot, e está rodando na <a href="http://simplesideias.com.br/desconto-na-dreamhost/">Dreamhost</a>, em Passenger.</p>

<p>Você pode acessar o Tracker na URL <a href="http://tracker.simplesideias.com.br">tracker.simplesideias.com.br</a>.</p>

<p>Deixe sua sugestão ou crítica nos comentários.</p>

<p><strong>UPDATE:</strong> Agora todas as plataformas são indexadas. Também adicionei filtros por console, ordenação e notificação no Twitter de jogos que você se interessar!</p><img src="http://feeds.feedburner.com/~r/simplesideias/~4/R2wSEXjBr_8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simplesideias.com.br/tracker/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		<feedburner:origLink>http://simplesideias.com.br/tracker/</feedburner:origLink></item>
		<item>
		<title>Usando ruby-debug com Rails 3.0 no Ruby 1.9</title>
		<link>http://feedproxy.google.com/~r/simplesideias/~3/kXQHRQBdJF4/</link>
		<comments>http://simplesideias.com.br/usando-ruby-debug-com-rails-3-0-no-ruby-1-9/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 11:08:18 +0000</pubDate>
		<dc:creator>Nando Vieira</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://simplesideias.com.br/?p=488</guid>
		<description><![CDATA[Por muito tempo, o ruby-debug não funcionou no Ruby 1.9. Mas existe hoje uma versão totalmente funcional específica para o Ruby 1.9. Para instalá-la, basta executar o comando sudo gem install ruby-debug19 Seu uso continua o mesmo. Você chama o método debugger e o interpretador abrirá um prompt onde você pode inspecionar aquele trecho de [...]]]></description>
			<content:encoded><![CDATA[<p>Por muito tempo, o <a rel="external" href="http://rubyforge.org/projects/ruby-debug/">ruby-debug</a> não funcionou no <a rel="external" href="http://ruby-lang.org">Ruby 1.9</a>. Mas existe hoje uma versão totalmente funcional específica para o Ruby 1.9. Para instalá-la, basta executar o comando</p>

<pre class="bash"><code>sudo gem install ruby-debug19</code></pre>

<p>Seu uso continua o mesmo. Você chama o método <code>debugger</code> e o interpretador abrirá um prompt onde você pode inspecionar aquele trecho de código, listar variáveis e tudo mais.</p>

<p>Para utilizá-lo no <a rel="external" href="http://rubyonrails.org">Rails 3.0</a>, que ainda está em versão beta, você precisa adicionar a seguinte regra ao seu arquivo <code>Gemfile</code>.</p>

<pre class="ruby"><code>gem <span class="st0">&quot;ruby-debug19&quot;</span></code></pre>

<p>Simples assim!</p><img src="http://feeds.feedburner.com/~r/simplesideias/~4/kXQHRQBdJF4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simplesideias.com.br/usando-ruby-debug-com-rails-3-0-no-ruby-1-9/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://simplesideias.com.br/usando-ruby-debug-com-rails-3-0-no-ruby-1-9/</feedburner:origLink></item>
		<item>
		<title>Documentando projetos com RDoc - PDF Grátis!</title>
		<link>http://feedproxy.google.com/~r/simplesideias/~3/engleTHFmCo/</link>
		<comments>http://simplesideias.com.br/documentando-projetos-com-rdoc-pdf-gratis/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 11:58:49 +0000</pubDate>
		<dc:creator>Nando Vieira</dc:creator>
				<category><![CDATA[HOWTO]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[documentação]]></category>
		<category><![CDATA[rdoc]]></category>

		<guid isPermaLink="false">http://simplesideias.com.br/?p=475</guid>
		<description><![CDATA[E está no ar mais um PDF da série HOWTO, desta vez abordando o RDoc, marcação de documentação para códigos escritos em Ruby. O RDoc é utilizado por quase todos os grandes projetos como Ruby on Rails e RSpec, dentre muitos outros. Este guia de 17 páginas mostra como utilizar o RDoc, com muitos exemplos [...]]]></description>
			<content:encoded><![CDATA[<p class="align-right"><img src="http://m.simplesideias.com.br/howto-documentando-projetos-com-rdoc.png" alt="" /></p>

<p>
	E está no ar mais um PDF da série <a href="http://howtocode.com.br" rel="external">HOWTO</a>, desta vez abordando o <a href="http://rdoc.rubyforge.org" rel="external">RDoc</a>, marcação de documentação para códigos escritos em Ruby. 
</p>

<p>
O RDoc é utilizado por quase todos os grandes projetos como <a href="http://api.rubyonrails.com" rel="external">Ruby on Rails</a> e <a href="http://rspec.rubyforge.org/rspec/1.2.9/" rel="external">RSpec</a>, dentre muitos outros.
</p>

<p>
	Este guia de <strong>17 páginas</strong> mostra como utilizar o RDoc, com muitos exemplos de formatação.
</p>

<p>
	O PDF é gratuito pode ser baixado em <a href="http://howtocode.com.br/documentando-projetos-com-rdoc" rel="external">http://howtocode.com.br/documentando-projetos-com-rdoc</a>.
</p>

<p>Não perca tempo e baixe já a sua cópia!</p><img src="http://feeds.feedburner.com/~r/simplesideias/~4/engleTHFmCo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simplesideias.com.br/documentando-projetos-com-rdoc-pdf-gratis/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://simplesideias.com.br/documentando-projetos-com-rdoc-pdf-gratis/</feedburner:origLink></item>
		<item>
		<title>Criando eventos recorrentes com Recurrence</title>
		<link>http://feedproxy.google.com/~r/simplesideias/~3/PiTCIFN0CWo/</link>
		<comments>http://simplesideias.com.br/criando-eventos-recorrentes-com-recurrence/#comments</comments>
		<pubDate>Fri, 18 Dec 2009 14:38:36 +0000</pubDate>
		<dc:creator>Nando Vieira</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Eventos]]></category>
		<category><![CDATA[Recurrence]]></category>

		<guid isPermaLink="false">http://simplesideias.com.br/?p=468</guid>
		<description><![CDATA[Recurrence é uma biblioteca criada para gerar eventos recorrentes de maneira simples. Eu criei essa gem há tempos, mas nunca escrevi nada sobre ela. Eis que muitas pessoas começaram a me mandar e-mails perguntando como utilizá-la e chegou a hora de fazer um artigo mostrando seu uso na prática. A primeira coisa que você precisa [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="external" href="http://github.com/fnando/recurrence">Recurrence</a> é uma biblioteca criada para gerar eventos recorrentes de maneira simples. Eu criei essa gem há tempos, mas nunca escrevi nada sobre ela. Eis que muitas pessoas começaram a me mandar e-mails perguntando como utilizá-la e chegou a hora de fazer um artigo mostrando seu uso na prática.</p>

<p>A primeira coisa que você precisa fazer é instalar a gem.</p>

<pre class="ruby"><code>sudo gem install recurrence</code></pre>

<p>Depois, basta adicionar à biblioteca.</p>

<pre class="ruby"><code><span class="kw3">require</span> <span class="st0">&quot;rubygems&quot;</span>
<span class="kw3">require</span> <span class="st0">&quot;recurrence&quot;</span></code></pre>

<p>A maneira mais simples de usar é instanciar um objeto através dos métodos de classe <code>daily</code>, <code>weekly</code>, <code>monthly</code> e <code>yearly</code>, que permitem criar eventos diários, semanais, mensais e anuais, respectivamente.</p>

<pre class="ruby"><code>r = Recurrence.<span class="me1">daily</span></code></pre>

<p>Para retornar a próxima data, você deve utilizar o método <code>Recurrence#next</code>.</p>

<pre class="ruby"><code>r.<span class="kw1">next</span>
<span class="co1">#=&gt; Fri, 18 Dec 2009</span>
&nbsp;
r.<span class="kw1">next</span>
<span class="co1">#=&gt; Fri, 18 Dec 2009</span></code></pre>

<p>Você também pode utilizar o método <code>Recurrence#next!</code>, que altera a variável interna de data, como mostra o exemplo abaixo.</p>

<pre class="ruby"><code>r.<span class="kw1">next</span>!
<span class="co1">#=&gt; Fri, 18 Dec 2009</span>
&nbsp;
r.<span class="kw1">next</span>!
<span class="co1">#=&gt; Sat, 19 Dec 2009</span></code></pre>

<p>Se você quiser, pode especificar o intervalo de dias que o evento pode se repetir; basta utilizar a opção <code>:starts</code> e <code>:ends</code>.</p>

<pre class="ruby"><code><span class="co1"># define the starting date to 2009-12-24</span>
r = Recurrence.<span class="me1">daily</span><span class="br0">&#40;</span><span class="re3">:starts</span> =&gt; <span class="kw4">Date</span>.<span class="me1">new</span><span class="br0">&#40;</span><span class="nu0">2009</span>, <span class="nu0">12</span>, <span class="nu0">24</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span class="co1"># define the ending date to 2009-12-31</span>
r = Recurrence.<span class="me1">daily</span><span class="br0">&#40;</span><span class="re3">:ends</span> =&gt; <span class="kw4">Date</span>.<span class="me1">new</span><span class="br0">&#40;</span><span class="nu0">2009</span>, <span class="nu0">12</span>, <span class="nu0">31</span><span class="br0">&#41;</span><span class="br0">&#41;</span></code></pre>

<p>Você também pode passar essas datas como strings, desde que elas sejam interpretadas pelo método <code>Date#parse</code>.</p>

<pre class="ruby"><code>r = Recurrence.<span class="me1">daily</span><span class="br0">&#40;</span><span class="re3">:starts</span> =&gt; <span class="st0">&quot;2009-12-24&quot;</span><span class="br0">&#41;</span></code></pre>

<p>Os atalhos são uma excelente maneira de tornar o código mais semântico, mas em alguns casos é melhor seguir com o bom e velho método <code>new</code>.</p>

<pre class="ruby"><code>r = Recurrence.<span class="me1">new</span><span class="br0">&#40;</span><span class="re3">:every</span> =&gt; <span class="re3">:week</span>, <span class="re3">:on</span> =&gt; <span class="re3">:saturday</span>, <span class="re3">:interval</span> =&gt; <span class="nu0">2</span><span class="br0">&#41;</span></code></pre>

<p>Como você pode ver no exemplo acima, estamos criando um evento <strong>semanal</strong>, que acontece aos <strong>sábados</strong>, a cada <strong>duas semanas</strong>. Ao utilizar o método <strong>Recurrence#next!</strong> você terá algo como isso:</p>

<pre class="ruby"><code>r.<span class="kw1">next</span>!
<span class="co1">#=&gt; Sat, 19 Dec 2009</span>
&nbsp;
r.<span class="kw1">next</span>!
<span class="co1">#=&gt; Sat, 02 Jan 2010</span></code></pre>

<p>Você também pode especificar uma lista com os dias da semana que o evento deve ocorrer.</p>

<pre class="ruby"><code>r = Recurrence.<span class="me1">weekly</span><span class="br0">&#40;</span><span class="re3">:on</span> =&gt; <span class="br0">&#91;</span><span class="re3">:saturday</span>, <span class="re3">:sunday</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
r.<span class="kw1">next</span>!
<span class="co1">#=&gt; Sat, 19 Dec 2009</span>
&nbsp;
r.<span class="kw1">next</span>!
<span class="co1">#=&gt; Sun, 20 Dec 2009</span>
&nbsp;
r.<span class="kw1">next</span>!
<span class="co1">#=&gt; Sat, 26 Dec 2009</span></code></pre>

<p>Para acessar uma lista com todos os eventos disponíveis, basta utilizar o método <code>Recurrence#events</code>.</p>

<pre class="ruby"><code>r.<span class="me1">events</span>
<span class="co1">#=&gt; [Sun, 20 Dec 2009, Sun, 27 Dec 2009]</span></code></pre>

<p>Esse método fará irá guardar a lista de datas geradas, aumentando a performance se ele for acessado mais de uma vez. Se você quiser regerar essas datas, pode utilizar o método <code>Recurrence#events!</code>.</p>

<p>Também é possível verificar se uma data está no intervalo especificado no objeto <code>Recurrence</code>.</p>

<pre class="ruby"><code>r = Recurrence.<span class="me1">weekly</span><span class="br0">&#40;</span><span class="re3">:on</span> =&gt; <span class="re3">:saturday</span><span class="br0">&#41;</span>
&nbsp;
r.<span class="kw1">include</span>? <span class="st0">&quot;2009-12-19&quot;</span>
<span class="co1">#=&gt; true</span></code></pre>

<h3>Como usar na prática</h3>

<p>Como você pode ver, o Recurrence é totalmente parametrizado. Essa abordagem permite que você armazene os itens necessários para montar sua recorrência em um banco de dados, por exemplo. Digamos que você tenha um modelo <code>Event</code>, com o seguinte schema:</p>

<pre class="ruby"><code><span class="kw1">class</span> CreateEvents &lt; <span class="re2">ActiveRecord::Migration</span>
  <span class="kw1">def</span> <span class="kw2">self</span>.<span class="me1">up</span>
    create_table <span class="re3">:events</span> <span class="kw1">do</span> |t|
      t.<span class="kw3">string</span> <span class="re3">:title</span>,        <span class="re3">:null</span> =&gt; <span class="kw2">false</span>
      t.<span class="me1">binary</span> <span class="re3">:meta</span>,         <span class="re3">:null</span> =&gt; <span class="kw2">false</span>
      t.<span class="me1">date</span>   <span class="re3">:scheduled_to</span>, <span class="re3">:null</span> =&gt; <span class="kw2">false</span>
    <span class="kw1">end</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<p>Os atributos que serão utilizados no Recurrence são <code>:meta</code> e <code>:scheduled_to</code>. O primeiro irá armazenar o tipo de recorrência e as informações como dia, intervalo, etc. Já o segundo, irá armazenar a próxima data do evento, para diminuir a geração de datas. O modelo <code>Event</code> pode armazenar os atributos como este exemplo:</p>

<pre class="ruby"><code><span class="kw1">class</span> Event &lt; <span class="re2">ActiveRecord::Base</span>
  serialize <span class="re3">:meta</span>, <span class="kw4">Hash</span>
&nbsp;
  validates_presence_of <span class="re3">:meta</span>, <span class="re3">:title</span>, <span class="re3">:scheduled_to</span>
<span class="kw1">end</span></code></pre>

<p>Veja um exemplo de como cadastrar um evento &#034;Pagamento&#034;, que acontece todo mês no dia 5.</p>

<pre class="rails"><code>options = <span class="br0">&#123;</span>:every =&gt; <span class="re3">:month</span>, <span class="re3">:on</span> =&gt; <span class="nu0">5</span><span class="br0">&#125;</span>
r = Recurrence.<span class="kw5">new</span><span class="br0">&#40;</span>options<span class="br0">&#41;</span>
&nbsp;
event = Event.<span class="kw5">new</span><span class="br0">&#40;</span><span class="re3">:title</span> =&gt; <span class="st0">&quot;Pagamento&quot;</span>, <span class="re3">:meta</span> =&gt; options, <span class="re3">:scheduled_to</span> =&gt; r.<span class="kw1">next</span><span class="br0">&#41;</span>
event.<span class="kw5">save</span>!</code></pre>

<p>Na hora de montar o objeto de recorrência, você pode utilizar algo como isto:</p>

<pre class="rails"><code>event = Event.<span class="kw5">first</span>
&nbsp;
r = Recurrence.<span class="kw5">new</span><span class="br0">&#40;</span>event.<span class="me1">meta</span>.<span class="me1">merge</span><span class="br0">&#40;</span><span class="re3">:starts</span> =&gt; event.<span class="me1">scheduled_to</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
r.<span class="kw1">next</span>
<span class="co1">#=&gt; Tue, 05 Jan 2010</span></code></pre>

<p>Se você precisar exibir um evento mais de uma vez, utilize este mesmo processo e exiba os eventos com o método <code>events</code>.</p>

<h3>Finalizando</h3>

<p>Criar eventos recorrentes nem sempre é uma tarefa simples, principalmente no que diz respeito à performance. O <a rel="external" href="http://github.com/josevalim">José Valim</a> fez uma série de contribuições que ajudaram a melhor esse ponto, além de outras funcionalidades como os atalhos.</p>

<p>Para conhecer mais sobre as opções disponíveis do <a rel="external" href="http://github.com/fnando/recurrence">Recurrence</a>, acesse o <a rel="external" href="http://github.com/fnando/recurrence/blob/master/README.markdown"><span class="caps">README</span></a> do projeto no <a rel="external" href="http://github.com">Github</a>.</p>
<img src="http://feeds.feedburner.com/~r/simplesideias/~4/PiTCIFN0CWo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simplesideias.com.br/criando-eventos-recorrentes-com-recurrence/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		<feedburner:origLink>http://simplesideias.com.br/criando-eventos-recorrentes-com-recurrence/</feedburner:origLink></item>
		<item>
		<title>7 coisas que você precisa conhecer no RSpec</title>
		<link>http://feedproxy.google.com/~r/simplesideias/~3/l6HHG5kN_Ak/</link>
		<comments>http://simplesideias.com.br/7-coisas-que-voce-precisa-conhecer-no-rspec/#comments</comments>
		<pubDate>Fri, 11 Dec 2009 11:42:19 +0000</pubDate>
		<dc:creator>Nando Vieira</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Dicas]]></category>
		<category><![CDATA[RSpec]]></category>

		<guid isPermaLink="false">http://simplesideias.com.br/?p=456</guid>
		<description><![CDATA[O RSpec é um framework bastante completo e, por isso mesmo, muitas coisas são desconhecidas por grande parte dos desenvolvedores. Neste artigo, você conhecerá 7 coisas que irão mudar a maneira como você utiliza o RSpec. Subject O RSpec possui um método muito útil chamado subject, que retorna uma instância da classe que está sendo [...]]]></description>
			<content:encoded><![CDATA[<p>O <a rel="external" href="http://rspec.info">RSpec</a> é um framework bastante completo e, por isso mesmo, muitas coisas são desconhecidas por grande parte dos desenvolvedores. Neste artigo, você conhecerá 7 coisas que irão mudar a maneira como você utiliza o RSpec.</p>

<h3>Subject</h3>

<p>O RSpec possui um método muito útil chamado <code>subject</code>, que retorna uma instância da classe que está sendo utilizada como contexto do exemplo.</p>

<pre class="rails"><code>describe User <span class="kw1">do</span>
  it <span class="br0">&#123;</span> should_not be_admin <span class="br0">&#125;</span>
<span class="kw1">end</span></code></pre>

<p>A grande vantagem desta abordagem é que você aumenta consideravelmente a legibilidade de suas especificações. Mas você não precisa utilizar apenas o contexto especificado no método <code>describe</code>; se quiser, você pode definir o seu próprio!</p>

<pre class="rails"><code>describe User <span class="kw1">do</span>
  subject <span class="br0">&#123;</span> User.<span class="kw5">new</span><span class="br0">&#40;</span><span class="re3">:admin</span> =&gt; <span class="kw2">true</span><span class="br0">&#41;</span> <span class="br0">&#125;</span>
  it <span class="br0">&#123;</span> should be_admin <span class="br0">&#125;</span>
<span class="kw1">end</span></code></pre>

<p>Quando outros tipos de objetos (como módulos ou strings) são passados ao método <code>describe</code>, ele irá retornar o próprio objeto.</p>

<h3>Message expectation</h3>

<h4>O método stub_chain</h4>

<p>Sempre que você precisar fazer uma chamada encadeada e quiser verificar o último valor, utilize o método <code>stub_chain</code>. Ele permite transformar um bloco como este</p>

<pre class="rails"><code>describe <span class="st0">&quot;Mocks&quot;</span> <span class="kw1">do</span>
  before <span class="kw1">do</span>
    <span class="re1">@user</span> = mock<span class="br0">&#40;</span><span class="br0">&#41;</span>
    <span class="re1">@things</span> = mock<span class="br0">&#40;</span><span class="br0">&#41;</span>
    <span class="re1">@recent</span> = mock<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
    <span class="re1">@user</span>.<span class="me1">stub</span>!<span class="br0">&#40;</span><span class="re3">:things</span><span class="br0">&#41;</span>.<span class="me1">and_return</span><span class="br0">&#40;</span>@things<span class="br0">&#41;</span>
    <span class="re1">@things</span>.<span class="me1">stub</span>!<span class="br0">&#40;</span><span class="re3">:recent</span><span class="br0">&#41;</span>.<span class="me1">and_return</span><span class="br0">&#40;</span>@recent<span class="br0">&#41;</span>
    <span class="re1">@recent</span>.<span class="me1">should_receive</span><span class="br0">&#40;</span><span class="re3">:count</span><span class="br0">&#41;</span>.<span class="me1">and_return</span><span class="br0">&#40;</span><span class="nu0">100</span><span class="br0">&#41;</span>
  <span class="kw1">end</span>
&nbsp;
  it <span class="st0">&quot;should return the recent things count from an user&quot;</span> <span class="kw1">do</span>
    <span class="re1">@user</span>.<span class="me1">things</span>.<span class="me1">recent</span>.<span class="kw5">count</span>.<span class="me1">should</span> == <span class="nu0">100</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<p>em uma coisa bem mais simples como esta</p>

<pre class="rails"><code>describe <span class="st0">&quot;Mocks&quot;</span> <span class="kw1">do</span>
  before <span class="kw1">do</span>
    <span class="re1">@user</span> = mock<span class="br0">&#40;</span><span class="br0">&#41;</span>
    <span class="re1">@user</span>.<span class="me1">stub_chain</span><span class="br0">&#40;</span><span class="re3">:things</span>, <span class="re3">:recent</span>, <span class="re3">:count</span><span class="br0">&#41;</span>.<span class="me1">and_return</span><span class="br0">&#40;</span><span class="nu0">100</span><span class="br0">&#41;</span>
  <span class="kw1">end</span>
&nbsp;
  it <span class="st0">&quot;should return the recent things count from an user&quot;</span> <span class="kw1">do</span>
    <span class="re1">@user</span>.<span class="me1">things</span>.<span class="me1">recent</span>.<span class="kw5">count</span>.<span class="me1">should</span> == <span class="nu0">100</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<h4>O método and_return</h4>

<p>Você alguma vez precisou acessar um stub mais de uma vez e queria que ele retornasse diferentes valores em cada chamada? Veja este exemplo.</p>

<pre class="rails"><code><span class="kw3">require</span> <span class="st0">&quot;open-uri&quot;</span>
&nbsp;
<span class="kw1">class</span> Dice
  API_URL = <span class="st0">&quot;http://www.random.org/integers/?num=1&amp;min=1&amp;max=6&amp;col=1&amp;base=10&amp;format=plain&amp;rnd=new&quot;</span>
&nbsp;
  <span class="kw1">def</span> roll
    <span class="kw3">open</span><span class="br0">&#40;</span>API_URL<span class="br0">&#41;</span>.<span class="kw5">to_i</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<p>Toda vez que o método <code>roll</code> for chamado, ele irá fazer uma requisição diferente ao <a rel="external" href="http://random.org">http://random.org</a>. Imagine que por algum motivo você precisasse retornar diferentes valores toda vez que o método <code>open</code> você invocado. Tudo o que você precisa fazer é retornar mais de um valor com o método <code>and_return</code>.</p>

<pre class="rails"><code>describe Dice <span class="kw1">do</span>
  before <span class="kw1">do</span>
    subject.<span class="me1">should_receive</span><span class="br0">&#40;</span><span class="re3">:open</span><span class="br0">&#41;</span>.<span class="me1">and_return</span><span class="br0">&#40;</span><span class="st0">&quot;1&quot;</span>, <span class="st0">&quot;4&quot;</span>, <span class="st0">&quot;2&quot;</span><span class="br0">&#41;</span>
  <span class="kw1">end</span>
&nbsp;
  it <span class="st0">&quot;should not cache request&quot;</span> <span class="kw1">do</span>
    subject.<span class="me1">roll</span>.<span class="me1">should</span> == <span class="nu0">1</span>
    subject.<span class="me1">roll</span>.<span class="me1">should</span> == <span class="nu0">4</span>
    subject.<span class="me1">roll</span>.<span class="me1">should</span> == <span class="nu0">2</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<h4>O método with</h4>

<p>O RSpec disponibiliza uma série de métodos que podem ser usados em conjunto com o método <code>with</code>. Veja alguns exemplos:</p>

<pre class="rails"><code><span class="kw1">module</span> Echo
  extend <span class="kw2">self</span>
&nbsp;
  <span class="kw1">def</span> echo<span class="br0">&#40;</span>*args<span class="br0">&#41;</span>
    args.<span class="me1">inspect</span>
  <span class="kw1">end</span>
<span class="kw1">end</span>
&nbsp;
describe Echo <span class="kw1">do</span>
  <span class="co1"># with any kind of argument</span>
  specify<span class="br0">&#40;</span><span class="st0">&quot;anything&quot;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    subject.<span class="me1">should_receive</span><span class="br0">&#40;</span><span class="re3">:echo</span><span class="br0">&#41;</span>.<span class="me1">with</span><span class="br0">&#40;</span>anything<span class="br0">&#41;</span>
    subject.<span class="me1">echo</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span>
  <span class="br0">&#125;</span>
&nbsp;
  <span class="co1"># with hash containing values</span>
  specify<span class="br0">&#40;</span><span class="st0">&quot;hash_including&quot;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    subject.<span class="me1">should_receive</span><span class="br0">&#40;</span><span class="re3">:echo</span><span class="br0">&#41;</span>.<span class="me1">with</span><span class="br0">&#40;</span>hash_including<span class="br0">&#40;</span><span class="re3">:say</span> =&gt; <span class="st0">&quot;hello&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
    subject.<span class="me1">echo</span><span class="br0">&#40;</span><span class="re3">:say</span> =&gt; <span class="st0">&quot;hello&quot;</span><span class="br0">&#41;</span>
  <span class="br0">&#125;</span>
&nbsp;
  <span class="co1"># with an instance of String</span>
  specify<span class="br0">&#40;</span><span class="st0">&quot;instance_of&quot;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    subject.<span class="me1">should_receive</span><span class="br0">&#40;</span><span class="re3">:echo</span><span class="br0">&#41;</span>.<span class="me1">with</span><span class="br0">&#40;</span>instance_of<span class="br0">&#40;</span><span class="kw3">String</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
    subject.<span class="me1">echo</span><span class="br0">&#40;</span><span class="st0">&quot;hello&quot;</span><span class="br0">&#41;</span>
  <span class="br0">&#125;</span>
&nbsp;
  <span class="co1"># with an object that responds to some methods</span>
  specify<span class="br0">&#40;</span><span class="st0">&quot;duck_type&quot;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    subject.<span class="me1">should_receive</span><span class="br0">&#40;</span><span class="re3">:echo</span><span class="br0">&#41;</span>.<span class="me1">twice</span>.<span class="me1">with</span><span class="br0">&#40;</span>duck_type<span class="br0">&#40;</span>:&lt;&lt;<span class="br0">&#41;</span><span class="br0">&#41;</span>
    subject.<span class="me1">echo</span><span class="br0">&#40;</span><span class="kw3">Array</span>.<span class="kw5">new</span><span class="br0">&#41;</span>
    subject.<span class="me1">echo</span><span class="br0">&#40;</span><span class="kw3">String</span>.<span class="kw5">new</span><span class="br0">&#41;</span>
  <span class="br0">&#125;</span>
<span class="kw1">end</span></code></pre>

<p>Para ver mais exemplos, acesse <a rel="external" href="https://gist.github.com/45b97f90a83c8acf3f29">https://gist.github.com/45b97f90a83c8acf3f29</a>.</p>

<h3>before e after globais</h3>

<p>Muitas vezes precisamos preparar nosso ambiente antes de executarmos nossos testes. Quando isso precisa ser feito em mais de uma especificação, você pode diminuir a duplicação de código utilizando blocos globais.</p>

<p>No seu arquivo <code>spec_helper.rb</code>, você pode utilizar os métodos <code>append_before</code>, <code>append_after</code>, <code>prepend_before</code> e <code>prepend_after</code>.</p>

<pre class="rails"><code><span class="re2">Spec::Runner</span>.<span class="me1">configure</span> <span class="kw1">do</span> |config|
  config.<span class="me1">prepend_after</span> <span class="br0">&#123;</span> <span class="st0">`rm -rf some/path`</span> <span class="br0">&#125;</span>
<span class="kw1">end</span></code></pre>

<h3>Pending</h3>

<p>Em vez de comentar temporariamente exemplos que você não quer que sejam executados, você pode utilizar o método <code>pending</code>. O método <code>pending</code> pode ser utilizado nos blocos de <code>before</code>. Assim, todos os exemplos daquele contexto de <code>describe</code> serão automaticamente marcados como pendente.</p>

<pre class="rails"><code>describe <span class="st0">&quot;Pending examples&quot;</span> <span class="kw1">do</span>
  before <span class="kw1">do</span>
    pending
  <span class="kw1">end</span>
&nbsp;
  <span class="co1"># lots of examples</span>
<span class="kw1">end</span></code></pre>

<p>Você também pode deixar apenas um exemplo pendente.</p>

<pre class="rails"><code>describe <span class="st0">&quot;Pending examples&quot;</span> <span class="kw1">do</span>
  it <span class="st0">&quot;should be pending&quot;</span> <span class="kw1">do</span>
    pending <span class="st0">&quot;need to work on it&quot;</span>
    Env.<span class="me1">setup</span>!
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<p>Ou apenas uma parte dele.</p>

<pre class="rails"><code>describe <span class="st0">&quot;Pending examples&quot;</span> <span class="kw1">do</span>
  it <span class="st0">&quot;should be pending with a block&quot;</span> <span class="kw1">do</span>
    pending<span class="br0">&#40;</span><span class="st0">&quot;need to working on it as well&quot;</span><span class="br0">&#41;</span> <span class="kw1">do</span>
      Env.<span class="me1">setup</span>!
    <span class="kw1">end</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<p>Uma outra alternativa (que não é deixar como pendente mas sim desabilitado) é utilizar o método <code>xit</code> em vez de <code>it</code>.</p>

<pre class="rails"><code>describe <span class="st0">&quot;Pending examples&quot;</span> <span class="kw1">do</span>
  xit <span class="st0">&quot;should be pending with alias&quot;</span> <span class="kw1">do</span>
    Env.<span class="me1">setup</span>!
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<h3>Matchers personalizados</h3>

<p>Sempre que você perceber que está repetindo um padrão na hora de escrever seus exemplos, automatize o processo criando novos matchers. O RSpec possui duas maneiras diferentes de fazer isso. A mais simples delas é utilizando o método <code>simple_matcher</code>. Crie um módulo chamado <code>TheAnswerMatchers</code> para adicionarmos novos matchers.</p>

<pre class="rails"><code><span class="kw1">module</span> TheAnswerMatchers
  <span class="kw1">def</span> be_the_answer
    simple_matcher <span class="kw1">do</span> |given, matcher|
      <span class="co1"># save some typing</span>
      the_answer = <span class="st0">&quot;the Answer to Life, the Universe, and Everything&quot;</span>
&nbsp;
      matcher.<span class="me1">description</span> = <span class="st0">&quot;be #{the_answer}&quot;</span>
      matcher.<span class="me1">failure_message</span> = <span class="st0">&quot;expected #{given.inspect} to be #{the_answer}&quot;</span>
      matcher.<span class="me1">negative_failure_message</span> = <span class="st0">&quot;expected #{given.inspect} not to be #{the_answer}&quot;</span>
      given == <span class="nu0">42</span>
    <span class="kw1">end</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<p>Agora, basta fazer com que o RSpec reconheça esses novos matchers; é só incluir o módulo.</p>

<pre class="rails"><code><span class="re2">Spec::Runner</span>.<span class="me1">configure</span> <span class="kw1">do</span> |config|
  config.<span class="kw1">include</span> TheAnswerMatchers
<span class="kw1">end</span></code></pre>

<p>E para escrever seus exemplos, você pode usar o matcher <code>be_the_answer</code>:</p>

<pre class="rails"><code>describe <span class="st0">&quot;The Answer to Life, the Universe, and Everything&quot;</span> <span class="kw1">do</span>
  specify <span class="br0">&#123;</span> <span class="nu0">42</span>.<span class="me1">should</span> be_the_answer <span class="br0">&#125;</span>
  specify <span class="br0">&#123;</span> <span class="st0">&quot;the wrong answer&quot;</span>.<span class="me1">should_not</span> be_the_answer <span class="br0">&#125;</span>
<span class="kw1">end</span></code></pre>

<h3>Finalizando&#8230;</h3>

<p>Como você pode perceber, é bem simples escrever exemplos melhores no RSpec. Se você olhar as specs do RSpec, encontrará bastante coisa legal que você normalmente não veria (porque tem muita coisa para ler) no <a rel="external" href="http://rspec.rubyforge.org/rspec/1.2.9/">RDocs</a>.</p>

<p>E você, tem alguma dica para compartilhar?</p><img src="http://feeds.feedburner.com/~r/simplesideias/~4/l6HHG5kN_Ak" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simplesideias.com.br/7-coisas-que-voce-precisa-conhecer-no-rspec/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://simplesideias.com.br/7-coisas-que-voce-precisa-conhecer-no-rspec/</feedburner:origLink></item>
		<item>
		<title>Ceará on Rails 2009: Testando Rails apps com RSpec</title>
		<link>http://feedproxy.google.com/~r/simplesideias/~3/kJT1g420OuI/</link>
		<comments>http://simplesideias.com.br/ceara-on-rails-2009-testando-rails-apps-com-rspec/#comments</comments>
		<pubDate>Sat, 07 Nov 2009 23:31:46 +0000</pubDate>
		<dc:creator>Nando Vieira</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://simplesideias.com.br/?p=452</guid>
		<description><![CDATA[Acabei de fazer minha apresentação no Ceará on Rails, que foi um excelente evento! Se você não pode comparacer, pode ver os slides Gostaria de agradecer aos comentários positivos e, principalmente, aos organizadores. Keep on rockin&#039;!]]></description>
			<content:encoded><![CDATA[<p>Acabei de fazer minha apresentação no <a href="http://cearaonrails.com.br">Ceará on Rails</a>, que foi um excelente evento!</p>

<p>Se você não pode comparacer, pode ver os <a href="http://www.slideshare.net/fnando/testando-rails-apps-com-rspec">slides</a></p>

<p><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=rspec-091107170547-phpapp02&amp;stripped_title=testando-rails-apps-com-rspec" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=rspec-091107170547-phpapp02&amp;stripped_title=testando-rails-apps-com-rspec" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></p>

<p>Gostaria de agradecer aos comentários positivos e, principalmente, aos organizadores. Keep on rockin&#039;!</p><img src="http://feeds.feedburner.com/~r/simplesideias/~4/kJT1g420OuI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simplesideias.com.br/ceara-on-rails-2009-testando-rails-apps-com-rspec/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://simplesideias.com.br/ceara-on-rails-2009-testando-rails-apps-com-rspec/</feedburner:origLink></item>
	</channel>
</rss>
