#261 Testing JavaScript with Jasmine
Are you testing your JavaScript? Learn how to add specs using Jasmine. This episode also covers jQuery integration with jasmine-jquery.
- Download:
- source codeProject Files in Zip (275 KB)
- mp4Full Size H.264 Video (27.7 MB)
- m4vSmaller H.264 Video (17.2 MB)
- webmFull Size VP8 Video (41.3 MB)
- ogvFull Size Theora Video (35.1 MB)
Resources
bash
bundle
rails g jasmine:install
rake jasmine
rake jasmine:ci
curl http://cloud.github.com/downloads/velesin/jasmine-jquery/jasmine-jquery-1.2.0.js > spec/javascripts/helpers/jasmine_jquery-1.2.0.js
bundle rails g jasmine:install rake jasmine rake jasmine:ci curl http://cloud.github.com/downloads/velesin/jasmine-jquery/jasmine-jquery-1.2.0.js > spec/javascripts/helpers/jasmine_jquery-1.2.0.js
Gemfile
gem 'jasmine', :group => [:development, :test]
gem 'jasmine', :group => [:development, :test]
credit_card_spec.js
describe("CreditCard", function() {
it("cleans number by removing spaces and dashes", function() {
expect(CreditCard.cleanNumber("123 4-5")).toEqual("12345");
});
it("validates based on mod 10", function() {
expect(CreditCard.validNumber("4111 1111-11111111")).toBeTruthy();
expect(CreditCard.validNumber("4111111111111121")).toBeFalsy();
});
it("validates when text field loses focus", function() {
loadFixtures("order_form.html");
$("#card_number").validateCreditCardNumber();
$("#card_number").val("123");
$("#card_number").blur();
expect($("#card_number_error")).toHaveText("Invalid credit card number.");
$("#card_number").val("4111 1111-11111111");
$("#card_number").blur();
expect($("#card_number_error")).toHaveText("");
});
});
describe("CreditCard", function() { it("cleans number by removing spaces and dashes", function() { expect(CreditCard.cleanNumber("123 4-5")).toEqual("12345"); }); it("validates based on mod 10", function() { expect(CreditCard.validNumber("4111 1111-11111111")).toBeTruthy(); expect(CreditCard.validNumber("4111111111111121")).toBeFalsy(); }); it("validates when text field loses focus", function() { loadFixtures("order_form.html"); $("#card_number").validateCreditCardNumber(); $("#card_number").val("123"); $("#card_number").blur(); expect($("#card_number_error")).toHaveText("Invalid credit card number."); $("#card_number").val("4111 1111-11111111"); $("#card_number").blur(); expect($("#card_number_error")).toHaveText(""); }); });
credit_card.js
var CreditCard = {
cleanNumber: function(number) {
return number.replace(/[- ]/g, "");
},
validNumber: function(number) {
var total = 0;
number = this.cleanNumber(number);
for (var i=number.length-1; i >= 0; i--) {
var n = parseInt(number[i]);
if ((i+number.length) % 2 == 0) {
n = n*2 > 9 ? n*2 - 9 : n*2;
}
total += n;
};
return total % 10 == 0;
}
};
(function($){
$.fn.validateCreditCardNumber = function() {
return this.each(function() {
$(this).blur(function() {
if (!CreditCard.validNumber(this.value)) {
$("#" + this.id + "_error").text("Invalid credit card number.");
} else {
$("#" + this.id + "_error").text("");
}
});
});
};
})(jQuery);
var CreditCard = { cleanNumber: function(number) { return number.replace(/[- ]/g, ""); }, validNumber: function(number) { var total = 0; number = this.cleanNumber(number); for (var i=number.length-1; i >= 0; i--) { var n = parseInt(number[i]); if ((i+number.length) % 2 == 0) { n = n*2 > 9 ? n*2 - 9 : n*2; } total += n; }; return total % 10 == 0; } }; (function($){ $.fn.validateCreditCardNumber = function() { return this.each(function() { $(this).blur(function() { if (!CreditCard.validNumber(this.value)) { $("#" + this.id + "_error").text("Invalid credit card number."); } else { $("#" + this.id + "_error").text(""); } }); }); }; })(jQuery);
application.js
$(function() {
$("#order_credit_card_number").validateCreditCardNumber();
});
$(function() { $("#order_credit_card_number").validateCreditCardNumber(); });
orders/_form.html.erb
<%= f.text_field :credit_card_number %>
<span id="order_credit_card_number_error"></span>
<%= f.text_field :credit_card_number %> <span id="order_credit_card_number_error"></span>
spec/javascripts/fixtures/order_form.html
<form>
<input type="text" id="card_number">
<div id="card_number_error"></div>
</form>
<form> <input type="text" id="card_number"> <div id="card_number_error"></div> </form>

