Tuesday, March 19, 2013

HTML 5 - Navigation with the nav element

One of the new elements for HTML 5 is the <nav> element which allows you to group together links, resulting in more semantic markup and extra structure which may help screenreaders.


HTML5 nav tag defines the section for navigation links in a document. It is not mandatory to place all the links of a document in nav element, but the major navigational links should be placed under it. This element can be used more than one place within a document. But nav element should be placed in such places in a document so that visitors can easily access the navigational links.

Important point need to be remembered:

HTML5 nav element is supported by latest versions of all web browsers. Internet Explorer 8 or earlier versions of Internet Explorer do not support nav element.


How to use it

You are probably used to using something like

<div id="nav">
<ul>
<li><a.... etc
Or

<ul id="mainNav">
Well, for the sake of your markup, nothing much will change as you will now have something like this

<nav>
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="/about/">About</a></li>
<li><a href="/blog/">Blog</a></li>
</ul>
</nav>

The specification


In the following example, the page has several places where links are present, but only one of those places is considered a navigation section.

<body>
<header>
<h1>Wake up sheeple!</h1>
<p><a href="news.html">News</a> -
<a href="blog.html">Blog</a> -
<a href="forums.html">Forums</a></p>
<p>Last Modified: <time>2009-04-01</time></p>

<nav>
<h1>Navigation</h1>
<ul>
<li><a href="articles.html">Index of all articles</a></li>
<li><a href="today.html">Things sheeple need to wake up for today</a></li>
<li><a href="successes.html">Sheeple we have managed to wake</a></li>
</ul>
</nav>

</header>
<article>
<p>...page content would be here...</p>
</article>
<footer>
<p>Copyright © 2006 The Example Company</p>
<p><a href="about.html">About</a> -
<a href="policy.html">Privacy Policy</a> -
<a href="contact.html">Contact Us</a></p>
</footer>
</body>

There are six items of navigation in the header element there. But only three are in the nav tag. There is no explanation as to what differentiates the first three links with the second three links – both go to different pages and all are in internal to that current site.

See a second example:

<body>
<h1>The Wiki Center Of Exampland</h1>

<nav>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/events">Current Events</a></li>
...more...
</ul>
</nav>

<article>
<header>
<h1>Demos in Exampland</h1>

<nav>
<ul>
<li><a href="#public">Public demonstrations</a></li>
<li><a href="#destroy">Demolitions</a></li>
...more...
</ul>
</nav>

</header>
<section id="public">
<h1>Public demonstrations</h1>
<p>...more...</p>
</section>
<section id="destroy">
<h1>Demolitions</h1>
<p>...more...</p>
</section>
...more...
<footer>
<p><a href="?edit">Edit</a> | <a href="?delete">Delete</a> | <a href="?Rename">Rename</a></p>
</footer>
</article>
<footer>
<p><small>© copyright 1998 Exampland Emperor</small></p>
</footer>
</body>

This is a little more helpful as I find the biggest isse of the <nav> element is deciding which sets of links should be classed as major navigation.


Other Possible Uses

Below are a few more examples of other areas of the site in which you might consider using the <nav> element. It is also important to note that while XHTML 2 <nl> element, this hasn’t been replicated in HTML 5 because navigation does not have to take list form, as we’ll see.

  • Table of Contents
  • Previous/next buttons (or pagination)
  • Menu - developers are using the <menu> element for navigation rather than the <nav> element. We thought it best to clarify that <menu> is to be used for a list of commands and is an interactive element and more likely to be used exclusively in Web Applications.


HTML 5 - The header element


Several new tags or elements have been added in HTML5. The header tag (<header>) is one of them. It is used as header of one or more sections or as a header of the document. HTML5 header tag should be used as a container of introductory contents like <h1> – <h6> tags, table of contents, search form, logo etc. with or without navigational links. More than header element can be used in a HTML5 document and it is generally placed at the beginning of the document or <article> tag.

Important points need to be remembered:

1. <header> and <head> tags are completely different.
2. A <header> tag can’t be placed within <footer> or <address> tag. Also header element can’t be placed within another header element.
3. HTML5 header element is supported by latest versions of all web browsers. Internet Explorer 8 or earlier versions of Internet Explorer do not support header element.

There are few HTML5 header tag examples given below:

Below the header tag is used as document header

1 <header>
2 <h1>This is the heading of the page</h1>
3 With some supplementary information
4 </header>
Below the header element is used as article header

