cantango-core 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/README.mdown +12 -34
  2. data/VERSION +1 -1
  3. data/cantango-core.gemspec +33 -16
  4. data/lib/cantango/ability/base.rb +8 -52
  5. data/lib/cantango/ability/cache/simple_key.rb +1 -0
  6. data/lib/cantango/ability/callbacks.rb +36 -0
  7. data/lib/cantango/ability/executor/base.rb +21 -46
  8. data/lib/cantango/ability/executor/modal.rb +46 -0
  9. data/lib/cantango/ability/executor.rb +24 -1
  10. data/lib/cantango/ability/mode/base.rb +32 -0
  11. data/lib/cantango/ability/mode/finder.rb +19 -0
  12. data/lib/cantango/ability/mode/no_cache.rb +8 -0
  13. data/lib/cantango/ability/mode.rb +7 -0
  14. data/lib/cantango/ability/rules.rb +24 -0
  15. data/lib/cantango/ability.rb +1 -6
  16. data/lib/cantango/adaptor/active_record.rb +1 -1
  17. data/lib/cantango/adaptor/data_mapper.rb +1 -1
  18. data/lib/cantango/adaptor/mongo.rb +1 -1
  19. data/lib/cantango/adaptor/mongo_mapper.rb +1 -1
  20. data/lib/cantango/adaptor/mongoid.rb +1 -1
  21. data/lib/cantango/adaptor.rb +24 -26
  22. data/lib/cantango/core.rb +1 -1
  23. data/lib/cantango/helpers/debug.rb +4 -2
  24. data/lib/cantango/loader/yaml.rb +5 -1
  25. data/spec/active_record/001_create_posters.rb +13 -0
  26. data/spec/active_record/002_create_users.rb +13 -0
  27. data/spec/cantango/ability/base_spec.rb +3 -6
  28. data/spec/cantango/ability/callbacks_spec.rb +48 -0
  29. data/spec/cantango/ability/executor/base_spec.rb +15 -14
  30. data/spec/cantango/ability/executor/custom_spec.rb +3 -3
  31. data/spec/cantango/ability/executor/modal_spec.rb +35 -0
  32. data/spec/cantango/ability/executor_spec.rb +29 -0
  33. data/spec/cantango/ability/mode/base_example.rb +28 -0
  34. data/spec/cantango/ability/mode/base_spec.rb +15 -0
  35. data/spec/cantango/ability/mode/no_cache_spec.rb +15 -0
  36. data/spec/cantango/ability/rules_spec.rb +48 -0
  37. data/spec/cantango/adaptor/active_record_spec.rb +11 -2
  38. data/spec/cantango/loader/yaml_spec.rb +9 -1
  39. data/spec/cantango/rspec/be_allowed_to_spec.rb +1 -1
  40. data/spec/db/database.yml +4 -0
  41. data/spec/fixtures/test.yml +2 -0
  42. data/spec/migration_helper.rb +17 -0
  43. data/spec/spec_helper.rb +4 -0
  44. metadata +51 -37
  45. data/lib/cantango/ability/base/callbacks.rb +0 -37
  46. data/lib/cantango/ability/executor/modes.rb +0 -52
  47. data/lib/cantango/ability/executor/no_cache_mode.rb +0 -13
  48. data/spec/cantango/ability/executor/modes_spec.rb +0 -46
  49. data/spec/cantango/ability/executor/no_cache_mode_spec.rb +0 -29
data/lib/cantango/core.rb CHANGED
@@ -13,6 +13,6 @@ SweetLoader.mode = :require
13
13
 
14
14
  module CanTango
15
15
  autoload_modules :Helpers, :Ability, :Engine, :Filter
16
- autoload_modules :Loader, :Model
16
+ autoload_modules :Loader, :Model, :Adaptor
17
17
  autoload_modules :Scope
18
18
  end
@@ -29,11 +29,13 @@ module CanTango
29
29
  end
30
30
 
31
31
  def debug?
32
- @do_debug ||= self.class.debug?
32
+ @do_debug ||= self.class.debug? if self.class.respond_to? :debug?
33
+ @do_debug ||= false
33
34
  end
34
35
 
35
36
  def debug_writer
36
- @debug_writer ||= self.class.debug_writer
37
+ @debug_writer ||= self.class.debug_writer if self.class.respond_to? :debug_writer
38
+ @debug_writer ||= lambda {|m| puts m }
37
39
  end
38
40
  end
39
41
  end
