the other day i was coding with JavaScript, everything was good until i deployed my code.. we use jammit for our assets compression, after the compile the files came up empty (0 bytes), that's a sign that some is wrong (obviously right?)
well the problem is that when YUI compressor finds an error, then it just stop the whole package compression and says nothing about it (no error message, no file where to check, no nothing..), so i started looking for posible missing ; or stuff like that.
i found maybe 10 of those missing ;. i fixed them and try to recompile…. still not working..
then some of my friends asked me why i didn't use JSLint before all this problem, i realize that they were true, it was a little irresponsible on my part to no validate the coding style using a lint..
since my editor is vim then i start looking for a jslint pugling for it (i dont want to be pasting code all the time to JSLint.com), the one i use is jslint.vim the installation was a breeze, just clone the repo and do a rake install (off course if you are in OS X, if not then check the repo and follow the instructions there).
you can set the options for JSLint in ~/.jslintrc, the config file looks something like this
/*jslint browser: true, regexp: true */
/*global jQuery, $ */
/* vim: set ft=javascript: */
there you set all your global variables, libraries etc. also you can set all the options that JSLint has in this file, check http://www.jslint.com/lint.html for the list of options.
well after pasing my files through JSLint i found a one error that i totally overlooked.
- You shall not use reserved words for object properties (here is a list of JavaScript reserved words).
actually you can use those, but is not a good practice, also YUI Compressor fails if you use reserved words in your code.. thins like foo.class, foo.delete var float = 2.2 will fail to compile..
so i learned a lesson that day, "always, ALWAYS!!, pass your code through JSLint"
The other day browsing around my rss feed, i saw that Steve Klabnik is using Svbtle, i tried to register but is an invitation only magazine, so i didn't even bother to request an invitation.
i really like the design, so i cloned it for my Jekyll based page, you can take a look at repo. All configurations are located at the base.html file header, you can set all your parameters there.
The "Kudos" button uses localStorage to track if the user already "kudoed" a post or not, also you can pass an url parameter so after the user "Kudos" a post, it will send an ajax POST request with the post id. Those id are grabbed from the post customid parameter, i need to look for a better way to handle this.
there's still a lot missing (like grab the kudo number from an external app) but i will clean the code and add the missing functionality later this week. (off course pull requests are so much welcome <3)
probably you just have to do rvm get stable and should work ok.
Right now im working in a gem called Rubytrick, its a wrapper for theHattrick's CHPP API. Hattrick is a Web soccer simulation game. its pretty fun actually, and can became quickly part of your daily internet life (like Facebook or Twitter).
since this an API wrapper, its expected to have a lot of HTTP requests, first i was stubbing all this requests by hand using WebMock, but it was a PITA to write XML data manually just to get my tests pass.. so i start looking for a library that could solve that problem.. and it was VCR.
With VCR you make real HTTP requests the first time, then theses requests are saved in a fixture folder, and when a test request the same URL, VCR pass the saved fixture instead of hitting the web once again, its a like magic really, saves a lot of work.
Well, im using RSpec (unless you are DHH you should be using it too), so this post will show code that works if you have RSpec too.
now.. first you install you need to istall RSpec or RSpec-rails if you are using Rails.
RSpec 2.8 has a command for starting with the default spec skeleton, its really helpful in case youre writing a gem, just install RSpec and then write
rspec --init
#or
rspec --init --autotest #if your using autotest
these two commands generate some files to start with RSpec. for now you are done with RSpec, now lets install WebMock.
the install its easy too just write gem install webmock or write it in your Gemfile and then bundle install.
once you have WebMock installed, go to your spec directory and open your spec_helper.rb file.
add require 'webmock/rspec' on top of the file, and thats all for now. by default, WebMock doesnt allow real http connections, so all external requests have to be stubbed, this is easy since when your code makes a request, WebMock gives you a WebMock::NetConnectNotAllowedError with information on how you can stub that request, but since we will be using VCR we dont need to stub anything by ourselfs.
now we need to install VCR. just like WebMock, make a gem install vcr of put it in your Gemfile then bundle install
now that you have VCR installed, we need to configure it. go to your spec_helper.rb file and add this block
require 'vcr'
VCR.config do |c|
c.cassette_library_dir = 'spec/fixtures/vcr_cassettes' # where VCR should place the stub files.
c.stub_with :webmock #this tells WebMock to use VCR.
end
you have to add config.extend VCR::RSpec::Macros to your RSpec config block to enable VCR's helpers for RSpec. like this.
RSpec.configure do |config|
... #other lines
config.extend VCR::RSpec::Macros
end
that line enables use_vcr_cassette method for RSpec, you can get more info about this method in the VCR's documentation.
and now we are ready to start recording requests. im going to paste a spec to explain the work flow.
require 'spec_helper'
describe Rubytrick::HT, 'Fans' do
use_vcr_cassette :record => :new_episodes
before(:all) do
Rubytrick.oauth_keys = {:consumer_key => 'key', :consumer_secret => 'secret'}
end
before(:each) do
@session = Rubytrick::Session.new('token','secret')
end
it 'should have a pull data method' do
@session.fans.respond_to?(:pull_data).should be_true
end
it 'should retrieve data from hattrick already parsed' do
@session.fans.data.should_not == nil
@session.fans.data.class.should == Hash
@session.fans.data[:file_name].should == 'fans.xml'
end
end
the important part of this file is the command use_vcr_cassette, the :record => :new_episodes tells VCR to record new requests, and replay the requests that are already saved. you can ignore the other lines of the spec since these are project specific.
use_vcr_cassette also accepts a name, like use_vcr_cassette 'fixture_name_here', if we dont supply a name, then VCR will create one using the describe header of the spec. in this case, the file that VCR creates its called Rubytrick_HT_Fans.yml and that file contains the entire HTTP response, including header and everything, pretty cool.
the first time you run your tests, it will take a few seconds to capture the request and save it into the fixture file, but after that, they run really fast.
and thats all for now, VCR + WebMock makes an awesome couple if you want to test with real data.
Today i was looking for a easy way to push to multiple git repos.. a quick look at stackoverflow answered my question.
once you create your local git repo, add some remotes.
git remote add hashlabs git@git.hashlabs.com:orlandodelaguila.github.com.git
git remote add origin git@github.com:orlandodelaguila/orlandodelaguila.github.com.git
then open your .git/config file and look at it.. should look like this one.
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = git@github.com:orlandodelaguila/orlandodelaguila.github.com.git
fetch = +refs/heads/*:refs/remotes/origin/*
[remote "hashlabs"]
url = git@git.hashlabs.com:orlandodelaguila.github.com.git
fetch = +refs/heads/*:refs/remotes/hashlabs/*
fire up vim and add another remote that includes multiple urls.. like this
[remote "all"]
url = git@git.hashlabs.com:orlandodelaguila.github.com.git
url = git@github.com:orlandodelaguila/orlandodelaguila.github.com.git
when you do git push all master it would push to the both url in the same order that you write them, one repo at a time. this tricky comes really handy because im lazy and i dont want to type git push multiple times.
another timesaver trick is using echo for creating .rvmrc and README files..
#for .rvmrc files
#if you use --create use will create the gemset if it's not present
echo "rvm --create use 1.9.3@orlandodelaguila" >> .rvmrc
#for README.md
#adding -e enables the interpretation of backslash
#so you could write an entire readme in 1 line =P.
echo -e "#README\n Some text here about your readme " >> README.md
both of these commands will create a new file with the text that you pass with echo.
Today i was looking into Capybara DSL as a replacement to Cucumber, dont get me wrong, i love Cucumber but i want to try something new..
Using OmniAuth + OmniAuth-Twitter makes oauth with twitter painless. The setup its pretty straight forward, just put this 2 in your Gemfile, bundle install and follow the instructions in the OmniAuth github page, you could check the RailsApps tutorial if you have any doubt.
Rspec and Capybara install its a breeze too, just follow the steps in the github page and you will get it running in just a few minutes.
now that you have Rspec and Capybara installed, were ready to start with the code.
at this point you should have in your config/routes.rb something like this.
match '/auth/:provider/callback', to: 'sessions#create'
That line will tell OmniAuth what controller should receive the data from twitter (in short.. the callback).
With that line in place, we could use the helpers that OmniAuth has for testing.. go to your spec/spec_helper.rb file and add this.
...
RSpec.configure do |config|
...
OmniAuth.config.test_mode = true
OmniAuth.config.mock_auth[:twitter] = {
'provider' => 'twitter',
'uid' => '123545',
}
that tells RSpec that when a test hits 'auth/twitter' OmniAuth will respond with a mockup, this comes really handy because you dont have to use something like FakeWeb to fake the http responses and its a lot easier using the OmniAuth's Build in methods.
Since i have some validations in my User model, i have to pass more data in the mock.. so my mock looks something like this
...
RSpec.configure do |config|
...
OmniAuth.config.test_mode = true
OmniAuth.config.mock_auth[:twitter] = {
'provider' => 'twitter',
'uid' => '123545',
'info' => {'name' => 'Orlando', 'nickname' => 'djlandox'}
}
my SessionsController and my User model looks something like this
class SessionsController < ApplicationController
def new
redirect_to '/auth/twitter'
end
def create
auth = request.env["omniauth.auth"]
user = User.get_user(auth)
session[:user_id] = user.id
redirect_to root_url, :notice => "Bienvenido! #{user.name.titleize}"
end
def failure
redirect_to root_url, :alert => 'Error en el Login'
end
def destroy
reset_session
redirect_to root_url, :notice => 'Vuelve Pronto!'
end
end
class User
include Mongoid::Document
field :provider, :type => String
field :uid, :type => String
field :name, :type => String
field :email, :type => String
field :screen_name, :type => String
field :image_url, :type => String
field :user_role, :type => String
validates_presence_of :name, :uid, :provider
def self.create_with_omniauth(auth)
create! do |user|
user.provider = auth['provider']
user.uid = auth['uid']
if auth['info']
user.name = auth['info']['name'] || ""
user.email = auth['info']['email'] || ""
user.screen_name = auth['info']['nickname'] || ""
user.image_url = auth['info']['image'] || ""
end
end
end
end
with all the code in place, the following tests should be green :), create a folder in your spec directory and a file called something like oauth_spec.rb
require 'rspec'
require 'capybara/rspec'
feature "OmniAuth" do
scenario "should login successfully" do
visit '/auth/twitter'
page.should have_content("Bienvenido! Orlando")
end
scenario "should logout successfully" do
visit '/auth/twitter'
page.should have_content("Bienvenido! Orlando")
click_on 'Log out'
page.should have_content("Vuelve Pronto!")
end
end
when you hit visit '/auth/twitter', OmniAuth will respond with a POST call to the SessionsController#create method, and that methods redirect to root_url' with a flash message..
and thats how you easily test OmniAuth with Capybara and RSpec. :)