1 <article>
2 <header>
3 <h1>Title of this article</h1>
4 By S Ghosh
5 </header>
6 Contents of the article
7 </article>

In summary <header> give us some great added semantic value in order to describe the head of a section.

An Inroduction to HTML 5


HTML5 is the latest version of Hyper Text Markup Language. The version of this language is 5 and it is still under development. The main aim of HTML5 is to increase the latest multimedia support and to decrease the dependency on client side scripting language like JavaScript and third party plugging like Adobe Flash Player etc. HTML5 can be effectively run on low-powered devices such as smart phones, tablets etc. Several new elements like <video>, <audio>, <canvas> etc. have been introduced in HTML5.

HTML5 is being developed in joint collaboration of the Web Hypertext Application Technology Working Group (WHATWG) and World Wide Web Consortium (W3C). As the development of HTML5 are still going on so it is not yet an official standard. No web browser supports all HTML5 elements yet, but popular web browsers like (Firefox, Chrome, Internet Explorer, Safari, Opera etc.) are adding more HTML5 tags support in their latest versions.
HTML5 and CSS3 have become popular tools that help in building a well-defined website. Each of them have many advanced features of their own but nowadays, they are used in combination with each other by expert web designers, to create refined web pages with semantic accuracy. Let us have a look at some advantages of HTML5 and CSS3.
  • The first benefit you get is that the readable codes are semantically accurate. When a web design is not semantically accurate, it cannot attain a good rank. HTML5 and CSS3 help you to overcome this. The readable codes are very simple and easy to understand.

  • The tutorials in the language help designers in developing a better web page. This paves way for the designers to make use of apt tools or elements in the language for a website.

  • Many websites need some extra plug-ins to view the videos in the web page. In case of  HTML5 and CSS3, the audio and video effects are tagged and viewed without the support of third party plug-ins.

  • Using separate codes for the purpose of updations are important for all types of websites. These codes do not give a proper output at times. In HTML5 and CSS3, as the scripting is not necessary
     for validation you can avoid the usage of confusing complex codes.

  • Many browsers do not support all types of web pages but HTML5 and CSS3 help the designer to develop a web page that is compatible even with previous versions of your browsers.
  • Some elements in HTML5 and CSS3 allow you to handle graphics and photos efficiently. These elements use some procedural methodologies to draw up the graphics directly into the browser.

  • Flash applications are bound to cause problems. HTML5 combined with CSS3 provides you with many alternative features to support media. As CSS3 has enhanced itself with many  features, there are many added elements that bring in the wow factor, when it is used with HTML5.

  • Creating Box Shadow requires numerous images and this process is made simple by using these new technologies. The text shadow is an element added to make the webpage more attractive. This can be carried out using the simple codes in CSS3. It makes the web layout very simple.

  • One of the popular elements in web design is the use of rounded corners for buttons, layout elements, menus and much more. Using the ‘border-radius’ property, you can easily create rounded corners.

  • Many websites have contact forms, that help the clients get in touch with the company. Some forms may not be supported by browsers. There are many types of forms designed with HTML5 and CSS3 which have a unique design and are compatible with all the common browsers.

  • Using these technologies you can have full control over the colors in the templates, thereby eliminating the need to use separate codes for the color theme.






Wednesday, February 27, 2013

INTRODUCTION TO OBJECT ORIENTED JAVASCIRPT



This article explains different ways you can create a custom object using the JavaScript language. The JavaScript language includes several built-in objects, such as Array, String, and Date etc... But, if there are custom functions that you want to create, you can create your own custom objects using one of the available methods.
Properties and methods are what make objects functional and usable.
The best way to understand the concept of an object is to think of a real-life object.
 For example, use a dog as your object. A dog can have properties such as legs, ears, a tail, possibly a collar, and so on. A dog can have methods such as barking, eating, sleeping, and so on. The methods can alter the properties of the dog. For example, if the dog is barking, its ears may stand up, and if the dog is sleeping its ears might be floppy .Imagine wanting to use a dog object in your project. It can save a lot of time if you are interested in creating multiple dog objects because they all have a lot of the same basic properties and methods. And, if you want to use a dog object in another project, you can easily reuse the object you already created.
Following are the different ways to create a custom object using the JavaScript language:
  • The Object function.
  • Literal notation.
  • Object constructor and prototyping.
