cantango-core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.rspec +3 -0
- data/Gemfile +54 -0
- data/Gemfile.lock +231 -0
- data/LICENSE.txt +20 -0
- data/README.mdown +90 -0
- data/Rakefile +48 -0
- data/VERSION +1 -0
- data/cantango-core.gemspec +177 -0
- data/lib/cantango/ability.rb +5 -0
- data/lib/cantango/ability/base.rb +61 -0
- data/lib/cantango/ability/cache.rb +7 -0
- data/lib/cantango/ability/cache/key.rb +38 -0
- data/lib/cantango/ability/cached.rb +28 -0
- data/lib/cantango/ability/executor.rb +7 -0
- data/lib/cantango/ability/executor/base.rb +53 -0
- data/lib/cantango/ability/executor/cache_mode.rb +33 -0
- data/lib/cantango/ability/executor/modes.rb +52 -0
- data/lib/cantango/ability/executor/no_cache_mode.rb +17 -0
- data/lib/cantango/ability/helper.rb +11 -0
- data/lib/cantango/ability/helper/account.rb +13 -0
- data/lib/cantango/ability/helper/engine.rb +32 -0
- data/lib/cantango/ability/helper/role.rb +21 -0
- data/lib/cantango/ability/helper/role_group.rb +21 -0
- data/lib/cantango/ability/helper/user.rb +18 -0
- data/lib/cantango/cancan/rule.rb +6 -0
- data/lib/cantango/core.rb +84 -0
- data/lib/cantango/engine.rb +39 -0
- data/lib/cantango/filter.rb +5 -0
- data/lib/cantango/filter/base.rb +31 -0
- data/lib/cantango/helpers.rb +5 -0
- data/lib/cantango/helpers/debug.rb +10 -0
- data/lib/cantango/loader.rb +5 -0
- data/lib/cantango/loader/yaml.rb +33 -0
- data/lib/cantango/macros.rb +11 -0
- data/lib/cantango/macros/account.rb +14 -0
- data/lib/cantango/macros/user.rb +16 -0
- data/lib/cantango/model.rb +5 -0
- data/lib/cantango/model/guest.rb +25 -0
- data/lib/cantango/rails.rb +7 -0
- data/lib/cantango/rails/engine.rb +63 -0
- data/lib/cantango/rails/helpers/base_helper.rb +29 -0
- data/lib/cantango/rails/helpers/controller_helper.rb +17 -0
- data/lib/cantango/rails/helpers/rest_helper.rb +76 -0
- data/lib/cantango/rails/helpers/view_helper.rb +17 -0
- data/lib/cantango/rails/railtie.rb +7 -0
- data/lib/cantango/rspec.rb +1 -0
- data/lib/cantango/rspec/config.rb +3 -0
- data/lib/cantango/rspec/matchers.rb +1 -0
- data/lib/cantango/rspec/matchers/be_allowed_to.rb +28 -0
- data/lib/cantango/rules.rb +8 -0
- data/lib/cantango/rules/adaptor.rb +37 -0
- data/lib/cantango/rules/adaptor/active_record.rb +10 -0
- data/lib/cantango/rules/adaptor/data_mapper.rb +11 -0
- data/lib/cantango/rules/adaptor/generic.rb +16 -0
- data/lib/cantango/rules/adaptor/mongo.rb +19 -0
- data/lib/cantango/rules/adaptor/mongo_mapper.rb +10 -0
- data/lib/cantango/rules/adaptor/mongoid.rb +9 -0
- data/lib/cantango/rules/adaptor/relational.rb +13 -0
- data/lib/cantango/rules/dsl.rb +24 -0
- data/lib/cantango/rules/relation.rb +67 -0
- data/lib/cantango/rules/rule_class.rb +11 -0
- data/lib/cantango/rules/scope.rb +24 -0
- data/lib/cantango/scope.rb +5 -0
- data/lib/cantango/scope/ability.rb +20 -0
- data/lib/generators/cantango/install/install_generator.rb +37 -0
- data/lib/generators/cantango/install/templates/cantango.rb +4 -0
- data/lib/generators/cantango/install/templates/categories.yml +0 -0
- data/lib/generators/cantango/install/templates/permissions.yml +6 -0
- data/spec/cantango/ability/base_spec.rb +73 -0
- data/spec/cantango/ability/cached_spec.rb +0 -0
- data/spec/cantango/ability/executor/base2.rb +75 -0
- data/spec/cantango/ability/executor/base_spec.rb +67 -0
- data/spec/cantango/ability/executor/cache_mode_spec.rb +77 -0
- data/spec/cantango/ability/executor/modes_spec.rb +68 -0
- data/spec/cantango/ability/executor/no_cache_mode_spec.rb +0 -0
- data/spec/cantango/cancan/rule_spec.rb +0 -0
- data/spec/cantango/core_spec.rb +9 -0
- data/spec/cantango/engine_spec.rb +0 -0
- data/spec/cantango/filter/base_spec.rb +0 -0
- data/spec/cantango/helpers/debug_spec.rb +0 -0
- data/spec/cantango/loader/yaml_spec.rb +0 -0
- data/spec/cantango/macros/account_spec.rb +0 -0
- data/spec/cantango/macros/user_spec.rb +0 -0
- data/spec/cantango/rspec/be_allowed_to_spec.rb +0 -0
- data/spec/cantango/rules/adaptor/active_record_spec.rb +0 -0
- data/spec/cantango/rules/adaptor/data_mapper_spec.rb +0 -0
- data/spec/cantango/rules/adaptor/mongo_mapper_spec.rb +0 -0
- data/spec/cantango/rules/adaptor/mongoid_spec.rb +0 -0
- data/spec/cantango/rules/adaptor_spec.rb +0 -0
- data/spec/cantango/rules/dsl_spec.rb +0 -0
- data/spec/cantango/rules/relation_spec.rb +0 -0
- data/spec/cantango/rules/rule_class_spec.rb +0 -0
- data/spec/cantango/rules/scope_spec.rb +0 -0
- data/spec/cantango/rules_spec.rb +55 -0
- data/spec/cantango/scope/ability_spec.rb +0 -0
- data/spec/cantango_spec.rb +0 -0
- data/spec/generators/cantango/install_generator_spec.rb +42 -0
- data/spec/spec_helper.rb +9 -0
- metadata +310 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require 'active_support/inflector'
|
|
2
|
+
|
|
3
|
+
module CanTango
|
|
4
|
+
module Rules
|
|
5
|
+
class Relation
|
|
6
|
+
attr_reader :attribute, :permit, :scope, :models
|
|
7
|
+
|
|
8
|
+
include CanTango::Rules::Adaptor
|
|
9
|
+
include CanTango::Rules::RuleClass
|
|
10
|
+
|
|
11
|
+
def initialize attribute, permit, scope, *models, &block
|
|
12
|
+
@attribute = attribute
|
|
13
|
+
@scope = scope
|
|
14
|
+
@permit = permit
|
|
15
|
+
@models = models
|
|
16
|
+
|
|
17
|
+
check_models
|
|
18
|
+
use_adaptor! self, user_scope
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def can(action)
|
|
22
|
+
models.each do |model|
|
|
23
|
+
rules << rule_class.new(true, action, model, nil, condition_block(model))
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def cannot(action)
|
|
28
|
+
models.each do |model|
|
|
29
|
+
rules << rule_class.new(false, action, model, nil, condition_block(model))
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
protected
|
|
34
|
+
|
|
35
|
+
def condition_block model
|
|
36
|
+
return attribute_condition(attribute, user_scope) if model.new.respond_to?(attribute)
|
|
37
|
+
return include_condition(plural_attribute, user_scope) if model.new.respond_to?(plural_attribute)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def user_scope
|
|
41
|
+
@user_scope ||= (scope == :account) ? permit.user_account : permit.user
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def scope_key
|
|
45
|
+
@scope_key ||= (scope == :account) ? :user_account : :user
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def ability
|
|
49
|
+
permit.ability
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def rules
|
|
53
|
+
ability.send :rules
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def plural_attribute
|
|
57
|
+
:"#{attribute.to_s.pluralize}"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def check_models
|
|
61
|
+
models.each do |model|
|
|
62
|
+
raise "#{model} has no :#{attribute} or :#{plural_attribute} defined" if !model.new.respond_to?(attribute) && !model.new.respond_to?(plural_attribute)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module CanTango
|
|
2
|
+
module Rules
|
|
3
|
+
class Scope
|
|
4
|
+
attr_reader :name, :permit
|
|
5
|
+
|
|
6
|
+
def initialize name, permit, &block
|
|
7
|
+
@name = name.to_sym
|
|
8
|
+
@permit = permit
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
::CanTango.config.user.relations.each do |relationship|
|
|
12
|
+
base.class_eval %{
|
|
13
|
+
def #{relationship}_of *models, &block
|
|
14
|
+
options = models.extract_options!
|
|
15
|
+
scope = options[:scope] || name
|
|
16
|
+
relation = UserRelation.new :#{relationship}, permit, scope, models, &block
|
|
17
|
+
yield relation if block
|
|
18
|
+
relation
|
|
19
|
+
end
|
|
20
|
+
}
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module CanTango
|
|
2
|
+
module Scope
|
|
3
|
+
class Ability
|
|
4
|
+
attr_accessor :ability
|
|
5
|
+
|
|
6
|
+
def initialize ability
|
|
7
|
+
@ability = ability
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def can? *args
|
|
11
|
+
ability.can? *args
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def cannot? *args
|
|
15
|
+
ability.cannot? *args
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Cantango
|
|
2
|
+
module Generators
|
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
|
4
|
+
desc "Add role strategy to a User model"
|
|
5
|
+
|
|
6
|
+
source_root File.expand_path("../templates", __FILE__)
|
|
7
|
+
|
|
8
|
+
class_option :categories, :type => :boolean, :default => true, :desc => "Create categories"
|
|
9
|
+
class_option :permissions, :type => :boolean, :default => true, :desc => "Create yaml permissions store"
|
|
10
|
+
|
|
11
|
+
def copy_initializer
|
|
12
|
+
template "cantango.rb", "config/initializers/cantango.rb"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def copy_categories
|
|
16
|
+
return unless categories?
|
|
17
|
+
template "categories.yml", "config/categories.yml"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def copy_permissions
|
|
21
|
+
return unless permissions?
|
|
22
|
+
template "permissions.yml", "config/permissions.yml"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
protected
|
|
26
|
+
|
|
27
|
+
def permissions?
|
|
28
|
+
options[:permissions]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def categories?
|
|
32
|
+
options[:categories]
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
File without changes
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require 'rspec'
|
|
2
|
+
require 'cantango'
|
|
3
|
+
require 'fixtures/models'
|
|
4
|
+
require 'cantango/rspec'
|
|
5
|
+
|
|
6
|
+
def config_folder
|
|
7
|
+
File.dirname(__FILE__)+ "/../fixtures/config/"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
CanTango.configure do |config|
|
|
11
|
+
config.clear!
|
|
12
|
+
# config.permissions.set :on
|
|
13
|
+
config.engines.all :on
|
|
14
|
+
|
|
15
|
+
config.permission_engine.config_path = config_folder
|
|
16
|
+
config.categories.register :blog_items => [Article, Post]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class PublishersRoleGroupPermit < CanTango::RoleGroupPermit
|
|
20
|
+
def initialize ability
|
|
21
|
+
super
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
protected
|
|
25
|
+
|
|
26
|
+
def static_rules
|
|
27
|
+
can :write, category(:blog_items)
|
|
28
|
+
cannot :write, Post
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class EditorRolePermit < CanTango::RolePermit
|
|
33
|
+
def initialize ability
|
|
34
|
+
super
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
protected
|
|
38
|
+
|
|
39
|
+
def static_rules
|
|
40
|
+
can :read, Comment
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
describe CanTango::Ability do
|
|
46
|
+
let (:user) do
|
|
47
|
+
User.new 'krisy', 'krisy@gmail.com'
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
let (:user_account) do
|
|
51
|
+
ua = UserAccount.new user, :roles => [:editor], :role_groups => [:publishers]
|
|
52
|
+
user.account = ua
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
before do
|
|
56
|
+
CanTango.config.clear!
|
|
57
|
+
@ability = CanTango::Ability.new user_account
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
specify { CanTango.config.roles.excluded.should be_empty }
|
|
61
|
+
specify { CanTango.config.role_groups.excluded.should be_empty }
|
|
62
|
+
|
|
63
|
+
subject { @ability }
|
|
64
|
+
specify { @ability.should be_allowed_to(:read, Comment) }
|
|
65
|
+
specify { @ability.should be_allowed_to(:write, Article) }
|
|
66
|
+
specify { @ability.should_not be_allowed_to(:write, Post) }
|
|
67
|
+
|
|
68
|
+
its(:user_account) { should be_a(UserAccount) }
|
|
69
|
+
its(:user) { should be_a(User) }
|
|
70
|
+
|
|
71
|
+
its(:roles) { should_not be_empty }
|
|
72
|
+
its(:role_groups) { should_not be_empty }
|
|
73
|
+
end
|
|
File without changes
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require 'rspec'
|
|
2
|
+
require 'cantango'
|
|
3
|
+
# require 'simple_roles'
|
|
4
|
+
require 'fixtures/models'
|
|
5
|
+
require 'cantango/rspec'
|
|
6
|
+
|
|
7
|
+
def config_folder
|
|
8
|
+
File.dirname(__FILE__)+ "/../fixtures/config/"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
CanTango.configure do |config|
|
|
12
|
+
config.clear!
|
|
13
|
+
end
|
|
14
|
+
# CanTango.debug!
|
|
15
|
+
|
|
16
|
+
class User
|
|
17
|
+
tango_user
|
|
18
|
+
include_and_extend SimpleRoles
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class AdminRolePermit < CanTango::RolePermit
|
|
22
|
+
def initialize ability
|
|
23
|
+
super
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
protected
|
|
27
|
+
|
|
28
|
+
def static_rules
|
|
29
|
+
can :read, Article
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
module Cached
|
|
33
|
+
def permit_rules
|
|
34
|
+
can :edit, Article
|
|
35
|
+
can :delete, Article
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
module CanTango
|
|
41
|
+
class Ability
|
|
42
|
+
def permit_rules
|
|
43
|
+
can :read, Post
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe CanTango::AbilityExecutor do
|
|
49
|
+
context 'non-cached only' do
|
|
50
|
+
before do
|
|
51
|
+
CanTango.configure.ability.mode = :no_cache
|
|
52
|
+
|
|
53
|
+
@user = User.new 'admin', 'admin@mail.ru', :role => 'admin'
|
|
54
|
+
@abil = CanTango::AbilityExecutor.new @user
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
subject { CanTango::AbilityExecutor.new @user }
|
|
58
|
+
|
|
59
|
+
describe 'config no_cache' do
|
|
60
|
+
specify { CanTango.configure.ability.modes.should == [:no_cache] }
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
describe 'engines_on?' do
|
|
64
|
+
specify { subject.engines_on?.should be_true }
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
its(:cached_rules) { should be_empty }
|
|
68
|
+
its(:non_cached_rules) { should_not be_empty }
|
|
69
|
+
|
|
70
|
+
describe 'rules contain only non-cached rules' do
|
|
71
|
+
specify { subject.rules.size.should == @abil.non_cached_rules.size }
|
|
72
|
+
specify { subject.rules.size.should == 2 }
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require 'rspec'
|
|
2
|
+
require 'cantango'
|
|
3
|
+
require 'fixtures/models'
|
|
4
|
+
require 'cantango/rspec'
|
|
5
|
+
|
|
6
|
+
def config_folder
|
|
7
|
+
File.dirname(__FILE__)+ "/../fixtures/config/"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
CanTango.configure do |config|
|
|
11
|
+
config.clear!
|
|
12
|
+
config.ability.mode = :no_cache
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class MyExecutor
|
|
16
|
+
include CanTango::Ability::Executor
|
|
17
|
+
|
|
18
|
+
attr_reader :ability
|
|
19
|
+
|
|
20
|
+
def initialize ability
|
|
21
|
+
@ability = ability
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def valid?
|
|
25
|
+
true
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def cache_key
|
|
29
|
+
:my_exec
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def permit_rules
|
|
33
|
+
ability.permit_rules
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
module CanTango
|
|
38
|
+
class Ability
|
|
39
|
+
def permit_rules
|
|
40
|
+
can :edit, Project
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
describe CanTango::Ability::Executor do
|
|
46
|
+
context 'no-cache' do
|
|
47
|
+
let (:ability) do
|
|
48
|
+
CanTango::Ability.new @user
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
before do
|
|
52
|
+
@user = User.new 'kris'
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
subject { MyExecutor.new ability }
|
|
56
|
+
|
|
57
|
+
describe '#execute!' do
|
|
58
|
+
before do
|
|
59
|
+
subject.execute!
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
specify { subject.ability.send(:rules).should_not be_empty }
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
require 'rspec'
|
|
2
|
+
require 'cantango'
|
|
3
|
+
# require 'simple_roles'
|
|
4
|
+
require 'fixtures/models'
|
|
5
|
+
require 'cantango/rspec'
|
|
6
|
+
|
|
7
|
+
def config_folder
|
|
8
|
+
File.dirname(__FILE__)+ "/../fixtures/config/"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
CanTango.configure do |config|
|
|
12
|
+
config.clear!
|
|
13
|
+
config.ability.mode = :cache
|
|
14
|
+
end
|
|
15
|
+
# CanTango.debug!
|
|
16
|
+
|
|
17
|
+
class User
|
|
18
|
+
tango_user
|
|
19
|
+
include_and_extend SimpleRoles
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class AdminRolePermit < CanTango::Permit::Role
|
|
23
|
+
def initialize ability
|
|
24
|
+
super
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
protected
|
|
28
|
+
|
|
29
|
+
def static_rules
|
|
30
|
+
can :read, Article
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
module Cached
|
|
34
|
+
def permit_rules
|
|
35
|
+
can :edit, Article
|
|
36
|
+
can :delete, Article
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
module CanTango
|
|
42
|
+
class CachedAbility
|
|
43
|
+
def permit_rules
|
|
44
|
+
can :read, Post
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
describe CanTango::Ability::Executor::CacheMode do
|
|
50
|
+
context 'cached only' do
|
|
51
|
+
before do
|
|
52
|
+
CanTango.configure.ability.mode = :cache
|
|
53
|
+
|
|
54
|
+
@user = User.new 'admin', 'admin@mail.ru', :role => 'admin'
|
|
55
|
+
@abil = CanTango::AbilityExecutor.new @user
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
subject { CanTango::AbilityExecutor.new @user }
|
|
59
|
+
|
|
60
|
+
describe 'config cache' do
|
|
61
|
+
specify { CanTango.configure.ability.modes.should == [:cache] }
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
describe 'engines_on?' do
|
|
65
|
+
specify { subject.engines_on?.should be_true }
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
its(:cached_rules) { should_not be_empty }
|
|
69
|
+
its(:non_cached_rules) { should be_empty }
|
|
70
|
+
|
|
71
|
+
describe 'rules contain only non-cached rules' do
|
|
72
|
+
specify { subject.rules.size.should == @abil.cached_rules.size }
|
|
73
|
+
specify { subject.rules.size.should == 4 }
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|