On Dec 21, 2010, at 2:11 PM, rejeep wrote: > Hey, > > I have lots of problems to refactor RSpec macros and make them DRY. > Right now I'm stuck in such a situation for some role macros. > > In my controller tests, I want to write: > > 1) it_should_grant_access(:super_admin, :to => :countries) > 2) it_should_grant_access(:admin, :to => :countries, :only => > [:index, :show]) > 3) it_should_not_grant_access(:user, :to => :countries) > > These three rules should make sure that: > > 1) Super admin should be granted access to all default actions in > the countries controller > 2) Admin should be granted access to index and show, but not to new, > create, edit, update or destroy > 3) User should not be granted access to any of the default actions > > Since I want to be using this from many places, I used a module: > > module RoleMacros > DEFAULT_ACTIONS = > [:index, :show, :new, :create, :edit, :update, :destroy] > > def it_should_grant_access(role, options) > > # ... > > if except.present? > actions = DEFAULT_ACTIONS - Array(except) > elsif only.present? > actions = Array(only) > else > actions = DEFAULT_ACTIONS > end > > # ... > > end > > def it_not_should_grant_access(role, options) > # ... > end > end > > As you see from the example code there are some stuff I need to do > before I can do the actual testing. > > My question is how to solve this in a DRY way so that I can use the > set up code in the "not" case as well?
Just use the Extract Method refactoring: def it_should_grant_access(role, options) actions_from(options).each do |action| # ... end end def it_not_should_grant_access(role, options) actions_from(options).each do |action| # ... end end def actions_from(options) if options[:except] DEFAULT_ACTIONS - options[:except] elsif options[:only] options[:only] else DEFAULT_ACTIONS end end > Another problem is that when I specify that some role should have > access to some actions, it also means that the role should not have > access to all but those actions. This means that I must have each > request test in separate so that I can call them. But I'm not sure how > to do this. Just use one macro: def it_should_grant_access(role, options) actions_from(options).each do |action| # ... specify grant access end (DEFAULT_ACTIONS - actions_from(options)).each do |action| # ... specify deny access end end HTH, David > Thanks! > _______________________________________________ > rspec-users mailing list > rspec-users@rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users Cheers, David _______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users