patriarch 0.2.2 → 0.2.3

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/.gitignore CHANGED
@@ -1,4 +1,4 @@
1
- redis_reclip_cleaner.rb
1
+ Guardfile
2
2
  spec/dummy
3
3
  stats.svg
4
4
  *.gem
@@ -1,6 +1,5 @@
1
- class Patriarch::Services::<%= class_name %>::AuthorizationService < Patriarch::AuthorizationService
2
- def grant?(transaction_item)
3
- # Insert authorization logic here ...
4
- true
1
+ class Patriarch::Services::<%= class_name %>::AuthorizationService < Patriarch::AuthorizationService
2
+ def grant?(transac)
3
+ super
5
4
  end
6
5
  end
@@ -5,8 +5,54 @@ module Patriarch
5
5
  include Singleton
6
6
 
7
7
  # override if necessary
8
- def grant?(*args)
9
- true
8
+ def grant?(transac)
9
+ # Insert authorization logic here ...
10
+ if verify_types(transac)
11
+ true
12
+ else
13
+ raise "that behaviour is not authorized"
14
+ end
15
+ #true
16
+ end
17
+
18
+ def verify_types(transac)
19
+ actor_model = transac.actor.class
20
+ actor_model_sym = actor_model.name.underscore.to_sym
21
+
22
+ target_model = transac.target.class
23
+ target_model_sym = target_model.name.underscore.to_sym
24
+
25
+ medium_model = transac.medium.class
26
+ medium_model_sym = medium_model.name.underscore.to_sym
27
+
28
+ behaviour = transac.relation_type.to_s.sub(/undo_/,'').underscore.to_sym
29
+ auths = []
30
+
31
+ if transac.tripartite?
32
+ # Verif for actor
33
+ auths << actor_model.patriarch_behaviours[behaviour][:on].map{ |b_sym| b_sym.to_s.underscore.to_sym }.include?(target_model_sym)
34
+ auths << actor_model.patriarch_behaviours[behaviour][:via].map{ |b_sym| b_sym.to_s.underscore.to_sym }.include?(medium_model_sym)
35
+
36
+ # Verif for target
37
+ auths << target_model.patriarch_behaviours[behaviour][:by].map{ |b_sym| b_sym.to_s.underscore.to_sym }.include?(actor_model_sym)
38
+ auths << target_model.patriarch_behaviours[behaviour][:via].map{ |b_sym| b_sym.to_s.underscore.to_sym }.include?(medium_model_sym)
39
+
40
+ # Verif for medium
41
+ auths << medium_model.patriarch_behaviours[behaviour][:medium_between].map{ |dual_sym_tab| dual_sym_tab.map{ |b_sym| b_sym.to_s.underscore.to_sym } }.include?(
42
+ [actor_model_sym, target_model_sym]
43
+ )
44
+ # cas particulier
45
+ else
46
+ auths << actor_model.patriarch_behaviours[behaviour][:on].map{ |b_sym| b_sym.to_s.underscore.to_sym }.include?(target_model_sym)
47
+ auths << target_model.patriarch_behaviours[behaviour][:by].map{ |b_sym| b_sym.to_s.underscore.to_sym }.include?(actor_model_sym)
48
+ end
49
+
50
+
51
+ if auths.include? false
52
+ false
53
+ else
54
+ true
55
+ end
10
56
  end
11
57
  end
12
58
  end
@@ -36,16 +36,16 @@ module Patriarch
36
36
  Patriarch::ToolServices::RedisExtractorService.instance.
37
37
  get_models_from_ids(self,acted_on_model.to_s.classify.constantize,raw_tool_method_name,options)
38
38
  end
39
- if options[:relation_type_alias]
40
- alias_for_classic = classic_tool_method_name.sub(relation_type.to_s, options[:relation_type_alias].to_s)
39
+ if options[:as]
40
+ alias_for_classic = classic_tool_method_name.sub(relation_type.to_s, options[:as].to_s)
41
41
  alias_method alias_for_classic, classic_tool_method_name
42
42
  end
43
43
 
44
44
  define_method(raw_tool_method_name) do |options={}|
45
45
  Patriarch::ToolServices::RedisExtractorService.instance.get_ids_from_sorted_set(self,redis_key,options)
46
46
  end
47
- if options[:relation_type_alias]
48
- alias_for_raw = raw_tool_method_name.sub(relation_type.to_s, options[:relation_type_alias].to_s)
47
+ if options[:as]
48
+ alias_for_raw = raw_tool_method_name.sub(relation_type.to_s, options[:as].to_s)
49
49
  alias_method alias_for_raw, raw_tool_method_name
50
50
  end
51
51
  end
@@ -69,8 +69,8 @@ module Patriarch
69
69
  Patriarch::ToolServices::RedisExtractorService.instance.
70
70
  get_models_from_ids(self,targetted_by_model.to_s.classify.constantize,raw_tool_method_name,options)
71
71
  end
72
- if options[:relation_type_alias]
73
- progressive_present_relation_type_alias = (Verbs::Conjugator.conjugate options[:relation_type_alias], :aspect => :progressive).split(/ /).last
72
+ if options[:as]
73
+ progressive_present_relation_type_alias = (Verbs::Conjugator.conjugate options[:as], :aspect => :progressive).split(/ /).last
74
74
  alias_for_classic = classic_tool_method_name.sub(progressive_present_relation_type,progressive_present_relation_type_alias)
75
75
  alias_method alias_for_classic, classic_tool_method_name
76
76
  end
@@ -78,8 +78,8 @@ module Patriarch
78
78
  define_method(raw_tool_method_name) do |options={}|
79
79
  Patriarch::ToolServices::RedisExtractorService.instance.get_ids_from_sorted_set(self,redis_key,options)
80
80
  end
81
- if options[:relation_type_alias]
82
- progressive_present_relation_type_alias = (Verbs::Conjugator.conjugate options[:relation_type_alias], :aspect => :progressive).split(/ /).last
81
+ if options[:as]
82
+ progressive_present_relation_type_alias = (Verbs::Conjugator.conjugate options[:as], :aspect => :progressive).split(/ /).last
83
83
  alias_for_raw = raw_tool_method_name.sub(progressive_present_relation_type,progressive_present_relation_type_alias)
84
84
  alias_method alias_for_raw, raw_tool_method_name
85
85
  end
@@ -89,7 +89,6 @@ module Patriarch
89
89
  end
90
90
  end
91
91
 
92
-
93
92
  def complete_custom_active_module_tripartite(module_to_complete,relation_type,acted_on_model_list,via_model_list,options={})
94
93
  module_to_complete.class_eval do
95
94
 
@@ -97,31 +96,54 @@ module Patriarch
97
96
  via_model_list.each do |via_model|
98
97
 
99
98
  # Compute names based on conventions
100
- classic_tool_method_name = "#{acted_on_model.to_s.tableize}_i_#{relation_type.to_s}_via_#{via_model.to_s.tableize}"
101
- raw_tool_method_name = classic_tool_method_name + "_ids"
102
- redis_key = "patriarch_" + classic_tool_method_name
99
+ # fallen_angels_i_praise_via_love_letters
100
+ target_classic_tool_method_name = "#{acted_on_model.to_s.tableize}_i_#{relation_type.to_s}_via_#{via_model.to_s.tableize}"
101
+ target_raw_tool_method_name = target_classic_tool_method_name + "_ids"
102
+
103
+ # love_letters_i_use_to_praise_fallen_angels
104
+ medium_classic_tool_method_name = "#{via_model.to_s.tableize}_i_use_to_#{relation_type.to_s}_#{acted_on_model.to_s.tableize}"
105
+ medium_raw_tool_method_name = medium_classic_tool_method_name + "_ids"
106
+
107
+ redis_key = "patriarch_" + target_classic_tool_method_name
103
108
 
104
109
  # Define methods with the pattern : items_i_like that returns models and items_i_like_ids that return
