Correcting a Git corruption problem

Git — Tags: — dc.rec1 @ 7:07 pm

Sometimes when we work with submodules the wrong way we end corrupting the repository and after trying to pull the server we get:

error: git-upload-pack: git-pack-objects died with error.
fatal: git-upload-pack: aborting due to possible repository corruption on the remote side.
remote: Generating pack…
remote: Done counting 39 objects.
remote: Result has 28 objects.
remote: error: unable to find b490fa1a6d81e39d3a8d99f9cce8b57c3397b7d7
remote: fatal: unable toremote: aborting due to possible repository corruption on the remote side.
fatal: protocol error: bad pack header

I’m not sure if this is the best solution but pulling from the public URL and then pushing to the server solves the problem.

Remarkable plugins for ActsAsTaggableOn, Paperclip and ThinkingSphinx

I created this three Remarkable plugins so they could help me in a project I’m working on:

Basically they let you write code like this:

describe User do
  should_act_as_taggable_on :categories
 
  should_have_attached_file :logo
 
  should_index 'addresses.city', :as => :address
  should_have_index_attribute :priority
end

If this plugins help you, please consider to recommend me at Working With Rails.

Cool tests in the Java Maven platform now possible with rspec-maven-plugin

BDD, Java, Maven, RSpec, TDD — Tags: , , , , , — dc.rec1 @ 2:19 pm

I don’t like Maven at all but sometimes depending of the project and the people you need to use this. After playing with RSpec I stop considering any Java language framework acceptable for testing so for this project I’m working on right now I needed to find a solution that could integrate RSpec with Maven.

After googling I found this post from Bob McWhirter where he presented a official rspec-maven-plugin. I tried to use it but it wasn’t working so I forked it, fixed it and changed some things.

The forked version of rspec-maven-plugin is at GitHub and to use it you should:

install the plugin in the local repository (this is necessary only one time):

git clone git://github.com/dcrec1/rspec-maven-plugin.git
cd rspec-maven-plugin
mvn install

configure your project’s pom.xml adding this:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>rspec-maven-plugin</artifactId>
    <executions>
        <execution>
            <id>test</id>
            <phase>test</phase>
            <goals>
                <goal>spec</goal>
            </goals>
        </execution>
    </executions>
</plugin>

set the JRUBY_HOME system variable, for example:

export JRUBY_HOME=/opt/jruby-1.1.6/

The plugin will run in the test phase of the Maven build cycle.

Happy testing!

Common attributes translations with activerecord_i18n_defaults

ActiveRecord, Ruby on Rails, i18n — Tags: , , , — dc.rec1 @ 7:40 pm

The plugin activerecord_i18n_defaults lets you write locale’s files in a Rails 2.2 application like this:

pt-BR:
  activerecord:
    attributes:
      _all:
        login: "Identificação"
        name: "Nome"
      admin:
        age: "Idade"
      customer:
        nickname: "Apelido"
      user:
        email: "Endereço de e-mail"

instead of like this:

pt-BR:
  activerecord:
    attributes:
      admin:
        login: "Identificação"
        name: "Nome"
        age: "Idade"
      customer:
        login: "Identificação"
        name: "Nome"
        nickname: "Apelido"
      user:
        login: "Identificação"
        name: "Nome"
        email: "Endereço de e-mail"

Next time you need to create a locale’s file put your common attributes in the key _all and DRY.

If you like this plugin please consider to recommend me at Working With Rails.

Is “one assertion per test” a “false idol”?

BDD, Patterns, TDD — Tags: , , , — dc.rec1 @ 8:04 pm

A few days ago I wrote in my portuguese blog an article trying to demonstrate why the “one assertion per test” pattern is an excellent one. If you dont know much about this pattern, I suggest you to follow this link which is a post from Jay Fields talking about it.

Some people gave me some feedback in the comments and one of them pointed me to this post from the guys from thoughtbot where among other practices, they criticized the one I was trying to evangelize :)

I like arguments and in this case arguments are present, but I think they aren’t valid, we’ll see why.

6 database records created

