surrounded 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: eec57f6f3717bca03404f2acde19afb3cb2a08d4
4
+ data.tar.gz: 7c6fef1028b60551bcc1cafdb5e7e9099d1ab7ef
5
+ SHA512:
6
+ metadata.gz: 2fe9113c6aaed6c7a09c687045cb54ba792bc59521b8917b09fdbc43a7d17c065cb54eac1a437a1fabcd9d4f094e78e9d67bf75333553ffef6cc63b7d000524e
7
+ data.tar.gz: 6472c2aef734c56f55d9dc2a0f9992b7e4f693f2ff677685586a3fee3a872cb9bf2602f6cb05e9b68b82a040fc0bf2be32b6aec0c3d4f7ef849df02874a95f65
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .rvmrc
7
+ .DS_Store
8
+ Gemfile.lock
9
+ InstalledFiles
10
+ _yardoc
11
+ coverage
12
+ doc/
13
+ lib/bundler/man
14
+ pkg
15
+ rdoc
16
+ spec/reports
17
+ test/tmp
18
+ test/version_tmp
19
+ tmp
data/.simplecov ADDED
@@ -0,0 +1,3 @@
1
+ SimpleCov.start do
2
+ add_filter 'test'
3
+ end
data/.travis.yml ADDED
@@ -0,0 +1,15 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - jruby-19mode # JRuby in 1.9 mode
6
+ - ruby-head
7
+ - jruby-head
8
+ - rbx-19mode
9
+ env:
10
+ - COVERALLS=true
11
+ matrix:
12
+ allow_failures:
13
+ - rvm: ruby-head
14
+ - rvm: jruby-head
15
+ - rvm: rbx-19mode
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ group :test do
4
+ gem 'minitest'
5
+ gem "simplecov"
6
+ gem 'coveralls', :require => false
7
+ gem 'casting'
8
+ end
9
+
10
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 'Jim Gay'
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,205 @@
1
+ # Surrounded
2
+
3
+ [![Build Status](https://travis-ci.org/saturnflyer/surrounded.png?branch=master)](https://travis-ci.org/saturnflyer/surrounded)
4
+ [![Code Climate](https://codeclimate.com/github/saturnflyer/surrounded.png)](https://codeclimate.com/github/saturnflyer/surrounded)
5
+ [![Coverage Status](https://coveralls.io/repos/saturnflyer/surrounded/badge.png)](https://coveralls.io/r/saturnflyer/surrounded)
6
+
7
+ ## Create encapsulated environments for your objects.
8
+
9
+ Keep the distraction of other features out of your way. Write use cases and focus on just the business logic
10
+
11
+ ## Usage
12
+
13
+ Add `Surrounded` to your objects to give them awareness of other objects.
14
+
15
+ ```ruby
16
+ class User
17
+ include Surrounded
18
+ end
19
+ ```
20
+
21
+ Now your user instances will be able to get objects in their environment.
22
+
23
+ _What environment!? I don't get it._
24
+
25
+ I didn't explain that yet.
26
+
27
+ You can make an object which contains other objects. It acts as an environment
28
+ and objects inside should have knowledge of the other objects in the environment.
29
+ Take a breath, because there's a lot going on.
30
+
31
+ First, you extend a class with the appropriate module to turn it into an object environment:
32
+
33
+ ```ruby
34
+ class MyEnvironment
35
+ extend Surrounded::Context
36
+ end
37
+ ```
38
+
39
+ Typical initialization of this environment has a lot of code. For example:
40
+
41
+ ```ruby
42
+ class MyEnvironment
43
+ extend Surrounded::Context
44
+
45
+ attr_reader :employee, :boss
46
+ private :employee, :boss
47
+ def initialize(employee, boss)
48
+ @employee = employee.extend(Exmployee)
49
+ @boss = boss
50
+ end
51
+
52
+ module Employee
53
+ # extra behavior here...
54
+ end
55
+ end
56
+ ```
57
+
58
+ _WTF was all that!?_
59
+
60
+ Relax. I'll explain.
61
+
62
+ When you create an instance of `MyEnvironment` it has certain objects inside.
63
+ Here we see that it has an `employee` and a `boss`. Inside the methods of the environment it's simpler and easier to write `employee` instead of `@employee` so we make them `attr_reader`s. But we don't need these methods to be externally accessible so we set them to private.
64
+
65
+ Next, we want to add environment-specific behavior to the `employee` so we extend the object with the module `Employee`.
66
+
67
+ If you're going to be doing this a lot, it's painful. Here's what `Surrounded` does for you:
68
+
69
+ ```ruby
70
+ class MyEnvironment
71
+ extend Surrounded::Context
72
+
73
+ setup(:employee, :boss)
74
+
75
+ module Employee
76
+ # extra behavior here...
77
+ end
78
+ end
79
+ ```
80
+
81
+ There! All that boilerplate code is cleaned up.
82
+
83
+ Notice that there's no `Boss` module. If a module of that name does not exist, the object passed into initialize simply won't gain any new behavior.
84
+
85
+ _OK. I think I get it, but what about the objects? How are they aware of their environment? Isn't that what this is supposed to do?_
86
+
87
+ Yup. Ruby doesn't have a notion of a local environment, so we lean on `method_missing` to do the work for us.
88
+
89
+ ```ruby
90
+ class User
91
+ include Surrounded
92
+ end
93
+ ```
94
+
95
+ With that, all instances of `User` have implicit access to their surroundings.
96
+
97
+ _Yeah... How?_
98
+
99
+ Via `method_missing` those `User` instances can access a `context` object stored in `Thread.current`. I didn't mention how the context is set, however.
100
+
101
+ Your environment will have methods of it's own that will trigger actions on the objects inside, but we need those trigger methods to set the environment instance as the current context so that the objects it contains can access them.
102
+
103
+ Here's an example of what we want:
104
+
105
+ ```ruby
106
+ class MyEnvironment
107
+ # other stuff from above is still here...
108
+
109
+ def shove_it
110
+ Thread.current[:context] = self
111
+ employee.quit
112
+ Thread.current[:context] = nil
113
+ end
114
+
115
+ module Employee
116
+ def quit
117
+ say("I'm sick of this place, #{boss.name}!")
118
+ stomp
119
+ throw_papers
120
+ say("I quit!")
121
+ end
122
+ end
123
+ end
124
+ ```
125
+
126
+ What's happening in there is that when the `shove_it` method is called, the current environment object is stored as the context.
127
+
128
+ The behavior defined in the `Employee` module assumes that it may access other objects in it's local environment. The `boss` object, for example, is never explicitly passed in as an argument.
129
+
130
+ _WTF!? That's insane!_
131
+
132
+ I thought so too, at first. But continually passing references assumes there's no relationship between objects in that method. What `Surrounded` does for us is to make the relationship between objects and gives them the ability to access each other.
133
+
134
+ This simple example may seem trivial, but the more contextual code you have the more cumbersome passing references becomes. By moving knowledge to the local environment, you're free to make changes to the procedures without the need to alter method signatures with new refrences or the removal of unused ones.
135
+
136
+ By using `Surrounded::Context` you are declaring a relationship between the objects inside.
137
+
138
+ Because all the behavior is defined internally and only relevant internally, those relationships don't exist outside of the environment.
139
+
140
+ _OK. I think I understand. So I can change business logic just by changing the procedures and the objects. I don't need to adjust arguments for a new requirement. That's kind of cool!_
141
+
142
+ Damn right.
143
+
144
+ But you don't want to continually set those `Thread` variables, do you?
145
+
146
+ _No. That's annoying._
147
+
148
+ Yeah. Instead, it would be easier to have this library do the work for us.
149
+ Here's what you can do:
150
+
151
+ ```ruby
152
+ class MyEnvironment
153
+ # the other code from above...
154
+
155
+ trigger :shove_it do
156
+ employee.quit
157
+ end
158
+ end
159
+ ```
160
+
161
+ By using this `trigger` keyword, our block is the code we care about, but internally the method is written to set the `Thread` variables.
162
+
163
+ _Hmm. I don't like having to do that._
164
+
165
+ Me either. I'd rather just use `def` but getting automatic code for setting the context is really convenient.
166
+ It also allows us to store the triggers so that you can, for example, provide details outside of the environment about what triggers exist.
167
+
168
+ ```ruby
169
+ context = MyEnvironment.new(current_user, the_boss)
170
+ context.triggers #=> [:shove_it]
171
+ ```
172
+
173
+ You might find that useful for dynamically defining user interfaces.
174
+
175
+ ## Dependencies
176
+
177
+ The dependencies are minimal. The plan is to keep it that way but allow you to configure things as you need.
178
+
179
+ If you're using [Casting](http://github.com/saturnflyer/casting), for example, Surrounded will attempt to use that before extending an object, but it will still work without it.
180
+
181
+ ## To Do
182
+
183
+ Casting provides a way to remove features outside of a block. For now, the code doesn't attempt to `uncast` an object. It will in the future though.
184
+
185
+ ## Installation
186
+
187
+ Add this line to your application's Gemfile:
188
+
189
+ gem 'surrounded'
190
+
191
+ And then execute:
192
+
193
+ $ bundle
194
+
195
+ Or install it yourself as:
196
+
197
+ $ gem install surrounded
198
+
199
+ ## Contributing
200
+
201
+ 1. Fork it
202
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
203
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
204
+ 4. Push to the branch (`git push origin my-new-feature`)
205
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rake/testtask'
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.libs << "test"
7
+ t.test_files = FileList['test/*_test.rb']
8
+ t.ruby_opts = ["-w"]
9
+ t.verbose = true
10
+ end
11
+ task :default => :test
data/examples/rails.rb ADDED
@@ -0,0 +1,65 @@
1
+ # Here's an example of how you might use this in rails.
2
+
3
+ # First, be guarded against changes in third-party libraries
4
+ module Awareness
5
+ include Surrounded
6
+ include Casting::Client
7
+ delegate_missing_methods
8
+ end
9
+
10
+ class User
11
+ include Awareness
12
+ end
13
+
14
+ class ApplicationController
15
+ include Awareness
16
+ end
17
+
18
+ class SomeUseCase
19
+ extend Surrounded::Context
20
+
21
+ setup(:user, :other_user, :listener)
22
+
23
+ trigger :do_something do
24
+ user.something
25
+ end
26
+
27
+ module User
28
+ def something
29
+ puts "Hello, #{other_user}"
30
+ listener.redirect_to('/')
31
+ end
32
+ end
33
+ end
34
+
35
+ class SomethingController < ApplicationController
36
+ use_case = :SomeUseCase
37
+ def create
38
+ use_case = :SomeOverrideUseCase
39
+ trigger :do_something, current_user, User.last
40
+ end
41
+
42
+ def trigger(meth, *args)
43
+ use_case.new(*(args << self)).send(meth)
44
+ end
45
+
46
+ def self.use_case=(name)
47
+ @_default_use_case_name = name
48
+ end
49
+
50
+ def self.use_case
51
+ @_default_use_case_name.to_s.constantize
52
+ end
53
+
54
+ def use_case=(name)
55
+ @_use_case_name = name
56
+ end
57
+
58
+ def use_case
59
+ if defined?(@_use_case_name)
60
+ @_use_case_name.to_s.constantize
61
+ else
62
+ self.class.use_case
63
+ end
64
+ end
65
+ end
data/lib/surrounded.rb ADDED
@@ -0,0 +1,24 @@
1
+ require "surrounded/version"
2
+
3
+ module Surrounded
4
+ private
5
+
6
+ def method_missing(meth, *args, &block)
7
+ context.role?(meth){} || super
8
+ end
9
+
10
+ def respond_to_missing?(meth, include_private=false)
11
+ !!context.role?(meth){} || super
12
+ end
13
+
14
+ def context
15
+ Thread.current[:context] ||= []
16
+ Thread.current[:context].first || NullContext.new
17
+ end
18
+
19
+ class NullContext < BasicObject
20
+ def role?(*args)
21
+ nil
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,86 @@
1
+ require 'set'
2
+ module Surrounded
3
+ module Context
4
+ def self.extended(base)
5
+ base.send(:include, InstanceMethods)
6
+ end
7
+
8
+ def triggers
9
+ @triggers.dup
10
+ end
11
+
12
+ private
13
+
14
+ def setup(*setup_args)
15
+ attr_reader(*setup_args)
16
+ private(*setup_args)
17
+
18
+ define_method(:initialize){ |*args|
19
+ Hash[setup_args.zip(args)].each{ |role, object|
20
+
21
+ role_module_name = Context.classify_string(role)
22
+ klass = self.class
23
+
24
+ if mod = klass.const_defined?(role_module_name) && !mod.is_a?(Class)
25
+ object = Context.modify(object, klass.const_get(role_module_name))
26
+ end
27
+
28
+ roles[role.to_s] = object
29
+ instance_variable_set("@#{role}", object)
30
+ }
31
+ }
32
+ end
33
+
34
+ def trigger(name, *args, &block)
35
+ store_trigger(name)
36
+
37
+ define_method(:"trigger_#{name}", *args, &block)
38
+
39
+ private :"trigger_#{name}"
40
+
41
+ define_method(name, *args){
42
+ begin
43
+ (Thread.current[:context] ||= []).unshift(self)
44
+ self.send("trigger_#{name}", *args)
45
+ ensure
46
+ (Thread.current[:context] ||= []).shift
47
+ end
48
+ }
49
+ end
50
+
51
+ def store_trigger(name)
52
+ @triggers ||= Set.new
53
+ @triggers << name
54
+ end
55
+
56
+ def self.classify_string(string)
57
+ string.to_s.gsub(/(?:^|_)([a-z])/) { $1.upcase }
58
+ end
59
+
60
+ def self.modify(obj, mod)
61
+ return obj if mod.is_a?(Class)
62
+ if obj.respond_to?(:cast_as)
63
+ obj.cast_as(mod)
64
+ else
65
+ obj.extend(mod)
66
+ end
67
+ end
68
+
69
+ module InstanceMethods
70
+ def role?(name, &block)
71
+ accessor = eval('self', block.binding)
72
+ roles.values.include?(accessor) && roles[name.to_s]
73
+ end
74
+
75
+ def triggers
76
+ self.class.triggers
77
+ end
78
+
79
+ private
80
+
81
+ def roles
82
+ @roles ||= {}
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,3 @@
1
+ module Surrounded
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'surrounded/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "surrounded"
8
+ spec.version = Surrounded::VERSION
9
+ spec.authors = ["'Jim Gay'"]
10
+ spec.email = ["jim@saturnflyer.com"]
11
+ spec.description = %q{Gives an object implicit access to other objects in it's environment.}
12
+ spec.summary = %q{Create encapsulated environments for your objects.}
13
+ spec.homepage = "http://github.com/saturnflyer/surrounded"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ end
@@ -0,0 +1,161 @@
1
+ require 'test_helper'
2
+
3
+ describe Surrounded::Context, '#triggers' 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 'lists the externally accessible trigger methods' do
9
+ assert context.triggers.include?(:access_other_object)
10
+ end
11
+
12
+ it 'prevents altering the list of triggers externally' do
13
+ original_trigger_list = context.triggers
14
+ context.triggers << 'another_trigger'
15
+ assert_equal original_trigger_list, context.triggers
16
+ end
17
+ end
18
+
19
+ describe Surrounded::Context, '.triggers' do
20
+ it 'lists the externally accessible trigger methods' do
21
+ assert TestContext.triggers.include?(:access_other_object)
22
+ end
23
+
24
+ it 'prevents altering the list of triggers externally' do
25
+ original_trigger_list = TestContext.triggers
26
+ TestContext.triggers << 'another_trigger'
27
+ assert_equal original_trigger_list, TestContext.triggers
28
+ end
29
+ end
30
+
31
+ describe Surrounded::Context, '.trigger' do
32
+ let(:user){ User.new("Jim") }
33
+ let(:other_user){ User.new("Guille") }
34
+ let(:context){ TestContext.new(user, other_user) }
35
+
36
+ it 'defines a public method on the context' do
37
+ assert context.respond_to?(:access_other_object)
38
+ end
39
+
40
+ it 'gives objects access to each other inside the method' do
41
+ assert_raises(NoMethodError){
42
+ user.other_user
43
+ }
44
+ assert_equal "Guille", context.access_other_object
45
+ end
46
+ end
47
+
48
+ describe Surrounded::Context, '#role?' do
49
+ let(:user){
50
+ test_user = User.new("Jim")
51
+
52
+ def test_user.get_role(name, context)
53
+ context.role?(name){}
54
+ end
55
+
56
+ test_user
57
+ }
58
+ let(:other_user){ User.new("Guille") }
59
+ let(:external){
60
+ external_object = Object.new
61
+ def external_object.get_role_from_context(name, context)
62
+ context.role?(name){}
63
+ end
64
+ external_object
65
+ }
66
+ let(:context){ TestContext.new(user, other_user) }
67
+
68
+ it 'returns the object assigned to the named role' do
69
+ assert_equal user, user.get_role(:user, context)
70
+ end
71
+
72
+ it 'returns false if the role does not exist' do
73
+ refute user.get_role(:non_existant_role, context)
74
+ end
75
+
76
+ it 'returns false if the accessing object is not a role player in the context' do
77
+ refute external.get_role_from_context(:user, context)
78
+ end
79
+
80
+ it 'checks for the role based upon the calling object' do
81
+ refute context.role?(:user){} # this test is the caller
82
+ end
83
+ end
84
+
85
+ require 'casting'
86
+ CastingUser = Struct.new(:name)
87
+ class CastingUser
88
+ include Casting::Client
89
+ delegate_missing_methods
90
+ end
91
+
92
+ class RoleAssignmentContext
93
+ extend Surrounded::Context
94
+
95
+ setup(:user, :other_user)
96
+
97
+ trigger :user_ancestors do
98
+ user.singleton_class.ancestors
99
+ end
100
+
101
+ trigger :other_user_ancestors do
102
+ other_user.singleton_class.ancestors
103
+ end
104
+
105
+ trigger :check_user_response do
106
+ user.respond_to?(:a_method!)
107
+ end
108
+
109
+ trigger :check_other_user_response do
110
+ user.respond_to?(:a_method!)
111
+ end
112
+
113
+ module User
114
+ def a_method!; end
115
+ end
116
+ module OtherUser
117
+ def a_method!; end
118
+ end
119
+ end
120
+
121
+ describe Surrounded::Context, 'assigning roles' do
122
+ let(:user){ CastingUser.new("Jim") }
123
+ let(:other_user){ User.new("Guille") }
124
+ let(:context){ RoleAssignmentContext.new(user, other_user) }
125
+
126
+ it 'tries to use casting to add roles' do
127
+ refute_includes(context.user_ancestors, RoleAssignmentContext::User)
128
+ end
129
+
130
+ it 'extends objects with role modules failing casting' do
131
+ assert_includes(context.other_user_ancestors, RoleAssignmentContext::OtherUser)
132
+ end
133
+
134
+ it 'sets role players to respond to role methods' do
135
+ assert context.check_user_response
136
+ assert context.check_other_user_response
137
+ end
138
+
139
+ it 'will not use classes as roles' do
140
+ ClassRoleAssignmentContext = Class.new do
141
+ extend Surrounded::Context
142
+
143
+ setup(:thing, :the_test)
144
+
145
+ trigger :check_user_response do
146
+ the_test.refute thing.respond_to?(:method_from_class), 'did respond to :method_from_class'
147
+ end
148
+
149
+ class Thing
150
+ def method_from_class; end
151
+ end
152
+
153
+ end
154
+
155
+ user = User.new('Jim')
156
+
157
+ context = ClassRoleAssignmentContext.new(user, self)
158
+
159
+ context.check_user_response
160
+ end
161
+ end
@@ -0,0 +1,43 @@
1
+ require 'test_helper'
2
+
3
+ describe "Surrounded", 'without context' do
4
+
5
+ let(:jim){ User.new("Jim") }
6
+
7
+ it "never has context roles" do
8
+ Thread.current[:context] = []
9
+ assert_nil jim.send(:context).role?('anything')
10
+ end
11
+
12
+ end
13
+
14
+ describe "Surrounded" do
15
+ let(:jim){ User.new("Jim") }
16
+ let(:guille){ User.new("Guille") }
17
+ let(:external_user){ User.new("External User") }
18
+
19
+ let(:context){
20
+ TestContext.new(jim, guille)
21
+ }
22
+
23
+ before do
24
+ Thread.current[:context] = [context]
25
+ end
26
+
27
+ it "has access to objects in the context" do
28
+ assert_equal jim.other_user, guille
29
+ end
30
+ it "responds to messages for roles on the context" do
31
+ assert jim.respond_to?(:other_user)
32
+
33
+ Thread.current[:context] = []
34
+
35
+ refute jim.respond_to?(:other_user)
36
+ end
37
+
38
+ it "prevents access to context objects for external objects" do
39
+ assert_raises(NoMethodError){
40
+ external_user.user
41
+ }
42
+ end
43
+ end
@@ -0,0 +1,25 @@
1
+ require 'simplecov'
2
+ require 'minitest/autorun'
3
+ require 'coveralls'
4
+
5
+ if ENV['COVERALLS']
6
+ Coveralls.wear!
7
+ end
8
+
9
+ require 'surrounded'
10
+ require 'surrounded/context'
11
+
12
+ User = Struct.new(:name)
13
+ class User
14
+ include Surrounded
15
+ end
16
+
17
+ class TestContext
18
+ extend Surrounded::Context
19
+
20
+ setup(:user, :other_user)
21
+
22
+ trigger :access_other_object do
23
+ user.other_user.name
24
+ end
25
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: surrounded
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - '''Jim Gay'''
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-06-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Gives an object implicit access to other objects in it's environment.
42
+ email:
43
+ - jim@saturnflyer.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - .gitignore
49
+ - .simplecov
50
+ - .travis.yml
51
+ - Gemfile
52
+ - LICENSE.txt
53
+ - README.md
54
+ - Rakefile
55
+ - examples/rails.rb
56
+ - lib/surrounded.rb
57
+ - lib/surrounded/context.rb
58
+ - lib/surrounded/version.rb
59
+ - surrounded.gemspec
60
+ - test/surrounded_context_test.rb
61
+ - test/surrounded_test.rb
62
+ - test/test_helper.rb
63
+ homepage: http://github.com/saturnflyer/surrounded
64
+ licenses:
65
+ - MIT
66
+ metadata: {}
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 2.0.3
84
+ signing_key:
85
+ specification_version: 4
86
+ summary: Create encapsulated environments for your objects.
87
+ test_files:
88
+ - test/surrounded_context_test.rb
89
+ - test/surrounded_test.rb
90
+ - test/test_helper.rb