105
110
  # Redis key has the same radical as the method in class by convention (but has a patriarch_ prefix to avoid collisions with other gems)
106
- define_method(classic_tool_method_name) do |options={}|
111
+ define_method(target_classic_tool_method_name) do |options={}|
107
112
  Patriarch::ToolServices::RedisExtractorService.instance.
108
- get_models_from_ids(self,acted_on_model.to_s.classify.constantize,raw_tool_method_name,options.merge({:tripartite => true}))
113
+ get_models_from_ids(self,acted_on_model.to_s.classify.constantize,target_raw_tool_method_name,options.merge({:tripartite => true}))
109
114
  end
110
- if options[:relation_type_alias]
111
- alias_for_classic = classic_tool_method_name.sub(relation_type.to_s, options[:relation_type_alias].to_s)
112
- alias_method alias_for_classic, classic_tool_method_name
115
+ if options[:as]
116
+ alias_for_classic = target_classic_tool_method_name.sub(relation_type.to_s, options[:as].to_s)
117
+ alias_method alias_for_classic, target_classic_tool_method_name
113
118
  end
114
119
 
115
- define_method(raw_tool_method_name) do |options={}|
116
- Patriarch::ToolServices::RedisExtractorService.instance.get_ids_from_sorted_set(self,redis_key,options.merge({:tripartite => true, :protagonist_type => :actor}))
117
- # triplet is by convention [actor,target,medium]
118
- # TODO Marshallize true items instead of some crappy convention ...
120
+ define_method(target_raw_tool_method_name) do |options={}|
121
+ Patriarch::ToolServices::RedisExtractorService.instance.get_ids_from_sorted_set(self,redis_key,options.merge({:tripartite => true, :protagonist_type => :target}))
119
122
  end
120
- if options[:relation_type_alias]
121
- alias_for_raw = raw_tool_method_name.sub(relation_type.to_s, options[:relation_type_alias].to_s)
122
- alias_method alias_for_raw, raw_tool_method_name
123
+ if options[:as]
124
+ alias_for_target_raw = target_raw_tool_method_name.sub(relation_type.to_s, options[:as].to_s)
125
+ alias_method alias_for_target_raw, target_raw_tool_method_name
123
126
  end
124
127
 
128
+ #
129
+ define_method(medium_classic_tool_method_name) do |options={}|
130
+ Patriarch::ToolServices::RedisExtractorService.instance.
131
+ get_models_from_ids(self,via_model.to_s.classify.constantize,medium_raw_tool_method_name,options.merge({:tripartite => true}))
132
+ end
133
+ if options[:as]
134
+ alias_for_medium_classic = medium_classic_tool_method_name.sub(relation_type.to_s, options[:as].to_s)
135
+ alias_method alias_for_medium_classic, medium_classic_tool_method_name
136
+ end
137
+ #
138
+
139
+ define_method(medium_raw_tool_method_name) do |options={}|
140
+ Patriarch::ToolServices::RedisExtractorService.instance.get_ids_from_sorted_set(self,redis_key,options.merge({:tripartite => true, :protagonist_type => :medium}))
141
+ end
142
+ if options[:as]
143
+ alias_for_medium_raw = medium_raw_tool_method_name.sub(relation_type.to_s, options[:as].to_s)
144
+ alias_method alias_for_medium_raw, medium_raw_tool_method_name
145
+ end
146
+
125
147
  end
126
148
  end
127
149
 
@@ -135,35 +157,45 @@ module Patriarch
135
157
  via_model_list.each do |via_model|
136
158
  # Compute names based on conventions
137
159
  progressive_present_relation_type = (Verbs::Conjugator.conjugate relation_type.to_sym, :aspect => :progressive).split(/ /).last
138
- classic_tool_method_name = "#{targetted_by_model.to_s.tableize}_#{progressive_present_relation_type}_me_via_#{via_model.to_s.tableize}"
139
- raw_tool_method_name = classic_tool_method_name + "_ids"
140
- redis_key = "patriarch_" + classic_tool_method_name
141
-
142
- # Define methods with the pattern : items_i_like that returns models and items_i_like_ids that return
143
- # Redis key has the same radical as the method in class by convention (but has a patriarch_ prefix to avoid collisions with other gems)
144
- define_method(classic_tool_method_name) do |options={}|
160
+
161
+ actor_classic_tool_method_name = "#{targetted_by_model.to_s.tableize}_#{progressive_present_relation_type}_me_via_#{via_model.to_s.tableize}"
162
+ actor_raw_tool_method_name = actor_classic_tool_method_name + "_ids"
163
+
164
+ #"love_letters_used_by_monsters_to_praise_me"
165
+ medium_classic_tool_method_name = "#{via_model.to_s.tableize}_used_by_#{targetted_by_model.to_s.tableize}_to_#{relation_type.to_s}_me"
166
+ medium_raw_tool_method_name = medium_classic_tool_method_name + "_ids"
167
+
168
+ redis_key = "patriarch_" + actor_classic_tool_method_name
169
+
170
+ define_method(actor_classic_tool_method_name) do |options={}|
145
171
  Patriarch::ToolServices::RedisExtractorService.instance.
146
- get_models_from_ids(self,targetted_by_model.to_s.classify.constantize,raw_tool_method_name,options.merge({:tripartite => true}))
172
+ get_models_from_ids(self,targetted_by_model.to_s.classify.constantize,actor_raw_tool_method_name,options.merge({:tripartite => true}))
147
173
  end
148
- if options[:relation_type_alias]
149
- progressive_present_relation_type_alias = (Verbs::Conjugator.conjugate options[:relation_type_alias], :aspect => :progressive).split(/ /).last
150
- alias_for_classic = classic_tool_method_name.sub(progressive_present_relation_type,progressive_present_relation_type_alias)
151
- alias_method alias_for_classic, classic_tool_method_name
174
+ if options[:as]
175
+ progressive_present_relation_type_alias = (Verbs::Conjugator.conjugate options[:as], :aspect => :progressive).split(/ /).last
176
+ alias_for_actor_classic = actor_classic_tool_method_name.sub(progressive_present_relation_type,progressive_present_relation_type_alias)
177
+ alias_method alias_for_actor_classic, actor_classic_tool_method_name
152
178
  end
153
179
 
154
-
155
- define_method(raw_tool_method_name) do |options={}|
156
- Patriarch::ToolServices::RedisExtractorService.instance.get_ids_from_sorted_set(self,redis_key,options.merge({:tripartite => true , :protagonist_type => :target}))
157
-
158
- # triplet is by convention [actor,target,medium]
159
- # TODO Marshallize true items instead of some crappy convention ...
180
+ define_method(actor_raw_tool_method_name) do |options={}|
181
+ Patriarch::ToolServices::RedisExtractorService.instance.get_ids_from_sorted_set(self,redis_key,options.merge({:tripartite => true , :protagonist_type => :actor}))
160
182
  end
161
- if options[:relation_type_alias]
162
- progressive_present_relation_type_alias = (Verbs::Conjugator.conjugate options[:relation_type_alias], :aspect => :progressive).split(/ /).last
163
- alias_for_raw = raw_tool_method_name.sub(progressive_present_relation_type,progressive_present_relation_type_alias)
164
- alias_method alias_for_raw, raw_tool_method_name
183
+ if options[:as]
184
+ progressive_present_relation_type_alias = (Verbs::Conjugator.conjugate options[:as], :aspect => :progressive).split(/ /).last
185
+ alias_for_actor_raw = actor_raw_tool_method_name.sub(progressive_present_relation_type,progressive_present_relation_type_alias)
186
+ alias_method alias_for_actor_raw, actor_raw_tool_method_name
165
187
  end
166
188
 
