at 0.1.4 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/.rvmrc +1 -0
- data/Gemfile.lock +9 -5
- data/LICENSE +1 -1
- data/README.md +188 -28
- data/VERSION +1 -1
- data/at.gemspec +3 -3
- data/lib/at.rb +7 -29
- data/lib/at/instance_variable_delegator.rb +25 -0
- data/lib/at/setup.rb +6 -0
- data/spec/at_spec.rb +74 -1
- data/spec/spec_helper.rb +1 -1
- metadata +9 -6
- data/.yardoc/object_types +0 -0
- data/.yardoc/objects/root.dat +0 -0
- data/.yardoc/proxy_types +0 -0
- data/lib/at/import.rb +0 -10
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use --create 1.9.3@at
|
data/Gemfile.lock
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
at (0.1.
|
5
|
-
version (~> 1.0
|
4
|
+
at (0.1.4)
|
5
|
+
version (~> 1.0)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: http://rubygems.org/
|
9
9
|
specs:
|
10
|
-
activesupport (3.
|
10
|
+
activesupport (3.2.12)
|
11
|
+
i18n (~> 0.6)
|
12
|
+
multi_json (~> 1.0)
|
11
13
|
coderay (1.0.8)
|
12
14
|
diff-lcs (1.1.3)
|
13
15
|
fuubar (1.1.0)
|
@@ -26,9 +28,11 @@ GEM
|
|
26
28
|
guard-yard (2.0.1)
|
27
29
|
guard (>= 1.1.0)
|
28
30
|
yard (>= 0.7.0)
|
31
|
+
i18n (0.6.1)
|
29
32
|
listen (0.6.0)
|
30
33
|
lumberjack (1.0.2)
|
31
34
|
method_source (0.8.1)
|
35
|
+
multi_json (1.6.1)
|
32
36
|
pry (0.9.10)
|
33
37
|
coderay (~> 1.0.5)
|
34
38
|
method_source (~> 0.8)
|
@@ -54,11 +58,11 @@ PLATFORMS
|
|
54
58
|
ruby
|
55
59
|
|
56
60
|
DEPENDENCIES
|
57
|
-
activesupport (~> 3)
|
61
|
+
activesupport (~> 3.2)
|
58
62
|
at!
|
59
63
|
fuubar (~> 1.1)
|
60
64
|
github-markup (~> 0.7)
|
61
65
|
guard-rspec (~> 2.1)
|
62
66
|
guard-yard (~> 2.0)
|
63
67
|
rb-fsevent (~> 0.9)
|
64
|
-
redcarpet (~> 2.2
|
68
|
+
redcarpet (~> 2.2)
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,44 +1,118 @@
|
|
1
1
|
# At
|
2
2
|
|
3
|
-
`At` is a small library
|
4
|
-
if they were
|
3
|
+
`At` is a small library provides an `at` method for all Objects which allows you to access instance variables
|
4
|
+
on an object as if they were accessors for testing purposes, usually within test setups and teardowns.
|
5
|
+
|
6
|
+
## Install
|
7
|
+
|
8
|
+
### Bundler: `gem 'at'` in `group :test`
|
9
|
+
|
10
|
+
### RubyGems: `gem install at`
|
11
|
+
|
12
|
+
## Usage
|
13
|
+
|
14
|
+
### TL;DR
|
5
15
|
|
6
16
|
Basically, `at` directly translates this:
|
7
17
|
|
8
18
|
```ruby
|
9
|
-
value =
|
10
|
-
|
19
|
+
value = user.instance_eval { @name }
|
20
|
+
user.instance_eval { @name = "#{value}!" }
|
11
21
|
```
|
12
22
|
|
13
23
|
into this:
|
14
24
|
|
15
25
|
```ruby
|
16
|
-
value =
|
17
|
-
|
26
|
+
value = user.at.name
|
27
|
+
user.at.name = "#{value}!"
|
18
28
|
```
|
19
29
|
|
20
|
-
|
30
|
+
### Use Case
|
21
31
|
|
22
|
-
|
32
|
+
`lib/user.rb`
|
23
33
|
|
24
|
-
|
34
|
+
```ruby
|
35
|
+
class User
|
36
|
+
|
37
|
+
def initialize(first_name=nil, last_name=nil)
|
38
|
+
@first_name, @last_name = first_name, last_name
|
39
|
+
end
|
40
|
+
|
41
|
+
def full_name
|
42
|
+
[@first_name, @last_name].compact.join(" ")
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
```
|
25
47
|
|
26
|
-
|
48
|
+
`spec/spec_helper.rb`
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
require 'user'
|
52
|
+
require 'at/setup'
|
53
|
+
```
|
54
|
+
|
55
|
+
`spec/user_spec.rb`
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
describe User do
|
59
|
+
|
60
|
+
describe '#full_name' do
|
61
|
+
|
62
|
+
before :all do
|
63
|
+
subject.at.first_name = 'John'
|
64
|
+
subject.at.last_name = 'Doe'
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should output the full name correctly' do
|
68
|
+
subject.full_name.should == 'John Doe'
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
```
|
75
|
+
|
76
|
+
Check out the specs for a better usage example.
|
77
|
+
|
78
|
+
## FAQ
|
79
|
+
|
80
|
+
### Why is this named "At"?
|
27
81
|
|
28
|
-
|
29
|
-
below, I would normally have three options for testing all possible outcomes;
|
30
|
-
initialize a `User` object for each test case, initialize one `User` object and
|
31
|
-
use `instance_eval` to set the instance variables individually, or create
|
32
|
-
`attr_accessor`s for each instance variable I would like to test. In Rspec, I
|
33
|
-
can use `assigns` to test the value of the instance variable, but I can't
|
34
|
-
_get_ the value of the instance variable.
|
82
|
+
Because the at symbol (`@`) is how an instance variable is declared in Ruby!
|
35
83
|
|
36
|
-
`
|
84
|
+
### What if my class defines an `at` instance method?
|
85
|
+
|
86
|
+
`At` is included on the `Object` class, so when your class defines the `at` instance method, you are actually overwriting
|
87
|
+
the `At#at` method. Luckily, the `at` method is just an alias of the `_at` method, which you can use instead:
|
37
88
|
|
38
89
|
```ruby
|
39
|
-
|
90
|
+
describe Event do
|
91
|
+
|
92
|
+
describe "#at" do
|
93
|
+
|
94
|
+
let(:event_at) { DateTime.now }
|
95
|
+
|
96
|
+
before(:all) { subject._at.at = event_at }
|
97
|
+
|
98
|
+
it 'should return the DateTime the Event is happening' do
|
99
|
+
subject.at.should == event_at
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
```
|
40
106
|
|
107
|
+
### How can I include the `at` and `_at` methods on a single object?
|
108
|
+
|
109
|
+
Include `At` to the object's class:
|
110
|
+
|
111
|
+
`lib/user.rb`
|
112
|
+
|
113
|
+
```ruby
|
41
114
|
class User
|
115
|
+
|
42
116
|
def initialize(first_name=nil, last_name=nil)
|
43
117
|
@first_name, @last_name = first_name, last_name
|
44
118
|
end
|
@@ -46,19 +120,105 @@ class User
|
|
46
120
|
def full_name
|
47
121
|
[@first_name, @last_name].compact.join(" ")
|
48
122
|
end
|
123
|
+
|
49
124
|
end
|
125
|
+
```
|
126
|
+
|
127
|
+
`spec/spec_helper.rb`
|
50
128
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
129
|
+
```ruby
|
130
|
+
require 'user'
|
131
|
+
require 'at'
|
132
|
+
|
133
|
+
class User
|
134
|
+
include At
|
135
|
+
end
|
136
|
+
```
|
137
|
+
|
138
|
+
`spec/user_spec.rb`
|
139
|
+
|
140
|
+
```ruby
|
141
|
+
|
142
|
+
describe User do
|
143
|
+
|
144
|
+
describe '#full_name' do
|
145
|
+
|
146
|
+
before :all do
|
147
|
+
subject.at.first_name = 'John'
|
148
|
+
subject.at.last_name = 'Doe'
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'should output the full name correctly' do
|
152
|
+
subject.full_name.should == 'John Doe'
|
153
|
+
end
|
154
|
+
|
57
155
|
end
|
156
|
+
|
58
157
|
end
|
59
158
|
```
|
60
159
|
|
61
|
-
|
160
|
+
### How can I include the `at` method outside of a test environment?
|
161
|
+
|
162
|
+
Same premise as the above answer:
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
require 'at'
|
166
|
+
|
167
|
+
class User
|
168
|
+
|
169
|
+
include At
|
170
|
+
|
171
|
+
def initialize(first_name=nil, last_name=nil)
|
172
|
+
@first_name, @last_name = first_name, last_name
|
173
|
+
end
|
174
|
+
|
175
|
+
def full_name
|
176
|
+
[@first_name, @last_name].compact.join(" ")
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
```
|
181
|
+
|
182
|
+
### How can I use instance variable delegation without the `at` method?
|
183
|
+
|
184
|
+
Simply use `At::InstanceVariableDelegator`:
|
185
|
+
|
186
|
+
```ruby
|
187
|
+
require 'at/instance_variable_delegator'
|
188
|
+
|
189
|
+
class Application
|
190
|
+
|
191
|
+
class Config
|
192
|
+
attr_reader :hostname, :port
|
193
|
+
end
|
194
|
+
|
195
|
+
attr_reader :config
|
196
|
+
|
197
|
+
def initialize(&block)
|
198
|
+
@config = Config.new
|
199
|
+
|
200
|
+
configure(&block) if block_given?
|
201
|
+
end
|
202
|
+
|
203
|
+
def configure(&block)
|
204
|
+
raise ArgumentError, 'block must be supplied' unless block_given?
|
205
|
+
delegator = At::InstanceVariableDelegator.new(@config)
|
206
|
+
|
207
|
+
block.call(delegator)
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|
211
|
+
|
212
|
+
# Usage:
|
213
|
+
app = Application.new
|
214
|
+
app.configure do |c|
|
215
|
+
c.hostname = 'example.com'
|
216
|
+
c.port = 8080
|
217
|
+
end
|
218
|
+
|
219
|
+
p app.config.hostname # => 'example.com'
|
220
|
+
p app.config.port # => 8080
|
221
|
+
```
|
62
222
|
|
63
223
|
## Contributing
|
64
224
|
|
@@ -72,6 +232,6 @@ Check out the specs for a better usage example.
|
|
72
232
|
|
73
233
|
## Copyright
|
74
234
|
|
75
|
-
Copyright © 2012 Ryan Scott Lewis <ryan@rynet.us>.
|
235
|
+
Copyright © 2012-2013 Ryan Scott Lewis <ryan@rynet.us>.
|
76
236
|
|
77
|
-
The MIT License (MIT) - See LICENSE for further details.
|
237
|
+
The MIT License (MIT) - See LICENSE for further details.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/at.gemspec
CHANGED
@@ -2,14 +2,14 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "at"
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.2.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Ryan Scott Lewis"]
|
9
|
-
s.date = "
|
9
|
+
s.date = "2013-02-16"
|
10
10
|
s.description = "Make instance variables accessible for testing purposes."
|
11
11
|
s.email = "ryan@rynet.us"
|
12
|
-
s.files = [".
|
12
|
+
s.files = [".gitignore", ".rvmrc", "Gemfile", "Gemfile.lock", "Guardfile", "LICENSE", "README.md", "Rakefile", "VERSION", "at.gemspec", "lib/at.rb", "lib/at/instance_variable_delegator.rb", "lib/at/setup.rb", "spec/at_spec.rb", "spec/spec_helper.rb"]
|
13
13
|
s.homepage = "http://github.com/RyanScottLewis/at"
|
14
14
|
s.require_paths = ["lib"]
|
15
15
|
s.rubygems_version = "1.8.24"
|
data/lib/at.rb
CHANGED
@@ -1,39 +1,17 @@
|
|
1
1
|
require 'version'
|
2
2
|
|
3
|
+
# `At` is a small library provides an `at` method for all Objects which allows you to access instance variables
|
4
|
+
# on an object as if they were accessors for testing purposes, usually within test setups and teardowns
|
3
5
|
module At
|
4
|
-
|
5
6
|
is_versioned
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
12
|
-
|
13
|
-
def method_missing(meth, *args)
|
14
|
-
@parent.instance_eval do
|
15
|
-
|
16
|
-
if match = meth.to_s.match(/(.*)\=$/)
|
17
|
-
value = args.length == 1 ? args.first : args
|
18
|
-
instance_variable_set("@#{match[1]}", value)
|
19
|
-
else
|
20
|
-
if args.empty?
|
21
|
-
instance_variable_get("@#{meth}")
|
22
|
-
else
|
23
|
-
value = args.length == 1 ? args.first : args
|
24
|
-
instance_variable_set("@#{meth}", value)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
8
|
+
require 'at/instance_variable_delegator'
|
9
|
+
# @return [InstanceVariableDelegator] The memoized InstanceVariableDelegator proxy instance for this Object instance
|
10
|
+
def _at
|
11
|
+
@_at ||= InstanceVariableDelegator.new(self)
|
31
12
|
end
|
32
13
|
|
33
|
-
|
34
|
-
@_method_to_instance_variable_proxy ||= MethodToInstanceVariableProxy.new(self)
|
35
|
-
end
|
14
|
+
alias_method :at, :_at
|
36
15
|
|
37
16
|
end
|
38
17
|
|
39
|
-
require 'at/import'
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module At
|
2
|
+
|
3
|
+
# InstanceVariableDelegator is a simply class which delegates it's methods it an object's instance variables.
|
4
|
+
class InstanceVariableDelegator
|
5
|
+
|
6
|
+
# @param [Object] parent The object to delegate accessors to it's instance variables.
|
7
|
+
def initialize(parent)
|
8
|
+
@parent = parent
|
9
|
+
end
|
10
|
+
|
11
|
+
# If the method ends with an equal sign (`=`), we will set the instance variable on the @parent object.
|
12
|
+
# Otherwise, we will /get/ the instance variable on the @parent object.
|
13
|
+
def method_missing(meth, value=nil)
|
14
|
+
@parent.instance_eval do
|
15
|
+
match = meth.to_s.match(/(.*)\=$/)
|
16
|
+
raise ArgumentError, '`value` must be given' if match && value.nil?
|
17
|
+
raise ArgumentError, '`value` must not be given' if !match && !value.nil?
|
18
|
+
|
19
|
+
match ? instance_variable_set("@#{match[1]}", value) : instance_variable_get("@#{meth}")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/lib/at/setup.rb
ADDED
data/spec/at_spec.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
+
# TODO: Move classes to spec/support
|
4
|
+
|
3
5
|
class Configuration
|
4
6
|
attr_reader :configuration
|
5
7
|
|
@@ -9,13 +11,17 @@ class Configuration
|
|
9
11
|
end
|
10
12
|
|
11
13
|
describe Configuration do
|
14
|
+
|
12
15
|
describe "#configuration" do
|
16
|
+
|
13
17
|
it "should return the @configuration instance variable" do
|
14
18
|
subject.configuration.should == "default"
|
15
19
|
subject.at.configuration = "the result"
|
16
20
|
subject.configuration.should == "the result"
|
17
21
|
end
|
22
|
+
|
18
23
|
end
|
24
|
+
|
19
25
|
end
|
20
26
|
|
21
27
|
#===-----------------------------------------------------------------------===#
|
@@ -31,6 +37,7 @@ class User
|
|
31
37
|
end
|
32
38
|
|
33
39
|
describe User do
|
40
|
+
|
34
41
|
describe "#initialize" do
|
35
42
|
subject { User.new("John", "Doe") }
|
36
43
|
|
@@ -60,6 +67,7 @@ describe User do
|
|
60
67
|
Proc.new { subject.last_name }.should raise_error(NoMethodError)
|
61
68
|
end
|
62
69
|
end
|
70
|
+
|
63
71
|
end
|
64
72
|
|
65
73
|
#===-----------------------------------------------------------------------===#
|
@@ -102,4 +110,69 @@ describe Twitter do
|
|
102
110
|
Twitter.search(:q => "test").should == "{'some':'json response'}"
|
103
111
|
end
|
104
112
|
end
|
105
|
-
end
|
113
|
+
end
|
114
|
+
|
115
|
+
#===-----------------------------------------------------------------------===#
|
116
|
+
|
117
|
+
# This class has it's own `at` method
|
118
|
+
class Event
|
119
|
+
|
120
|
+
attr_reader :at
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
describe Event do
|
125
|
+
|
126
|
+
let(:event_at) { DateTime.now }
|
127
|
+
|
128
|
+
before(:all) { subject._at.at = event_at }
|
129
|
+
|
130
|
+
describe "#at" do
|
131
|
+
|
132
|
+
it 'should return the DateTime the Event is happening' do
|
133
|
+
subject.at.should == event_at
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
|
142
|
+
|
143
|
+
|
144
|
+
|
145
|
+
|
146
|
+
|
147
|
+
|
148
|
+
# class Application
|
149
|
+
#
|
150
|
+
# class Config
|
151
|
+
# attr_reader :hostname, :port
|
152
|
+
# end
|
153
|
+
#
|
154
|
+
# attr_reader :config
|
155
|
+
#
|
156
|
+
# def initialize(&block)
|
157
|
+
# @config = Config.new
|
158
|
+
#
|
159
|
+
# configure(&block) if block_given?
|
160
|
+
# end
|
161
|
+
#
|
162
|
+
# def configure(&block)
|
163
|
+
# raise ArgumentError, 'block must be supplied' unless block_given?
|
164
|
+
# delegator = At::InstanceVariableDelegator.new(@config)
|
165
|
+
#
|
166
|
+
# block.call(delegator)
|
167
|
+
# end
|
168
|
+
#
|
169
|
+
# end
|
170
|
+
#
|
171
|
+
# app = Application.new
|
172
|
+
# app.configure do |c|
|
173
|
+
# c.hostname = 'example.com'
|
174
|
+
# c.port = 8080
|
175
|
+
# end
|
176
|
+
#
|
177
|
+
# p app.config.hostname # => 'example.com'
|
178
|
+
# p app.config.port # => 8080
|
data/spec/spec_helper.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
require 'bundler/setup'
|
2
|
-
require 'at'
|
2
|
+
require 'at/setup'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: at
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-02-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: version
|
@@ -145,9 +145,8 @@ executables: []
|
|
145
145
|
extensions: []
|
146
146
|
extra_rdoc_files: []
|
147
147
|
files:
|
148
|
-
- .
|
149
|
-
- .
|
150
|
-
- .yardoc/proxy_types
|
148
|
+
- .gitignore
|
149
|
+
- .rvmrc
|
151
150
|
- Gemfile
|
152
151
|
- Gemfile.lock
|
153
152
|
- Guardfile
|
@@ -157,7 +156,8 @@ files:
|
|
157
156
|
- VERSION
|
158
157
|
- at.gemspec
|
159
158
|
- lib/at.rb
|
160
|
-
- lib/at/
|
159
|
+
- lib/at/instance_variable_delegator.rb
|
160
|
+
- lib/at/setup.rb
|
161
161
|
- spec/at_spec.rb
|
162
162
|
- spec/spec_helper.rb
|
163
163
|
homepage: http://github.com/RyanScottLewis/at
|
@@ -172,6 +172,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
172
172
|
- - ! '>='
|
173
173
|
- !ruby/object:Gem::Version
|
174
174
|
version: '0'
|
175
|
+
segments:
|
176
|
+
- 0
|
177
|
+
hash: -1052782577
|
175
178
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
176
179
|
none: false
|
177
180
|
requirements:
|
data/.yardoc/object_types
DELETED
Binary file
|
data/.yardoc/objects/root.dat
DELETED
Binary file
|
data/.yardoc/proxy_types
DELETED
Binary file
|