Saturday, November 23, 2013

Using Fabrication and Faker to generate test objects

Assigning text or value to a test object is quite often a tedious thing. Nevertheless, it has been an auto-generator to do this: 'Fabrication' and 'Faker'.

Fabrication (GitHub site) is a simple and powerful object generation library. Just define Fabricators, the schematics for your objects, it fabricates objects quickly as needed. Faker library that generates fake data. By combining these two gems, an automatic test object generator is ready to go for the rspec test.

Installation: Just add the following two lines to Gemfile and run bundle install to install the gems.
gem 'fabrication'
gem 'faker'
Just create the fabricator file for the Video Model object as:
spec/fabricator/video_fabricator.rb
Add the following lines to generate the two attributes of Video object:
Fabricator(:video) do
  title { Faker::Lorem.words(5).join(" ") }
  description { Faker::Lorem.paragraph(2) }
end
And it's ready to go!

In model/video_spec.rb, you have to create a Video object using:
Video.create(title: "Bones", description: "Great movie!")
When using 'Fabrication' and 'Faker' gem, all you have to do is:
let(:video)      { Fabricate(:video) }
And that is it!

Friday, November 22, 2013

Primitive Obsession


Primitive Obsession is using primitive data types to represent domain ideas. For example, we use a String to represent a message, an Integer to represent an amount of money, or a Struct/Dictionary/Hash to represent a specific object.  

In fact, if we can create an object to represent the data type, not only the basic data but also more functional attributes can be created and managed.

For example, we need to create a message type with attributes 'title', 'body', 'sender', 'receiver', 'created_date', 'attachment', 'is_deleted' and so on.  You can realize at once that it's impossible ( or at least very difficult ) to use 'String' data type to represent all the attributes, including 'created_date'. The best way is to utilize object-oriented programming features: 'OBJECT'!  Just create a 'Message Object'.

There is a good article with better explainations:    
Get Rid of That Code Smell – Primitive Obsession

The things happen while upgrading from Rails 3.2 to 4

The things happen while upgrading from Rails 3.2 to 4

Oops! Here comes the deprecation warning.  It's the "secret_key_token".
The secret_key_base is not required, however,  you will get a deprecation warning if this line is missing:

DEPRECATION WARNING: You didn't set config.secret_key_base.

There is a new value for that initializer in config/initializers/secret_token.rb
Myapp::Application.config.secret_token = '6839bw..' # your current token
Myapp::Application.config.secret_key_base ='db6s..' # secret value, this needs to be added
In order to generate a random secret_key value, you can use rake task:

rake secret

Just copy the value generated to the second line above, then restart the server and it's done!

More details: Upgrading to Rails 4.0 from Rails 3.2 – Test case

BootstrapForm

BootstrapForm is a form builder that makes it super easy to integrate Twitter Bootstrap-style forms into your Rails App.


I found it is very powerful to use when you try to build a data-binding form.

Installation 
gem 'bootstrap_form'
Note that there are "bootstrap-form" and "bootstrap_forms" gems, so don't make mistake!

Here's a quick example you can start up with:

<%= bootstrap_form_for(@user, html: { class: 'form-horizontal' }, help: :block) do |f| %>
  <%= f.alert_message "Please fix the errors below." %>

  <%= f.text_field :twitter_username, prepend: '@', label: 'Twitter' %>
  <%= f.text_field :email %>
  <%= f.password_field :password, help: 'Must be at least 6 characters long' %>
  <%= f.password_field :password_confirmation, label: 'Confirm Password' %>
  <%= f.control_group :terms do %>
    <%= f.check_box :terms, label: 'I agree to the Terms of Service' %>
  <% end %>

  <%= f.actions do %>
    <%= f.primary 'Create My Account', disable_with: 'Saving...' %>
  <% end %>
<% end %>

The magic of BootstrapFrom is as this screen slice below shows:




If there are errors, they will be shown just aside or below the input box. An error notice is also shown as well. It's a really nice feature. 

Just a note for it!

Haml!

Haml (HTML Abstraction Markup Language)