189
+ define_method(medium_classic_tool_method_name) do |options={}|
190
+ Patriarch::ToolServices::RedisExtractorService.instance.
191
+ get_models_from_ids(self,via_model.to_s.classify.constantize,medium_raw_tool_method_name,options.merge({:tripartite => true}))
192
+ end
193
+ #TODO add alias there
194
+ # FIXME id in it is wrong ...
195
+ define_method(medium_raw_tool_method_name) do |options={}|
196
+ Patriarch::ToolServices::RedisExtractorService.instance.get_ids_from_sorted_set(self,redis_key,options.merge({:tripartite => true , :protagonist_type => :medium}))
197
+ end
198
+
167
199
  end
168
200
  end
169
201
 
@@ -210,19 +242,29 @@ module Patriarch
210
242
 
211
243
  module ClassMethods
212
244
 
213
- def add_behaviour(behaviour,options)
245
+ def check_add_behaviour_syntax(behaviour,options)
214
246
  if options[:medium_between] || options[:via]
215
- add_tripartite_behaviour(behaviour,options)
247
+ check_tripartite_add_behaviour_syntax(behaviour,options)
216
248
  elsif options[:on] || options[:by]
217
- add_bipartite_behaviour(behaviour,options)
218
- else
219
- raise AddBehaviourSyntaxError, "syntax is wrong, declaration does not suplly enough arguments declared with right options"
249
+ check_bipartite_add_behaviour_syntax(behaviour,options)
220
250
  end
221
251
  end
222
252
 
223
- def add_tripartite_behaviour(behaviour,options)
224
- behaviour = behaviour.to_s.underscore
253
+ def check_bipartite_add_behaviour_syntax(behaviour,options)
254
+ # Either you add a behaviour on another model or allow a behaviour on you by another model
255
+ unless options[:by].nil? ^ options[:on].nil?
256
+ raise AddBehaviourSyntaxError, "you must not define a behaviour as active (using on) and passive at the same time (using by)"
257
+ end
258
+
259
+ # as option should be a string or symbol
260
+ if options[:as]
261
+ unless [Symbol,String].include?(options[:as].class)
262
+ raise AddBehaviourSyntaxError, "as option should be a string or symbol"
263
+ end
264
+ end
265
+ end
225
266
 
267
+ def check_tripartite_add_behaviour_syntax(behaviour,options)
226
268
  # Xor on options :medium_between and :via, disparate cases ...
227
269
  unless options[:medium_between].nil? ^ options[:via].nil?
228
270
  raise AddBehaviourSyntaxError, "you must not define a behaviour as active (using on) and passive at the same time (using by)"
@@ -239,222 +281,220 @@ module Patriarch
239
281
  end
240
282
  end
241
283
 
242
- complete_module_options = {}
243
284
  if options[:as]
244
285
  # as option should be a string or symbol
245
286
  unless [Symbol,String].include?(options[:as].class)
246
287
  raise AddBehaviourSyntaxError, "as option should be a string or symbol"
247
288
  end
248
- complete_module_options.merge! :relation_type_alias => options[:as]
249
289
  end
290
+ end
250
291
 
251
- methods_mod = Module.new do; end
252
- methods_mod.const_set(:Behaviour,behaviour)
292
+ def add_behaviour(behaviour,options)
293
+ if options[:medium_between] || options[:via]
294
+ add_tripartite_behaviour(behaviour,options)
295
+ elsif options[:on] || options[:by]
296
+ add_bipartite_behaviour(behaviour,options)
297
+ else
298
+ raise AddBehaviourSyntaxError, "syntax is wrong, declaration does not suplly enough arguments declared with right options"
299
+ end
300
+ end
301
+
302
+ def add_aliases_for_functionnalities(module_to_complete,behaviour,options)
253
303
  if options[:as]
254
- methods_mod.const_set(:BehaviourAlias,options[:as].to_sym)
255
- end
304
+ behaviour_alias = options[:as].to_s
305
+ end
256
306
 
257
307
  if options[:undo_as]
258
- methods_mod.const_set(:UndoBehaviourAlias,options[:undo_as].to_sym)
259
- end
308
+ behaviour_undo_alias = options[:undo_as].to_s
309
+ end
310
+
311
+ if options[:on]
312
+ module_to_complete.instance_eval do
313
+ # add behaviour_alias
314
+ if options[:as]
315
+ alias_method behaviour_alias, behaviour
316
+ end
260
317
 
318
+ # add undo_behaviour_alias
319
+ if options[:undo_as]
320
+ alias_method behaviour_undo_alias, Patriarch.undo(behaviour)
321
+ end
322
+ end
323
+ end
324
+ end
261
325
 
262
- # Target on Actor cases
263
- if options[:via]
264
- # Actor case
265
- if options[:on]
266
- methods_mod.instance_eval do
267
- # Defines the hook thing ...
268
- # TODO
269
- def self.included(klass)
270
- klass.extend ActiveModel::Callbacks
271
- klass.send(:define_model_callbacks, self.const_get(:Behaviour).to_sym, Patriarch.undo(self.const_get(:Behaviour)).to_sym)
272
- end
326
+ def add_functionnalities_for_bipartite(module_to_complete,behaviour,options)
327
+ module_to_complete.instance_eval do
273
328
 
274
- # behave
275
- define_method(methods_mod.const_get(:Behaviour).to_sym) do |entity,via_entity,options={}|
276
- run_callbacks methods_mod.const_get(:Behaviour).to_sym do
277
- "Patriarch::Services::#{methods_mod.const_get(:Behaviour).classify}::ManagerService".constantize.instance.resolve(self,entity,via_entity,options)
278
- end
279
- end
280
- if options[:as]
281
- alias_method methods_mod.const_get(:BehaviourAlias), methods_mod.const_get(:Behaviour).to_sym
282
- end
283
-
284
- # undo_behave
285
- define_method(Patriarch.undo(methods_mod.const_get(:Behaviour)).to_sym) do |entity,via_entity,options={}|
286
- run_callbacks Patriarch.undo(methods_mod.const_get(:Behaviour)).to_sym do
287
- "Patriarch::Services::#{(Patriarch.undo(methods_mod.const_get(:Behaviour))).classify}::ManagerService".constantize.instance.resolve(self,entity,via_entity,options)
288
- end
289
- end
290
- if options[:undo_as]
291
- alias_method methods_mod.const_get(:UndoBehaviourAlias), Patriarch.undo(methods_mod.const_get(:Behaviour))
292
- end
329
+ instance_eval do
330
+ (class << self; self; end).send(:define_method,:included) do |klass|
331
+ klass.extend ActiveModel::Callbacks
332
+ klass.send(:define_model_callbacks, behaviour, Patriarch.undo(behaviour))
333
+ end
334
+ end
293
335
 
336
+ # behave
337
+ define_method(behaviour) do |entity,options={}|
338
+ run_callbacks behaviour do
339
+ "Patriarch::Services::#{behaviour.classify}::ManagerService".constantize.instance.resolve(self,entity,options)
294
340
  end
341
+ end
295
342
 
296
- acted_on_model_list = Array(options[:on])
297
- via_model_list = Array(options[:via])
298
- Patriarch::Behaviours.complete_custom_active_module_tripartite(methods_mod,behaviour,acted_on_model_list,via_model_list,complete_module_options)
299
- #Target case
300
- elsif options[:by]
301
- targetted_by_model_list = Array(options[:by])
302
- via_model_list = Array(options[:via])
303
- Patriarch::Behaviours.complete_custom_passive_module_tripartite(methods_mod,behaviour,targetted_by_model_list,via_model_list,complete_module_options)
343
+ # undo_behave
344
+ define_method(Patriarch.undo(behaviour).to_sym) do |entity,options={}|
345
+ run_callbacks Patriarch.undo(behaviour).to_sym do
346
+ "Patriarch::Services::#{(Patriarch.undo(behaviour)).classify}::ManagerService".constantize.instance.resolve(self,entity,options)
347
+ end
304
348
  end