@@ -3,6 +3,10 @@ module CanTango
3
3
  class Yaml
4
4
  attr_accessor :file_name
5
5
 
6
+ def initialize file_name
7
+ @file_name = file_name
8
+ end
9
+
6
10
  def self.inherited subclass
7
11
  subclass.extend ClassMethods
8
12
  end
@@ -14,7 +18,7 @@ module CanTango
14
18
  def yml_content
15
19
  YAML.load_file(file_name)
16
20
  rescue
17
- raise "Couldn't YAML file: #{file_name}"
21
+ raise "Couldn't load YAML file: #{file_name}"
18
22
  end
19
23
 
20
24
  module ClassMethods
@@ -0,0 +1,13 @@
1
+ class CreatePosters < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :posters do |t|
4
+ t.integer :user_id
5
+ t.string :body
6
+ t.timestamps
7
+ end
8
+ end
9
+
10
+ def self.down
11
+ drop_table :posters
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ class CreateUsers < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :users do |t|
4
+ t.string :name
5
+ t.string :email
6
+ t.timestamps
7
+ end
8
+ end
9
+
10
+ def self.down
11
+ drop_table :users
12
+ end
13
+ end
@@ -3,9 +3,7 @@ require 'fixtures/models'
3
3
 
4
4
  module CanTango::Ability
5
5
  class Base
6
- include CanTango::Ability::Helper::Account
7
-
8
- def permit_rules
6
+ def calculate_rules
9
7
  can :edit, Project
10
8
  end
11
9
  end
@@ -13,11 +11,10 @@ end
13
11
 
14
12
  describe CanTango::Ability::Base do
15
13
  before do
16
- user = User.new 'krisy', 'krisy@gmail.com'
17
- @account = Account.new user
14
+ @user = User.new 'krisy', 'krisy@gmail.com'
18
15
  end
19
16
 
20
- subject { CanTango::Ability::Base.new @account }
17
+ subject { CanTango::Ability::Base.new @user }
21
18
 
22
19
  specify { subject.should be_allowed_to(:edit, Project) }
23
20
  end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+ require 'fixtures/models'
3
+
4
+ module CanTango::Ability
5
+ class Base
6
+ include CanTango::Ability::Callbacks
7
+
8
+ before_execute :add_x
9
+ after_execute :add_y
10
+
11
+ def execute
12
+ within_callbacks do
13
+ clear_rules!
14
+ calculate_rules
15
+ end
16
+ end
17
+
18
+ protected
19
+
20
+ def buffer
21
+ @buffer ||= ""
22
+ end
23
+
24
+ def add_x
25
+ buffer << 'x'
26
+ end
27
+
28
+ def add_y
29
+ buffer << 'y'
30
+ end
31
+ end
32
+ end
33
+
34
+ describe CanTango::Ability::Callbacks do
35
+ before do
36
+ @user = User.new 'admin', 'admin@mail.ru'
37
+ end
38
+
39
+ subject { CanTango::Ability::Base.new @user }
40
+
41
+ describe 'handle_callbacks :before' do
42
+ its(:buffer) { should match /x/ }
43
+ end
44
+
45
+ describe 'handle_callbacks :after' do
46
+ its(:buffer) { should match /y/ }
47
+ end
48
+ end
@@ -1,27 +1,28 @@
1
1
  require 'spec_helper'
2
2
  require 'fixtures/models'
3
3
 
4
- module CanTango::Ability
4
+ module CanTango::Ability::Executor
5
5
  class Base
6
- def permit_rules
7
- can :read, Post
6
+ def calculate_rules
7
+ puts "calculate_rules"
8
+ can :write, Post
8
9
  end
9
10
  end
10
11
  end
11
12
 
12
13
  describe CanTango::Ability::Executor::Base do
13
- context 'non-cached only' do
14
- before do
15
- @user = User.new 'admin', 'admin@mail.ru'
16
- end
17
-
18
- subject { CanTango::Ability::Executor::Base.new @user }
14
+ before do
15
+ @user = User.new 'admin', 'admin@mail.ru'
16
+ @ability = CanTango::Ability::Base.new @user
17
+ end
19
18
 
20
- its(:non_cached_rules) { should_not be_empty }
19
+ subject do
20
+ CanTango::Ability::Executor::Base.new @ability
21
+ end
21
22
 