「Haml is a markup language that’s used to cleanly and simply describe the HTML of any web document, without the use of inline code. Haml functions as a replacement for inline page templating systems such as PHP, ERB, and ASP. However, Haml avoids the need for explicitly coding HTML into the template, because it is actually an abstract description of the HTML, with some code to generate dynamic content.」

So what does haml looks like?

haml:
    %one
      %two
        %three Hey there
html:
    <one>
      <two>
        <three>Hey there</three>
      </two>
    </one>

Haml doesn't use close tag such as </xxx>. Therefore, indentation is so important. At the beginning, the haml code was not easy to read, but eventually I got used to it gradually.

GitHub Flow

The GitHub Flow mentioned by Scott Chacon is by using a simplified workflow to manage the version control instead of the complicated git-flow.
Here is the points of the whole idea:
  • Anything in the master branch is deployable.
  • To work on something new, create a descriptively named branch off of master (ie: new-oauth2-scopes).
  • Commit to that branch locally and regularly push your work to the same named branch on the server.
  • When you need feedback or help, or you think the branch is ready for merging, open a pull request.
  • After someone else has reviewed and signed off on the feature, you can merge it into master .
  • Once it is merged and pushed to 'master' , you can and should deploy immediately.
There is a web page explaining how to use GitHub in Traditional Chinese, pretty concise!
Here: 在 GitHub 當中使用的 work flow

Easy to follow! Enjoy!

Friday, November 8, 2013

Some notes about Github flow and code review

GitHub Flow: a simplified and useful approach
  • Anything in the master branch is deployable
  • To work on something new, create a descriptively named branch off of master (ie: new-oauth2-scopes)
    git checkout -b Mod0      # -b : create branch locally
                ----\    
                   branch name
    
  • Commit to that branch locally and regularly push your work to the same named branch on the server
    git push origin Mod0
    
  • When you need feedback or help, or you think the branch is ready for merging, open a pull request.
    • from my own module branch to my own master branch )
    • ask for code review from others
    • finally, merge to the master branch
  • After someone else has reviewed and signed off on the feature, you can merge it into master
    • so after this step, we can check out the branch again from Github to the local master.
    git pull origin master
    • do development again.
  • Once it is merged and pushed to ‘master’, you can and should deploy immediately.
    git push heroku master

Shoulda Matchers

In rspec test case, there is a very useful gem called 'shoulda-matchers', which can save you a lot of writing test code.

For example:
    it "save itself" do
      video = Video.new(title: "Bones_test", description: 'Test informations', small_cover_url: '/img/bones_small.jpg', large_cover_url: '/img/bones_large.jpg', category_id: 1)
      video.save
      Video.first.title.should == "Bones_test"
      Video.first.description.should == 'Test informations'
      Video.first.small_cover_url.should == '/img/bones_small.jpg'
      Video.first.large_cover_url.should == '/img/bones_large.jpg'
      Video.first.category_id.should ==  1
    end

    it "belongs to category" do
      video = Video.create(title: "Bones_test", description: 'Test informations', small_cover_url: '/img/bones_small.jpg', large_cover_url: '/img/bones_large.jpg', category_id: 1)
      category = Category.create(name: "Movie")
      expect(Video.first.category).to eq(category)
    end

    it "is invalid without a title" do
      expect(Video.new(title: nil)).to have(1).errors_on(:title)    
    end

    it "is invalid without a description" do
      expect(Video.new(description: nil)).to have(1).errors_on(:description)    
    end

    it "is invalid if has a same title" do
      Video.create(title: "Bones", description: "Great movie!")
      expect(Video.create(title: "Bones", description: "Fun movie!")).to have(1).errors_on(:title)  
    end
can be re-writed as:
    it { should belong_to(:category)}
    it { should validate_presence_of(:title)}
    it { should validate_presence_of(:description)}
    it { should validate_uniqueness_of(:title)}
Awesome!!!

Two ways to have in-line HTML for link_to

Sometimes we need to have multiple or complex HTML or ERB code in the link_to comment, we can do it as:
    <%= link_to post_path(@post) do %>
      <i class="icon-ok icon-white"></i> Go to the post@
    <% end %>
or
    <%= link_to '<i class="icon-ok icon-white"></i>"Go to the post@".html_safe, post_path(@post) %>
Just make a note for it!