305
- # Medium case
306
- elsif options[:medium_between]
307
- # Define tool_methods_here ...
308
- end
309
349
 
310
- # Finally ...
311
- self.send(:include,methods_mod)
312
- # include in which we can overwite the methods of the previous custom module included there ...
313
- self.send(:include,"Patriarch::Behaviours::#{behaviour.classify}::ToolsMethods".constantize)
350
+ end # instance_eval
351
+ end
352
+
353
+ def add_functionnalities_for_tripartite(module_to_complete,behaviour,options)
354
+ module_to_complete.instance_eval do
355
+
356
+ instance_eval do
357
+ (class << self; self; end).send(:define_method,:included) do |klass|
358
+ klass.extend ActiveModel::Callbacks
359
+ klass.send(:define_model_callbacks, behaviour, Patriarch.undo(behaviour))
360
+ end
361
+ end
362
+
363
+ # behave
364
+ define_method(behaviour) do |via_entity,entity,options={}|
365
+ run_callbacks behaviour.to_sym do
366
+ "Patriarch::Services::#{behaviour.classify}::ManagerService".constantize.instance.resolve(self,entity,via_entity,options)
367
+ end
368
+ end
369
+
370
+
371
+ # undo_behave
372
+ define_method(Patriarch.undo(behaviour)) do |via_entity,entity,options={}|
373
+ run_callbacks Patriarch.undo(behaviour).to_sym do
374
+ "Patriarch::Services::#{Patriarch.undo(behaviour).classify}::ManagerService".constantize.instance.resolve(self,entity,via_entity,options)
375
+ end
376
+ end
377
+
378
+ end # instance_eval
379
+ end
380
+
381
+ def register_bipartite_behaviour(behaviour,options)
382
+ self.patriarch_behaviours ||= { }
383
+ #self.patriarch_behaviours[behaviour.underscore.to_sym] ||= { :on => [], :by =>[] }
384
+ self.patriarch_behaviours[behaviour.underscore.to_sym] ||= { }
385
+ self.patriarch_behaviours[behaviour.underscore.to_sym][:on] ||= []
386
+ self.patriarch_behaviours[behaviour.underscore.to_sym][:by] ||= []
387
+
388
+ if options[:on]
389
+ self.patriarch_behaviours[behaviour.underscore.to_sym][:on] << options[:on]
390
+ self.patriarch_behaviours[behaviour.underscore.to_sym][:on].uniq!
391
+ self.patriarch_behaviours[behaviour.underscore.to_sym][:on].flatten!
392
+ elsif options[:by]
393
+ self.patriarch_behaviours[behaviour.underscore.to_sym][:by] << options[:by]
394
+ self.patriarch_behaviours[behaviour.underscore.to_sym][:by].uniq!
395
+ self.patriarch_behaviours[behaviour.underscore.to_sym][:by].flatten!
396
+ end
397
+ end
398
+
399
+ def register_tripartite_behaviour(behaviour,options)
314
400
  # TODO disjonction register tripartite
315
401
  # register the behaviour we just added
402
+ behaviour = behaviour.underscore.to_sym
403
+
316
404
  self.patriarch_behaviours ||= { }
317
- self.patriarch_behaviours[behaviour.underscore.to_sym] ||= {}
405
+ self.patriarch_behaviours[behaviour] ||= {}
318
406
 
319
407
  if options[:via]
320
408
  #self.patriarch_behaviours[behaviour.underscore.to_sym] ||= { :on => [], :by => [], :via => [] }
321
- self.patriarch_behaviours[behaviour.underscore.to_sym][:on] ||= []
322
- self.patriarch_behaviours[behaviour.underscore.to_sym][:by] ||= []
323
- self.patriarch_behaviours[behaviour.underscore.to_sym][:via] ||= []
409
+ self.patriarch_behaviours[behaviour][:on] ||= []
410
+ self.patriarch_behaviours[behaviour][:by] ||= []
411
+ self.patriarch_behaviours[behaviour][:via] ||= []
324
412
  elsif options[:medium_between]
325
413
  #self.patriarch_behaviours[behaviour.underscore.to_sym] ||= { :medium_between => [] }
326
- self.patriarch_behaviours[behaviour.underscore.to_sym][:medium_between] ||= []
414
+ self.patriarch_behaviours[behaviour][:medium_between] ||= []
327
415
  end
328
416
 
329
417
  if options[:via]
330
418
  if options[:on]
331
- self.patriarch_behaviours[behaviour.underscore.to_sym][:on] << options[:on]
332
- self.patriarch_behaviours[behaviour.underscore.to_sym][:on].uniq!
333
- self.patriarch_behaviours[behaviour.underscore.to_sym][:on].flatten!
419
+ self.patriarch_behaviours[behaviour][:on] << options[:on]
420
+ self.patriarch_behaviours[behaviour][:on].uniq!
421
+ self.patriarch_behaviours[behaviour][:on].flatten!
334
422
  elsif options[:by]
335
- self.patriarch_behaviours[behaviour.underscore.to_sym][:by] << options[:by]
336
- self.patriarch_behaviours[behaviour.underscore.to_sym][:by].uniq!
337
- self.patriarch_behaviours[behaviour.underscore.to_sym][:by].flatten!
423
+ self.patriarch_behaviours[behaviour][:by] << options[:by]
424
+ self.patriarch_behaviours[behaviour][:by].uniq!
425
+ self.patriarch_behaviours[behaviour][:by].flatten!
338
426
  end
339
- self.patriarch_behaviours[behaviour.underscore.to_sym][:via] << options[:via]
340
- self.patriarch_behaviours[behaviour.underscore.to_sym][:via].uniq!
341
- self.patriarch_behaviours[behaviour.underscore.to_sym][:via].flatten!
427
+ self.patriarch_behaviours[behaviour][:via] << options[:via]
428
+ self.patriarch_behaviours[behaviour][:via].uniq!
429
+ self.patriarch_behaviours[behaviour][:via].flatten!
342
430
  elsif options[:medium_between]
343
- self.patriarch_behaviours[behaviour.underscore.to_sym][:medium_between] << options[:medium_between]
344
- self.patriarch_behaviours[behaviour.underscore.to_sym][:medium_between].uniq!
345
- self.patriarch_behaviours[behaviour.underscore.to_sym][:medium_between]
431
+ self.patriarch_behaviours[behaviour][:medium_between] << options[:medium_between]
432
+ self.patriarch_behaviours[behaviour][:medium_between].uniq!
433
+ self.patriarch_behaviours[behaviour][:medium_between]
346
434
  end
347
435
  end
348
436
 
349
- def add_bipartite_behaviour(behaviour,options)
350
- # add_behaviour :like, :by => bla, :on => [:item,:user] || :community, :as => :aimer, :reverse_as => :haïr ...
351
-
437
+ def add_tripartite_behaviour(behaviour,options)
352
438
  behaviour = behaviour.to_s.underscore
353
439
 
354
- # Xor on options :on and :by, is what is needed, raise an exception otherwise
355
- unless options[:by].nil? ^ options[:on].nil?
356
- raise AddBehaviourSyntaxError, "you must not define a behaviour as active (using on) and passive at the same time (using by)"
357
- end
440
+ check_add_behaviour_syntax(behaviour,options)
358
441
 
359
442
  methods_mod = Module.new do; end
360
- methods_mod.const_set(:Behaviour,behaviour)
361
- if options[:as]
362
- methods_mod.const_set(:BehaviourAlias,options[:as].to_sym)
363
- end
364
- if options[:undo_as]
365
- methods_mod.const_set(:UndoBehaviourAlias,options[:undo_as].to_sym)
366
- end
367
-
368
- if options[:on]
369
- # Adds active methods and defines the hook to set callbacks on them
370
- methods_mod.instance_eval do
371
-
372
- # Defines the hook thing ...
373
- # TODO
374
- def self.included(klass)
375
- klass.extend ActiveModel::Callbacks
376
- klass.send(:define_model_callbacks, self.const_get(:Behaviour).to_sym, Patriarch.undo(self.const_get(:Behaviour)).to_sym)
377
- end
378
443
 
