patriarch 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
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: