Click here to load reader
Upload
rubyc-slides
View
1.960
Download
1
Embed Size (px)
Citation preview
Testing your Javascript with Jasmine
Getting the fun of BDD into JS
What is Jasmine?
Jasmine is a behavior driven development framework to test your javascript code. With a sintax similar to that of Rspec, Jasmine can help us to ensure our Javascript is well integrated across our site.
spec-diff
describe Admin::UsersController do
fixtures :users
before(:each) do
@users = User.make
end
describe "GET 'index'" do
...
it "is successful" do
get :index
response.should be_success
end
end
describe("checkBoxesEnhanced", function() { beforeEach(function() { ... });
describe("clicking the master checkbox", function(){ it("should be able to check all product attributes checkboxes when checked", function() { checkAll.attr('checked', true); checkAll.click(); expect(controlled.attr('checked')).toBe(true); }); ... ... });});
The master-slave checkbox problem
For one of the developments we have @ crowdint, we had a task that involved a master checkbox controlling a set of slave checkboxes and viceversa. The following were the requirements:
The master-slave checkbox problem
When clicking the master checkbox: - When checked, all the slave checkboxes
should be checked and should remove the "partially-selected" class if present.
- When unchecked, all the slave checkboxes should be unchecked and should remove the "partially-selected" class if present.
The master-slave checkbox problem
When clicking the slave checkboxes:
-When all of the slave checkboxes are checked, the master checkbox should be checked, and remove the "partially-selected" class if present.
-When all of the slave checkboxes are unchecked, the master checkbox should be unchecked, and remove the "partially-selected" class if present.
-When some of the slave boxes are checked and some other are unchecked, the master checkbox should be unchecked and have a "partially-selected" class.
Installing Jasmine
Add gem "jasmine" to your Gemfile
Bundle install
Go to the spec directory in your rails app and do jasmine init
Next, run “rake jasmine”
Now you should be able to goto: http://localhost:8888 and you will have 2 tests run.
The spec file
So, in order to create my specs, I have to create a file under the directory spec/javascrips (remember we called the jasmine init command at that level), so I will create MasterSlaveCheckbox.js over there
spec/javascripts/MasterSlaveCheckbox.js
Next time we reload the localhost:8888, it will check this file for "it" blocks and will show them.
JS Source files
So, we may have created our specs, but don't rush, because Jasmine is not like rspec and will not try to find a similar file name without the spec suffix. In order to see the source files, Jasmine needs you to include them in a special file
spec/javascripts/support/jasmine.yml
So , in this file include the following line under src_files:
-public/javascripts/MasterSlaveChecbox.js
and create your source file with the path specified above.
Coding our tests
Let us begin with one of our requirements: When clicking the master checkbox: - When checked, all the slave checkboxes
should be checked.
Coding our tests
describe("MasterSlaveCheckbox", function{
describe("when clicking on the master checkbox",function{
it("should check all slave checkboxes when checked", function(){
slaves.attr("checked", false);
master.attr("checked", true);
master.click();
expect(slaves.attr("checked")).toBeTruthy();
});
});
});
Setting up our DOM
describe("checkBoxesEnhanced", function() {
beforeEach(function() {
elements = $("<input type= \"checkbox\" id=\"master\"><input type= \"checkbox\" class=\"slave\"><input type= \"checkbox\" class=\"slave\">");
$("body").append(elements);
master = $("#master");
slaves = $(".slave");
slave1 = controlled.first();
slave2 = controlled.last();
checkOrUncheckBoxesWithBox(master, slaves);
});
The "real" code
function checkOrUncheckBoxesWithBox(master, slaves){
master.click(function(){
slaves.attr("checked", $(this).attr("checked"));
removeClassIfPresent(master, "partially-checked");
});
});
function removeClassIfPresent(e,klass){
if(e.hasClass(klass)){
e.removeClass(klass);
}
}