The author of the posts shows a code written in Shoulda where before each test he creates a record in the database and claims that the pattern is bad because to follow it he needed to create six database records instead of just one. Now I ask, did anyone tell anybody to create a record before each test? In my first post talking about the pattern I wrote an example which contains the following code:

before :all do
  email = Email.new("morena@opensource.com")
end

Note that I wrote before :all and not before :each, that’s because independent of the pattern, the tests need to be smart. In the case you couldn’t specify in Shoulda a block to be executed before all tests, that’s a problem of the framework and not of the pattern.

TDD should feel rhythmic

In the same code talked before, the author wrote some tests consisting of one line (Shoulda macros) and others consisting of three lines. Then he argues that the pattern in discussion is bad because the code hasn’t rhythm and TDD should have rhythm. Does this have any sense? The pattern doesn’t talk about having tests in one line or three, just about having one assertion per test. This doesn’t have any relation with the pattern, I might have the same behavior without following it, like this:

should_respond_with_xml_for 'user' 
 
should 'include the user id and user name' do 
  assert_select 'id', @user.id.to_s 
  assert_select 'name', @user.name 
end

What about now? Can we say that Shoulda is bad because I wrote a code that I consider it has no rhyme? Are then Shoulda macros not that good because they take they rhythm of the code?

Test names are not intention-revealing

I’m not sure if I understood this argument very well but I think the author claimed that the more tests you have, the more you have to give specific names to them. Assuming I’m right in my understanding, the intent of the pattern is precisely this, to create tests that specify what they are testing and what the code should do. When you run your tests, I surely think it’s better to receive this:

a GET to /users/:id.xml should respond with success
a GET to /users/:id.xml should render template show
a GET to /users/:id.xml should find the correct User
a GET to /users/:id.xml should respond with xml for user
a GET to /users/:id.xml should include the user id
a GET to /users/:id.xml should include the user name

than

user show xml

I did write “user show xml” because the second code wrote by the author is a single test with the name “test_user_show_xml”. “user show xml” doesn’t tell us anything about the system. If I read this test I will think that the user must show a xml. The first case tells us much more about the system, it’s an executable specification.

If context/describe/should/it blocks want to make things shorter then why aren’t we using a library (Test::Unit) that makes them one line?

What relation does this have with the pattern? Again, the pattern just tells about having one assertion per test, not about leaving the code smaller. Moreover, I think this argument is good for the pattern. There are people who say that they don’t follow the pattern because they prefer to write less code. In this case, if you want to write less code then you should use Test::Unit :P

The author shows then the code written in Test::Unit that I talked about before, with a lot of asserts in only one test. I think this test is really bad because it doesn’t specify anything at all and to understand it you need to read the code, not just the title.

Finally, the post mentioned that the pattern is a solution for a problem that doesn’t exist, but the problem does really exists and it’s this:

Writing non-executable documentation of a code is very expensive because every change in the behavior of the code generates also a change in the documentation and that creates double work. Besides the double work, the non-executable documentation does not guarantee that the code does what it should. The solution to this is to create executable documentation and executable documentation means tests that specify and to create tests that specify the easiest solution is to follow “the one assert per test” pattern.

The GemHub way to create RubyGems.

RubyGems — Tags: , , , , — dc.rec1 @ 2:58 pm

What is GemHub?

GemHub is a gem that creates a simple directory structure to build a gem which is gonna be tested with RSpec and hosted on GitHub.

Why not use NewGem or Sow?

If you’re writing a gem and you’re planning to host it in GitHub then NewGem may be not the best option, because it was created with RubyForge in mind and creates a lot of stuff that with GitHub you don’t really need, like a history, post-installation and manifest files, a task folder for putting your tasks, a doc folder for documentation and some scripts generators.

When thinking in GitHub you don’t need a history file because you got Git’s commit history with a click. Also, you can write all kind of instructions in a Readme.textile and that information will appear in the repository site. If you need more detailed documentation, you can write them in the wiki. Finally, when writing a not so complex gem is much probably that you will not need any other task that GemHub’s defaults.