379
- # like
380
- define_method(methods_mod.const_get(:Behaviour).to_sym) do |entity,options={}|
381
- run_callbacks methods_mod.const_get(:Behaviour).to_sym do
382
- "Patriarch::Services::#{methods_mod.const_get(:Behaviour).classify}::ManagerService".constantize.instance.resolve(self,entity,options)
383
- end
384
- end
385
- if options[:as]
386
- alias_method methods_mod.const_get(:BehaviourAlias), methods_mod.const_get(:Behaviour).to_sym
387
- end
388
-
389
- # undo_like
390
- define_method(Patriarch.undo(methods_mod.const_get(:Behaviour)).to_sym) do |entity,options={}|
391
- run_callbacks Patriarch.undo(methods_mod.const_get(:Behaviour)).to_sym do
392
- "Patriarch::Services::#{(Patriarch.undo(methods_mod.const_get(:Behaviour))).classify}::ManagerService".constantize.instance.resolve(self,entity,options)
393
- end
394
- end
395
- if options[:undo_as]
396
- alias_method methods_mod.const_get(:UndoBehaviourAlias), Patriarch.undo(methods_mod.const_get(:Behaviour))
397
- end
398
-
399
- # Not used / not tested, added this method "en passant"
400
- # FIX requirements with users
401
- # likes?
402
- define_method((Verbs::Conjugator.conjugate methods_mod.const_get(:Behaviour).to_sym, :person => :third).split(/ /).last) do |entity|
403
- self.send("#{entity.class.name.tableize}_i_#{methods_mod.const_get(:Behaviour)}_ids").include? entity.id
404
- end
444
+ # Target on Actor cases
445
+ if options[:via]
446
+ # Actor case
447
+ if options[:on]
448
+ add_functionnalities_for_tripartite(methods_mod,behaviour,options)
449
+ add_aliases_for_functionnalities(methods_mod,behaviour,options)
450
+ acted_on_model_list = Array(options[:on])
451
+ via_model_list = Array(options[:via])
452
+ Patriarch::Behaviours.complete_custom_active_module_tripartite(methods_mod,behaviour,acted_on_model_list,via_model_list,options)
453
+ #Target case
454
+ elsif options[:by]
455
+ targetted_by_model_list = Array(options[:by])
456
+ via_model_list = Array(options[:via])
457
+ Patriarch::Behaviours.complete_custom_passive_module_tripartite(methods_mod,behaviour,targetted_by_model_list,via_model_list,options)
405
458
  end
459
+ # Medium case
460
+ elsif options[:medium_between]
461
+ # Define tool_methods_here ...
406
462
  end
407
463
 
408
- if options[:by]
409
- methods_mod.instance_eval do
410
- # reverse_of_likes?
411
- # TODO find naming convention and build general ...
412
- # define_method(:reverse_of_likes) do |entity|
413
- # progressive_present_relation_type = (Verbs::Conjugator.conjugate methods_mod.const_get(:Behaviour).to_sym, :aspect => :progressive).split(/ /).last
414
- # self.send("#{entity.class.name.tableize}_#{progressive_present_relation_type}_me_ids").include? entity.id
415
- #end
416
- end
417
- end
464
+ # Finally ...
465
+ include methods_mod
466
+ # include in which we can overwite the methods of the previous custom module included there ...
467
+ include "Patriarch::Behaviours::#{behaviour.classify}::ToolsMethods".constantize
468
+ # register behaviour we just added
469
+ register_tripartite_behaviour(behaviour,options)
470
+ end
418
471
 
419
- complete_module_options = {}
420
- if options[:as]
421
- # as option should be a string or symbol
422
- unless [Symbol,String].include?(options[:as].class)
423
- raise AddBehaviourSyntaxError, "as option should be a string or symbol"
424
- end
425
- complete_module_options.merge! :relation_type_alias => options[:as]
426
- end
472
+ def add_bipartite_behaviour(behaviour,options)
473
+ # add_behaviour :like, :by => bla, :on => [:item,:user] || :community, :as => :aimer, :reverse_as => :haïr ...
474
+
475
+ behaviour = behaviour.to_s.underscore
476
+
477
+ check_add_behaviour_syntax(behaviour,options)
427
478
 
479
+ methods_mod = Module.new do; end
428
480
 
429
481
  if options[:on]
482
+ # Adds active methods and defines the hook to set callbacks on them
483
+ add_functionnalities_for_bipartite(methods_mod,behaviour,options)
484
+ add_aliases_for_functionnalities(methods_mod,behaviour,options)
430
485
  acted_on_model_list = Array(options[:on])
431
- Patriarch::Behaviours.complete_custom_active_module_bipartite(methods_mod,behaviour,acted_on_model_list,complete_module_options)
486
+ Patriarch::Behaviours.complete_custom_active_module_bipartite(methods_mod,behaviour,acted_on_model_list,options)
432
487
  else
433
488
  targetted_by_model_list = Array(options[:by])
434
- Patriarch::Behaviours.complete_custom_passive_module_bipartite(methods_mod,behaviour,targetted_by_model_list,complete_module_options)
489
+ Patriarch::Behaviours.complete_custom_passive_module_bipartite(methods_mod,behaviour,targetted_by_model_list,options)
435
490
  end
436
491
 
437
- # Finally ...
438
- self.send(:include,methods_mod)
492
+ # Finally includes the custom module
493
+ include methods_mod
439
494
  # include in which we can overwite the methods of the previous custom module included there ...
440
- self.send(:include,"Patriarch::Behaviours::#{behaviour.classify}::ToolsMethods".constantize)
441
-
495
+ include "Patriarch::Behaviours::#{behaviour.classify}::ToolsMethods".constantize
442
496
  # register the behaviour we just added
443
- self.patriarch_behaviours ||= { }
444
- #self.patriarch_behaviours[behaviour.underscore.to_sym] ||= { :on => [], :by =>[] }
445
- self.patriarch_behaviours[behaviour.underscore.to_sym] ||= { }
446
- self.patriarch_behaviours[behaviour.underscore.to_sym][:on] ||= []
447
- self.patriarch_behaviours[behaviour.underscore.to_sym][:by] ||= []
448
-
449
- if options[:on]
450
- self.patriarch_behaviours[behaviour.underscore.to_sym][:on] << options[:on]
451
- self.patriarch_behaviours[behaviour.underscore.to_sym][:on].uniq!
452
- self.patriarch_behaviours[behaviour.underscore.to_sym][:on].flatten!
453
- elsif options[:by]
454
- self.patriarch_behaviours[behaviour.underscore.to_sym][:by] << options[:by]
455
- self.patriarch_behaviours[behaviour.underscore.to_sym][:by].uniq!
456
- self.patriarch_behaviours[behaviour.underscore.to_sym][:by].flatten!
457
- end
497
+ register_bipartite_behaviour(behaviour,options)
458
498
  end
459
499
  end
460
500
 
@@ -25,6 +25,9 @@ class Patriarch::DAOServices::BipartiteRelationshipBuilderService < Patriarch::S
25
25
  l = lambda { actor_dao.delete transaction_item.target_id }
26
26
  ll = lambda { target_dao.delete transaction_item.actor_id }
27
27
 
28
+ # p "#{l.inspect} is deleting on key #{actor_dao.key} : #{transaction_item.target_type} #{transaction_item.target_id}"
29
+ # p "#{ll.inspect} is deleting on key #{target_dao.key} : #{transaction_item.actor_type} #{transaction_item.actor_id}"
30
+
28
31
  transaction_item.add_to_queue l
29
32
  transaction_item.add_to_queue ll
30
33
  end