The Object function
The JavaScript language includes a function named Object, which when used with the new operator creates an object. The Object function is the starting point for any custom functionality you want to achieve by creating an object.
var Gallery = new Object();

To make the Gallery object helpful, you can add properties and methods to give it functionality.

2. A custom Gallery object with properties and methods

var Gallery = new Object();
 
/* 
The properties of the Gallery object are CurrentIndex, Images, and _loopInterval.
 
To define them as properties of the Gallery object, you simply assign them to the 
Gallery object using dot syntax—append a dot and a variable name and then assign 
that variable a value. */
 
window.onload= function()
{
    Gallery.Images = ['istockphoto_14149033.jpg', 'istockphoto_14232771.jpg', 
'istockphoto_14667148.jpg'];
    Gallery.CurrentIndex = 0;
    Gallery._loopInterval = setInterval(Gallery.Next, 2500);
};
 
/*  The methods used are Next, Prev, and Display
To define them as methods of the Gallery object, you use dot syntax and assign 
each one its own function. 
*/
 
Gallery.Next = function()
{
    if(Gallery.CurrentIndex < (Gallery.Images.length-1))
    {
        Gallery.CurrentIndex++;
    }
    else
    {
        Gallery.CurrentIndex = 0;
    }
    Gallery.Display();
};
 
Gallery.Prev = function()
{
    if(Gallery.CurrentIndex > 0)
    {
        Gallery.CurrentIndex--;
    }
    else
    {
        Gallery.CurrentIndex = (Gallery.Images.length-1);
    }
    Gallery.Display();
};
 
Gallery.Display = function()
{
    var photoGallery = document.getElementById('photo-gallery');
    var currentImage = Gallery.Images[Gallery.CurrentIndex];
    photoGallery.src = "../assets/img/"+currentImage;
};


/* Both the Next and Prev methods use the properties in this object. The CurrentIndex property identifies what the current index of the Images array is so that when you increase or decrease the index it references a different array item. The Images property is an array that stores the images that you are displaying in the gallery. The _loopInterval property automatically loops through the images in the gallery every 2.5 seconds. */

To call one of the methods in this object, such as the Next method, you simply need to reference the Gallery object, followed by a dot, followed by the name of the method (Next), and, finally, followed by opening and closing parentheses
 
3. Calling the Next method in the custom Gallery object
 
Gallery.Next();
 
To actually put this object into action, you can easily create controls that 
navigate the images in your Images array. First, you need to include the 
JavaScript file, which in this case is an external file named Gallery.js.
 Then you just need to add an HTML img tag that displays the images and add 
hyperlinks that control the next and previous navigation
 

<html>
<head>
<title>Getting Started with Object-Oriented JavaScript</title>
<script type="text/javascript" src="js/Gallery.js"></script>
</head>

<body>

<img src="../assets/img/istockphoto_14149033.jpg" id="photo-gallery" />
<p>
    <a href="#" onclick="Gallery.Prev();">&lt; Previous</a>
    &nbsp;
    <a href="#" onclick="Gallery.Next();">Next &gt;</a>
</p>

</body>
</html>


To be continued …

Tuesday, October 23, 2012

Difference between Application server and Web Server

What is Application Server and Web Server? Your search ends here .. 

apache, nginx, IIS are web servers
mongrel, webrick, phusion passenger are app servers

App server is something which works with particular programming language and parses and executes the code
since mongrel and webrick can only work with rails, so they are app servers

Web servers are servers which can take the request from the browser.
Web servers normally works on port 80 though we can change the port in configuration 
since mongrel and webrick can take that request directly, so they can be thought of as web servers but web servers do have a lot of other functionality like request pipeline, load balancing etc.
App servers lack these functionalities.

About Mongrel server:
mongrel work as web as well as app server if you are talking about dev environment
but in production, mongrel alone can not work it will be too slow
so we need a web server in front of mongrel

Ruby On Rails Interview Preparation


1. Why Ruby on Rails?
Ans: There are lot of advantages of using ruby on rails
1. DRY Principal
2. Convention over Configuration
3. Gems and Plugins
4. Scaffolding
5. Pure OOP Concept
6. Rest Support
7. Rack support
8. Action Mailer
9. Rpc support
10. Rexml Support
11. etc..