22
- describe 'rules contain only non-cached rules' do
23
- specify { subject.rules.size.should == @abil.non_cached_rules.size }
24
- specify { subject.rules.size.should == 1 }
23
+ describe 'should not be executable' do
24
+ specify do
25
+ lambda { subject.execute }.should raise_error
25
26
  end
26
27
  end
27
- end
28
+ end
@@ -16,14 +16,14 @@ class MyExecutor < CanTango::Ability::Executor::Base
16
16
  :my_exec
17
17
  end
18
18
 
19
- def permit_rules
20
- ability.permit_rules
19
+ def calculate_rules
20
+ ability.calculate_rules
21
21
  end
22
22
  end
23
23
 
24
24
  module CanTango::Ability
25
25
  class Base
26
- def permit_rules
26
+ def calculate_rules
27
27
  can :edit, Project
28
28
  end
29
29
  end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+ require 'fixtures/models'
3
+
4
+ module CanTango::Ability::Mode
5
+ class NoCache
6
+ def calculate_rules
7
+ can :write, Post
8
+ end
9
+ end
10
+ end
11
+
12
+ describe CanTango::Ability::Executor::Modal do
13
+ before do
14
+ @user = User.new 'admin', 'admin@mail.ru'
15
+ @ability = CanTango::Ability::Base.new @user
16
+ end
17
+
18
+ context 'Set execution mode to :no_cache' do
19
+ subject do
20
+ CanTango::Ability::Executor::Modal.new @ability, :no_cache
21
+ end
22
+
23
+ its(:rules) { should be_empty }
24
+
25
+ describe 'rules should be calculated on execute' do
26
+ before do
27
+ subject.execute
28
+ end
29
+
30
+ specify { subject.rules.should_not be_empty }
31
+ specify { subject.rules.size.should == 1 }
32
+ specify { subject.rules.first.should be_a CanCan::Rule }
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+ require 'fixtures/models'
3
+
4
+ module CanTango::Ability
5
+ class MyExecutor
6
+ include CanTango::Ability::Executor
7
+ end
8
+ end
9
+
10
+ describe CanTango::Ability::Executor do
11
+ before do
12
+ @user = User.new 'krisy', 'krisy@gmail.com'
13
+ @ability = CanTango::Ability::Base.new @user
14
+ end
15
+
16
+ subject { CanTango::Ability::MyExecutor.new @ability }
17
+
18
+ describe 'calculate_rules by default returns rules' do
19
+ specify do
20
+ subject.calculate_rules.should == []
21
+ end
22
+ end
23
+
24
+ describe 'execute by default calls calculate_rules' do
25
+ specify do
26
+ subject.execute.should == []
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+ require 'fixtures/models'
3
+
4
+ shared_examples_for CanTango::Ability::Mode::Base do
5
+ before do
6
+ @user = User.new 'admin', 'admin@mail.ru'
7
+ @ability = CanTango::Ability::Base.new @user
8
+ end
9
+
10
+ subject { mode_class.new @ability }
11
+
12
+ describe 'Does NOT execute on instantiation' do
13
+ specify do
14
+ subject.rules.should == []
15
+ end
16
+ end
17
+
18
+ describe 'execute will calculate rules' do
19
+ before do
20
+ subject.execute
21
+ end
22
+ specify { subject.rules.should_not be_empty }
23
+ specify { subject.rules.size.should == 1 }
24
+ specify { subject.rules.first.should be_a CanCan::Rule }
25
+
26
+ specify { subject.should be_allowed_to(:read, Post) }
27
+ end
28
+ end
@@ -0,0 +1,15 @@
1
+ require 'cantango/ability/mode/base_example'
2
+
3
+ module CanTango::Ability::Mode
4
+ class Base
5
+ def calculate_rules
6
+ can :read, Post
7
+ end
8
+ end
9
+ end
10
+
11
+ describe CanTango::Ability::Mode::Base do
12
+ it_should_behave_like CanTango::Ability::Mode::Base do
13
+ let(:mode_class) { CanTango::Ability::Mode::Base }
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'cantango/ability/mode/base_example'
2
+
3
+ module CanTango::Ability::Mode
4
+ class NoCache
5
+ def calculate_rules
6
+ can :read, Post
7
+ end
8
+ end
9
+ end
10
+
11
+ describe CanTango::Ability::Mode::NoCache do
12
+ it_should_behave_like CanTango::Ability::Mode::Base do
13
+ let(:mode_class) { CanTango::Ability::Mode::NoCache }
14
+ end
15
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+ require 'fixtures/models'
3
+
4
+ module CanTango::Ability
5
+ class Base
6
+ include CanTango::Ability::Rules
7
+
8
+ def calculate_rules
9
+ can :edit, Project
10
+ end
11
+ end
12
+ end
13
+
14
+ describe CanTango::Ability::Rules do
15
+ before do
16
+ @user = User.new 'krisy', 'krisy@gmail.com'
17
+ end
18
+
19
+ subject { CanTango::Ability::Base.new @user }
20
+
21
+ describe 'rules' do
22
+ specify do
23
+ subject.rules.should == []
24
+ end
25
+ end
26
+
27
+ describe 'clear_rules!' do
28
+ before do
29
+ subject.rules = [1]
30
+ subject.clear_rules!
31
+ end
32
+
33
+ specify do
34
+ subject.rules.should == []
35
+ end
36
+ end
37
+
38
+ describe 'normalize_rules!' do
39
+ before do
40
+ subject.rules = [[1,2], 3]
41
+ subject.normalize_rules!
42
+ end
43
+
44
+ specify do
45
+ subject.rules.should == [1,2,3]
46
+ end
47
+ end
48
+ end
@@ -1,10 +1,17 @@
1
1
  # This is used to wrap the CanCan ORM adapters, that enable convenient