@@ -6,7 +6,7 @@ class Patriarch::ToolServices::RedisCleanerService < Patriarch::Service
6
6
  options = { :transac => transac }
7
7
 
8
8
  calling_entity.class.patriarch_behaviours.keys.each do |behaviour|
9
- clean_behaviour(calling_entity,behaviour,options)
9
+ transac.steps << clean_behaviour(calling_entity,behaviour)
10
10
  end
11
11
 
12
12
  transac
@@ -47,7 +47,7 @@ class Patriarch::ToolServices::RedisCleanerService < Patriarch::Service
47
47
  calling_entity.send("#{acted_on_model.to_s.tableize}_i_#{behaviour.to_s}_via_#{via_model.to_s.tableize}", :with_medium => true).each do |tripartite_hash|
48
48
  target_i_behaved_on = Array(acted_on_model.to_s.classify.constantize.find(tripartite_hash[:target])).first
49
49
  medium_for_behaviour = Array(via_model.to_s.classify.constantize.find(tripartite_hash[:medium])).first
50
- calling_entity.send(Patriarch.undo(behaviour.to_s).underscore,target_i_behaved_on,medium_for_behaviour,options)
50
+ calling_entity.send(Patriarch.undo(behaviour.to_s).underscore,medium_for_behaviour,target_i_behaved_on,options)
51
51
  end
52
52
  end
53
53
  end
@@ -64,7 +64,7 @@ class Patriarch::ToolServices::RedisCleanerService < Patriarch::Service
64
64
  actor_that_behaved_on_me = Array(targetted_by_model.to_s.classify.constantize.find(tripartite_hash[:actor])).first
65
65
  medium_for_behaviour = Array(via_model.to_s.classify.constantize.find(tripartite_hash[:medium])).first
66
66
  #
67
- actor_that_behaved_on_me.send(Patriarch.undo(behaviour.to_s).underscore,calling_entity,medium_for_behaviour,options)
67
+ actor_that_behaved_on_me.send(Patriarch.undo(behaviour.to_s).underscore,medium_for_behaviour,calling_entity,options)
68
68
  end
69
69
  end
70
70
  end
@@ -92,7 +92,15 @@ class Patriarch::ToolServices::RedisCleanerService < Patriarch::Service
92
92
  options = { :transac => transac, :stop_execution => true}
93
93
 
94
94
  if my_behaviours.include? behaviour.to_s.underscore.to_sym
95
-
95
+ # Dealing with passive behaviour
96
+ if my_behaviours[behaviour.to_s.underscore.to_sym][:by]
97
+ targetted_by_models = my_behaviours[behaviour.to_s.underscore.to_sym][:by]
98
+ targetted_by_models.each do |targetted_by_model|
99
+ calling_entity.send("#{targetted_by_model.to_s.tableize}_#{progressive_present_behaviour}_me").each do |target_that_behaved_on_me|
100
+ target_that_behaved_on_me.send(Patriarch.undo(behaviour.to_s).underscore,calling_entity,options)
101
+ end
102
+ end
103
+ end
96
104
  # Dealing with active behaviour
97
105
  if my_behaviours[behaviour.to_s.underscore.to_sym][:on]
98
106
  acted_on_models = my_behaviours[behaviour.to_s.underscore.to_sym][:on]
@@ -103,15 +111,7 @@ class Patriarch::ToolServices::RedisCleanerService < Patriarch::Service
103
111
  end
104
112
  end
105
113
 
106
- # Dealing with passive behaviour
107
- if my_behaviours[behaviour.to_s.underscore.to_sym][:by]
108
- targetted_by_models = my_behaviours[behaviour.to_s.underscore.to_sym][:by]
109
- targetted_by_models.each do |targetted_by_model|
110
- calling_entity.send("#{targetted_by_model.to_s.tableize}_#{progressive_present_behaviour}_me").each do |target_that_behaved_on_me|
111
- target_that_behaved_on_me.send(Patriarch.undo(behaviour.to_s).underscore,calling_entity,options)
112
- end
113
- end
114
- end
114
+
115
115
  end # if my_behaviours.include?
116
116
 
117
117
  transac
@@ -36,16 +36,16 @@ class Patriarch::ToolServices::RedisExtractorService < Patriarch::Service
36
36
  result.map!{ |triplet_id_with_score| [triplet_id_with_score.first[0],tuple.last]}
37
37
  elsif options[:protagonist_type] == :target
38
38
  result.map!{ |triplet_id_with_score| [triplet_id_with_score.first[1],tuple.last]}
39
- #elsif options[:protagonist_type] == :medium
40
- # result.map!{ |triplet_id_with_score| [triplet_id_with_score.first[2],tuple.last]}
39
+ elsif options[:protagonist_type] == :medium
40
+ result.map!{ |triplet_id_with_score| [triplet_id_with_score.first[2],tuple.last]}
41
41
  end
42
42
  else
43
43
  if options[:protagonist_type] == :actor
44
44
  result.map!{ |triplet_id| triplet_id[0] }
45
45
  elsif options[:protagonist_type] == :target
46
46
  result.map!{ |triplet_id| triplet_id[1] }
47
- #elsif options[:protagonist_type] == :medium
48
- # result.map!{ |triplet_id| triplet_id[2] }
47
+ elsif options[:protagonist_type] == :medium
48
+ result.map!{ |triplet_id| triplet_id[2] }
49
49
  end
50
50
  end
51
51
  end
@@ -1,6 +1,7 @@
1
1
  module Patriarch
2
2
  class Transaction
3
3
  attr_reader :id, :steps, :current_step_number
4
+ attr_writer :steps
4
5
  attr_reader :type
5
6
 