2. Explain about the programming language ruby?
Ruby is the brain child of a Japanese programmer Matz. He created Ruby. It is a cross platform object oriented language. It helps you in knowing what your code does in your application. With legacy code it gives you the power of administration and organization tasks. Being open source, it did go into great lengths of development.
3. Explain about ruby names?
Classes, variables, methods, constants and modules can be referred by ruby names. When you want to distinguish between various names you can specify that by the first character of the name. Some of the names are used as reserve words which should not be used for any other purpose. A name can be lowercase letter, upper case letter, number, or an underscore, make sure that you follow the name by name characters.

4. What is the Difference between Symbol and String?
Ans: Symbol are same like string but both behaviors is different based on object_id, memory and process time (cpu time) Strings are mutable , Symbols are immutable.
Mutable objects can be changed after assignment while immutable objects can only be overwritten. For example

p "string object jak".object_id #=> 22956070
p "string object jak".object_id #=> 22956030
p "string object jak".object_id #=> 22956090

p :symbol_object_jak.object_id #=> 247378
p :symbol_object_jak.object_id #=> 247378
p :symbol_object_jak.object_id #=> 247378

p " string object jak ".to_sym.object_id #=> 247518
p " string object jak ".to_sym.object_id #=> 247518
p " string object jak ".to_sym.object_id #=> 247518

p :symbol_object_jak.to_s.object_id #=> 22704460
p :symbol_object_jak.to_s.object_id #=> 22687010
p :symbol_object_jak.to_s.object_id #=> 21141310

And also it will differ by process time

For example:

Testing two symbol values for equality (or non-equality) is faster than testing two string values for equality,

Note : Each unique string value has an associated symbol


5. What is Session and Cookies?
Ans: Session: are used to store user information on the server side.
cookies: are used to store information on the browser side or we can say client side
Session : say session[:user] = “arunkumar” it remains when the browser is not closed
6. What is request.xhr?
Ans: A request.xhr tells the controller that the new Ajax request has come, It always return Boolean values (TRUE or FALSE)
7. What is MVC? and how it Works?
Ans: MVC tends for Model-View-Controller, used by many languages like PHP, Perl, Python etc. The flow goes like this: Request first comes to the controller, controller finds and appropriate view and interacts with model, model interacts with your database and send the response to controller then controller based on the response give the output parameter to view, for Example your url is something like this:
http://localhost:3000/users/new
here users is your controller and new is your method, there must be a file in your views/users folder named new.html.erb, so once the submit button is pressed, User model or whatever defined in the rhtml form_for syntax, will be called and values will be stored into the database.

8. What things we can define in the model?
Ans: There are lot of things you can define in models few are:
1. Validations (like validates_presence_of, numeracility_of, format_of etc.)
2. Relationships(like has_one, has_many, HABTM etc.)
3. Callbacks(like before_save, after_save, before_create etc.)
4. Suppose you installed a plugin say validation_group, So you can also define validation_group settings in your model
5. ROR Queries in Sql
6. Active record Associations Relationship
9. What is ORM in Rails?
Ans: ORM tends for Object-Relationship-Model, it means that your Classes are mapped to table in the database, and Objects are directly mapped to the rows in the table.

10. How many Types of Associations Relationships does a Model has?
Ans: When you have more than one model in your rails application, you would need to create connection between those models. You can do this via associations. Active Record supports three types of associations:
one-to-one : A one-to-one relationship exists when one item has exactly one of another item. For example, a person has exactly one birthday or a dog has exactly one owner.
one-to-many : A one-to-many relationship exists when a single object can be a member of many other objects. For instance, one subject can have many books.
many-to-many : A many-to-many relationship exists when the first object is related to one or more of a second object, and the second object is related to one or many of the first object.
You indicate these associations by adding declarations to your models: has_one, has_many, belongs_to, and has_and_belongs_to_many.

11. Difference between render and redirect?
Ans:

render example:
 render :partial
 render :new
  It will render the template new.rhtml without
  calling or redirecting to the new action.


redirect example:
 redirect_to :controller => ‘users’, :action => ‘new’
  It forces the clients browser to request the
  new action.

12. What is the Difference between Static and Dynamic Scaffolding?
Ans: The Syntax of Static Scaffold is like this:
ruby script/generate scaffold User Comment
Where Comment is the model and User is your controller, So all n all static scaffold takes 2 parameter i.e your controller name and model name, whereas in dynamic scaffolding you have to define controller and model one by one.

13. How you run your Rails Application without creating database ?
Ans: You can run application by uncomment the line in environment.rb

Path => rootpath conf/ environment.rb

