troles 0.5.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/.rspec +1 -0
- data/Gemfile +26 -0
- data/Gemfile.lock +161 -0
- data/MIT-LICENSE +20 -0
- data/README.textile +686 -0
- data/Rakefile +48 -0
- data/VERSION +1 -0
- data/config/database.yml +4 -0
- data/development.sqlite3 +0 -0
- data/lib/trole/adapters/active_record/config.rb +23 -0
- data/lib/trole/adapters/active_record/storage.rb +0 -0
- data/lib/trole/adapters/active_record/strategy.rb +0 -0
- data/lib/trole/adapters/active_record.rb +8 -0
- data/lib/trole/adapters/mongoid/config.rb +34 -0
- data/lib/trole/adapters/mongoid/storage.rb +0 -0
- data/lib/trole/adapters/mongoid/strategy.rb +0 -0
- data/lib/trole/adapters/mongoid.rb +0 -0
- data/lib/trole/api/cache.rb +9 -0
- data/lib/trole/api/config.rb +12 -0
- data/lib/trole/api/core.rb +20 -0
- data/lib/trole/api/event.rb +9 -0
- data/lib/trole/api/read.rb +14 -0
- data/lib/trole/api/validation.rb +9 -0
- data/lib/trole/api/write.rb +25 -0
- data/lib/trole/api.rb +41 -0
- data/lib/trole/config.rb +15 -0
- data/lib/trole/macros.rb +5 -0
- data/lib/trole/operations/read.rb +12 -0
- data/lib/trole/operations/write.rb +11 -0
- data/lib/trole/operations.rb +34 -0
- data/lib/trole/storage/base_one.rb +46 -0
- data/lib/trole/storage/bit_one.rb +43 -0
- data/lib/trole/storage/embed_one.rb +36 -0
- data/lib/trole/storage/ref_one.rb +39 -0
- data/lib/trole/storage/string_one.rb +50 -0
- data/lib/trole/storage.rb +14 -0
- data/lib/trole/strategy.rb +35 -0
- data/lib/trole.rb +10 -0
- data/lib/troles/adapters/active_record/Design Notes.textile +4 -0
- data/lib/troles/adapters/active_record/config.rb +51 -0
- data/lib/troles/adapters/active_record/storage/embed_many.rb +8 -0
- data/lib/troles/adapters/active_record/storage.rb +5 -0
- data/lib/troles/adapters/active_record/strategy.rb +11 -0
- data/lib/troles/adapters/active_record.rb +8 -0
- data/lib/troles/adapters/mongoid/Design Notes.textile +3 -0
- data/lib/troles/adapters/mongoid/config.rb +45 -0
- data/lib/troles/adapters/mongoid.rb +8 -0
- data/lib/troles/api/cache.rb +4 -0
- data/lib/troles/api/config.rb +9 -0
- data/lib/troles/api/core.rb +9 -0
- data/lib/troles/api/event.rb +4 -0
- data/lib/troles/api/read.rb +4 -0
- data/lib/troles/api/validation.rb +4 -0
- data/lib/troles/api/write.rb +4 -0
- data/lib/troles/api.rb +40 -0
- data/lib/troles/common/api/cache.rb +12 -0
- data/lib/troles/common/api/config.rb +4 -0
- data/lib/troles/common/api/core.rb +52 -0
- data/lib/troles/common/api/event.rb +39 -0
- data/lib/troles/common/api/read.rb +44 -0
- data/lib/troles/common/api/validation.rb +44 -0
- data/lib/troles/common/api/write.rb +76 -0
- data/lib/troles/common/api.rb +28 -0
- data/lib/troles/common/config/schema.rb +72 -0
- data/lib/troles/common/config/schema_helpers.rb +95 -0
- data/lib/troles/common/config/static_roles.rb +14 -0
- data/lib/troles/common/config/valid_roles.rb +21 -0
- data/lib/troles/common/config.rb +96 -0
- data/lib/troles/common/dependencies.rb +9 -0
- data/lib/troles/common/event_manager.rb +40 -0
- data/lib/troles/common/macros/configuration/base_loader.rb +40 -0
- data/lib/troles/common/macros/configuration/config_loader.rb +19 -0
- data/lib/troles/common/macros/configuration/storage_loader.rb +20 -0
- data/lib/troles/common/macros/configuration/strategy_loader.rb +38 -0
- data/lib/troles/common/macros/configuration.rb +89 -0
- data/lib/troles/common/macros/static_roles.rb +9 -0
- data/lib/troles/common/macros/strategy_options.rb +21 -0
- data/lib/troles/common/macros.rb +38 -0
- data/lib/troles/common/marshaller/bitmask.rb +43 -0
- data/lib/troles/common/marshaller/generic.rb +24 -0
- data/lib/troles/common/marshaller.rb +14 -0
- data/lib/troles/common/operations/read.rb +28 -0
- data/lib/troles/common/operations/write.rb +42 -0
- data/lib/troles/common/operations.rb +33 -0
- data/lib/troles/common/storage.rb +73 -0
- data/lib/troles/common.rb +17 -0
- data/lib/troles/config.rb +15 -0
- data/lib/troles/macros.rb +7 -0
- data/lib/troles/meta.rb +5 -0
- data/lib/troles/operations/read.rb +6 -0
- data/lib/troles/operations/write.rb +6 -0
- data/lib/troles/operations.rb +12 -0
- data/lib/troles/storage/base_many.rb +25 -0
- data/lib/troles/storage/bit_many.rb +56 -0
- data/lib/troles/storage/embed_many.rb +58 -0
- data/lib/troles/storage/ref_many.rb +44 -0
- data/lib/troles/storage/string_many.rb +41 -0
- data/lib/troles/storage.rb +13 -0
- data/lib/troles/strategy.rb +34 -0
- data/lib/troles.rb +11 -0
- data/playbox/old_rake +25 -0
- data/spec/Guide to running specs.textile +16 -0
- data/spec/active_record/migrations/many/bit_many.rb +16 -0
- data/spec/active_record/migrations/many/ref_many.rb +31 -0
- data/spec/active_record/migrations/many/string_many.rb +16 -0
- data/spec/active_record/migrations/one/bit_one.rb +14 -0
- data/spec/active_record/migrations/one/ref_one.rb +20 -0
- data/spec/active_record/migrations/one/string_one.rb +14 -0
- data/spec/active_record/models/ref_many.rb +10 -0
- data/spec/active_record/models/ref_one.rb +10 -0
- data/spec/active_record/models/role.rb +2 -0
- data/spec/active_record/models/user.rb +5 -0
- data/spec/active_record/models.rb +2 -0
- data/spec/active_record/strategies/many/bit_many_spec.rb +41 -0
- data/spec/active_record/strategies/many/ref_many_spec.rb +45 -0
- data/spec/active_record/strategies/many/string_many_spec.rb +39 -0
- data/spec/active_record/strategies/one/bit_one_spec.rb +35 -0
- data/spec/active_record/strategies/one/ref_one_spec.rb +41 -0
- data/spec/active_record/strategies/one/string_one_spec.rb +35 -0
- data/spec/active_record/strategy_helper.rb +4 -0
- data/spec/active_record_helper.rb +50 -0
- data/spec/db/database.yml +4 -0
- data/spec/dummy/Gemfile.lock +108 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/images/rails.png +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +9 -0
- data/spec/dummy/app/assets/stylesheets/application.css +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/main_controller.rb +16 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/spec/dummy/app/models/ref_many_user.rb +7 -0
- data/spec/dummy/app/models/ref_one_user.rb +3 -0
- data/spec/dummy/app/models/role.rb +4 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/main/index.html.erb +3 -0
- data/spec/dummy/config/application.rb +54 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +24 -0
- data/spec/dummy/config/environments/production.rb +52 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/troles.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +12 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +60 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/migrate/01_create_roles.rb +14 -0
- data/spec/dummy/db/migrate/02_create_ref_many_users.rb +20 -0
- data/spec/dummy/db/schema.rb +32 -0
- data/spec/dummy/db/seeds.rb +4 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/dummy_spec_helper.rb +33 -0
- data/spec/factories.rb +8 -0
- data/spec/generic/models/accounts/admin_account.rb +7 -0
- data/spec/generic/models/accounts/blogger_account.rb +7 -0
- data/spec/generic/models/accounts/user_account.rb +7 -0
- data/spec/generic/models/accounts.rb +1 -0
- data/spec/generic/models/base_user.rb +27 -0
- data/spec/generic/models/role.rb +37 -0
- data/spec/generic/models/user.rb +7 -0
- data/spec/generic/models.rb +3 -0
- data/spec/integration/navigation_spec.rb +9 -0
- data/spec/integration/troles/Running dummy tests.textile +35 -0
- data/spec/integration/troles/navigation_spec.rb +49 -0
- data/spec/mongoid/models/ref_many.rb +15 -0
- data/spec/mongoid/models/ref_one.rb +15 -0
- data/spec/mongoid/models/role.rb +5 -0
- data/spec/mongoid/models/user.rb +9 -0
- data/spec/mongoid/models.rb +2 -0
- data/spec/mongoid/strategies/many/bit_many_spec.rb +35 -0
- data/spec/mongoid/strategies/many/ref_many_spec.rb +35 -0
- data/spec/mongoid/strategies/many/string_many_spec.rb +30 -0
- data/spec/mongoid/strategies/one/bit_one_spec.rb +26 -0
- data/spec/mongoid/strategies/one/ref_one_spec.rb +31 -0
- data/spec/mongoid/strategies/one/string_one_spec.rb +26 -0
- data/spec/mongoid/strategy_helper.rb +4 -0
- data/spec/mongoid_helper.rb +19 -0
- data/spec/playbox/rspec_examples.rb +381 -0
- data/spec/support/shared_examples.rb +1 -0
- data/spec/trole/Trole Design.textile +4 -0
- data/spec/trole/api/cache_api_spec.rb +2 -0
- data/spec/trole/api/core_api_spec.rb +4 -0
- data/spec/trole/api/event_api.rb +2 -0
- data/spec/trole/api/operations_api_spec.rb +2 -0
- data/spec/trole/api/read_api_spec.rb +5 -0
- data/spec/trole/api/validation_api_spec.rb +2 -0
- data/spec/trole/api/write_api_spec.rb +2 -0
- data/spec/trole/api_spec.rb +60 -0
- data/spec/trole/multi_roles_spec.rb +163 -0
- data/spec/trole/operations/read_spec.rb +18 -0
- data/spec/trole/operations/write_spec.rb +0 -0
- data/spec/trole/playbox/shared_examples.rb +107 -0
- data/spec/trole/strategies/bit_one_spec.rb +22 -0
- data/spec/trole/strategies/embed_one_spec.rb +32 -0
- data/spec/trole/strategies/ref_one_spec.rb +29 -0
- data/spec/trole/strategies/string_one_spec.rb +26 -0
- data/spec/trole/strategy_helper.rb +3 -0
- data/spec/trole/two_roles_spec.rb +76 -0
- data/spec/trole_spec.rb +12 -0
- data/spec/trole_spec_helper.rb +20 -0
- data/spec/troles/api/cache_api_spec.rb +2 -0
- data/spec/troles/api/core_api_spec.rb +4 -0
- data/spec/troles/api/event_api.rb +2 -0
- data/spec/troles/api/read_api_spec.rb +2 -0
- data/spec/troles/api/validation_api_spec.rb +2 -0
- data/spec/troles/api/write_api_spec.rb +2 -0
- data/spec/troles/api_spec.rb +41 -0
- data/spec/troles/common/api/cache_api_spec.rb +31 -0
- data/spec/troles/common/api/config_api.rb +0 -0
- data/spec/troles/common/api/core_api_spec.rb +14 -0
- data/spec/troles/common/api/event_api_spec.rb +9 -0
- data/spec/troles/common/api/operations_api_spec.rb +55 -0
- data/spec/troles/common/api/read_api_spec.rb +23 -0
- data/spec/troles/common/api/validation_api_spec.rb +46 -0
- data/spec/troles/common/api/write_api_spec.rb +81 -0
- data/spec/troles/common/api_spec.rb +101 -0
- data/spec/troles/common/config_spec.rb +11 -0
- data/spec/troles/common/multi_roles_spec.rb +142 -0
- data/spec/troles/marshaller/bitmask_spec.rb +14 -0
- data/spec/troles/operations/read_ops_spec.rb +0 -0
- data/spec/troles/operations/write_ops_spec.rb +0 -0
- data/spec/troles/playbox/shared_examples.rb +68 -0
- data/spec/troles/strategies/bit_many_spec.rb +30 -0
- data/spec/troles/strategies/embed_many_spec.rb +35 -0
- data/spec/troles/strategies/ref_many_spec.rb +36 -0
- data/spec/troles/strategies/string_many_spec.rb +32 -0
- data/spec/troles/strategy_helper.rb +3 -0
- data/spec/troles_spec.rb +10 -0
- data/troles.gemspec +325 -0
- metadata +469 -0
@@ -0,0 +1,35 @@
|
|
1
|
+
require "mongoid/strategy_helper"
|
2
|
+
|
3
|
+
User.troles_strategy :bit_many do |c|
|
4
|
+
c.valid_roles = [:user, :admin, :blogger, :editor]
|
5
|
+
end.configure!
|
6
|
+
|
7
|
+
module UserSetup
|
8
|
+
def create_no_roles_user
|
9
|
+
Factory.create :user, :name => 'no roles', :troles => 0
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_user
|
13
|
+
Factory.create :user, :name => 'normal', :troles => 1
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_admin_user
|
17
|
+
Factory.create :user, :name => 'admin', :troles => 2
|
18
|
+
end
|
19
|
+
|
20
|
+
def create_complex_user
|
21
|
+
Factory.create :user, :name => 'user and admin', :troles => 3
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
require 'troles/common/api_spec' # Common API examples
|
27
|
+
|
28
|
+
describe 'Troles strategy :bit_many' do
|
29
|
+
after do
|
30
|
+
CreateBitMany.down
|
31
|
+
end
|
32
|
+
|
33
|
+
it_should_behave_like "Common API"
|
34
|
+
# it_should_behave_like "Troles API"
|
35
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "mongoid/strategy_helper"
|
2
|
+
|
3
|
+
User.troles_strategy :ref_many do |c|
|
4
|
+
c.valid_roles = [:user, :admin, :blogger, :editor]
|
5
|
+
end.configure!
|
6
|
+
|
7
|
+
module UserSetup
|
8
|
+
def find_role name
|
9
|
+
Role.where(:name => name.to_sym).first
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_no_roles_user
|
13
|
+
Factory.create :user, :name => 'no roles', :troles => []
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_user
|
17
|
+
Factory.create :user, :name => 'normal', :troles => [ find_role(:user) ]
|
18
|
+
end
|
19
|
+
|
20
|
+
def create_admin_user
|
21
|
+
Factory.create :user, :name => 'admin', :troles => [ find_role(:admin) ]
|
22
|
+
end
|
23
|
+
|
24
|
+
def create_complex_user
|
25
|
+
Factory.create :user, :name => 'user and admin', :troles => [ find_role(:user), find_role(:admin) ]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
require 'troles/common/api_spec' # Common API examples
|
31
|
+
|
32
|
+
describe 'Troles strategy :ref_many' do
|
33
|
+
it_should_behave_like "Common API"
|
34
|
+
# it_should_behave_like "Troles API"
|
35
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "mongoid/strategy_helper"
|
2
|
+
|
3
|
+
User.troles_strategy :string_many do |c|
|
4
|
+
c.valid_roles = [:user, :admin, :blogger, :editor]
|
5
|
+
end.configure!
|
6
|
+
|
7
|
+
module UserSetup
|
8
|
+
def create_no_roles_user
|
9
|
+
Factory.create :user, :name => 'no roles', :troles => ''
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_user
|
13
|
+
Factory.create :user, :name => 'normal', :troles => 'user'
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_admin_user
|
17
|
+
Factory.create :user, :name => 'admin', :troles => 'admin'
|
18
|
+
end
|
19
|
+
|
20
|
+
def create_complex_user
|
21
|
+
Factory.create :user, :name => 'user and admin', :troles => 'user,admin'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'troles/common/api_spec' # Common API examples
|
26
|
+
|
27
|
+
describe 'Troles strategy :string_many' do
|
28
|
+
it_should_behave_like "Common API"
|
29
|
+
# it_should_behave_like "Troles API"
|
30
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "mongoid/strategy_helper"
|
2
|
+
|
3
|
+
User.troles_strategy :bit_one do |c|
|
4
|
+
c.valid_roles = [:user, :admin]
|
5
|
+
end.configure!
|
6
|
+
|
7
|
+
module UserSetup
|
8
|
+
def create_no_roles_user
|
9
|
+
Factory.create :user, :name => 'no roles', :trole => false
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_user
|
13
|
+
Factory.create :user, :name => 'normal', :trole => false
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_admin_user
|
17
|
+
Factory.create :user, :name => 'admin', :trole => true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'troles/common/api_spec' # Common API examples
|
22
|
+
|
23
|
+
describe 'Troles strategy :bit_one' do
|
24
|
+
it_should_behave_like "Common API"
|
25
|
+
# it_should_behave_like "Troles API"
|
26
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "mongoid/strategy_helper"
|
2
|
+
|
3
|
+
User.troles_strategy :ref_one, :orm => :active_record do |c|
|
4
|
+
c.valid_roles = [:user, :admin, :blogger, :editor]
|
5
|
+
end.configure!
|
6
|
+
|
7
|
+
module UserSetup
|
8
|
+
def find_role name
|
9
|
+
Role.where(:name => name.to_sym).first
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_no_roles_user
|
13
|
+
Factory.create :user, :name => 'no roles', :trole => nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_user
|
17
|
+
Factory.create :user, :name => 'normal', :trole => find_role(:user)
|
18
|
+
end
|
19
|
+
|
20
|
+
def create_admin_user
|
21
|
+
Factory.create :user, :name => 'admin', :trole => find_role(:admin)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
require 'troles/common/api_spec' # Common API examples
|
27
|
+
|
28
|
+
describe 'Troles strategy :ref_one' do
|
29
|
+
it_should_behave_like "Common API"
|
30
|
+
# it_should_behave_like "Troles API"
|
31
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "mongoid/strategy_helper"
|
2
|
+
|
3
|
+
User.troles_strategy :string_one do |c|
|
4
|
+
c.valid_roles = [:user, :admin, :blogger, :editor]
|
5
|
+
end.configure!
|
6
|
+
|
7
|
+
module UserSetup
|
8
|
+
def create_no_roles_user
|
9
|
+
Factory.create :user, :name => 'no roles', :trole => ''
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_user
|
13
|
+
Factory.create :user, :name => 'normal', :trole => 'user'
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_admin_user
|
17
|
+
Factory.create :user, :name => 'admin', :trole => 'admin'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'troles/common/api_spec' # Common API examples
|
22
|
+
|
23
|
+
describe 'Troles strategy :string_one' do
|
24
|
+
it_should_behave_like "Common API"
|
25
|
+
# it_should_behave_like "Troles API"
|
26
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'troles'
|
2
|
+
require 'trole_spec_helper'
|
3
|
+
require 'mongoid'
|
4
|
+
require 'bson'
|
5
|
+
require 'mongoid/models'
|
6
|
+
|
7
|
+
Troles::Config.default_orm = :mongoid
|
8
|
+
Troles::Config.auto_load = true
|
9
|
+
|
10
|
+
Mongoid.configure.master = Mongo::Connection.new.db('troles_mongoid')
|
11
|
+
|
12
|
+
Mongoid.database.collections.each do |coll|
|
13
|
+
coll.remove
|
14
|
+
end
|
15
|
+
|
16
|
+
RSpec.configure do |config|
|
17
|
+
config.mock_with :mocha
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,381 @@
|
|
1
|
+
# RSpec Examples (RSpec Book, The Rails 3 Way, Custom)
|
2
|
+
|
3
|
+
# http://eggsonbread.com/2010/03/28/my-rspec-best-practices-and-tips/
|
4
|
+
|
5
|
+
################################################################################
|
6
|
+
# command line
|
7
|
+
# rspec --help (show help)
|
8
|
+
# rake -T spec (list all rspec-rails rake tasks)
|
9
|
+
# rspec spec (run all specs in spec folder)
|
10
|
+
# rspec spec/models/user_spec.rb (run only user_spec)
|
11
|
+
# rake spec:models (rails: run all model specs)
|
12
|
+
|
13
|
+
################################################################################
|
14
|
+
# configuration
|
15
|
+
|
16
|
+
# global before/after/around hooks
|
17
|
+
# (:each, :all, :suite)
|
18
|
+
RSpec.configure do |config|
|
19
|
+
config.after :suite do
|
20
|
+
Mongoid.master.collections.select do |collection|
|
21
|
+
collection.name !~ /system/
|
22
|
+
end.each(&:drop)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# inclusion filter
|
27
|
+
RSpec.configure do |c|
|
28
|
+
c.filter = { :focus => true }
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "group" do
|
32
|
+
it "example 1", :focus => true do
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# exclusion filter
|
38
|
+
RSpec.configure do |c|
|
39
|
+
c.exclusion_filter = { :slow => true }
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "group", :slow => true do
|
43
|
+
it "example 1" do
|
44
|
+
end
|
45
|
+
it "example 2" do
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# lambda filter
|
50
|
+
require 'ping'
|
51
|
+
RSpec.configure do |c|
|
52
|
+
c.exclusion_filter = {
|
53
|
+
:if => lambda { |what|
|
54
|
+
case what
|
55
|
+
when :network_available
|
56
|
+
!Ping.pingecho "example.com", 10, 80
|
57
|
+
end
|
58
|
+
}
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "network group" do
|
63
|
+
it "example 1", :if => :network_available do
|
64
|
+
end
|
65
|
+
it "example 2" do
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
################################################################################
|
70
|
+
# describe/context (describe for things, context (alias) for context)
|
71
|
+
describe User do
|
72
|
+
|
73
|
+
context "#create" do
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
################################################################################
|
80
|
+
# pending (instead of adding comment to disable example)
|
81
|
+
describe User do
|
82
|
+
before { pending }
|
83
|
+
|
84
|
+
it "should be successful" do
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "an empty array" do
|
90
|
+
it "should be empty" do
|
91
|
+
pending("bug report 18976") do
|
92
|
+
[].should be_empty
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
################################################################################
|
98
|
+
# before, after, around (before(:each) executed before each example)
|
99
|
+
describe Stack do
|
100
|
+
context "when empty" do
|
101
|
+
before(:each) do
|
102
|
+
@stack = Stack.new
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
################################################################################
|
108
|
+
# helper methods
|
109
|
+
describe Thing do
|
110
|
+
def create_thing(options)
|
111
|
+
thing = Thing.new
|
112
|
+
thing.set_status(options[:status])
|
113
|
+
thing
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe Thing do
|
118
|
+
def given_thing_with(options)
|
119
|
+
yield Thing.new do |thing|
|
120
|
+
thing.set_status(options[:status])
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should do something when ok" do
|
125
|
+
given_thing_with(:status => 'ok') do |thing|
|
126
|
+
thing.do_fancy_stuff(1, true, :move => 'left', :obstacles => nil)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
################################################################################
|
132
|
+
# helper modules
|
133
|
+
module UserExampleHelpers
|
134
|
+
def create_valid_user
|
135
|
+
User.new(:email => 'email@example.com', :password => 'shhhhh')
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
describe User do
|
140
|
+
include UserExampleHelpers
|
141
|
+
it "does something when it is valid" do
|
142
|
+
user = create_valid_user
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# or include in all example groups
|
147
|
+
RSpec.configure do |config|
|
148
|
+
config.include(UserExampleHelpers)
|
149
|
+
end
|
150
|
+
|
151
|
+
################################################################################
|
152
|
+
# shared examples
|
153
|
+
# spec/support/shared_examples.rb
|
154
|
+
shared_examples_for "a phone field" do
|
155
|
+
it "has 10 digits" do
|
156
|
+
Business.new(phone_field => '8004567890').should
|
157
|
+
have(:no).errors_on(phone_field)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
describe "phone" do
|
162
|
+
let(:phone_field) { :phone }
|
163
|
+
it_should_behave_like "a phone field"
|
164
|
+
end
|
165
|
+
|
166
|
+
################################################################################
|
167
|
+
# let (instead of instance variables in before block)
|
168
|
+
let(:blog_post) { BlogPost.create :title => 'Hello' }
|
169
|
+
let!(:comment) { blog_post.comments.create :text => 'first post' }
|
170
|
+
|
171
|
+
################################################################################
|
172
|
+
# specify (generated descriptions)
|
173
|
+
# instead of repeating expectation with: it "should not be published"...)
|
174
|
+
specify { blog_post.should_not be_published }
|
175
|
+
|
176
|
+
################################################################################
|
177
|
+
# subject (delegate should/should_not to subject)
|
178
|
+
subject { BlogPost.new :title => 'foo', :body => 'bar' }
|
179
|
+
it "sets published timestamp" do
|
180
|
+
subject.publish!
|
181
|
+
subject.should be_published
|
182
|
+
end
|
183
|
+
|
184
|
+
it { should be_valid }
|
185
|
+
its(:errors) { should be_empty }
|
186
|
+
its(:title) { should == 'foo' }
|
187
|
+
its(:body) { should == 'bar' }
|
188
|
+
its(:published_on) { should == Date.today }
|
189
|
+
|
190
|
+
################################################################################
|
191
|
+
# matchers
|
192
|
+
# be
|
193
|
+
target.should be
|
194
|
+
target.should be_true
|
195
|
+
target.should be_false
|
196
|
+
target.should be_nil
|
197
|
+
target.should_not be_nil
|
198
|
+
thing.should be # passes if thing is not nil or false
|
199
|
+
collection.should be_empty # passes if target.empty?
|
200
|
+
target.should_not be_empty # passes unless target.empty?
|
201
|
+
target.should_not be_under_age(16) # passes unless target.under_age?(16)
|
202
|
+
user.should be_in_role("admin") # passes if user.in_role?("admin") returns true
|
203
|
+
result.should be_close(5.25, 0.005)
|
204
|
+
|
205
|
+
# be_a, be_an
|
206
|
+
"a string".should be_an_instance_of(String)
|
207
|
+
3.should be_a_kind_of(Fixnum)
|
208
|
+
3.should be_a_kind_of(Numeric)
|
209
|
+
3.should be_an_instance_of(Fixnum)
|
210
|
+
3.should_not be_instance_of(Numeric) #fails
|
211
|
+
|
212
|
+
# operators
|
213
|
+
result.should == 3
|
214
|
+
result.should =~ /some regexp/
|
215
|
+
result.should be < 7
|
216
|
+
result.should be <= 7
|
217
|
+
result.should be >= 7
|
218
|
+
result.should be > 7
|
219
|
+
|
220
|
+
# include
|
221
|
+
[1, 2, 3].should include(1)
|
222
|
+
[1, 2, 3].should_not include(4)
|
223
|
+
"foobar".should include("bar")
|
224
|
+
"foobar".should_not include("baz")
|
225
|
+
|
226
|
+
# have
|
227
|
+
{:foo => "foo"}.should have_key(:foo)
|
228
|
+
{:bar => "bar"}.should_not have_key(:foo)
|
229
|
+
"this string".should have(11).characters
|
230
|
+
[1, 2, 3].should have(3).items
|
231
|
+
schedule.should have(3).days # passes if schedule.days.length == 3
|
232
|
+
home_team.should have(9).players_on(field) # delegates players_on to home_team
|
233
|
+
widget.should have(1).error_on(:name)
|
234
|
+
model.should have(:no).errors_on(:title)
|
235
|
+
model.should have(1).record
|
236
|
+
day.should have_exactly(24).hours
|
237
|
+
dozen_bagels.should have_at_least(12).bagels
|
238
|
+
internet.should have_at_most(2037).killer_social_networking_apps
|
239
|
+
|
240
|
+
# respond_to
|
241
|
+
list.should respond_to(:length)
|
242
|
+
|
243
|
+
# errors
|
244
|
+
lambda { Object.new.explode! }.should raise_error(NameError)
|
245
|
+
|
246
|
+
# when all else fails...
|
247
|
+
actual.should satisfy { |actual| block } # passes if block returns true
|
248
|
+
|
249
|
+
################################################################################
|
250
|
+
# expect
|
251
|
+
# for changes
|
252
|
+
expect { BlogPost.create :title => "Hello"}.to change { BlogPost.count }.by(1)
|
253
|
+
expect { seller.accept Offer.new(250_000) }.to change{agent.commission}.by(7_500)
|
254
|
+
expect { blog_post.publish! }.to change { blog_post.published_on }.from(nil).to(Date.today)
|
255
|
+
expect { subject.update_with_omniauth(omniauth) }.to_not change { subject.score }
|
256
|
+
|
257
|
+
# for errors
|
258
|
+
expect { do_something_risky }.to raise_error
|
259
|
+
expect { account.withdraw 75, :dollars }.to raise_error(/attempted to withdraw 75 dollars/)
|
260
|
+
expect { account.withdraw 75, :dollars }.to raise_error(InsufficientFundsError)
|
261
|
+
|
262
|
+
course = Course.new(:seats => 20)
|
263
|
+
20.times { course.register Student.new }
|
264
|
+
lambda {
|
265
|
+
course.register Student.new
|
266
|
+
}.should throw_symbol(:course_full, 20)
|
267
|
+
|
268
|
+
################################################################################
|
269
|
+
# custom matcher dsl
|
270
|
+
# joe.reports_to?(beatrice).should be_true
|
271
|
+
joe.should report_to(beatrice)
|
272
|
+
|
273
|
+
RSpec::Matchers.define :report_to do |boss|
|
274
|
+
match do |employee|
|
275
|
+
employee.reports_to?(boss)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
################################################################################
|
280
|
+
# doubles/stubs/mocks (aliases)
|
281
|
+
# doubles/stubs: method stubs (stub(:method).and_return(data))
|
282
|
+
# mocks: expectations (should_receive...)
|
283
|
+
describe Statement do
|
284
|
+
it "uses the customer's name in the header" do
|
285
|
+
customer = double('customer')
|
286
|
+
customer.stub(:name).and_return('Aslak')
|
287
|
+
statement = Statement.new(customer)
|
288
|
+
statement.generate.should =~ /^Statement for Aslak/
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
# shortcut
|
293
|
+
customer = double('customer', :name => 'Aslak')
|
294
|
+
|
295
|
+
# null object
|
296
|
+
null_object = mock('null', :null_object => true)
|
297
|
+
|
298
|
+
# fakes
|
299
|
+
ages = double('ages')
|
300
|
+
ages.stub(:age_for) do |what|
|
301
|
+
if what == 'drinking'
|
302
|
+
21
|
303
|
+
elsif what == 'voting'
|
304
|
+
18
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
# stub chains
|
309
|
+
article = double()
|
310
|
+
Article.stub_chain(:recent, :published, :authored_by).and_return(article)
|
311
|
+
|
312
|
+
# partial stubbing/mocking
|
313
|
+
describe WidgetsController do
|
314
|
+
describe "PUT update with valid attributes" do
|
315
|
+
# partial stubbing
|
316
|
+
it "redirects to the list of widgets" do
|
317
|
+
widget = Widget.new()
|
318
|
+
Widget.stub(:find).and_return(widget)
|
319
|
+
widget.stub(:update_attributes).and_return(true)
|
320
|
+
put :update, :id => 37
|
321
|
+
response.should redirect_to(widgets_path)
|
322
|
+
end
|
323
|
+
# partial mocking
|
324
|
+
it "updates the widget's attributes" do
|
325
|
+
widget = Widget.new()
|
326
|
+
Widget.stub(:find).and_return(widget)
|
327
|
+
widget.should_receive(:update_attributes).and_return(true)
|
328
|
+
put :update, :id => 37
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
# expectations
|
334
|
+
echo = mock('echo')
|
335
|
+
echo.should_receive(:sound).with("hey").and_return("hey")
|
336
|
+
echo.should_receive(:sound).with("hey") { "hey" }
|
337
|
+
mock_account.should_receive(:withdraw).exactly(1).times
|
338
|
+
network_double.should_receive(:open_connection).at_most(5).times
|
339
|
+
network_double.should_receive(:open_connection).at_least(2).times
|
340
|
+
account_double.should_receive(:withdraw).once
|
341
|
+
account_double.should_receive(:deposit).twice
|
342
|
+
checking_account.should_receive(:transfer).with(50, savings_account)
|
343
|
+
source_account.should_receive(:transfer).with(target_account, instance_of(Fixnum))
|
344
|
+
source_account.should_receive(:transfer).with(anything(), 50)
|
345
|
+
source_account.should_receive(:transfer).with(any_args())
|
346
|
+
collaborator.should_receive(:message).with(no_args())
|
347
|
+
mock_account.should_receive(:add_payment_accounts).with(hash_including('Electric' => '123', 'Gas' => '234'))
|
348
|
+
mock_account.should_receive(:add_payment_accounts).with(hash_not_including('Electric' => '123', 'Gas' => '234'))
|
349
|
+
mock_atm.should_receive(:login).with(/.* User/)
|
350
|
+
network_double.should_not_receive(:open_connection)
|
351
|
+
network_double.should_receive(:open_connection).never
|
352
|
+
|
353
|
+
# ordering (ensure count is called before add)
|
354
|
+
database.should_receive(:count).with('Roster', :course_id => 37).ordered
|
355
|
+
database.should_receive(:add).with(student).ordered
|
356
|
+
|
357
|
+
# errors
|
358
|
+
account_double.should_receive(:withdraw).and_raise
|
359
|
+
account_double.should_receive(:withdraw).and_raise(InsufficientFunds)
|
360
|
+
account_double.should_receive(:withdraw).and_throw(:insufficient_funds)
|
361
|
+
|
362
|
+
# custom argument matchers
|
363
|
+
class GreaterThanMatcher
|
364
|
+
def initialize(expected)
|
365
|
+
@expected = expected
|
366
|
+
end
|
367
|
+
|
368
|
+
def description
|
369
|
+
"a number greater than #{@expected}"
|
370
|
+
end
|
371
|
+
|
372
|
+
def ==(actual)
|
373
|
+
actual > @expected
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
def greater_than(floor)
|
378
|
+
GreaterThanMatcher.new(floor)
|
379
|
+
end
|
380
|
+
|
381
|
+
calculator.should_receive(:add).with(greater_than(37))
|
@@ -0,0 +1 @@
|
|
1
|
+
|