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.
Files changed (243) hide show
  1. data/.rspec +1 -0
  2. data/Gemfile +26 -0
  3. data/Gemfile.lock +161 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.textile +686 -0
  6. data/Rakefile +48 -0
  7. data/VERSION +1 -0
  8. data/config/database.yml +4 -0
  9. data/development.sqlite3 +0 -0
  10. data/lib/trole/adapters/active_record/config.rb +23 -0
  11. data/lib/trole/adapters/active_record/storage.rb +0 -0
  12. data/lib/trole/adapters/active_record/strategy.rb +0 -0
  13. data/lib/trole/adapters/active_record.rb +8 -0
  14. data/lib/trole/adapters/mongoid/config.rb +34 -0
  15. data/lib/trole/adapters/mongoid/storage.rb +0 -0
  16. data/lib/trole/adapters/mongoid/strategy.rb +0 -0
  17. data/lib/trole/adapters/mongoid.rb +0 -0
  18. data/lib/trole/api/cache.rb +9 -0
  19. data/lib/trole/api/config.rb +12 -0
  20. data/lib/trole/api/core.rb +20 -0
  21. data/lib/trole/api/event.rb +9 -0
  22. data/lib/trole/api/read.rb +14 -0
  23. data/lib/trole/api/validation.rb +9 -0
  24. data/lib/trole/api/write.rb +25 -0
  25. data/lib/trole/api.rb +41 -0
  26. data/lib/trole/config.rb +15 -0
  27. data/lib/trole/macros.rb +5 -0
  28. data/lib/trole/operations/read.rb +12 -0
  29. data/lib/trole/operations/write.rb +11 -0
  30. data/lib/trole/operations.rb +34 -0
  31. data/lib/trole/storage/base_one.rb +46 -0
  32. data/lib/trole/storage/bit_one.rb +43 -0
  33. data/lib/trole/storage/embed_one.rb +36 -0
  34. data/lib/trole/storage/ref_one.rb +39 -0
  35. data/lib/trole/storage/string_one.rb +50 -0
  36. data/lib/trole/storage.rb +14 -0
  37. data/lib/trole/strategy.rb +35 -0
  38. data/lib/trole.rb +10 -0
  39. data/lib/troles/adapters/active_record/Design Notes.textile +4 -0
  40. data/lib/troles/adapters/active_record/config.rb +51 -0
  41. data/lib/troles/adapters/active_record/storage/embed_many.rb +8 -0
  42. data/lib/troles/adapters/active_record/storage.rb +5 -0
  43. data/lib/troles/adapters/active_record/strategy.rb +11 -0
  44. data/lib/troles/adapters/active_record.rb +8 -0
  45. data/lib/troles/adapters/mongoid/Design Notes.textile +3 -0
  46. data/lib/troles/adapters/mongoid/config.rb +45 -0
  47. data/lib/troles/adapters/mongoid.rb +8 -0
  48. data/lib/troles/api/cache.rb +4 -0
  49. data/lib/troles/api/config.rb +9 -0
  50. data/lib/troles/api/core.rb +9 -0
  51. data/lib/troles/api/event.rb +4 -0
  52. data/lib/troles/api/read.rb +4 -0
  53. data/lib/troles/api/validation.rb +4 -0
  54. data/lib/troles/api/write.rb +4 -0
  55. data/lib/troles/api.rb +40 -0
  56. data/lib/troles/common/api/cache.rb +12 -0
  57. data/lib/troles/common/api/config.rb +4 -0
  58. data/lib/troles/common/api/core.rb +52 -0
  59. data/lib/troles/common/api/event.rb +39 -0
  60. data/lib/troles/common/api/read.rb +44 -0
  61. data/lib/troles/common/api/validation.rb +44 -0
  62. data/lib/troles/common/api/write.rb +76 -0
  63. data/lib/troles/common/api.rb +28 -0
  64. data/lib/troles/common/config/schema.rb +72 -0
  65. data/lib/troles/common/config/schema_helpers.rb +95 -0
  66. data/lib/troles/common/config/static_roles.rb +14 -0
  67. data/lib/troles/common/config/valid_roles.rb +21 -0
  68. data/lib/troles/common/config.rb +96 -0
  69. data/lib/troles/common/dependencies.rb +9 -0
  70. data/lib/troles/common/event_manager.rb +40 -0
  71. data/lib/troles/common/macros/configuration/base_loader.rb +40 -0
  72. data/lib/troles/common/macros/configuration/config_loader.rb +19 -0
  73. data/lib/troles/common/macros/configuration/storage_loader.rb +20 -0
  74. data/lib/troles/common/macros/configuration/strategy_loader.rb +38 -0
  75. data/lib/troles/common/macros/configuration.rb +89 -0
  76. data/lib/troles/common/macros/static_roles.rb +9 -0
  77. data/lib/troles/common/macros/strategy_options.rb +21 -0
  78. data/lib/troles/common/macros.rb +38 -0
  79. data/lib/troles/common/marshaller/bitmask.rb +43 -0
  80. data/lib/troles/common/marshaller/generic.rb +24 -0
  81. data/lib/troles/common/marshaller.rb +14 -0
  82. data/lib/troles/common/operations/read.rb +28 -0
  83. data/lib/troles/common/operations/write.rb +42 -0
  84. data/lib/troles/common/operations.rb +33 -0
  85. data/lib/troles/common/storage.rb +73 -0
  86. data/lib/troles/common.rb +17 -0
  87. data/lib/troles/config.rb +15 -0
  88. data/lib/troles/macros.rb +7 -0
  89. data/lib/troles/meta.rb +5 -0
  90. data/lib/troles/operations/read.rb +6 -0
  91. data/lib/troles/operations/write.rb +6 -0
  92. data/lib/troles/operations.rb +12 -0
  93. data/lib/troles/storage/base_many.rb +25 -0
  94. data/lib/troles/storage/bit_many.rb +56 -0
  95. data/lib/troles/storage/embed_many.rb +58 -0
  96. data/lib/troles/storage/ref_many.rb +44 -0
  97. data/lib/troles/storage/string_many.rb +41 -0
  98. data/lib/troles/storage.rb +13 -0
  99. data/lib/troles/strategy.rb +34 -0
  100. data/lib/troles.rb +11 -0
  101. data/playbox/old_rake +25 -0
  102. data/spec/Guide to running specs.textile +16 -0
  103. data/spec/active_record/migrations/many/bit_many.rb +16 -0
  104. data/spec/active_record/migrations/many/ref_many.rb +31 -0
  105. data/spec/active_record/migrations/many/string_many.rb +16 -0
  106. data/spec/active_record/migrations/one/bit_one.rb +14 -0
  107. data/spec/active_record/migrations/one/ref_one.rb +20 -0
  108. data/spec/active_record/migrations/one/string_one.rb +14 -0
  109. data/spec/active_record/models/ref_many.rb +10 -0
  110. data/spec/active_record/models/ref_one.rb +10 -0
  111. data/spec/active_record/models/role.rb +2 -0
  112. data/spec/active_record/models/user.rb +5 -0
  113. data/spec/active_record/models.rb +2 -0
  114. data/spec/active_record/strategies/many/bit_many_spec.rb +41 -0
  115. data/spec/active_record/strategies/many/ref_many_spec.rb +45 -0
  116. data/spec/active_record/strategies/many/string_many_spec.rb +39 -0
  117. data/spec/active_record/strategies/one/bit_one_spec.rb +35 -0
  118. data/spec/active_record/strategies/one/ref_one_spec.rb +41 -0
  119. data/spec/active_record/strategies/one/string_one_spec.rb +35 -0
  120. data/spec/active_record/strategy_helper.rb +4 -0
  121. data/spec/active_record_helper.rb +50 -0
  122. data/spec/db/database.yml +4 -0
  123. data/spec/dummy/Gemfile.lock +108 -0
  124. data/spec/dummy/Rakefile +7 -0
  125. data/spec/dummy/app/assets/images/rails.png +0 -0
  126. data/spec/dummy/app/assets/javascripts/application.js +9 -0
  127. data/spec/dummy/app/assets/stylesheets/application.css +7 -0
  128. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  129. data/spec/dummy/app/controllers/main_controller.rb +16 -0
  130. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  131. data/spec/dummy/app/mailers/.gitkeep +0 -0
  132. data/spec/dummy/app/models/.gitkeep +0 -0
  133. data/spec/dummy/app/models/ref_many_user.rb +7 -0
  134. data/spec/dummy/app/models/ref_one_user.rb +3 -0
  135. data/spec/dummy/app/models/role.rb +4 -0
  136. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  137. data/spec/dummy/app/views/main/index.html.erb +3 -0
  138. data/spec/dummy/config/application.rb +54 -0
  139. data/spec/dummy/config/boot.rb +10 -0
  140. data/spec/dummy/config/database.yml +25 -0
  141. data/spec/dummy/config/environment.rb +5 -0
  142. data/spec/dummy/config/environments/development.rb +24 -0
  143. data/spec/dummy/config/environments/production.rb +52 -0
  144. data/spec/dummy/config/environments/test.rb +39 -0
  145. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  146. data/spec/dummy/config/initializers/inflections.rb +10 -0
  147. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  148. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  149. data/spec/dummy/config/initializers/session_store.rb +8 -0
  150. data/spec/dummy/config/initializers/troles.rb +3 -0
  151. data/spec/dummy/config/initializers/wrap_parameters.rb +12 -0
  152. data/spec/dummy/config/locales/en.yml +5 -0
  153. data/spec/dummy/config/routes.rb +60 -0
  154. data/spec/dummy/config.ru +4 -0
  155. data/spec/dummy/db/migrate/01_create_roles.rb +14 -0
  156. data/spec/dummy/db/migrate/02_create_ref_many_users.rb +20 -0
  157. data/spec/dummy/db/schema.rb +32 -0
  158. data/spec/dummy/db/seeds.rb +4 -0
  159. data/spec/dummy/log/.gitkeep +0 -0
  160. data/spec/dummy/public/404.html +26 -0
  161. data/spec/dummy/public/422.html +26 -0
  162. data/spec/dummy/public/500.html +26 -0
  163. data/spec/dummy/public/favicon.ico +0 -0
  164. data/spec/dummy/script/rails +6 -0
  165. data/spec/dummy_spec_helper.rb +33 -0
  166. data/spec/factories.rb +8 -0
  167. data/spec/generic/models/accounts/admin_account.rb +7 -0
  168. data/spec/generic/models/accounts/blogger_account.rb +7 -0
  169. data/spec/generic/models/accounts/user_account.rb +7 -0
  170. data/spec/generic/models/accounts.rb +1 -0
  171. data/spec/generic/models/base_user.rb +27 -0
  172. data/spec/generic/models/role.rb +37 -0
  173. data/spec/generic/models/user.rb +7 -0
  174. data/spec/generic/models.rb +3 -0
  175. data/spec/integration/navigation_spec.rb +9 -0
  176. data/spec/integration/troles/Running dummy tests.textile +35 -0
  177. data/spec/integration/troles/navigation_spec.rb +49 -0
  178. data/spec/mongoid/models/ref_many.rb +15 -0
  179. data/spec/mongoid/models/ref_one.rb +15 -0
  180. data/spec/mongoid/models/role.rb +5 -0
  181. data/spec/mongoid/models/user.rb +9 -0
  182. data/spec/mongoid/models.rb +2 -0
  183. data/spec/mongoid/strategies/many/bit_many_spec.rb +35 -0
  184. data/spec/mongoid/strategies/many/ref_many_spec.rb +35 -0
  185. data/spec/mongoid/strategies/many/string_many_spec.rb +30 -0
  186. data/spec/mongoid/strategies/one/bit_one_spec.rb +26 -0
  187. data/spec/mongoid/strategies/one/ref_one_spec.rb +31 -0
  188. data/spec/mongoid/strategies/one/string_one_spec.rb +26 -0
  189. data/spec/mongoid/strategy_helper.rb +4 -0
  190. data/spec/mongoid_helper.rb +19 -0
  191. data/spec/playbox/rspec_examples.rb +381 -0
  192. data/spec/support/shared_examples.rb +1 -0
  193. data/spec/trole/Trole Design.textile +4 -0
  194. data/spec/trole/api/cache_api_spec.rb +2 -0
  195. data/spec/trole/api/core_api_spec.rb +4 -0
  196. data/spec/trole/api/event_api.rb +2 -0
  197. data/spec/trole/api/operations_api_spec.rb +2 -0
  198. data/spec/trole/api/read_api_spec.rb +5 -0
  199. data/spec/trole/api/validation_api_spec.rb +2 -0
  200. data/spec/trole/api/write_api_spec.rb +2 -0
  201. data/spec/trole/api_spec.rb +60 -0
  202. data/spec/trole/multi_roles_spec.rb +163 -0
  203. data/spec/trole/operations/read_spec.rb +18 -0
  204. data/spec/trole/operations/write_spec.rb +0 -0
  205. data/spec/trole/playbox/shared_examples.rb +107 -0
  206. data/spec/trole/strategies/bit_one_spec.rb +22 -0
  207. data/spec/trole/strategies/embed_one_spec.rb +32 -0
  208. data/spec/trole/strategies/ref_one_spec.rb +29 -0
  209. data/spec/trole/strategies/string_one_spec.rb +26 -0
  210. data/spec/trole/strategy_helper.rb +3 -0
  211. data/spec/trole/two_roles_spec.rb +76 -0
  212. data/spec/trole_spec.rb +12 -0
  213. data/spec/trole_spec_helper.rb +20 -0
  214. data/spec/troles/api/cache_api_spec.rb +2 -0
  215. data/spec/troles/api/core_api_spec.rb +4 -0
  216. data/spec/troles/api/event_api.rb +2 -0
  217. data/spec/troles/api/read_api_spec.rb +2 -0
  218. data/spec/troles/api/validation_api_spec.rb +2 -0
  219. data/spec/troles/api/write_api_spec.rb +2 -0
  220. data/spec/troles/api_spec.rb +41 -0
  221. data/spec/troles/common/api/cache_api_spec.rb +31 -0
  222. data/spec/troles/common/api/config_api.rb +0 -0
  223. data/spec/troles/common/api/core_api_spec.rb +14 -0
  224. data/spec/troles/common/api/event_api_spec.rb +9 -0
  225. data/spec/troles/common/api/operations_api_spec.rb +55 -0
  226. data/spec/troles/common/api/read_api_spec.rb +23 -0
  227. data/spec/troles/common/api/validation_api_spec.rb +46 -0
  228. data/spec/troles/common/api/write_api_spec.rb +81 -0
  229. data/spec/troles/common/api_spec.rb +101 -0
  230. data/spec/troles/common/config_spec.rb +11 -0
  231. data/spec/troles/common/multi_roles_spec.rb +142 -0
  232. data/spec/troles/marshaller/bitmask_spec.rb +14 -0
  233. data/spec/troles/operations/read_ops_spec.rb +0 -0
  234. data/spec/troles/operations/write_ops_spec.rb +0 -0
  235. data/spec/troles/playbox/shared_examples.rb +68 -0
  236. data/spec/troles/strategies/bit_many_spec.rb +30 -0
  237. data/spec/troles/strategies/embed_many_spec.rb +35 -0
  238. data/spec/troles/strategies/ref_many_spec.rb +36 -0
  239. data/spec/troles/strategies/string_many_spec.rb +32 -0
  240. data/spec/troles/strategy_helper.rb +3 -0
  241. data/spec/troles_spec.rb +10 -0
  242. data/troles.gemspec +325 -0
  243. metadata +469 -0
