cantango-core 0.1.3 → 0.1.4

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.
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}