Sow, being a much more simpler option, also generates a history and manifest files. It does also create a Readme file, but with txt extension, what means not cool formatting for GitHub. A bin folder is created by Sow, too. The intention of the bin folder is to put scripts that will be executed in a terminal, what mosts gems don’t need.

Finally, both NewGem and Sow creates tests using Test::Unit. Writing tests with lots of asserts is very ugly when compared to RSpec’s cool expectations, so GemHub uses RSpec as they testing framework.

Working with GemHub

When executed:

gemhub gem_name

GemHub will create a spec/gem_name.rb file to specify your gem’s behavior, a lib/gem_name.rb to implement your gem specification, a README.textile file (with an MIT license included) to write whatever you want and a Rakefile with common tasks. In this Rakefile there are also the details from your gem (name, version, platform, etc).

      create  
      create  lib
      create  spec
      create  lib/gem_name.rb
      create  spec/gem_name_spec.rb
      create  README.textile
      create  Rakefile

Anytime before you get ready to create your gemspec file, you should open the Rakefile file and edit the gem details. With your Rakefile edited, you can run rake make_spec to generate the gemspec file of your gem, rake gem to build a gem from your gemspec file and rake install to install the built gem locally. It’s a good practice that before you push your code to GitHub you execute also rake specs to verify that your code operates as expected and rake gem to verify that your gemspec is OK, so GitHub can build your gem without problems.

Rocking your application with Rails 2.2 i18n support

Ruby on Rails — Tags: , — admin @ 2:21 pm

I know Sven Fuchs wrote about the Rails i18n core API back in July (when Rails 2.2 was not yet released), but since then, the i18n API has changed a little and now that Rails 2.2 is out I’ll write the steps you need to rock your application with this new excellent support.

1. Configure the I18n module

You need to select the translations files the module will load and the default locale in case the user don’t specify one. As you need to do this only once, you can put the next code in the config/environment.rb file:

I18n.default_locale = "pt-BR"
I18n.load_path += Dir.glob("config/locales/*.yml")

Update: We should add elements to the load_path instead of assigning a new array to not overwrite Rails 2.2 provided paths.

2. Set the locale in each request

You need to tell the I18n module which locale it should use in the current process. This can be done in a filter, before the controller executes the action. A good place to do the filter should be the application controller:

before_filter :set_locale
 
def set_locale
  I18n.locale = params[:locale] || I18n.default_locale
end

3. Internationalize

From now on the only thing you need to do is translate and localize, so from any place in your application you can call the translate and localize methods (t and l are alias) , for example:

I18n.t 'store.title'
I18n.l Time.now

Now that we know how to get our applications internationalized, I’ll talk about the process.

How does the Rails 2.2 i18n work?

The I18n module stores a backend that implements the localize and translate methods. Every time we call I18n.translate or I18n.localize, the I18n module delegates this calls to the configured backend. Rails 2.2 comes with a default backend called Simple Backend.

The first time the Simple Backend internationalizes something it loads the internationalizations files defined in I18n.load_path .

The internationalizations files

The internationalizations files can be a Ruby Hash or a YAML script:

Ruby Hash

{
  :'pt-BR' => {
    :foo => {
      :bar => "baz"
    }
  }
}

YAML

pt-BR:
  foo:
    bar: baz

Reloading internationalizations files

If for any reason you are using the Simple Backend and you want to load/reload an internationalization file after the first internationalization has been done you can call the load_translations(*file_names) method:

I18n.backend.load_translations("config/locales/es-PE.yml", "config/locales/en-US.yml")

Update: This is considered a hack because no methods in the backend should be called directly and should only be used for testing purpose, when working with script/console for example.

Update2: Since this post there have been created a new method in the I18n module that reloads the translations:

I18n.reload!

This method is not considered a hack! :)

More information

If you want to know about interpolation, pluralization, default values and scopes you should read the corresponded sections in the post from Sven Fuchs. I’m not talking about this features here because nothing has changed and because Sven Fuchs did a great thing explaining them in a simple way.

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License.
(c) 2009 Diego Carrion | powered by WordPress with Barecity