@@ -0,0 +1,15 @@
1
+ class User
2
+ include Mongoid::Document
3
+
4
+ belongs_to :trole, :class_name => 'Role'
5
+
6
+ field :name
7
+ end
8
+
9
+ class Role
10
+ include Mongoid::Document
11
+
12
+ has_many :users, :class_name => 'User'
13
+
14
+ field :name
15
+ end
@@ -0,0 +1,5 @@
1
+ class Role
2
+ include Mongoid::Document
3
+
4
+ field :name
5
+ end
@@ -0,0 +1,9 @@
1
+ class User
2
+ include Mongoid::Document
3
+
4
+ field :name
5
+
6
+ def role_list_value
7
+ instance_variable_get "@role_list"
8
+ end
9
+ end
@@ -0,0 +1,2 @@
1
+ require 'mongoid/models/user'
2
+ require 'mongoid/models/role'
@@ -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,4 @@
1
+ require 'mongoid_helper'
2
+ require 'trole'
3
+ require 'troles'
4
+ require 'troles/macros'
@@ -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
+
@@ -0,0 +1,4 @@
1
+ h1. Trole Design
2
+
3
+ Trole should be designed to work with a very generic underlying model. The specs here will use all the strategies listed in the README.
4
+ Some of the strategies require a Role class.
@@ -0,0 +1,2 @@
1
+ shared_examples_for "Trole Cache API" do
2
+ end
@@ -0,0 +1,4 @@
1
+ shared_examples_for "Trole Core API" do
2
+ subject { User }
3
+ its(:role_field) { should == :trole }
4
+ end
@@ -0,0 +1,2 @@
1
+ shared_examples_for "Trole Event API" do
2
+ end
@@ -0,0 +1,2 @@
1
+ shared_examples_for "Trole Operations API" do
2
+ end
@@ -0,0 +1,5 @@
1
+ shared_examples_for "Trole Read API" do
2
+
3
+ subject { user }
4
+ its(:role_name) { should == :user }
5
+ end
@@ -0,0 +1,2 @@
1
+ shared_examples_for "Trole Validation API" do
2
+ end
@@ -0,0 +1,2 @@
1
+ shared_examples_for "Trole Write API" do
2
+ end