2
2
  # 'simple' queries using hashes similar to 'metawhere' gem
3
3
  require 'spec_helper'
4
+ require 'migration_helper'
4
5
 
5
6
  class Poster < ActiveRecord::Base
7
+ belongs_to :owner, :class_name => "User", :foreign_key => "user_id"
6
8
  end
7
9
 
10
+ class User < ActiveRecord::Base
11
+ has_many :posters
12
+ end
13
+
14
+
8
15
  module CanTango::Ability
9
16
  class Base
10
17
  def permit_rules
@@ -16,8 +23,10 @@ end
16
23
 
17
24
  describe CanTango::Adaptor::ActiveRecord do
18
25
  before do
19
- @user = User.new 'admin', 'admin@mail.ru'
20
- @stranger = User.new 'stranger', 'stranger@mail.ru'
26
+ migrate!
27
+
28
+ @user = User.create :name => 'admin', :email => 'admin@mail.ru'
29
+ @stranger = User.create :name => 'stranger', :email => 'strange@mail.ru'
21
30
 
22
31
  @poster = Poster.create :owner => @user
23
32
  @poster.owner = @user
@@ -1,5 +1,13 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe CanTango::Loader::Yaml do
4
- pending 'Nothing much to spec here!'
4
+ subject { CanTango::Loader::Yaml.new File.join(spec_folder, 'fixtures/test.yml') }
5
+
6
+ describe 'Parser not implemented' do
7
+ specify do
8
+ lambda { subject.parser }.should raise_error
9
+ end
10
+ end
11
+
12
+ its(:yml_content) { should be_a Hash }
5
13
  end
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'RSpec::Matchers be_allowed_to' do
4
- pending 'It should work!'
4
+ # pending 'It works :)'
5
5
  end
@@ -0,0 +1,4 @@
1
+ adapter: sqlite3
2
+ database: spec/db/development.sqlite3
3
+ pool: 5
4
+ timeout: 5000
@@ -0,0 +1,2 @@
1
+ ---
2
+ hello: you
@@ -0,0 +1,17 @@
1
+ require 'active_record'
2
+ require 'database_cleaner'
3
+
4
+ path = File.dirname(__FILE__) + '/db/database.yml'
5
+ dbfile = File.open(path)
6
+ dbconfig = YAML::load(dbfile)
7
+ ActiveRecord::Base.establish_connection(dbconfig)
8
+ # ActiveRecord::Base.logger = Logger.new(STDERR)
9
+ DatabaseCleaner.strategy = :truncation
10
+
11
+ def migration_folder
12
+ File.join(File.dirname(__FILE__), 'active_record')
13
+ end
14
+
15
+ def migrate!
16
+ ActiveRecord::Migrator.migrate File.join(File.dirname(__FILE__), 'active_record')
17
+ end
data/spec/spec_helper.rb CHANGED
@@ -5,6 +5,10 @@ require 'cantango/core'
5
5
  class Project
6
6
  end
7
7
 
8
+ def spec_folder
9
+ File.dirname(__FILE__)
10
+ end
11
+
8
12
  # Requires supporting files with custom matchers and macros, etc,
9
13
  # in ./support/ and its subdirectories.
10
14
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}