# Skip frameworks you're not going to use (only works if using vendor/rails)
    config.frameworks -= [ :action_web_service, :action_mailer,:active_record ]
14. How to use sql db or mysql db. without defining it in the database.yml
Ans: You can use ActiveRecord anywhere!

require 'rubygems'

require 'active_record'

ActiveRecord::Base.establish_connection({

:adapter => 'postgresql',

:user => 'foo',

:password => 'bar',

:database => 'whatever'

})

class Task <>

set_table_tame "a_legacy_thingie"

def utility_methods

update_attribute(:title, "yep")

end

end

Task.find(:first)

Etcetera. It’s ActiveRecord, you know what to do. Going wild:

ActiveRecord::Base.establish_connection(:adapter => "sqlite3",

:dbfile => ":memory:")

ActiveRecord::Schema.define(:version => 1) do

create_table :posts do |t|

t.string :title

t.text :excerpt, :body

end

end

class Post <>

validates_presence_of :title

end

Post.create(:title => "A new post!")

Post.create(:title => "Another post",

:excerpt => "The excerpt is an excerpt.")

puts Post.count

15. What are helpers and how to use helpers in ROR?
Ans: Helpers (“view helpers”) are modules that provide methods which are automatically usable in your view. They provide shortcuts to commonly used display code and a way for you to keep the programming out of your views. The purpose of a helper is to simplify the view. It’s best if the view file (RHTML/RXML) is short and sweet, so you can see the structure of the output.

16. What is Active Record?
Ans: Active Record are like Object Relational Mapping(ORM), where classes are mapped to table , objects are mapped to columns and object attributes are mapped to data in the table

17. Ruby Support Single Inheritance/Multiple Inheritance or Both?
Ans: Ruby Supports only Single Inheritance.
You can achieve Multiple Inheritance through MIXIN concept means you achieve using module by including it with classes.
18. How many types of callbacks available in ROR?
Ans:

(-) save
(-) valid
(1) before_validation
(2) before_validation_on_create
(-) validate
(-) validate_on_create
(3) after_validation
(4) after_validation_on_create
(5) before_save
(6) before_create
(-) create
(7) after_create
(8) after_save

19. WHAT CAN RAILS MIGRATION DO?
ANS:
create_table(name, options)
drop_table(name)
rename_table(old_name, new_name)
add_column(table_name, column_name, type, options)
rename_column(table_name, column_name, new_column_name)
change_column(table_name, column_name, type, options)
remove_column(table_name, column_name)
add_index(table_name, column_name, index_type)
remove_index(table_name, column_name)
Migrations support all the basic data types: string, text, integer, float, datetime, timestamp, time, date, binary and boolean:

string - is for small data types such as a title.
text - is for longer pieces of textual data, such as the description.
integer - is for whole numbers.
float - is for decimals.
datetime and timestamp - store the date and time into a column.
date and time - store either the date only or time only.
binary - is for storing data such as images, audio, or movies.
boolean - is for storing true or false values.
Valid column options are:

limit ( :limit => “50” )
default (:default => “blah” )
null (:null => false implies NOT NULL)

20. What is the naming conventions for methods that return a boolean result?
Ans: Methods that return a boolean result are typically named with a ending question mark. For example: def active? return true #just always returning true end

21. How do the following methods differ: @my_string.strip and @my_string.strip! ?
Ans: The strip! method modifies the variable directly. Calling strip (without the !) returns a copy of the variable with the modifications, the original variable is not altered.
22. What's the difference in scope for these two variables: @name and @@name?

Ans: @name is an instance variable and @@name is a class variable

23. What is the log that has to seen to check for an error in ruby rails?
Ans: Rails will report errors from Apache in log/apache.log and errors from the Ruby code in log/development.log. If you're having a problem, do have a look at what these logs are saying. On Unix and Mac OS X you may run tail -f log/development.log in a separate terminal to monitor your application's execution.
24. What is the use of global variable $ in Ruby?
Ans: A class variable starts with an @@ sign which is immediately followed by upper or lower case letter. You can also put some name characters after the letters which stand to be a pure optional. A class variable can be shared among all the objects of a class. A single copy of a class variable exists for each and every given class.
To write a global variable you start the variable with a $ sign which should be followed by a name character. Ruby defines a number of global variables which also include other punctuation characters such as $_ and $-k.
For example: If you declare one variable as global we can access any where, where as class variable visibility only in the class Example
class Test
def h
 $a = 5
 @b = 4