6
7
  forwarded_methods_syms = [:relation_type,:actor_type,:target_type,:medium_type,
@@ -47,7 +48,13 @@ module Patriarch
47
48
  begin
48
49
  $redis.multi do
49
50
  steps.each do |step|
50
- step.execute
51
+ if step.is_a? TransactionStep
52
+ step.execute
53
+ elsif step.is_a? Transaction
54
+ step.steps.each do |nested_step|
55
+ nested_step.execute
56
+ end
57
+ end
51
58
  end
52
59
  end
53
60
  rescue Redis::BaseError => e #TODO find redis exception
@@ -1,3 +1,3 @@
1
1
  module Patriarch
2
- VERSION = "0.2.2"
2
+ VERSION = "0.2.3"
3
3
  end
data/patriarch.gemspec CHANGED
@@ -19,10 +19,10 @@ Gem::Specification.new do |spec|
19
19
 
20
20
  # Dependencies needed for testing
21
21
  spec.add_development_dependency "rspec"
22
+ spec.add_development_dependency "guard-rspec"
22
23
  spec.add_development_dependency "activerecord"
23
24
  spec.add_development_dependency "sqlite3"
24
- # TODO run with autotest/guard
25
-
25
+
26
26
  # Other options ...
27
27
  spec.files = `git ls-files`.split($\)
28
28
  spec.executables = spec.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
@@ -1,11 +1,15 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Patriarch::Behaviours do
4
+
5
+
4
6
  describe '#add_behaviour' do
7
+
5
8
  let(:monster) { Monster.create }
6
9
  let(:fallen_angel) { FallenAngel.create }
7
10
  let(:love_letter) { LoveLetter.create }
8
11
 
12
+
9
13
  context 'on a bipartite' do
10
14
 
11
15
  before(:all) do
@@ -160,6 +164,14 @@ describe Patriarch::Behaviours do
160
164
  monster.should respond_to("#{"fallen_angel".pluralize}_i_praise_via_#{"love_letter".pluralize}_ids")
161
165
  end
162
166
 
167
+ it "defines instances methods to retrieve instances of medium model instances used by actor model" do
168
+ monster.should respond_to("#{"love_letter".pluralize}_i_use_to_praise_#{"fallen_angel".pluralize}")
169
+ end
170
+
171
+ it "defines instances methods to retrieve ids of medium model instances used by actor model" do
172
+ monster.should respond_to("#{"love_letter".pluralize}_i_use_to_praise_#{"fallen_angel".pluralize}_ids")
173
+ end
174
+
163
175
  it "defines instances methods to retrieve model instances having relationships with target model" do
164
176
  progressive_praise = (Verbs::Conjugator.conjugate :praise, :aspect => :progressive).split(/ /).last
165
177
  fallen_angel.should respond_to("#{"monster".pluralize}_#{progressive_praise}_me_via_#{"love_letter".pluralize}")
@@ -170,6 +182,19 @@ describe Patriarch::Behaviours do
170
182
  fallen_angel.should respond_to("#{"monster".pluralize}_#{progressive_praise}_me_via_#{"love_letter".pluralize}_ids")
171
183
  end
172
184
 
185
+ it "defines instances methods to retrieve instances of medium model instances having relationships with target model" do
186
+ fallen_angel.should respond_to("#{"love_letter".pluralize}_used_by_#{"monster".pluralize}_to_praise_me")
187
+ end
188
+
189
+ it "defines instances methods to retrieve ids of medium model instances having relationships with target model" do
190
+ fallen_angel.should respond_to("#{"love_letter".pluralize}_used_by_#{"monster".pluralize}_to_praise_me_ids")
191
+ end
192
+
193
+ # TODO define_alias also ...
194
+ it "defines instances methods to retrieve ids of model instances entities behaviouring via medium model" do
195
+ pending('lazyness')
196
+ end
197
+
173
198
  it "defines behaviour instance method on actor model" do
174
199
  monster.should respond_to(:praise)
175
200
  end
@@ -219,15 +244,32 @@ describe Patriarch::Behaviours do
219
244
 
220
245
  context 'implements methods that' do
221
246
  it 'lets transaction build without running' do
222
- monster.praise(fallen_angel, love_letter, :stop_execution => true).should be_an_instance_of(Patriarch::Transaction)
247
+ monster.praise(love_letter, fallen_angel, :stop_execution => true).should be_an_instance_of(Patriarch::Transaction)
223
248
  end
224
249
 
225
250
  it 'lets undo transaction build without running' do
226
- monster.praise(fallen_angel, love_letter, :stop_execution => true).should be_an_instance_of(Patriarch::Transaction)
251
+ monster.praise(love_letter, fallen_angel, :stop_execution => true).should be_an_instance_of(Patriarch::Transaction)
227
252
  end
228
253
 
229
254
  # prepare examples to test both alias and normal methods ...
230
255
  shared_examples 'instances have behaviour working' do
256
+
257
+ it "allows actor to remember id of the medium used to behave on target" do
258
+ monster.love_letters_i_use_to_praise_fallen_angels_ids.should == [love_letter.id]
259
+ end
260
+
261
+ it "allows actor to remember instance of the medium used to behave on target" do
262
+ monster.love_letters_i_use_to_praise_fallen_angels.should == [love_letter]
263
+ end
264
+
265
+ it "allows target to remember id of the medium used to behave on him" do
266
+ fallen_angel.love_letters_used_by_monsters_to_praise_me_ids.should == [love_letter.id]
267
+ end
268
+
269
+ it "allows target to remember instance of the medium used to behave on him" do
270
+ fallen_angel.love_letters_used_by_monsters_to_praise_me.should == [love_letter]
271
+ end
272
+
231
273
  it "allows actor to remember target id" do
232
274
  monster.fallen_angels_i_praise_via_love_letters_ids.should == [fallen_angel.id]
233
275
  end
@@ -246,19 +288,36 @@ describe Patriarch::Behaviours do
246
288
  end
247
289
 
248
290
  context 'when doing direct behaviour' do
249
- before(:all) { monster.praise fallen_angel,love_letter }
291
+ before(:all) { monster.praise love_letter,fallen_angel }
250
292
  it_has_behavior 'instances have behaviour working'
251
- after(:all) { monster.undo_praise fallen_angel,love_letter }
293
+ after(:all) { monster.undo_praise love_letter,fallen_angel }
252
294
  end
253
295
 
254
296
  context 'when doing behaviour via alias method' do
255
- before(:all) { monster.flatter fallen_angel,love_letter }
297
+ before(:all) { monster.flatter love_letter,fallen_angel }
256
298
  it_has_behavior 'instances have behaviour working'
257
- after(:all) { monster.undo_praise fallen_angel,love_letter }
299
+ after(:all) { monster.undo_praise love_letter,fallen_angel }
258
300
  end
259
301
 
260
302
  # prepare examples to test both undo alias and undo normal methods ...
261
303
  shared_examples 'instances have undo behaviour working' do
304
+
305
+ it "erase medium id used to behave on target from actor's memory" do
306
+ monster.love_letters_i_use_to_praise_fallen_angels_ids.should be_empty
307
+ end
308
+
309
+ it "erase medium instance used to behave on target from actor's memory" do
310
+ monster.love_letters_i_use_to_praise_fallen_angels.should be_empty
311
+ end
312
+
313
+ it "erase medium id used to behave on target from target's memory" do
314
+ fallen_angel.love_letters_used_by_monsters_to_praise_me_ids.should be_empty
315
+ end
316
+
317
+ it "erase medium instance used to behave on target from target's memory" do
318
+ fallen_angel.love_letters_used_by_monsters_to_praise_me.should be_empty
319
+ end
320
+
262
321
  it "erase target id from actor's memory" do
263
322
  monster.fallen_angels_i_praise_via_love_letters_ids.should be_empty
264
323
  end
@@ -278,16 +337,16 @@ describe Patriarch::Behaviours do
278
337
 
279
338
  context 'when directly undoing behaviour' do
280
339
  before(:all) do
281
- monster.praise fallen_angel,love_letter
282
- monster.undo_praise fallen_angel,love_letter
340
+ monster.praise love_letter, fallen_angel
341
+ monster.undo_praise love_letter, fallen_angel
283
342
  end
284
343
  it_has_behavior 'instances have undo behaviour working'
285
344
  end
286
345
 
287
346
  context 'when undoing behaviour via undo alias' do
288
347
  before(:all) do
289
- monster.praise fallen_angel,love_letter
290
- monster.despise fallen_angel,love_letter
348
+ monster.praise love_letter,fallen_angel
349
+ monster.despise love_letter,fallen_angel
291
350
  end
292
351
  it_has_behavior 'instances have undo behaviour working'
293
352
  end
@@ -307,4 +366,32 @@ describe Patriarch::Behaviours do
307
366
  FallenAngell.add_behaviour :praise, :medium_between => [:monsterr,:fallenAngell]
308
367
  end
309
368
  end
369
+
370
+ context 'when using behaviour on entities that do not allow it' do
371
+
372
+ before(:all) do
373
+ class Monsterr < Monster; end
374
+ class FallenAngell < FallenAngel; end
375
+ class LoveLetterr < LoveLetter; end
376
+ Monsterr.add_behaviour :like, :on => [:fallenAngell], :as => :love, :undo_as => :hate
377
+ FallenAngell.add_behaviour :like, :by => [:monsterr] , :as => :love
378
+
379
+ Monsterr.add_behaviour :praise, :on => [:fallenAngell], :via => [:love_letter]
380
+ FallenAngell.add_behaviour :praise, :by => [:monsterr], :via => [:love_letter]
381
+ LoveLetterr.add_behaviour :praise, :medium_between => [:monsterr,:fallenAngell]
382
+ end
383
+
384
+ it "shall fail for bipartite" do
385
+ expect{ Monsterr.create.like(LoveLetterr.create) }.to raise_error
386
+ end
387
+
388
+ it "shall fail for triparite with unauthorized medium class instances" do
389
+ expect{ Monsterr.create.praise(Monsterr.create,FallenAngell.create) }.to raise_error
390
+ end
391
+
392
+ it "shall fail for triparite with unauthorized target class instances" do
393
+ expect{ Monsterr.create.praise(LoveLetterr.create,Monsterr.create) }.to raise_error
394
+ end
395
+ end
396
+
310
397
  end # desc Patriarch::Behaviours
@@ -43,7 +43,7 @@ describe 'entities including Patriarch::Behaviours #destroy' do
43
43
  end
44
44
 
45
45
  # This works with ActiveRecord as expected
46
- it "rollbacks redis clean" do
46
+ it "prevents redis clean" do
47
47
  f = FallenAngel.create
48
48
  m = Monster.create
49
49
  f.lure m
@@ -56,27 +56,4 @@ describe 'entities including Patriarch::Behaviours #destroy' do
56
56
  end
57
57
  end
58
58
 
59
- context "when redis transaction fails" do
60
- before(:all) do
61
- FallenAngel.class_eval do
62
- around_destroy :callback_fail
63
- def callback_fail
64
- # This will trigger Redis::CommandError if executed ...
65
- proc = Proc.new { $redis.hset "lal", "lil", 3 }
66
- proc_ = Proc.new { $redis.get "lal" }
67
- @redis_destroy_transac_object.add_to_queue proc
68
- @redis_destroy_transac_object.add_to_queue proc_
69
- puts @redis_destroy_transac_object.inspect
70
- end
71
- end
72
- end
73
-
74
- it "rollbacks sql transaction" do
75
- f = FallenAngel.create
76
- m = Monster.create
77
- f.lure m
78
- f.destroy #should fail
79
- f.destroyed?.should be_false
80
- end
81
- end
82
59
  end
@@ -9,14 +9,15 @@ describe Patriarch::ToolServices::RedisCleanerService.instance do
9
9
  FallenAngel.add_behaviour :like, :by => [:monster]
10
10
 
11
11
  # Tripartite behaviour ...
12
- FallenAngel.add_behaviour :praise, :on => [:monster], :via => [:loveLetter]
13
- Monster.add_behaviour :praise, :by => [:fallenAngel], :via => [:loveLetter]
12
+ FallenAngel.add_behaviour :praise, :by => [:monster], :via => [:loveLetter]
13
+ Monster.add_behaviour :praise, :on => [:fallenAngel], :via => [:loveLetter]
14
14
  LoveLetter.add_behaviour :praise, :medium_between => [:fallenAngel,:monster]
15
15
  end
16
16
 
17
17
  let(:monster) { Monster.create }
18
18
  let(:beast) { Monster.create }
19
19
  let(:love_letter) { LoveLetter.create }
20
+ let(:fallen_angel) { FallenAngel.create }
20
21
  # Wrong usage when summoning several times fallen_angel within tests; bad knowledge of
21
22
  # let is in cause i think
22
23
  # let(:fallen_angel) { FallenAngel.new }
@@ -26,8 +27,8 @@ describe Patriarch::ToolServices::RedisCleanerService.instance do
26
27
  it "removes presence into other sets for each behaviour" do
27
28
  f = FallenAngel.create
28
29
  m = Monster.create
29
- f.lure m
30
30
  m.like f
31
+ f.lure m
31
32
  instance.clean_all(f).execute
32
33
  f.monsters_i_lure.should be_empty
33
34
  f.monsters_liking_me.should be_empty
@@ -56,17 +57,17 @@ describe Patriarch::ToolServices::RedisCleanerService.instance do
56
57
  end
57
58
 
58
59
  it "removes given tripartite behaviour binds on other entities" do
59
- f = FallenAngel.create
60
- f.praise monster,love_letter
61
- instance.clean_behaviour(f,:praise).execute
62
- monster.fallen_angels_praising_me_via_love_letters.include?(f).should be_false
60
+ m = Monster.create
61
+ m.praise love_letter,fallen_angel
62
+ instance.clean_behaviour(m,:praise).execute
63
+ fallen_angel.monsters_praising_me_via_love_letters.include?(m).should be_false
63
64
  end
64
65
 
65
66
  it "removes given tripartite behaviour binds on self" do
66
- f = FallenAngel.create
67
- f.praise monster,love_letter
68
- instance.clean_behaviour(f,:praise).execute
69
- f.monsters_i_praise_via_love_letters.include?(monster).should be_false
67
+ m = Monster.create
68
+ m.praise love_letter,fallen_angel
69
+ instance.clean_behaviour(m,:praise).execute
70
+ m.fallen_angels_i_praise_via_love_letters.include?(monster).should be_false
70
71
  end
71
72
 
72
73
  it "runs within a unique transaction" do
data/spec/spec_helper.rb CHANGED
@@ -53,26 +53,15 @@ class LoveLetter < ActiveRecord::Base; include Patriarch::Behaviours; end
53
53
  # Setting standalone database to run tests
54
54
  ActiveRecord::Base.establish_connection(
55
55
  :adapter => "sqlite3",
56
- :database => ":memory:"
56
+ :database => ":memory:" #":memory:"
57
57
  )
58
58
 
59
59
  # Load minimal schema for database
60
60
 
61
- ActiveRecord::Schema.define do
62
-
63
- create_table "fallen_angels", :force => true do |t|
64
- t.datetime "created_at", :null => false
65
- t.datetime "updated_at", :null => false
66
- end
67
-
68
- create_table "love_letters", :force => true do |t|
69
- t.datetime "created_at", :null => false
70
- t.datetime "updated_at", :null => false
61
+ capture(:stdout) do
62
+ ActiveRecord::Schema.define do
63
+ create_table "fallen_angels", :force => true
64
+ create_table "love_letters", :force => true
65
+ create_table "monsters", :force => true
71
66
  end
72
-
73
- create_table "monsters", :force => true do |t|
74
- t.datetime "created_at", :null => false
75
- t.datetime "updated_at", :null => false
76
- end
77
-
78
- end
67
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: patriarch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-08 00:00:00.000000000 Z
12
+ date: 2012-12-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: verbs
16
- requirement: &8230400 !ruby/object:Gem::Requirement
16
+ requirement: &17816280 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *8230400
24
+ version_requirements: *17816280
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: railties
27
- requirement: &8229980 !ruby/object:Gem::Requirement
27
+ requirement: &17815860 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *8229980
35
+ version_requirements: *17815860
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: activerecord
38
- requirement: &8229560 !ruby/object:Gem::Requirement
38
+ requirement: &17815420 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *8229560
46
+ version_requirements: *17815420
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rspec
49
- requirement: &8229140 !ruby/object:Gem::Requirement
49
+ requirement: &17814980 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,21 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *8229140
57
+ version_requirements: *17814980
58
+ - !ruby/object:Gem::Dependency
59
+ name: guard-rspec
60
+ requirement: &17814500 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *17814500
58
69
  - !ruby/object:Gem::Dependency
59
70
  name: activerecord
60
- requirement: &8228720 !ruby/object:Gem::Requirement
71
+ requirement: &17813840 !ruby/object:Gem::Requirement
61
72
  none: false
62
73
  requirements:
63
74
  - - ! '>='
@@ -65,10 +76,10 @@ dependencies:
65
76
  version: '0'
66
77
  type: :development
67
78
  prerelease: false
68
- version_requirements: *8228720
79
+ version_requirements: *17813840
69
80
  - !ruby/object:Gem::Dependency
70
81
  name: sqlite3
71
- requirement: &8228300 !ruby/object:Gem::Requirement
82
+ requirement: &17813220 !ruby/object:Gem::Requirement
72
83
  none: false
73
84
  requirements:
74
85
  - - ! '>='
@@ -76,7 +87,7 @@ dependencies:
76
87
  version: '0'
77
88
  type: :development
78
89
  prerelease: false
79
- version_requirements: *8228300
90
+ version_requirements: *17813220
80
91
  description: Patriach is about adding behaviours on the fly to good old active record
81
92
  models.
82
93
  email: