surrounded 0.9.8 → 0.9.9

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f5e41776a1619ac88e5a77857ae85f6d0ef7bbf1
4
- data.tar.gz: 2e39e542b1955af150bf148dc4b15fd29bd7dd46
3
+ metadata.gz: 676d57f548d17fbf0d9112208472938b7c5a2e82
4
+ data.tar.gz: 830bf96b8114f786840315b24fba5f90450be813
5
5
  SHA512:
6
- metadata.gz: 2bbac0d9d89de2880aee0c54b8916a37d7862d4071f0d9a24f9e93cc7df53733fc9b9e206fbe7552736ef0c90f1320e728fe0990deeda8a03e5921b6080ccc59
7
- data.tar.gz: 94765d82ed5d64e8d2318ddb53cafd2ad633e3288157df9528df6a40687d04dda66f50b432572a1dc9f361bb73f0549e7d5453b9f5872ab69c4a5c2f6f8aeeab
6
+ metadata.gz: 1bc24e149d0fefd9961ea08c92a01390cbdc24d94a42fa6a06e542a219838572f3c75fa8e65ec6e54324236a53950461e4b81afd7e732a0a6765220e4c5a27d6
7
+ data.tar.gz: dd4ee61d04717d8418e011e6421031196bada55ae25d6fb04e24c9913fc06ccc2c199a443c4f554618f3298ef6e7319d81467ee69e43b135cf7da6aa2214f0cd
data/README.md CHANGED
@@ -475,7 +475,7 @@ This will allow you to write methods like you normally would. They are aliased i
475
475
 
476
476
  This works like Ruby's `public`,`protected`, and `private` keywords in that you can send symbols of method names to it. But `trigger` does not alter the parsing of the document like those core keywords do. In other words, you can't merely type `trigger` on one line, and have methods added afterward be treated as trigger methods.
477
477
 
478
- ## Access Control for Triggers
478
+ ## Access Control / Permissions for Triggers
479
479
 
480
480
  If you decide to build a user interface from the available triggers, you'll find you need to know what triggers are available.
481
481
 
@@ -647,6 +647,35 @@ context = Employment.new(current_user, the_boss)
647
647
  context.rebind(employee: another_user, boss: someone_else) # same context, new players
648
648
  ```
649
649
 
650
+ ## Background Processing
651
+
652
+ While there's no specific support for background processing, your context objects make it easy for you to add your own by remembering what arguments were provided during initialization.
653
+
654
+ When you initialize a context, it will keep track of the parameters and their matching arguments in a private hash called `initializer_arguments`. This allows you to write methods to create a context object and have itself sent to a background processor.
655
+
656
+ ```ruby
657
+ class ExpensiveCalculation
658
+ extend Surrounded::Context
659
+
660
+ initialize :leader, :members
661
+
662
+ def send_to_background(trigger_method)
663
+ background_arguments = initializer_arguments.merge(trigger: trigger_method)
664
+ BackgroundProcessor.enqueue(self.class.name, **background_arguments)
665
+ end
666
+
667
+ class BackgroundProcessor
668
+ def perform(**args)
669
+ trigger_name = args.delete(:trigger)
670
+ job_class.new(args).send(trigger_name)
671
+ end
672
+ end
673
+ end
674
+ ExpensiveCalculation.new(some_object, some_collection).send_to_background(:do_expensive_calculation)
675
+ ```
676
+
677
+ The above example is merely pseudo-code to show how `initializer_arguments` can be used. Customize it according to your own needs.
678
+
650
679
  ## Overview in code
651
680
 
652
681
  Here's a view of the possibilities in code.
@@ -36,12 +36,14 @@ module Surrounded
36
36
  line = __LINE__; mod.class_eval %{
37
37
  def initialize(#{params})
38
38
  @role_map = role_mapper_class.new
39
- map_roles(#{setup_args.to_s}.zip([#{setup_args.join(',')}]))
39
+ @initializer_arguments = Hash[#{setup_args.to_s}.zip([#{setup_args.join(',')}])]
40
+ map_roles(@initializer_arguments)
40
41
  self.class.apply_initializer_block(self)
41
42
  end
42
43
  }, __FILE__, line
43
44
  const_set("ContextInitializer", mod)
44
45
  include mod
46
+ private_attr_reader :initializer_arguments
45
47
  end
46
48
  end
47
49
  end
@@ -1,5 +1,5 @@
1
1
  module Surrounded
2
- VERSION = "0.9.8"
2
+ VERSION = "0.9.9"
3
3
 
4
4
  def self.version
5
5
  VERSION
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ require 'casting'
4
+ class CastingUser < User
5
+ include Casting::Client
6
+ delegate_missing_methods
7
+ end
@@ -0,0 +1,51 @@
1
+ require 'test_helper'
2
+
3
+ class CollectionContext
4
+ extend Surrounded::Context
5
+
6
+ initialize :members, :others
7
+
8
+ trigger :get_members_count do
9
+ members.member_count
10
+ end
11
+
12
+ trigger :get_member_show do
13
+ members.map(&:show).join(', ')
14
+ end
15
+
16
+ role :members do
17
+ def member_count
18
+ size
19
+ end
20
+ end
21
+
22
+ role :member do
23
+ def show
24
+ "member show"
25
+ end
26
+ end
27
+
28
+ role :others do; end
29
+ role :other do; end
30
+
31
+ end
32
+
33
+ describe Surrounded::Context, 'auto-assigning roles for collections' do
34
+ let(:member_one){ User.new('Jim') }
35
+ let(:member_two){ User.new('Amy') }
36
+ let(:members){ [member_one, member_two] }
37
+
38
+ let(:other_one){ User.new('Guille') }
39
+ let(:other_two){ User.new('Jason') }
40
+ let(:others){ [other_one, other_two] }
41
+
42
+ let(:context){ CollectionContext.new(members, others) }
43
+
44
+ it 'assigns the collection role to collections' do
45
+ assert_equal members.size, context.get_members_count
46
+ end
47
+
48
+ it 'assigns a defined role to each item in a role player collection' do
49
+ assert_equal "member show, member show", context.get_member_show
50
+ end
51
+ end
@@ -0,0 +1,22 @@
1
+ require 'test_helper'
2
+
3
+ describe Surrounded::Context, 'reusing context object' do
4
+ let(:user){ User.new("Jim") }
5
+ let(:other_user){ User.new("Guille") }
6
+ let(:context){ TestContext.new(user, other_user) }
7
+
8
+ it 'allows rebinding new players' do
9
+ expect(context.access_other_object).must_equal 'Guille'
10
+ context.rebind(user: User.new('Amy'), other_user: User.new('Elizabeth'))
11
+ expect(context.access_other_object).must_equal 'Elizabeth'
12
+ end
13
+
14
+ it 'clears internal storage when rebinding' do
15
+ originals = context.instance_variables.map{|var| context.instance_variable_get(var) }
16
+ context.rebind(user: User.new('Amy'), other_user: User.new('Elizabeth'))
17
+ new_ivars = context.instance_variables.map{|var| context.instance_variable_get(var) }
18
+ originals.zip(new_ivars).each do |original_ivar, new_ivar|
19
+ expect(original_ivar).wont_equal new_ivar
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,58 @@
1
+ require 'test_helper'
2
+
3
+ class InitContext
4
+ extend Surrounded::Context
5
+
6
+ initialize(:user, :other_user) do
7
+ @defined_by_initializer_block = 'yup'
8
+ end
9
+ end
10
+
11
+ describe Surrounded::Context, '.initialize' do
12
+ it 'defines an initialize method accepting the same arguments' do
13
+ assert_equal 2, InitContext.instance_method(:initialize).arity
14
+ end
15
+
16
+ it 'applies a provided block to the instance' do
17
+ context = InitContext.new(User.new('Jim'), User.new('Amy'))
18
+ assert_equal 'yup', context.instance_variable_get(:@defined_by_initializer_block)
19
+ end
20
+
21
+ it 'keeps track of the original initialize arguments' do
22
+ jim = User.new('Jim')
23
+ amy = User.new('Amy')
24
+ context = InitContext.new(jim, amy)
25
+ tracked = context.send(:initializer_arguments)
26
+ assert_equal jim, tracked[:user]
27
+ assert_equal amy, tracked[:other_user]
28
+ end
29
+ end
30
+
31
+ begin
32
+ class Keyworder
33
+ extend Surrounded::Context
34
+
35
+ keyword_initialize :this, :that do
36
+ self.instance_variable_set(:@defined_by_initializer_block, 'yes')
37
+ end
38
+ end
39
+
40
+ describe Surrounded::Context, 'keyword initializers' do
41
+ it 'works with keyword arguments' do
42
+ assert Keyworder.new(this: User.new('Jim'), that: User.new('Guille'))
43
+ end
44
+
45
+ it 'raises errors with missing keywords' do
46
+ err = assert_raises(ArgumentError){
47
+ Keyworder.new(this: User.new('Amy'))
48
+ }
49
+ assert_match(/missing keyword: that/, err.message)
50
+ end
51
+
52
+ it 'evaluates a given block' do
53
+ assert_equal 'yes', Keyworder.new(this: User.new('Jim'), that: User.new('Guille')).instance_variable_get(:@defined_by_initializer_block)
54
+ end
55
+ end
56
+ rescue SyntaxError
57
+ STDOUT.puts "No support for keywords"
58
+ end
@@ -0,0 +1,27 @@
1
+ require 'test_helper'
2
+
3
+ class BareObjectContext
4
+ extend Surrounded::Context
5
+
6
+ def initialize(number, string, user)
7
+ map_roles(:number => number, :string => string, :user => user)
8
+ end
9
+ private_attr_reader :number, :string, :user
10
+
11
+ role :user do
12
+ def output
13
+ [number.to_s, string, name].join(' - ')
14
+ end
15
+ end
16
+
17
+ trigger :output do
18
+ user.output
19
+ end
20
+ end
21
+
22
+ describe Surrounded::Context, 'skips affecting non-surrounded objects' do
23
+ it 'works with non-surrounded objects' do
24
+ context = BareObjectContext.new(123,'hello', User.new('Jim'))
25
+ assert_equal '123 - hello - Jim', context.output
26
+ end
27
+ end
@@ -97,18 +97,10 @@ describe Surrounded::Context, '#role?' do
97
97
  end
98
98
  end
99
99
 
100
- require 'casting'
101
- class CastingUser < User
102
- include Casting::Client
103
- delegate_missing_methods
104
- end
105
-
106
100
  class RoleAssignmentContext
107
101
  extend Surrounded::Context
108
102
 
109
- initialize(:user, :other_user) do
110
- self.instance_variable_set(:@defined_by_initializer_block, 'yup')
111
- end
103
+ initialize(:user, :other_user)
112
104
 
113
105
  def user_ancestors
114
106
  user.singleton_class.ancestors
@@ -152,12 +144,6 @@ class IgnoreExternalConstantsContext
152
144
  end
153
145
  end
154
146
 
155
- describe Surrounded::Context, '.initialize' do
156
- it 'defines an initialize method accepting the same arguments' do
157
- assert_equal 2, RoleAssignmentContext.instance_method(:initialize).arity
158
- end
159
- end
160
-
161
147
  class ClassRoleAssignmentContext
162
148
  extend Surrounded::Context
163
149
 
@@ -209,134 +195,4 @@ describe Surrounded::Context, 'assigning roles' do
209
195
  context = IgnoreExternalConstantsContext.new(user, special, other)
210
196
  assert_equal User, context.check_special
211
197
  end
212
-
213
- it 'applies a provided block to the instance' do
214
- assert_equal 'yup', context.instance_variable_get(:@defined_by_initializer_block)
215
- end
216
- end
217
-
218
- class BareObjectContext
219
- extend Surrounded::Context
220
-
221
- def initialize(number, string, user)
222
- map_roles(:number => number, :string => string, :user => user)
223
- end
224
- private_attr_reader :number, :string, :user
225
-
226
- role :user do
227
- def output
228
- [number.to_s, string, name].join(' - ')
229
- end
230
- end
231
-
232
- trigger :output do
233
- user.output
234
- end
235
- end
236
-
237
- describe Surrounded::Context, 'skips affecting non-surrounded objects' do
238
- it 'works with non-surrounded objects' do
239
- context = BareObjectContext.new(123,'hello', User.new('Jim'))
240
- assert_equal '123 - hello - Jim', context.output
241
- end
242
- end
243
-
244
- class CollectionContext
245
- extend Surrounded::Context
246
-
247
- initialize :members, :others
248
-
249
- trigger :get_members_count do
250
- members.member_count
251
- end
252
-
253
- trigger :get_member_show do
254
- members.map(&:show).join(', ')
255
- end
256
-
257
- role :members do
258
- def member_count
259
- size
260
- end
261
- end
262
-
263
- role :member do
264
- def show
265
- "member show"
266
- end
267
- end
268
-
269
- role :others do; end
270
- role :other do; end
271
-
272
- end
273
-
274
- describe Surrounded::Context, 'auto-assigning roles for collections' do
275
- let(:member_one){ User.new('Jim') }
276
- let(:member_two){ User.new('Amy') }
277
- let(:members){ [member_one, member_two] }
278
-
279
- let(:other_one){ User.new('Guille') }
280
- let(:other_two){ User.new('Jason') }
281
- let(:others){ [other_one, other_two] }
282
-
283
- let(:context){ CollectionContext.new(members, others) }
284
-
285
- it 'assigns the collection role to collections' do
286
- assert_equal members.size, context.get_members_count
287
- end
288
-
289
- it 'assigns a defined role to each item in a role player collection' do
290
- assert_equal "member show, member show", context.get_member_show
291
- end
292
- end
293
-
294
- describe Surrounded::Context, 'reusing context object' do
295
- let(:user){ User.new("Jim") }
296
- let(:other_user){ User.new("Guille") }
297
- let(:context){ TestContext.new(user, other_user) }
298
-
299
- it 'allows rebinding new players' do
300
- expect(context.access_other_object).must_equal 'Guille'
301
- context.rebind(user: User.new('Amy'), other_user: User.new('Elizabeth'))
302
- expect(context.access_other_object).must_equal 'Elizabeth'
303
- end
304
-
305
- it 'clears internal storage when rebinding' do
306
- originals = context.instance_variables.map{|var| context.instance_variable_get(var) }
307
- context.rebind(user: User.new('Amy'), other_user: User.new('Elizabeth'))
308
- new_ivars = context.instance_variables.map{|var| context.instance_variable_get(var) }
309
- originals.zip(new_ivars).each do |original_ivar, new_ivar|
310
- expect(original_ivar).wont_equal new_ivar
311
- end
312
- end
313
- end
314
-
315
- begin
316
- class Keyworder
317
- extend Surrounded::Context
318
-
319
- keyword_initialize :this, :that do
320
- self.instance_variable_set(:@defined_by_initializer_block, 'yes')
321
- end
322
- end
323
-
324
- describe Surrounded::Context, 'keyword initializers' do
325
- it 'works with keyword arguments' do
326
- assert Keyworder.new(this: User.new('Jim'), that: User.new('Guille'))
327
- end
328
-
329
- it 'raises errors with missing keywords' do
330
- err = assert_raises(ArgumentError){
331
- Keyworder.new(this: User.new('Amy'))
332
- }
333
- assert_match(/missing keyword: that/, err.message)
334
- end
335
-
336
- it 'evaluates a given block' do
337
- assert_equal 'yes', Keyworder.new(this: User.new('Jim'), that: User.new('Guille')).instance_variable_get(:@defined_by_initializer_block)
338
- end
339
- end
340
- rescue SyntaxError
341
- STDOUT.puts "No support for keywords"
342
- end
198
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: surrounded
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.8
4
+ version: 0.9.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - "'Jim Gay'"
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-16 00:00:00.000000000 Z
11
+ date: 2015-06-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: triad
@@ -83,14 +83,19 @@ files:
83
83
  - lib/surrounded/shortcuts.rb
84
84
  - lib/surrounded/version.rb
85
85
  - surrounded.gemspec
86
+ - test/casting_role_player_test.rb
87
+ - test/collection_role_players_test.rb
86
88
  - test/context_access_test.rb
87
89
  - test/context_forwarding_test.rb
90
+ - test/context_reuse_test.rb
88
91
  - test/context_shortcuts_test.rb
89
92
  - test/east_oriented_triggers_test.rb
90
93
  - test/example_delegate_class_test.rb
91
94
  - test/example_proxy_test.rb
92
95
  - test/example_threaded_test.rb
93
96
  - test/example_wrapper_test.rb
97
+ - test/initialization_test.rb
98
+ - test/non_surrounded_role_player_test.rb
94
99
  - test/override_methods_test.rb
95
100
  - test/role_context_method_test.rb
96
101
  - test/surrounded_context_test.rb
@@ -121,14 +126,19 @@ signing_key:
121
126
  specification_version: 4
122
127
  summary: Create encapsulated environments for your objects.
123
128
  test_files:
129
+ - test/casting_role_player_test.rb
130
+ - test/collection_role_players_test.rb
124
131
  - test/context_access_test.rb
125
132
  - test/context_forwarding_test.rb
133
+ - test/context_reuse_test.rb
126
134
  - test/context_shortcuts_test.rb
127
135
  - test/east_oriented_triggers_test.rb
128
136
  - test/example_delegate_class_test.rb
129
137
  - test/example_proxy_test.rb
130
138
  - test/example_threaded_test.rb
131
139
  - test/example_wrapper_test.rb
140
+ - test/initialization_test.rb
141
+ - test/non_surrounded_role_player_test.rb
132
142
  - test/override_methods_test.rb
133
143
  - test/role_context_method_test.rb
134
144
  - test/surrounded_context_test.rb