Â
while $a > 0
puts $a
$a= $a - 1
end
end
end
test = Test.new
test.h
puts $a                    # 5
puts @b                   #nil

25. Where does the start_tabnav gets informations for tabs rendering in ruby rail?
Ans: The main Symbol let the start_tabnav method know to look for a special MainTabnav class where all the magic happens

26. What is the Install rail package?
Ans: There are several packages that you can download and install. The prebuilt Rails installer called Install rail which currently is only for Windows
27. What is the log that has to seen to check for an error in ruby rails?
Ans: Rails will report errors from Apache in log/apache.log and errors from the Ruby code in log/development.log. If you're having a problem, do have a look at what these logs are saying. On Unix and Mac OS X you may run tail -f log/development.log in a separate terminal to monitor your application's execution.

28. What is the use of super in ruby rails?
Ans: Ruby uses the super keyword to call the superclass (Parent class) implementation of the current method

29. What is the difference between nil and false in ruby?
Ans: False is a boolean datatype, Nil is not a data type it have object_id 4

30. How is class methods defined in Ruby?
Ans: A:def self.methodname
--------
--------
end
or
def classname.methodname
--------
--------
end

31. How is object methods defined in Ruby?
Ans:
class jak
def method1
--------
--------
end
end

obj=jak.new
It is single object
def obj.object_method_one
--------
--------
end
obj.Send(object_method_every)
It will be created every for every object creation

32. What are the priority of operators available in Ruby ?
Ans: Something that used in an expression to manipulate objects such as + (plus), - (minus), * (multiply), and / (divide). You can also use operators to do comparisons,such as with <, >, and &&. The priority is based on "BODMAS"

33. What are the looping structures available in Ruby?
Ans: for..in
untill..end
while..end
do..end
Note: You can also use each to iterate a array as loop not exactly like loop
34. What are the object-oriented programming features supported by Ruby and how multiple inheritance supported in ?
Ans: Classes,Objects,Inheritance,Singleton methods,polymorphism(accomplished by over riding and overloading) are some oo concepts supported by ruby. Multiple inheritance supported using Mixin concept.
35. What is the scope of a local variable in Ruby and define it scope ?
Ans: A new scope for a local variable is introduced in the toplevel, a class (module) definition, a method defintion. In a procedure block a new scope is introduced but you can access to a local variable outside the block.
The scope in a block is special because a local variable should be localized in Thread and Proc objects.
36. How is an enumerator iterator handled in Ruby?
Ans: Iterator is handled using keyword 'each' in ruby.
For example
number=[1,2,3]
then we can use iterator as
number.each do |i|
puts i
end
Above prints the values of an array $no which is accomplished using iterator.
37. How is visibility of methods changed in Ruby (Encapsulation)?
Ans: By applying the access modifier : Public , Private and Protected access Modifier

38. What is the use of load,require, auto_load,require_relative in Ruby?
Ans: A method that loads and processes the Ruby code from a separate file, including whatever classes, modules, methods, and constants are in that file into the current scope. load is similar, but rather than performing the inclusion operation once, it reprocesses the code every time load is called.
auto_load - Whenever the interpreter call the method that time only it will initiate the method in hat file.
require_relative - It it to load local folder files.

More Questions:
1. Explain choose_weighted method with example
2. What is GIL in ruby ?
3. Is variable is a object ?
Ans : Variable is not an object
4. List of protocols supported by ruby ?
5. Explain Virtual attribute ?
6. How to validate and modify attribute value ?
7. How to serialize data with YAML ?

Thursday, August 9, 2012

Test Driven Development (TDD) in Ruby on Rails

Introduction

The purpose of this document is to describe the working principle of Ruby on Rails test frameworks, its application, advantages and disadvantages. This document contains an introduction to Test driven development (TDD).

Test  Driven Development (TDD)

            Test Driven Development is a development practice which involves writing test cases before writing the code. Start by writing a very small test for code that does not yet exist. Run the test and, naturally, it fails. Now we have to write the code to pass the test.ie, writing code only for the requirement. Large numbers of tests help to limit the number of defects in the code. The early and frequent nature of the testing helps to catch defects early in the development cycle, preventing them from becoming endemic and expensive problems.

TDD in Ruby on Rails
                   Ruby on rails supports test frameworks for Test Driven Development; A Test Framework is a tool or library that provides a backdrop for writing tests. This is an excellent way to build up a test suite that exercises every part of the application.
There are several testing frameworks in use for Ruby today:
  • Test::Unit is included with Ruby 1.8, and follows the "xUnit" conventions
  • Minitest is included with Ruby 1.9, and allows both xUnit and RSpec style tests
  • RSpec, which  has more concise syntax and can be used in the same project, but creates a separate suite of tests, called "specs"
  • In Cucumber, tests are written not in Ruby but in a language designed for tests
  • Rspec-2, which is used with Rails -3. Since We are using Rails -3 Rspec -2 is the best option we can use for test driven development
For using this, we have to twist thinking a little bit. Our goal is not to write eventual production code right away , but our goal is to make our test cases pass.
Work Flow Structure
We can structure the test driven workflow as follows:
  • First write a test: This test describes the behavior of a small element of your system. Tests in TDD are called programmer tests. When writing the tests it should be kept in mind that the tests should concentrate on testing the true behaviors, i.e. if a system has to handle multiple inputs, the tests should reflect multiple inputs.
  • Run the test:  The test definitely fails because you have not yet built the code for that part of your system. This important step tests your test case, verifying that your test case fails. The automatic tests should be run after each change of the application code in order to assure that the changes have not introduced errors to the previous version of the code
  • Write Code: Then only real coding comes, write enough code to make the test pass. In TDD, the code writing is actually a process for making the test work, i.e. writing the code that passes the test.
  • Run the test: Again run the test and verify that they pass.
·         Refactor the code - Refactoring is a process of improving the internal structure by editing the existing working code, without changing its external behavior. The idea of refactoring is to carry out the modifications as a series of small steps without introducing new defects into to the system
  • Run all tests:  To verify that the refactoring did not change the external behavior.
 See the Structure below:
     The first step involves simply writing a piece of code that tests the desired functionality. The second one is required to validate that the test is correct, i.e. the test must not pass at this point, because the behavior under implementation must not exist as yet. Nonetheless, if the test passes, the test is either not testing the correct behavior or the TDD principles have not been followed. The third step is the writing of the code. However, it should be kept in mind to only write as little code as possible to pass the. Next, all tests must be run in order to see that the change has not introduced any problems somewhere else in the system. Once all tests pass, the internal structure of the code should be improved by refactoring.

Rspec2
RSpec is a great tool in the behavior driven design process of writing human readable specifications that direct and validate the development of your application. What follows are some guidelines taken from the literature, online resources, and from our experience. Rspec is not a tool for Integration Testing but for Unit Testing, if you want to set up integration tests, then you should use Cucumber. Cucumber is designed to easy Behavior Driven Development but even if you don't BDD it is perfect for integration testing.
Examples  For Rspec-2  Test case
We can integrate Rspec to Ruby On Rails  by installing the Rspec2 gem.
            gem install rspec-rails

For this example, we’ll describe and develop the beginnings of a User class, which can be assigned any number of roles. Start by creating a directory for the files for this tutorial.
                   
                    * mkdir rspec_example
                    * cd rspec_example

 The first methods we’ll encounter are ` describe` and  `it`.
Create a file in this directory named user_spec.rb  and type the following:

describe User do
end

The describe method creates an instance of Behavior. So “describe User” is really saying “describe the behaviour of the User class”.
Run the following command:
               *  rspec spec/ user_spec.rb

     The rspec command gets installed when you install the rspec-rails gem. It supports   a large number of command line options.
     Running user_spec.rb should have resulted in output that includes the following error:
    ./user_spec.rb:1: uninitialized constant User (NameError)

We haven’t even written a single line of production code and already Rspec2 is telling us what code we need to write. We need to create a User class to resolve this error,



so create user.rb with the following:

class User
end
 And require it in user_spec.rb:
require 'user'

describe User do
end

Now run the rspec command again, will get a result like this
              
Finished in 6.0e-06 seconds
0 examples, 0 failures
The output shows that we have no examples yet, so let’s add one. We’ll start by describing the intent of example without any code.
describe User do
  it "should be in any roles assigned to it" do
  end
end

Run the spec, but this time adds the --format option:

$ rspec spec/user_spec.rb --format doc

User - should be in any roles assigned to it
Finished in 0.022865 seconds
1 example, 0 failures

Now add a Ruby statement that begins to express the described intent.

describe User do
  it "should be in any roles assigned to it" do
    user.should be_in_role ("assigned role")
  end
