surrounded 0.9.11 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +8 -5
- data/Changelog.md +6 -1
- data/Gemfile +1 -7
- data/README.md +43 -42
- data/lib/surrounded/context.rb +10 -8
- data/lib/surrounded/context/initializing.rb +2 -6
- data/lib/surrounded/context/role_builders.rb +3 -11
- data/lib/surrounded/version.rb +1 -1
- data/test/collection_role_players_test.rb +1 -1
- data/test/context_access_test.rb +1 -1
- data/test/context_forwarding_test.rb +1 -1
- data/test/context_reuse_test.rb +1 -1
- data/test/context_shortcuts_test.rb +1 -1
- data/test/east_oriented_triggers_test.rb +4 -4
- data/test/example_delegate_class_test.rb +1 -1
- data/test/example_proxy_test.rb +2 -2
- data/test/example_threaded_test.rb +1 -1
- data/test/example_wrapper_test.rb +1 -1
- data/test/initialization_test.rb +37 -29
- data/test/override_methods_test.rb +1 -1
- data/test/role_context_method_test.rb +3 -3
- data/test/surrounded_context_test.rb +7 -7
- data/test/surrounded_test.rb +3 -3
- data/test/test_helper.rb +2 -6
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 32e91c5123e8db80ef2b15289144c2cec4f5a774
|
4
|
+
data.tar.gz: 8ffdd46f4497eee0fc0c96f29de1efb0631879d6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a2c8b8e5b137b7b8b74c2642cdc490bbcab860dcd85ca0a08e9b67490ce0f1ff4c5b405821bb3daa1e3a643514e75023265cc902b0617a3cff1bee90a61a2480
|
7
|
+
data.tar.gz: a25fd8d9c292be440405e732ce59f5087a0100a628a0f424ad95a918f72e924377c8485eeeec4a70fa1d01dd900ad5828530ee693ab252d1b56ebfa569aa16ad
|
data/.travis.yml
CHANGED
@@ -3,14 +3,17 @@ before_install:
|
|
3
3
|
language: ruby
|
4
4
|
cache: bundler
|
5
5
|
rvm:
|
6
|
-
- 2.
|
7
|
-
- 2.
|
8
|
-
- 2.
|
6
|
+
- 2.4.1
|
7
|
+
- 2.3.4
|
8
|
+
- 2.2.7
|
9
9
|
- ruby-head
|
10
10
|
- jruby-head
|
11
|
-
env:
|
12
|
-
- COVERALLS=true
|
13
11
|
matrix:
|
14
12
|
allow_failures:
|
15
13
|
- rvm: ruby-head
|
16
14
|
- rvm: jruby-head
|
15
|
+
addons:
|
16
|
+
code_climate:
|
17
|
+
repo_token: 7488b157e7b7f48eac865a9f830fe90a39e6ac10b17f854e17b9529e1854762c
|
18
|
+
after_success:
|
19
|
+
- bundle exec codeclimate-test-reporter
|
data/Changelog.md
CHANGED
@@ -2,6 +2,11 @@
|
|
2
2
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
|
5
|
+
## [1.0.0]
|
6
|
+
|
7
|
+
- Drop deprecations around Context initialize method. It now requires keyword arguments. Non-keyword argumennts may be used with initialize_without_keywords
|
8
|
+
- Remove code supporting exception cause it InvalidRoleType prior to ruby 2.1
|
9
|
+
|
5
10
|
## [0.9.11]
|
6
11
|
|
7
12
|
- Rely on the standard library Forwardable to setup how the RoleMap forwards messages to the container.
|
@@ -11,4 +16,4 @@ All notable changes to this project will be documented in this file.
|
|
11
16
|
## [0.9.10]
|
12
17
|
|
13
18
|
- Do something with name collisions when a role player has an existing method of another role in the context.
|
14
|
-
- Move InvalidRoleType exception under the host context class namespace. This allows you to rescue from your own namespace.
|
19
|
+
- Move InvalidRoleType exception under the host context class namespace. This allows you to rescue from your own namespace.
|
data/Gemfile
CHANGED
@@ -2,15 +2,9 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
group :test do
|
4
4
|
gem 'minitest'
|
5
|
-
# gem 'mutant', git: 'https://github.com/kbrock/mutant.git', ref: 'minitest'
|
6
5
|
gem "simplecov"
|
7
|
-
gem '
|
6
|
+
gem 'codeclimate-test-reporter', '~> 1.0.8'
|
8
7
|
gem 'casting'
|
9
|
-
gem 'rubinius-coverage', :platform => :rbx
|
10
|
-
end
|
11
|
-
|
12
|
-
platforms :rbx do
|
13
|
-
gem 'rubysl', '~> 2.0'
|
14
8
|
end
|
15
9
|
|
16
10
|
gemspec
|
data/README.md
CHANGED
@@ -3,8 +3,6 @@
|
|
3
3
|
|
4
4
|
[](https://travis-ci.org/saturnflyer/surrounded)
|
5
5
|
[](https://codeclimate.com/github/saturnflyer/surrounded)
|
6
|
-
[](https://coveralls.io/r/saturnflyer/surrounded)
|
7
|
-
[](http://badge.fury.io/rb/surrounded)
|
8
6
|
|
9
7
|
Surrounded is designed to help you better manage your business logic by keeping cohesive behaviors together. Bring objects together to implement your use cases and gain behavior only when necessary.
|
10
8
|
|
@@ -43,7 +41,7 @@ Here, you've specified the order when initializing so you can use it like this:
|
|
43
41
|
```ruby
|
44
42
|
user1 = User.find(1)
|
45
43
|
user2 = User.find(2)
|
46
|
-
context = Employment.new(user1, user2)
|
44
|
+
context = Employment.new(employee: user1, boss: user2)
|
47
45
|
```
|
48
46
|
|
49
47
|
That ensures that `user1` will become (and have all the features of) the `employee` and `user2` will become (and have all the features of) the `boss`.
|
@@ -53,20 +51,20 @@ There are 2 things left to do:
|
|
53
51
|
1. define behaviors for each role and
|
54
52
|
2. define how you can trigger their actions
|
55
53
|
|
56
|
-
|
54
|
+
Initializing contexts does not require the use of keyword arguments, but you may opt out.
|
57
55
|
|
58
|
-
You should consider using explicit names when initialize now by using `
|
56
|
+
You should consider using explicit names when initialize now by using `initialize_without_keywords`:
|
59
57
|
|
60
58
|
```ruby
|
61
59
|
class Employment
|
62
60
|
extend Surrounded::Context
|
63
61
|
|
64
|
-
|
62
|
+
initialize_withou_keywords :employee, :boss
|
65
63
|
end
|
66
64
|
|
67
65
|
user1 = User.find(1)
|
68
66
|
user2 = User.find(2)
|
69
|
-
context = Employment.new(
|
67
|
+
context = Employment.new(user1, user2)
|
70
68
|
```
|
71
69
|
|
72
70
|
This will allow you to prepare your accessing code to use keywords.
|
@@ -135,7 +133,7 @@ end
|
|
135
133
|
You'll need to define way to trigger these behaviors to occur so that you can use them.
|
136
134
|
|
137
135
|
```ruby
|
138
|
-
context = Employment.new(user1, user2)
|
136
|
+
context = Employment.new(employee: user1, boss: user2)
|
139
137
|
|
140
138
|
context.plan_weekend_work
|
141
139
|
```
|
@@ -249,7 +247,7 @@ By adding `Surrounded::Context` you can shortcut all this work.
|
|
249
247
|
```ruby
|
250
248
|
class Employment
|
251
249
|
extend Surrounded::Context
|
252
|
-
|
250
|
+
|
253
251
|
initialize(:employee, :boss)
|
254
252
|
|
255
253
|
module Employee
|
@@ -269,7 +267,7 @@ Well, it just so happens that you can. This code will work just fine:
|
|
269
267
|
```ruby
|
270
268
|
class Employment
|
271
269
|
extend Surrounded::Context
|
272
|
-
|
270
|
+
|
273
271
|
initialize(:employee, :boss)
|
274
272
|
|
275
273
|
class Employee < SimpleDelegator
|
@@ -285,7 +283,7 @@ But the syntax can be even simpler than that if you want.
|
|
285
283
|
```ruby
|
286
284
|
class Employment
|
287
285
|
extend Surrounded::Context
|
288
|
-
|
286
|
+
|
289
287
|
initialize(:employee, :boss)
|
290
288
|
|
291
289
|
role :employee do
|
@@ -299,7 +297,7 @@ By default, this code will create a module for you named `Employee`. If you want
|
|
299
297
|
```ruby
|
300
298
|
class Employment
|
301
299
|
extend Surrounded::Context
|
302
|
-
|
300
|
+
|
303
301
|
initialize(:employee, :boss)
|
304
302
|
|
305
303
|
wrap :employee do
|
@@ -313,7 +311,7 @@ But if you're making changes and you decide to move from a module to a wrapper o
|
|
313
311
|
```ruby
|
314
312
|
class Employment
|
315
313
|
extend Surrounded::Context
|
316
|
-
|
314
|
+
|
317
315
|
initialize(:employee, :boss)
|
318
316
|
|
319
317
|
role :employee, :wrapper do
|
@@ -346,7 +344,7 @@ end
|
|
346
344
|
|
347
345
|
Now the `User` instances will be able to implicitly access objects in their environment.
|
348
346
|
|
349
|
-
Via `method_missing` those `User` instances can access a `context` object it stores in an internal collection.
|
347
|
+
Via `method_missing` those `User` instances can access a `context` object it stores in an internal collection.
|
350
348
|
|
351
349
|
Inside of the `Employment` context we saw above, the `employee` and `boss` objects are instances of `User` for this example.
|
352
350
|
|
@@ -442,7 +440,7 @@ context.triggers #=> [:plan_weekend_work]
|
|
442
440
|
|
443
441
|
You might find that useful for dynamically defining user interfaces.
|
444
442
|
|
445
|
-
Sometimes I'd rather not use this DSL, however. I want to just write regular methods.
|
443
|
+
Sometimes I'd rather not use this DSL, however. I want to just write regular methods.
|
446
444
|
|
447
445
|
We can do that too. You'll need to opt in to this by specifying `trigger :your_method_name` for the methods you want to use.
|
448
446
|
|
@@ -454,7 +452,7 @@ class Employment
|
|
454
452
|
employee.quit
|
455
453
|
end
|
456
454
|
trigger :plan_weekend_work
|
457
|
-
|
455
|
+
|
458
456
|
# or in Ruby 2.x
|
459
457
|
trigger def plan_weekend_work
|
460
458
|
employee.quit
|
@@ -487,12 +485,12 @@ By running `protect_triggers` you'll be able to define when triggers may or may
|
|
487
485
|
class Employment
|
488
486
|
extend Surrounded::Context
|
489
487
|
protect_triggers
|
490
|
-
|
488
|
+
|
491
489
|
def plan_weekend_work
|
492
490
|
employee.quit
|
493
491
|
end
|
494
492
|
trigger :plan_weekend_work
|
495
|
-
|
493
|
+
|
496
494
|
disallow :plan_weekend_work do
|
497
495
|
employee.bank_balance > 1000000
|
498
496
|
end
|
@@ -627,14 +625,14 @@ class Organization
|
|
627
625
|
extend Surrounded::Context
|
628
626
|
|
629
627
|
initialize_without_keywords :leader, :members
|
630
|
-
|
628
|
+
|
631
629
|
role :members do
|
632
630
|
# special behavior for the collection
|
633
631
|
end
|
634
|
-
|
632
|
+
|
635
633
|
role :member do
|
636
634
|
# special behavior to be applied to each member in the collection
|
637
|
-
end
|
635
|
+
end
|
638
636
|
end
|
639
637
|
```
|
640
638
|
|
@@ -643,7 +641,7 @@ end
|
|
643
641
|
If you create a context object and need to use the same type of object with new role players, you may use the `rebind` method. It will clear any instance_variables from your context object and map the given objects to their names:
|
644
642
|
|
645
643
|
```ruby
|
646
|
-
context = Employment.new(current_user, the_boss)
|
644
|
+
context = Employment.new(employee: current_user, boss: the_boss)
|
647
645
|
context.rebind(employee: another_user, boss: someone_else) # same context, new players
|
648
646
|
```
|
649
647
|
|
@@ -671,7 +669,7 @@ class ExpensiveCalculation
|
|
671
669
|
end
|
672
670
|
end
|
673
671
|
end
|
674
|
-
ExpensiveCalculation.new(some_object, some_collection).send_to_background(:do_expensive_calculation)
|
672
|
+
ExpensiveCalculation.new(leader: some_object, members: some_collection).send_to_background(:do_expensive_calculation)
|
675
673
|
```
|
676
674
|
|
677
675
|
The above example is merely pseudo-code to show how `initializer_arguments` can be used. Customize it according to your own needs.
|
@@ -686,14 +684,14 @@ Surrounded::Context.default_role_type = :module # also :wrap, :wrapper, or :inte
|
|
686
684
|
|
687
685
|
class ActiviatingAccount
|
688
686
|
extend Surrounded::Context
|
689
|
-
|
687
|
+
|
690
688
|
# set the default role type only for this class
|
691
689
|
self.default_role_type = :module # also :wrap, :wrapper, or :interface
|
692
690
|
|
693
691
|
# shortcut initialization code
|
694
692
|
initialize(:activator, :account)
|
695
693
|
# or handle it yourself
|
696
|
-
def initialize(activator
|
694
|
+
def initialize(activator:, account:)
|
697
695
|
# this must be done to handle the mapping of roles to objects
|
698
696
|
# pass an array of arrays with role name symbol and the object for that role
|
699
697
|
map_roles([[:activator, activator],[:account, account]])
|
@@ -707,18 +705,21 @@ class ActiviatingAccount
|
|
707
705
|
# these also must be done if you create your own initialize method.
|
708
706
|
# this is a shortcut for using attr_reader and private
|
709
707
|
private_attr_reader :activator, :account
|
710
|
-
|
708
|
+
|
711
709
|
# If you need to mix default initialzation and extra work use a block
|
712
710
|
initialize :activator, :account do
|
713
711
|
map_roles(:third_party => get_some_other_object)
|
712
|
+
# explicitly set a single role
|
713
|
+
map_role(:something_new, 'SomeRoleConstant', object_to_play_the_role)
|
714
714
|
end
|
715
|
+
|
715
716
|
# but remember to set the extra accessors:
|
716
|
-
private_attr_reader :third_party
|
717
|
+
private_attr_reader :third_party, :something_new
|
717
718
|
|
718
|
-
# initialize
|
719
|
-
|
720
|
-
# this makes the following instance method signature with
|
721
|
-
def initialize(activator
|
719
|
+
# initialize without keyword arguments
|
720
|
+
initialize_without_keywords(:activator, :account)
|
721
|
+
# this makes the following instance method signature with positional arguments
|
722
|
+
def initialize(activator, account)
|
722
723
|
# ...
|
723
724
|
end
|
724
725
|
|
@@ -756,7 +757,7 @@ class ActiviatingAccount
|
|
756
757
|
# end
|
757
758
|
# end
|
758
759
|
|
759
|
-
# if you use a regular method and want to use context-specific behavior,
|
760
|
+
# if you use a regular method and want to use context-specific behavior,
|
760
761
|
# you must handle storing the context yourself:
|
761
762
|
def regular_method
|
762
763
|
apply_behaviors # handles the adding of all the roles and behaviors
|
@@ -771,30 +772,30 @@ class ActiviatingAccount
|
|
771
772
|
trigger :some_trigger_method do
|
772
773
|
activator.some_behavior # behavior always available
|
773
774
|
end
|
774
|
-
|
775
|
+
|
775
776
|
trigger def some_other_trigger
|
776
777
|
activator.some_behavior # behavior always available
|
777
778
|
end
|
778
|
-
|
779
|
+
|
779
780
|
def regular_non_trigger
|
780
781
|
activator.some_behavior # behavior always available with the following line
|
781
782
|
end
|
782
783
|
trigger :regular_non_trigger # turns the method into a trigger
|
783
|
-
|
784
|
+
|
784
785
|
# create restrictions on what triggers may be used
|
785
786
|
protect_triggers # <-- this is required if you want to protect your triggers this way.
|
786
787
|
disallow :some_trigger_method do
|
787
788
|
# whatever conditional code for the instance of the context
|
788
789
|
end
|
789
790
|
# you could also use `guard` instead of `disallow`
|
790
|
-
|
791
|
+
|
791
792
|
# or define your own method without the `disallow` keyword
|
792
793
|
def disallow_some_trigger_method?
|
793
794
|
# whatever conditional code for the instance of the context
|
794
795
|
end
|
795
796
|
# Prefer using `disallow` because it will wrap role players in their roles for you;
|
796
797
|
# the `disallow_some_trigger_method?` defined above, does not.
|
797
|
-
|
798
|
+
|
798
799
|
# Create shortcuts for triggers as class methods
|
799
800
|
# so you can do ActiviatingAccount.some_trigger_method(activator, account)
|
800
801
|
# This will make all triggers shortcuts.
|
@@ -804,11 +805,11 @@ class ActiviatingAccount
|
|
804
805
|
instance = self.new(activator, account)
|
805
806
|
instance.some_trigger_method
|
806
807
|
end
|
807
|
-
|
808
|
+
|
808
809
|
# Set triggers to always return the context object
|
809
810
|
# so you can enforce East-oriented style or Tell, Don't Ask
|
810
811
|
east_oriented_triggers
|
811
|
-
|
812
|
+
|
812
813
|
# Forward context instance methods as triggers to role players
|
813
814
|
forward_trigger :role_name, :method_name
|
814
815
|
forward_trigger :role_name, :method_name, :alternative_trigger_name_for_method_name
|
@@ -816,9 +817,9 @@ class ActiviatingAccount
|
|
816
817
|
forwarding [:list, :of, :methods, :to, :forward] => :role_name
|
817
818
|
end
|
818
819
|
|
819
|
-
# with
|
820
|
+
# with initialize (also keyword_initialize)
|
820
821
|
context = ActiviatingAccount.new(activator: some_object, account: some_account)
|
821
|
-
# with
|
822
|
+
# with initialize_without_keywords
|
822
823
|
context = ActiviatingAccount.new(some_object, some_account)
|
823
824
|
context.triggers # => lists a Set of triggers
|
824
825
|
# when using protect_triggers
|
@@ -1072,7 +1073,7 @@ And then execute:
|
|
1072
1073
|
Or install it yourself as:
|
1073
1074
|
|
1074
1075
|
$ gem install surrounded
|
1075
|
-
|
1076
|
+
|
1076
1077
|
## Installation for Rails
|
1077
1078
|
|
1078
1079
|
See [surrounded-rails](https://github.com/saturnflyer/surrounded-rails)
|
data/lib/surrounded/context.rb
CHANGED
@@ -53,7 +53,7 @@ module Surrounded
|
|
53
53
|
def default_role_type=(type)
|
54
54
|
@default_role_type = type
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
# Provide the ability to create access control methods for your triggers.
|
58
58
|
def protect_triggers; self.extend(::Surrounded::AccessControl); end
|
59
59
|
|
@@ -68,7 +68,7 @@ module Surrounded
|
|
68
68
|
def role_const_defined?(name)
|
69
69
|
const_defined?(name, false)
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
# Set a named constant and make it private
|
73
73
|
def private_const_set(name, const)
|
74
74
|
unless role_const_defined?(name)
|
@@ -119,11 +119,13 @@ module Surrounded
|
|
119
119
|
self.class.triggers
|
120
120
|
end
|
121
121
|
|
122
|
-
def rebind(options_hash)
|
122
|
+
def rebind(**options_hash)
|
123
123
|
clear_instance_variables
|
124
|
-
|
125
|
-
|
126
|
-
|
124
|
+
begin
|
125
|
+
initialize(options_hash)
|
126
|
+
rescue ArgumentError
|
127
|
+
initialize(*options_hash.values)
|
128
|
+
end
|
127
129
|
self
|
128
130
|
end
|
129
131
|
|
@@ -193,7 +195,7 @@ module Surrounded
|
|
193
195
|
return obj if !wrapper_name
|
194
196
|
klass.method(wrapper_name).call(obj)
|
195
197
|
end
|
196
|
-
|
198
|
+
|
197
199
|
def remove_behavior(role, behavior, object)
|
198
200
|
if behavior && role_const_defined?(behavior)
|
199
201
|
remover_name = (module_removal_methods + unwrap_methods).find do |meth|
|
@@ -306,4 +308,4 @@ module Surrounded
|
|
306
308
|
end
|
307
309
|
end
|
308
310
|
end
|
309
|
-
end
|
311
|
+
end
|
@@ -7,16 +7,12 @@ module Surrounded
|
|
7
7
|
parameters = setup_args.join(',')
|
8
8
|
default_initializer(parameters, setup_args, &block)
|
9
9
|
end
|
10
|
-
def initialize(*setup_args, &block)
|
11
|
-
warn "Deprecated: The behavior of 'initialize' will require keywords in the future
|
12
|
-
Consider using keyword arguments or switching to 'initialize_without_keywords'\n\n"
|
13
|
-
initialize_without_keywords(*setup_args, &block)
|
14
|
-
end
|
15
10
|
|
16
|
-
def
|
11
|
+
def initialize(*setup_args, &block)
|
17
12
|
parameters = setup_args.map{|a| "#{a}:"}.join(',')
|
18
13
|
default_initializer(parameters, setup_args, &block)
|
19
14
|
end
|
15
|
+
alias keyword_initialize initialize
|
20
16
|
alias initialize_with_keywords keyword_initialize
|
21
17
|
|
22
18
|
def initializer_block
|
@@ -1,14 +1,6 @@
|
|
1
1
|
module Surrounded
|
2
2
|
module Context
|
3
|
-
class InvalidRoleType < ::StandardError
|
4
|
-
unless method_defined?(:cause)
|
5
|
-
def initialize(msg=nil)
|
6
|
-
super
|
7
|
-
@cause = $!
|
8
|
-
end
|
9
|
-
attr_reader :cause
|
10
|
-
end
|
11
|
-
end
|
3
|
+
class InvalidRoleType < ::StandardError; end
|
12
4
|
|
13
5
|
module RoleBuilders
|
14
6
|
|
@@ -67,7 +59,7 @@ module Surrounded
|
|
67
59
|
# Admin
|
68
60
|
private_const_set(RoleName(name), Negotiator.for_role(behavior))
|
69
61
|
end
|
70
|
-
|
62
|
+
|
71
63
|
private
|
72
64
|
def RoleName(text, suffix=nil)
|
73
65
|
RoleName.new(text, suffix)
|
@@ -75,4 +67,4 @@ module Surrounded
|
|
75
67
|
|
76
68
|
end
|
77
69
|
end
|
78
|
-
end
|
70
|
+
end
|
data/lib/surrounded/version.rb
CHANGED
@@ -39,7 +39,7 @@ describe Surrounded::Context, 'auto-assigning roles for collections' do
|
|
39
39
|
let(:other_two){ User.new('Jason') }
|
40
40
|
let(:others){ [other_one, other_two] }
|
41
41
|
|
42
|
-
let(:context){ CollectionContext.new(members, others) }
|
42
|
+
let(:context){ CollectionContext.new(members: members, others: others) }
|
43
43
|
|
44
44
|
it 'assigns the collection role to collections' do
|
45
45
|
assert_equal members.size, context.get_members_count
|
data/test/context_access_test.rb
CHANGED
@@ -37,7 +37,7 @@ end
|
|
37
37
|
describe Surrounded::Context, 'access control' do
|
38
38
|
let(:user){ User.new("Jim") }
|
39
39
|
let(:other_user){ User.new("Guille") }
|
40
|
-
let(:context){ FilteredContext.new(user, other_user) }
|
40
|
+
let(:context){ FilteredContext.new(user: user, other_user: other_user) }
|
41
41
|
|
42
42
|
it 'includes triggers when allowed' do
|
43
43
|
context.stub(:disallow_if_ready?, false) do
|
@@ -38,7 +38,7 @@ end
|
|
38
38
|
describe Surrounded::Context, 'forwarding triggers' do
|
39
39
|
let(:user){ User.new("Jim") }
|
40
40
|
let(:other_user){ User.new("Guille") }
|
41
|
-
let(:context){ Sending.new(user, other_user) }
|
41
|
+
let(:context){ Sending.new(one: user, two: other_user) }
|
42
42
|
|
43
43
|
it 'forwards multiple configured instance methods as triggers' do
|
44
44
|
assert_equal 'hello', context.hello
|
data/test/context_reuse_test.rb
CHANGED
@@ -3,7 +3,7 @@ require 'test_helper'
|
|
3
3
|
describe Surrounded::Context, 'reusing context object' do
|
4
4
|
let(:user){ User.new("Jim") }
|
5
5
|
let(:other_user){ User.new("Guille") }
|
6
|
-
let(:context){ TestContext.new(user, other_user) }
|
6
|
+
let(:context){ TestContext.new(user: user, other_user: other_user) }
|
7
7
|
|
8
8
|
it 'allows rebinding new players' do
|
9
9
|
expect(context.access_other_object).must_equal 'Guille'
|
@@ -21,6 +21,6 @@ describe Surrounded::Context, 'shortcuts' do
|
|
21
21
|
let(:user){ User.new("Jim") }
|
22
22
|
let(:other){ User.new("Guille") }
|
23
23
|
it 'creates shortcut class methods for triggers' do
|
24
|
-
assert_equal 'it works, shorty!', ShortcutContext.shorty(user, other)
|
24
|
+
assert_equal 'it works, shorty!', ShortcutContext.shorty(user: user, other: other)
|
25
25
|
end
|
26
26
|
end
|
@@ -14,7 +14,7 @@ end
|
|
14
14
|
describe Surrounded::Context, '.east_oriented_triggers' do
|
15
15
|
let(:user){ User.new("Jim") }
|
16
16
|
let(:other_user){ User.new("Guille") }
|
17
|
-
let(:context){ EastTestContext.new(user, other_user) }
|
17
|
+
let(:context){ EastTestContext.new(user: user, other_user: other_user) }
|
18
18
|
|
19
19
|
it 'returns the context object from trigger methods' do
|
20
20
|
assert_equal context, context.ask?
|
@@ -24,8 +24,8 @@ end
|
|
24
24
|
describe Surrounded::Context, '.east_oriented_triggers with protect_triggers' do
|
25
25
|
let(:user){ User.new("Jim") }
|
26
26
|
let(:other_user){ User.new("Guille") }
|
27
|
-
let(:context){
|
28
|
-
ctxt = EastTestContext.new(user, other_user)
|
27
|
+
let(:context){
|
28
|
+
ctxt = EastTestContext.new(user: user, other_user: other_user)
|
29
29
|
ctxt.singleton_class.send(:protect_triggers)
|
30
30
|
ctxt
|
31
31
|
}
|
@@ -33,4 +33,4 @@ describe Surrounded::Context, '.east_oriented_triggers with protect_triggers' do
|
|
33
33
|
it 'returns the context object from trigger methods' do
|
34
34
|
assert_equal context, context.ask?
|
35
35
|
end
|
36
|
-
end
|
36
|
+
end
|
@@ -21,7 +21,7 @@ end
|
|
21
21
|
|
22
22
|
describe DelegateClassContext do
|
23
23
|
let(:context){
|
24
|
-
DelegateClassContext.new(User.new('jim'), Object.new)
|
24
|
+
DelegateClassContext.new(user: User.new('jim'), task: Object.new)
|
25
25
|
}
|
26
26
|
it 'wraps objects using DelegateClass' do
|
27
27
|
assert_equal 'hello from the admin DelegateClass wrapper!', context.do_something
|
data/test/example_proxy_test.rb
CHANGED
@@ -66,7 +66,7 @@ describe ProxyContext do
|
|
66
66
|
OpenStruct.new(name: 'GTD')
|
67
67
|
}
|
68
68
|
let(:context){
|
69
|
-
ProxyContext.new(user, task)
|
69
|
+
ProxyContext.new(admin: user, task: task)
|
70
70
|
}
|
71
71
|
it 'proxys methods between objects and its interface' do
|
72
72
|
assert_equal 'hello from Jim, the admin interface!', context.do_something
|
@@ -105,7 +105,7 @@ describe ProxyContext do
|
|
105
105
|
end
|
106
106
|
|
107
107
|
it 'allows Surrounded objects to interact with others' do
|
108
|
-
assert context.rebind(
|
108
|
+
assert context.rebind(admin: User.new('Surrounded'), task: task).talking
|
109
109
|
end
|
110
110
|
|
111
111
|
it 'works with frozen and primitive objects' do
|
@@ -54,7 +54,7 @@ describe ThreadedContext do
|
|
54
54
|
let(:members){ [amy, guille, jason, dave] }
|
55
55
|
|
56
56
|
it 'works in multi-threaded environments' do
|
57
|
-
meeting = ThreadedContext.new(jim, members)
|
57
|
+
meeting = ThreadedContext.new(leader: jim, members: members)
|
58
58
|
|
59
59
|
result = meeting.meet
|
60
60
|
|
@@ -20,7 +20,7 @@ end
|
|
20
20
|
|
21
21
|
describe WrapperContext do
|
22
22
|
let(:context){
|
23
|
-
WrapperContext.new(Object.new, Object.new)
|
23
|
+
WrapperContext.new(admin: Object.new, task: Object.new)
|
24
24
|
}
|
25
25
|
it 'wraps objects and allows them to respond to new methods' do
|
26
26
|
assert_equal 'hello from the admin wrapper!', context.do_something
|
data/test/initialization_test.rb
CHANGED
@@ -1,58 +1,66 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class
|
3
|
+
class KeywordContext
|
4
4
|
extend Surrounded::Context
|
5
5
|
|
6
|
-
|
6
|
+
keyword_initialize(:user, :other_user) do
|
7
7
|
@defined_by_initializer_block = 'yup'
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
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
12
|
|
16
13
|
it 'applies a provided block to the instance' do
|
17
|
-
context =
|
14
|
+
context = KeywordContext.new(user: User.new('Jim'), other_user: User.new('Amy'))
|
18
15
|
assert_equal 'yup', context.instance_variable_get(:@defined_by_initializer_block)
|
19
16
|
end
|
20
17
|
|
21
18
|
it 'keeps track of the original initialize arguments' do
|
22
19
|
jim = User.new('Jim')
|
23
20
|
amy = User.new('Amy')
|
24
|
-
context =
|
21
|
+
context = KeywordContext.new(user: jim, other_user: amy)
|
25
22
|
tracked = context.send(:initializer_arguments)
|
26
23
|
assert_equal jim, tracked[:user]
|
27
24
|
assert_equal amy, tracked[:other_user]
|
28
25
|
end
|
26
|
+
|
27
|
+
it 'raises errors with missing keywords' do
|
28
|
+
err = assert_raises(ArgumentError){
|
29
|
+
KeywordContext.new(other_user: User.new('Amy'))
|
30
|
+
}
|
31
|
+
assert_match(/missing keyword: user/, err.message)
|
32
|
+
end
|
29
33
|
end
|
30
34
|
|
31
|
-
|
32
|
-
|
33
|
-
|
35
|
+
class NonKeyworder
|
36
|
+
extend Surrounded::Context
|
37
|
+
|
38
|
+
initialize_without_keywords :this, :that do
|
39
|
+
self.instance_variable_set(:@defined_by_initializer_block, 'yes')
|
40
|
+
end
|
41
|
+
|
42
|
+
trigger :access_other_object do
|
43
|
+
that.name
|
44
|
+
end
|
45
|
+
end
|
34
46
|
|
35
|
-
|
36
|
-
|
37
|
-
|
47
|
+
describe Surrounded::Context, 'non-keyword initializers' do
|
48
|
+
it 'defines an initialize method accepting the same arguments' do
|
49
|
+
assert_equal 2, NonKeyworder.instance_method(:initialize).arity
|
38
50
|
end
|
39
51
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
52
|
+
it 'works without keyword arguments' do
|
53
|
+
assert NonKeyworder.new(User.new('Jim'), User.new('Guille'))
|
54
|
+
end
|
44
55
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
}
|
49
|
-
assert_match(/missing keyword: that/, err.message)
|
50
|
-
end
|
56
|
+
it 'evaluates a given block' do
|
57
|
+
assert_equal 'yes', NonKeyworder.new(User.new('Jim'), User.new('Guille')).instance_variable_get(:@defined_by_initializer_block)
|
58
|
+
end
|
51
59
|
|
52
|
-
|
53
|
-
|
54
|
-
|
60
|
+
it 'allows rebinding with a hash' do
|
61
|
+
context = NonKeyworder.new(User.new('Jim'), User.new('Guille'))
|
62
|
+
expect(context.access_other_object).must_equal 'Guille'
|
63
|
+
context.rebind(this: User.new('Amy'), that: User.new('Elizabeth'))
|
64
|
+
expect(context.access_other_object).must_equal 'Elizabeth'
|
55
65
|
end
|
56
|
-
|
57
|
-
STDOUT.puts "No support for keywords"
|
58
|
-
end
|
66
|
+
end
|
@@ -49,7 +49,7 @@ describe Surrounded::Context, 'custom role application' do
|
|
49
49
|
let(:user){ User.new('Jim') }
|
50
50
|
let(:other){ User.new('Amy') }
|
51
51
|
|
52
|
-
let(:context){ PrependedRoles.new(user, other) }
|
52
|
+
let(:context){ PrependedRoles.new(user: user, other: other) }
|
53
53
|
|
54
54
|
it 'allows you to override existing methods on a role player' do
|
55
55
|
assert_equal "Not what you thought, Jim", context.get_name
|
@@ -69,7 +69,7 @@ describe Surrounded::Context, '.role' do
|
|
69
69
|
|
70
70
|
describe 'interfaces' do
|
71
71
|
let(:context){
|
72
|
-
InterfaceContext.new(Hello.new, Hello.new)
|
72
|
+
InterfaceContext.new(admin: Hello.new, other: Hello.new)
|
73
73
|
}
|
74
74
|
it 'sets interface objects to use interface methods before singleton methods' do
|
75
75
|
assert_equal 'hello from admin', context.admin_hello
|
@@ -121,7 +121,7 @@ describe Surrounded::Context, '.role' do
|
|
121
121
|
the_test.assert_kind_of SimpleDelegator, admin
|
122
122
|
end
|
123
123
|
end
|
124
|
-
context = CustomDefaultWrap.new(Object.new, self)
|
124
|
+
context = CustomDefaultWrap.new(admin: Object.new, the_test: self)
|
125
125
|
context.check_admin_type
|
126
126
|
end
|
127
127
|
|
@@ -142,7 +142,7 @@ describe Surrounded::Context, '.role' do
|
|
142
142
|
end
|
143
143
|
end
|
144
144
|
|
145
|
-
context = CustomGlobalDefault.new(Object.new, self)
|
145
|
+
context = CustomGlobalDefault.new(admin: Object.new, the_test: self)
|
146
146
|
context.check_admin_type
|
147
147
|
ensure
|
148
148
|
Surrounded::Context.default_role_type = old_default
|
@@ -3,7 +3,7 @@ require 'test_helper'
|
|
3
3
|
describe Surrounded::Context, '#triggers' do
|
4
4
|
let(:user){ User.new("Jim") }
|
5
5
|
let(:other_user){ User.new("Guille") }
|
6
|
-
let(:context){ TestContext.new(user, other_user) }
|
6
|
+
let(:context){ TestContext.new(user: user, other_user: other_user) }
|
7
7
|
|
8
8
|
it 'lists the externally accessible trigger methods' do
|
9
9
|
assert context.triggers.include?(:access_other_object)
|
@@ -31,7 +31,7 @@ end
|
|
31
31
|
describe Surrounded::Context, '.trigger' do
|
32
32
|
let(:user){ User.new("Jim") }
|
33
33
|
let(:other_user){ User.new("Guille") }
|
34
|
-
let(:context){ TestContext.new(user, other_user) }
|
34
|
+
let(:context){ TestContext.new(user: user, other_user: other_user) }
|
35
35
|
|
36
36
|
it 'defines a public method on the context' do
|
37
37
|
assert context.respond_to?(:access_other_object)
|
@@ -78,7 +78,7 @@ describe Surrounded::Context, '#role?' do
|
|
78
78
|
end
|
79
79
|
external_object
|
80
80
|
}
|
81
|
-
let(:context){ TestContext.new(user, other_user) }
|
81
|
+
let(:context){ TestContext.new(user: user, other_user: other_user) }
|
82
82
|
|
83
83
|
it 'returns the object assigned to the named role' do
|
84
84
|
assert_equal user, user.get_role(:user, context)
|
@@ -101,7 +101,7 @@ describe Surrounded::Context, '#role_player?' do
|
|
101
101
|
let(:player){ User.new("Jim") }
|
102
102
|
let(:other_player){ User.new("Amy") }
|
103
103
|
let(:non_player){ User.new("Guille") }
|
104
|
-
let(:context){ TestContext.new(player, other_player) }
|
104
|
+
let(:context){ TestContext.new(user: player, other_user: other_player) }
|
105
105
|
|
106
106
|
it 'is true if the given object is a role player' do
|
107
107
|
expect(context.role_player?(player)).must_equal true
|
@@ -181,7 +181,7 @@ describe Surrounded::Context, 'assigning roles' do
|
|
181
181
|
|
182
182
|
let(:user){ User.new("Jim") }
|
183
183
|
let(:other_user){ CastingUser.new("Guille") }
|
184
|
-
let(:context){ RoleAssignmentContext.new(user, other_user) }
|
184
|
+
let(:context){ RoleAssignmentContext.new(user: user, other_user: other_user) }
|
185
185
|
|
186
186
|
it 'tries to use casting to add roles' do
|
187
187
|
refute_includes(context.other_user_ancestors, RoleAssignmentContext::OtherUser)
|
@@ -199,7 +199,7 @@ describe Surrounded::Context, 'assigning roles' do
|
|
199
199
|
it 'will use classes as roles' do
|
200
200
|
user = User.new('Jim')
|
201
201
|
|
202
|
-
context = ClassRoleAssignmentContext.new(user, self)
|
202
|
+
context = ClassRoleAssignmentContext.new(thing: user, the_test: self)
|
203
203
|
|
204
204
|
assert context.check_user_response
|
205
205
|
end
|
@@ -207,7 +207,7 @@ describe Surrounded::Context, 'assigning roles' do
|
|
207
207
|
it 'does not use constants defined outside the context class' do
|
208
208
|
special = User.new('Special')
|
209
209
|
other = User.new('Other')
|
210
|
-
context = IgnoreExternalConstantsContext.new(user, special, other)
|
210
|
+
context = IgnoreExternalConstantsContext.new(user: user, special: special, other: other)
|
211
211
|
assert_equal User, context.check_special
|
212
212
|
end
|
213
213
|
end
|
data/test/surrounded_test.rb
CHANGED
@@ -16,7 +16,7 @@ describe "Surrounded" do
|
|
16
16
|
let(:external_user){ User.new("External User") }
|
17
17
|
|
18
18
|
let(:context){
|
19
|
-
TestContext.new(jim, guille)
|
19
|
+
TestContext.new(user: jim, other_user: guille)
|
20
20
|
}
|
21
21
|
|
22
22
|
it "has access to objects in the context" do
|
@@ -46,7 +46,7 @@ describe "Surrounded", "added to an existing object" do
|
|
46
46
|
|
47
47
|
other = User.new('Guille')
|
48
48
|
|
49
|
-
context = TestContext.new(thing, other)
|
49
|
+
context = TestContext.new(user: thing, other_user: other)
|
50
50
|
assert context.access_other_object
|
51
51
|
end
|
52
52
|
end
|
@@ -61,4 +61,4 @@ describe "Surrounded", "added to an object through another module" do
|
|
61
61
|
object.extend(SpecialSurrounding)
|
62
62
|
assert object.respond_to?(:context, true)
|
63
63
|
end
|
64
|
-
end
|
64
|
+
end
|
data/test/test_helper.rb
CHANGED
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.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "'Jim Gay'"
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-04-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: triad
|
@@ -125,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
125
125
|
version: '0'
|
126
126
|
requirements: []
|
127
127
|
rubyforge_project:
|
128
|
-
rubygems_version: 2.
|
128
|
+
rubygems_version: 2.6.8
|
129
129
|
signing_key:
|
130
130
|
specification_version: 4
|
131
131
|
summary: Create encapsulated environments for your objects.
|
@@ -149,4 +149,3 @@ test_files:
|
|
149
149
|
- test/surrounded_context_test.rb
|
150
150
|
- test/surrounded_test.rb
|
151
151
|
- test/test_helper.rb
|
152
|
-
has_rdoc:
|