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? 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. Thanks!
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 at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-usersCheers, David
Thanks for your reply David! My solution ended up something like this: def it_should_grant_access(role, options) request_index = proc do get :index response.success? end # ... actions_from(options).each do |action| request = instance_eval(&eval("request_#{action}")) request.should be_true, "#{role} should have been granted access to #{action}, but was not" end # ... end Not perfect, but it works. Btw, I solved the "not-case" by flipping only and except and then just call it_should_grant_access. Thanks! On Dec 22, 3:03?am, David Chelimsky <dchelim... at gmail.com> wrote:> 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-us... at rubyforge.org > >http://rubyforge.org/mailman/listinfo/rspec-users > > Cheers, > David > > _______________________________________________ > rspec-users mailing list > rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users