end

… and run the spec command.

$ rspec spec/user_spec.rb --format specdoc

User - should be in any roles assigned to it (ERROR - 1)

1) NameError in 'User should be in any roles assigned to it' undefined local variable or method `user' for #<#<Class:0x14ed15c>:0x14ecdd8> ./user_spec.rb:6:

Finished in 0.017956 seconds

1 example, 1 failure

The output tells us that there is an error that no user has been defined, so the next step is to make one:

describe User do
  it "should be in any roles assigned to it" do
    user = User.new
    user.should be_in_role ("assigned role")
  end
end

Run the spec command,
$ rspec spec/user_spec.rb --format specdoc

User - should be in any roles assigned to it (ERROR - 1)
1) NoMethodError in 'User should be in any roles assigned to it' undefined method `in_role?' for #<User:0x14ec8ec> ./user_spec.rb:7:
Finished in 0.020779 seconds
1 example, 1 failure

Now we learn that User does not respond to in_role?, so we add that to User:

class User
  def in_role?(role)
  end

$ rspec spec/user_spec.rb --format specdoc

User - should be in any roles assigned to it (FAILED - 1)
1) 'User should be in any roles assigned to it' FAILED expected in_role?("assigned role") to return true, 
got nil ./user_spec.rb:7:
Finished in 0.0172110000000001 seconds
1 example, 1 failure

We now have a failing example, which is the first goal. We always want to see a meaningful failure before 
success because that’s the only way we can be sure the success is the result of writing code in the right place in the system.

To get this to pass, we do the simplest thing that could possibly work:
Edit user.rb

class User
  def in_role?(role)
    true
  end


$ rspec spec/user_spec.rb --format specdoc

User - should be in any roles assigned to it
Finished in 0.018173 seconds
1 example, 0 failures

That passes, but we’re not done yet. Take a look again at the example:

describe User do
  it "should be in any roles assigned to it" do
    user = User.new
    user.should be_in_role("assigned role")
  end
end

The description says that the User “should be in any roles assigned to it”, but we haven’t assigned any roles to
 it. Let’s add that assignment to the example:

describe User do
  it "should be in any roles assigned to it" do
    user = User.new
    user.assign_role("assigned role")
    user.should be_in_role("assigned role")
  end
end

$ rspec spec/user_spec.rb --format specdoc

User - should be in any roles assigned to it (ERROR - 1)
1) NoMethodError in 'User should be in any roles assigned to it' undefined method `assign_role' for
 #<User:0x14ec784> ./user_spec.rb:6:
Finished in 0.018564 seconds
1 example, 1 failure

Following the advice in the output, we now add the assign_role method to User.

class User
  def in_role?(role)
    true
  end

  def assign_role(role)
  end
end

$ rspec spec/user_spec.rb --format specdoc

User - should be in any roles assigned to it
Finished in 0.018998 seconds
1 example, 0 failures


Advantages :
  • Testing improves your designs: Each target object that you test must have at least two clients: your production code, and your test case. These clients force you to decouple your code
  • Testing reduces unnecessary code: When you write your test cases first, you get in the habit of writing only enough code to make the test case pass. You reduce the temptation to code features because you might need them later.

  • Simple Development Procedure:  Each test case that you write establishes a small problem. Solving that problem with code is rewarding.

  • Testing allows more freedom:  If you have test cases that will catch likely errors, you'll find that you're more willing to make improvements to your code.

  • Efficient Product: If we can generate test cases for all the possible scenarios, then the result will be highly efficient, well documented product. TDD can lead to more modularized, flexible, and extensible code.

  • Documentation: After using this technique it satisfies a bunch of requirements, also have documentation, describing the behavior of the system, and a good start at a test suite. Each test case backs up a fundamental requirement in the system

Disadvantages :
  • Big time investment. For the simple case we lose about 20+% of the actual implementation, but for complicated cases you lose much more. Also more code to write. We have to create test cases  for models,  controllers  and  views ,which consumes a lot of time
  • Additional Complexity. For complex cases test cases are harder to calculate.
  •  Design Impacts. Sometimes the design is not clear at the start and evolves as we go along - this will force us to redo the test which will generate a big time lose
  • Continuous Tweaking. For data structures and black box algorithms unit tests would be perfect, but for algorithms that tend to be changed, tweaked or fine tuned, this can cause a big time investment that one might claim is not justified.